Skip to content

Commit ec7a594

Browse files
committed
drivers: ethernet: adin2111: add support for hardware reset
Add support for hardware reset via GPIO in the ADIN2111 PHY driver. The reset pin is configured via device tree using the reset-gpios property. Signed-off-by: Tim Pambor <[email protected]>
1 parent 16f4d6c commit ec7a594

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

drivers/ethernet/phy/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ config PHY_ADIN2111
4242
default y
4343
depends on DT_HAS_ADI_ADIN2111_PHY_ENABLED || DT_HAS_ADI_ADIN1100_PHY_ENABLED
4444
select MDIO
45+
select GPIO if ($(dt_compat_any_has_prop,$(DT_COMPAT_ADI_ADIN2111_PHY),reset-gpios) || \
46+
$(dt_compat_any_has_prop,$(DT_COMPAT_ADI_ADIN1100_PHY),reset-gpios))
4547
help
4648
Enable ADIN2111 PHY driver.
4749

drivers/ethernet/phy/phy_adin2111.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <stdbool.h>
1111
#include <zephyr/kernel.h>
1212
#include <zephyr/device.h>
13+
#include <zephyr/drivers/gpio.h>
1314
#include <zephyr/drivers/mdio.h>
1415
#include <zephyr/logging/log.h>
1516
#include <zephyr/net/mdio.h>
@@ -20,6 +21,14 @@
2021

2122
LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL);
2223

24+
/*
25+
* Only compile in support for the optional GPIOs if at least one enabled device tree node
26+
* has them.
27+
*/
28+
#define ADIN2111_RST_GPIO_SUPPORT \
29+
(DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) || \
30+
DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin2111_phy, reset_gpios))
31+
2332
/* PHYs out of reset check retry delay */
2433
#define ADIN2111_PHY_AWAIT_DELAY_POLL_US 15U
2534
/*
@@ -36,6 +45,8 @@ LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL);
3645

3746
/* Software reset, CLK_25 disabled time*/
3847
#define ADIN1100_PHY_SFT_RESET_MS 25U
48+
#define ADIN1100_PHY_HRD_RESET_MS 70U
49+
#define ADIN1100_PHY_HRD_RESET_PULSE_WIDTH_US 50U
3950

4051
/* PHYs autonegotiation complete timeout */
4152
#define ADIN2111_AN_COMPLETE_AWAIT_TIMEOUT_MS 3000U
@@ -90,6 +101,9 @@ LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL);
90101

91102
struct phy_adin2111_config {
92103
const struct device *mdio;
104+
#if ADIN2111_RST_GPIO_SUPPORT
105+
const struct gpio_dt_spec reset_gpio;
106+
#endif /* ADIN2111_RST_GPIO_SUPPORT */
93107
uint8_t phy_addr;
94108
bool led0_en;
95109
bool led1_en;
@@ -352,6 +366,30 @@ static int phy_adin2111_reset(const struct device *dev)
352366
{
353367
int ret;
354368

369+
#if ADIN2111_RST_GPIO_SUPPORT
370+
const struct phy_adin2111_config *config = dev->config;
371+
372+
if (config->reset_gpio.port) {
373+
/* Assert reset (min. reset pulse width 10us) */
374+
ret = gpio_pin_set_dt(&config->reset_gpio, 1);
375+
if (ret < 0) {
376+
return ret;
377+
}
378+
k_busy_wait(ADIN1100_PHY_HRD_RESET_PULSE_WIDTH_US);
379+
380+
/* Deassert reset */
381+
ret = gpio_pin_set_dt(&config->reset_gpio, 0);
382+
if (ret < 0) {
383+
return ret;
384+
}
385+
386+
k_msleep(ADIN1100_PHY_HRD_RESET_MS);
387+
388+
return 0;
389+
}
390+
#endif /* ADIN2111_RST_GPIO_SUPPORT */
391+
392+
/* Perform software reset */
355393
ret = phy_adin2111_c22_write(dev, MII_BMCR, MII_BMCR_RESET);
356394
if (ret < 0) {
357395
return ret;
@@ -439,6 +477,15 @@ static int phy_adin2111_init(const struct device *dev)
439477
data->state.is_up = false;
440478
data->state.speed = LINK_FULL_10BASE;
441479

480+
#if ADIN2111_RST_GPIO_SUPPORT
481+
if (cfg->reset_gpio.port) {
482+
ret = gpio_pin_configure_dt(&cfg->reset_gpio, GPIO_OUTPUT_INACTIVE);
483+
if (ret < 0) {
484+
return ret;
485+
}
486+
}
487+
#endif /* ADIN2111_RST_GPIO_SUPPORT */
488+
442489
/*
443490
* For adin1100 and further mii stuff,
444491
* reset may not be performed from the mac layer, doing a clean reset here.
@@ -617,9 +664,17 @@ static DEVICE_API(ethphy, phy_adin2111_api) = {
617664
.write = phy_adin2111_reg_write,
618665
};
619666

667+
#if ADIN2111_RST_GPIO_SUPPORT
668+
#define RESET_GPIO(n) \
669+
.reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}),
670+
#else
671+
#define RESET_GPIO(n)
672+
#endif /* reset gpio */
673+
620674
#define ADIN2111_PHY_INITIALIZE(n, model) \
621675
static const struct phy_adin2111_config phy_adin##model##_config_##n = { \
622676
.mdio = DEVICE_DT_GET(DT_INST_BUS(n)), \
677+
RESET_GPIO(n) \
623678
.phy_addr = DT_INST_REG_ADDR(n), \
624679
.led0_en = DT_INST_PROP(n, led0_en), \
625680
.led1_en = DT_INST_PROP(n, led1_en), \

dts/bindings/ethernet/phy/adi,adin2111-phy.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ properties:
1313
reg:
1414
required: true
1515
description: 5-bit physical/port address (PRTAD).
16+
reset-gpios:
17+
type: phandle-array
18+
description: GPIO connected to PHY reset signal pin. Reset is active low.
1619
led0-en:
1720
type: boolean
1821
description: Enable LED 0.

0 commit comments

Comments
 (0)