b3f950c648
At present, many of the NXP S32 shim drivers do not make use of devicetree instance-based macros because the NXP S32 HAL relies on an index-based approach, requiring knowledge of the peripheral instance index during both compilation and runtime, and this index might not align with the devicetree instance index. The proposed solution in this patch eliminates this limitation by determining the peripheral instance index during compilation through macrobatics and defining the driver's ISR within the shim driver itself. Note that for some peripheral instances is needed to redefine the HAL macros of the peripheral base address, since the naming is not uniform for all instances. Signed-off-by: Manuel Argüelles <manuel.arguelles@nxp.com>
106 lines
2.9 KiB
C
106 lines
2.9 KiB
C
/*
|
|
* Copyright 2022-2023 NXP
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#define DT_DRV_COMPAT nxp_s32_netc_emdio
|
|
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/drivers/mdio.h>
|
|
#include <zephyr/drivers/pinctrl.h>
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_REGISTER(nxp_s32_emdio, CONFIG_MDIO_LOG_LEVEL);
|
|
|
|
#include <Netc_EthSwt_Ip.h>
|
|
|
|
struct nxp_s32_mdio_config {
|
|
const struct pinctrl_dev_config *pincfg;
|
|
uint8_t instance;
|
|
};
|
|
|
|
struct nxp_s32_mdio_data {
|
|
struct k_mutex rw_mutex;
|
|
};
|
|
|
|
static int nxp_s32_mdio_read(const struct device *dev, uint8_t prtad,
|
|
uint8_t regad, uint16_t *regval)
|
|
{
|
|
const struct nxp_s32_mdio_config *cfg = dev->config;
|
|
struct nxp_s32_mdio_data *data = dev->data;
|
|
Std_ReturnType status;
|
|
|
|
k_mutex_lock(&data->rw_mutex, K_FOREVER);
|
|
status = Netc_EthSwt_Ip_ReadTrcvRegister(cfg->instance, prtad, regad, regval);
|
|
k_mutex_unlock(&data->rw_mutex);
|
|
|
|
return status == E_OK ? 0 : -EIO;
|
|
}
|
|
|
|
static int nxp_s32_mdio_write(const struct device *dev, uint8_t prtad,
|
|
uint8_t regad, uint16_t regval)
|
|
{
|
|
const struct nxp_s32_mdio_config *cfg = dev->config;
|
|
struct nxp_s32_mdio_data *data = dev->data;
|
|
Std_ReturnType status;
|
|
|
|
k_mutex_lock(&data->rw_mutex, K_FOREVER);
|
|
status = Netc_EthSwt_Ip_WriteTrcvRegister(cfg->instance, prtad, regad, regval);
|
|
k_mutex_unlock(&data->rw_mutex);
|
|
|
|
return status == E_OK ? 0 : -EIO;
|
|
}
|
|
|
|
static int nxp_s32_mdio_initialize(const struct device *dev)
|
|
{
|
|
struct nxp_s32_mdio_data *data = dev->data;
|
|
const struct nxp_s32_mdio_config *cfg = dev->config;
|
|
int err;
|
|
|
|
err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT);
|
|
if (err != 0) {
|
|
return err;
|
|
}
|
|
|
|
k_mutex_init(&data->rw_mutex);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void nxp_s32_mdio_noop(const struct device *dev)
|
|
{
|
|
/* intentionally left empty */
|
|
}
|
|
|
|
static const struct mdio_driver_api nxp_s32_mdio_api = {
|
|
.read = nxp_s32_mdio_read,
|
|
.write = nxp_s32_mdio_write,
|
|
/* NETC does not support enabling/disabling EMDIO controller independently */
|
|
.bus_enable = nxp_s32_mdio_noop,
|
|
.bus_disable = nxp_s32_mdio_noop,
|
|
};
|
|
|
|
#define NXP_S32_MDIO_HW_INSTANCE_CHECK(i, n) \
|
|
((DT_INST_REG_ADDR(n) == IP_NETC_EMDIO_##n##_BASE) ? i : 0)
|
|
|
|
#define NXP_S32_MDIO_HW_INSTANCE(n) \
|
|
LISTIFY(__DEBRACKET NETC_F1_INSTANCE_COUNT, NXP_S32_MDIO_HW_INSTANCE_CHECK, (|), n)
|
|
|
|
#define NXP_S32_MDIO_INSTANCE_DEFINE(n) \
|
|
PINCTRL_DT_INST_DEFINE(n); \
|
|
static struct nxp_s32_mdio_data nxp_s32_mdio##n##_data; \
|
|
static const struct nxp_s32_mdio_config nxp_s32_mdio##n##_cfg = { \
|
|
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
|
|
.instance = NXP_S32_MDIO_HW_INSTANCE(n), \
|
|
}; \
|
|
DEVICE_DT_INST_DEFINE(n, \
|
|
&nxp_s32_mdio_initialize, \
|
|
NULL, \
|
|
&nxp_s32_mdio##n##_data, \
|
|
&nxp_s32_mdio##n##_cfg, \
|
|
POST_KERNEL, \
|
|
CONFIG_MDIO_INIT_PRIORITY, \
|
|
&nxp_s32_mdio_api);
|
|
|
|
DT_INST_FOREACH_STATUS_OKAY(NXP_S32_MDIO_INSTANCE_DEFINE)
|