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>
@@ -36,6 +37,8 @@ LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL);
3637
3738/* Software reset, CLK_25 disabled time*/
3839#define ADIN1100_PHY_SFT_RESET_MS 25U
40+ #define ADIN1100_PHY_HRD_RESET_MS 70U
41+ #define ADIN1100_PHY_HRD_RESET_PULSE_WIDTH_US 16U
3942
4043/* PHYs autonegotiation complete timeout */
4144#define ADIN2111_AN_COMPLETE_AWAIT_TIMEOUT_MS 3000U
@@ -90,6 +93,9 @@ LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL);
9093
9194struct phy_adin2111_config {
9295 const struct device * mdio ;
96+ #if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY (adi_adin1100_phy , reset_gpios )
97+ const struct gpio_dt_spec reset_gpio ;
98+ #endif /* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) */
9399 uint8_t phy_addr ;
94100 bool led0_en ;
95101 bool led1_en ;
@@ -352,6 +358,30 @@ static int phy_adin2111_reset(const struct device *dev)
352358{
353359 int ret ;
354360
361+ #if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY (adi_adin1100_phy , reset_gpios )
362+ const struct phy_adin2111_config * config = dev -> config ;
363+
364+ if (config -> reset_gpio .port != NULL ) {
365+ /* Assert reset (min. reset pulse width 10us) */
366+ ret = gpio_pin_set_dt (& config -> reset_gpio , 1 );
367+ if (ret < 0 ) {
368+ return ret ;
369+ }
370+ k_busy_wait (ADIN1100_PHY_HRD_RESET_PULSE_WIDTH_US );
371+
372+ /* Deassert reset */
373+ ret = gpio_pin_set_dt (& config -> reset_gpio , 0 );
374+ if (ret < 0 ) {
375+ return ret ;
376+ }
377+
378+ k_msleep (ADIN1100_PHY_HRD_RESET_MS );
379+
380+ return 0 ;
381+ }
382+ #endif /* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) */
383+
384+ /* Perform software reset */
355385 ret = phy_adin2111_c22_write (dev , MII_BMCR , MII_BMCR_RESET );
356386 if (ret < 0 ) {
357387 return ret ;
@@ -439,6 +469,15 @@ static int phy_adin2111_init(const struct device *dev)
439469 data -> state .is_up = false;
440470 data -> state .speed = LINK_FULL_10BASE ;
441471
472+ #if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY (adi_adin1100_phy , reset_gpios )
473+ if (cfg -> reset_gpio .port != NULL ) {
474+ ret = gpio_pin_configure_dt (& cfg -> reset_gpio , GPIO_OUTPUT_INACTIVE );
475+ if (ret < 0 ) {
476+ return ret ;
477+ }
478+ }
479+ #endif /* DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(adi_adin1100_phy, reset_gpios) */
480+
442481 /*
443482 * For adin1100 and further mii stuff,
444483 * reset may not be performed from the mac layer, doing a clean reset here.
@@ -617,9 +656,17 @@ static DEVICE_API(ethphy, phy_adin2111_api) = {
617656 .write = phy_adin2111_reg_write ,
618657};
619658
659+ #if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY (adi_adin1100_phy , reset_gpios )
660+ #define RESET_GPIO (n ) \
661+ .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}),
662+ #else
663+ #define RESET_GPIO (n )
664+ #endif /* reset gpio */
665+
620666#define ADIN2111_PHY_INITIALIZE (n , model ) \
621667 static const struct phy_adin2111_config phy_adin##model##_config_##n = { \
622668 .mdio = DEVICE_DT_GET(DT_INST_BUS(n)), \
669+ RESET_GPIO(n) \
623670 .phy_addr = DT_INST_REG_ADDR(n), \
624671 .led0_en = DT_INST_PROP(n, led0_en), \
625672 .led1_en = DT_INST_PROP(n, led1_en), \
0 commit comments