diff --git a/drivers/mdio/CMakeLists.txt b/drivers/mdio/CMakeLists.txt index 4a16b4c36ca..bb939287e3d 100644 --- a/drivers/mdio/CMakeLists.txt +++ b/drivers/mdio/CMakeLists.txt @@ -5,3 +5,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_MDIO_SHELL mdio_shell.c) zephyr_library_sources_ifdef(CONFIG_MDIO_ATMEL_SAM mdio_sam.c) zephyr_library_sources_ifdef(CONFIG_MDIO_ESP32 mdio_esp32.c) +zephyr_library_sources_ifdef(CONFIG_MDIO_NXP_S32_NETC mdio_nxp_s32_netc.c) diff --git a/drivers/mdio/Kconfig b/drivers/mdio/Kconfig index 15fbead025f..603efb5ee64 100644 --- a/drivers/mdio/Kconfig +++ b/drivers/mdio/Kconfig @@ -27,6 +27,7 @@ config MDIO_SHELL # overridden (by defining symbols in multiple locations) source "drivers/mdio/Kconfig.esp32" source "drivers/mdio/Kconfig.sam" +source "drivers/mdio/Kconfig.nxp_s32" config MDIO_INIT_PRIORITY int "Init priority" diff --git a/drivers/mdio/Kconfig.nxp_s32 b/drivers/mdio/Kconfig.nxp_s32 new file mode 100644 index 00000000000..e13b1b5b2ef --- /dev/null +++ b/drivers/mdio/Kconfig.nxp_s32 @@ -0,0 +1,10 @@ +# Copyright 2022 NXP +# SPDX-License-Identifier: Apache-2.0 + +config MDIO_NXP_S32_NETC + bool "NXP S32 NETC External MDIO driver" + default y + depends on DT_HAS_NXP_S32_NETC_EMDIO_ENABLED + select NOCACHE_MEMORY + help + Enable NETC External MDIO Controller driver for NXP S32 SoCs. diff --git a/drivers/mdio/mdio_nxp_s32_netc.c b/drivers/mdio/mdio_nxp_s32_netc.c new file mode 100644 index 00000000000..4ce88ac96f7 --- /dev/null +++ b/drivers/mdio/mdio_nxp_s32_netc.c @@ -0,0 +1,110 @@ +/* + * Copyright 2022 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +LOG_MODULE_REGISTER(nxp_s32_emdio, CONFIG_MDIO_LOG_LEVEL); + +#include + +#define MDIO_NODE DT_NODELABEL(emdio) +#define NETC_SWT_IDX 0 + +struct nxp_s32_mdio_config { + int protocol; + const struct pinctrl_dev_config *pincfg; +}; + +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 devad, uint16_t *regval) +{ + const struct nxp_s32_mdio_config *const cfg = dev->config; + struct nxp_s32_mdio_data *data = dev->data; + Std_ReturnType status; + + if (cfg->protocol != CLAUSE_22) { + LOG_ERR("Unsupported protocol"); + return -ENOTSUP; + } + + k_mutex_lock(&data->rw_mutex, K_FOREVER); + status = Netc_EthSwt_Ip_ReadTrcvRegister(NETC_SWT_IDX, prtad, devad, 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 devad, uint16_t regval) +{ + const struct nxp_s32_mdio_config *const cfg = dev->config; + struct nxp_s32_mdio_data *data = dev->data; + Std_ReturnType status; + + if (cfg->protocol != CLAUSE_22) { + LOG_ERR("Unsupported protocol"); + return -ENOTSUP; + } + + k_mutex_lock(&data->rw_mutex, K_FOREVER); + status = Netc_EthSwt_Ip_WriteTrcvRegister(NETC_SWT_IDX, prtad, devad, 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, +}; + +PINCTRL_DT_DEFINE(MDIO_NODE); + +static struct nxp_s32_mdio_data nxp_s32_mdio0_data; + +static const struct nxp_s32_mdio_config nxp_s32_mdio0_cfg = { + .protocol = DT_ENUM_IDX(MDIO_NODE, protocol), + .pincfg = PINCTRL_DT_DEV_CONFIG_GET(MDIO_NODE), +}; + +DEVICE_DT_DEFINE(MDIO_NODE, + &nxp_s32_mdio_initialize, + NULL, + &nxp_s32_mdio0_data, + &nxp_s32_mdio0_cfg, + POST_KERNEL, + CONFIG_MDIO_INIT_PRIORITY, + &nxp_s32_mdio_api); diff --git a/drivers/mdio/mdio_shell.c b/drivers/mdio/mdio_shell.c index 6e7d274ef57..6ea87d7017a 100644 --- a/drivers/mdio/mdio_shell.c +++ b/drivers/mdio/mdio_shell.c @@ -18,6 +18,8 @@ LOG_MODULE_REGISTER(mdio_shell, CONFIG_LOG_DEFAULT_LEVEL); #define DT_DRV_COMPAT atmel_sam_mdio #elif DT_HAS_COMPAT_STATUS_OKAY(espressif_esp32_mdio) #define DT_DRV_COMPAT espressif_esp32_mdio +#elif DT_HAS_COMPAT_STATUS_OKAY(nxp_s32_netc_emdio) +#define DT_DRV_COMPAT nxp_s32_netc_emdio #else #error "No known devicetree compatible match for MDIO shell" #endif diff --git a/dts/bindings/mdio/nxp,s32-netc-emdio.yaml b/dts/bindings/mdio/nxp,s32-netc-emdio.yaml new file mode 100644 index 00000000000..2b3f1aff327 --- /dev/null +++ b/dts/bindings/mdio/nxp,s32-netc-emdio.yaml @@ -0,0 +1,18 @@ +# Copyright 2022 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP S32 NETC External MDIO controller + +compatible: "nxp,s32-netc-emdio" + +include: [mdio-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true