Commit fe29929c authored by Angelo Dureghello's avatar Angelo Dureghello Committed by Alberto Escolar
Browse files

drivers: mdio: add stm32 mdio support



MDIO is part of the ETH IP, but some phy chip may need a
specific phy driver to set up certain vendor registers enabling
particular features.

Add support for stm32 mdio access.

Signed-off-by: default avatarAngelo Dureghello <adureghello@baylibre.com>
parent b2f43210
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10,5 +10,6 @@ zephyr_library_sources_ifdef(CONFIG_MDIO_NXP_S32_GMAC mdio_nxp_s32_gmac.c)
zephyr_library_sources_ifdef(CONFIG_MDIO_ADIN2111	mdio_adin2111.c)
zephyr_library_sources_ifdef(CONFIG_MDIO_GPIO		mdio_gpio.c)
zephyr_library_sources_ifdef(CONFIG_MDIO_NXP_ENET	mdio_nxp_enet.c)
zephyr_library_sources_ifdef(CONFIG_MDIO_ST_STM32_HAL	mdio_stm32_hal.c)
zephyr_library_sources_ifdef(CONFIG_MDIO_INFINEON_XMC4XXX mdio_xmc4xxx.c)
zephyr_library_sources_ifdef(CONFIG_MDIO_NXP_ENET_QOS	mdio_nxp_enet_qos.c)
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ source "drivers/mdio/Kconfig.nxp_s32_gmac"
source "drivers/mdio/Kconfig.adin2111"
source "drivers/mdio/Kconfig.gpio"
source "drivers/mdio/Kconfig.nxp_enet"
source "drivers/mdio/Kconfig.stm32_hal"
source "drivers/mdio/Kconfig.xmc4xxx"
source "drivers/mdio/Kconfig.nxp_enet_qos"

+11 −0
Original line number Diff line number Diff line
# Copyright (c) 2024 BayLibre, SAS
# Copyright (c) 2024 Analog Devices Inc.
# SPDX-License-Identifier: Apache-2.0

config MDIO_ST_STM32_HAL
	bool "STM32 MDIO controller driver"
	default y
	depends on ETH_STM32_HAL_API_V2
	depends on DT_HAS_ST_STM32_MDIO_ENABLED
	help
	  Enable STM32 MDIO support.
+123 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2024 BayLibre, SAS
 * Copyright (c) 2024 Analog Devices Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdint.h>
#include <errno.h>
#include <zephyr/device.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/mdio.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/mdio.h>

#include <zephyr/logging/log.h>
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)
+24 −0
Original line number Diff line number Diff line
# Copyright (c) 2024 BayLibre, SAS
# Copyright (c) 2024 Analog Devices Inc.
# SPDX-License-Identifier: Apache-2.0

description: ST MDIO Features

compatible: "st,stm32-mdio"

include: [mdio-controller.yaml, pinctrl-device.yaml]

properties:
  "#address-cells":
    required: true
    const: 1

  "#size-cells":
    required: true
    const: 0

  pinctrl-0:
    required: true

  pinctrl-names:
    required: true