/* * Copyright (c) 2024 BayLibre, SAS * Copyright (c) 2024 Analog Devices Inc. * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include #include #include #include LOG_MODULE_REGISTER(mdio_stm32_hal, CONFIG_MDIO_LOG_LEVEL); #define DT_DRV_COMPAT st_stm32_mdio #define ADIN1100_REG_VALUE_MASK GENMASK(15, 0) struct mdio_stm32_data { struct k_sem sem; ETH_HandleTypeDef heth; }; struct mdio_stm32_config { const struct pinctrl_dev_config *pincfg; }; static int mdio_stm32_read(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t *data) { struct mdio_stm32_data *const dev_data = dev->data; ETH_HandleTypeDef *heth = &dev_data->heth; uint32_t read; int ret; k_sem_take(&dev_data->sem, K_FOREVER); ret = HAL_ETH_ReadPHYRegister(heth, prtad, regad, &read); k_sem_give(&dev_data->sem); if (ret != HAL_OK) { return -EIO; } *data = read & ADIN1100_REG_VALUE_MASK; return ret; } static int mdio_stm32_write(const struct device *dev, uint8_t prtad, uint8_t regad, uint16_t data) { struct mdio_stm32_data *const dev_data = dev->data; ETH_HandleTypeDef *heth = &dev_data->heth; int ret; k_sem_take(&dev_data->sem, K_FOREVER); ret = HAL_ETH_WritePHYRegister(heth, prtad, regad, data); k_sem_give(&dev_data->sem); if (ret != HAL_OK) { return -EIO; } return ret; } static void mdio_stm32_bus_enable(const struct device *dev) { ARG_UNUSED(dev); } static void mdio_stm32_bus_disable(const struct device *dev) { ARG_UNUSED(dev); } static int mdio_stm32_init(const struct device *dev) { struct mdio_stm32_data *const dev_data = dev->data; const struct mdio_stm32_config *const config = dev->config; int ret; ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); if (ret < 0) { return ret; } k_sem_init(&dev_data->sem, 1, 1); return 0; } static const struct mdio_driver_api mdio_stm32_api = { .read = mdio_stm32_read, .write = mdio_stm32_write, .bus_enable = mdio_stm32_bus_enable, .bus_disable = mdio_stm32_bus_disable, }; #define MDIO_STM32_HAL_DEVICE(inst) \ PINCTRL_DT_INST_DEFINE(inst); \ \ static struct mdio_stm32_data mdio_stm32_data_##inst = { \ .heth = {.Instance = (ETH_TypeDef *)DT_REG_ADDR(DT_INST_PARENT(inst))}, \ }; \ static struct mdio_stm32_config mdio_stm32_config_##inst = { \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ }; \ DEVICE_DT_INST_DEFINE(inst, &mdio_stm32_init, NULL, \ &mdio_stm32_data_##inst, &mdio_stm32_config_##inst, \ POST_KERNEL, CONFIG_ETH_INIT_PRIORITY, \ &mdio_stm32_api); DT_INST_FOREACH_STATUS_OKAY(MDIO_STM32_HAL_DEVICE)