1111#include <zephyr/device.h>
1212#include <zephyr/init.h>
1313#include <zephyr/kernel.h>
14+ #include <zephyr/drivers/gpio.h>
1415#include <zephyr/drivers/mdio.h>
1516#include <zephyr/net/phy.h>
1617#include <zephyr/net/mii.h>
@@ -22,6 +23,7 @@ LOG_MODULE_REGISTER(phy_mii, CONFIG_PHY_LOG_LEVEL);
2223
2324#define ANY_DYNAMIC_LINK UTIL_NOT(DT_ALL_INST_HAS_PROP_STATUS_OKAY(fixed_link))
2425#define ANY_FIXED_LINK DT_ANY_INST_HAS_PROP_STATUS_OKAY(fixed_link)
26+ #define ANY_RESET_GPIO DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
2527
2628struct phy_mii_dev_config {
2729 uint8_t phy_addr ;
@@ -30,6 +32,11 @@ struct phy_mii_dev_config {
3032 int fixed_speed ;
3133 enum phy_link_speed default_speeds ;
3234 const struct device * const mdio ;
35+ #if ANY_RESET_GPIO
36+ const struct gpio_dt_spec reset_gpio ;
37+ uint32_t reset_assert_duration_us ;
38+ uint32_t reset_deassertion_timeout_ms ;
39+ #endif /* ANY_RESET_GPIO */
3340};
3441
3542struct phy_mii_dev_data {
@@ -120,6 +127,33 @@ static int reset(const struct device *dev)
120127 uint32_t timeout = 12U ;
121128 uint16_t value ;
122129
130+ #if ANY_RESET_GPIO
131+ const struct phy_mii_dev_config * const cfg = dev -> config ;
132+ int ret ;
133+
134+ if (gpio_is_ready_dt (& cfg -> reset_gpio )) {
135+ /* Issue a hard reset */
136+ ret = gpio_pin_configure_dt (& cfg -> reset_gpio , GPIO_OUTPUT_ACTIVE );
137+ if (ret < 0 ) {
138+ LOG_ERR ("Failed to configure RST pin (%d)" , ret );
139+ return ret ;
140+ }
141+
142+ /* assertion time */
143+ k_busy_wait (cfg -> reset_assert_duration_us );
144+
145+ ret = gpio_pin_set_dt (& cfg -> reset_gpio , 0 );
146+ if (ret < 0 ) {
147+ LOG_ERR ("Failed to de-assert RST pin (%d)" , ret );
148+ return ret ;
149+ }
150+
151+ k_msleep (cfg -> reset_deassertion_timeout_ms );
152+
153+ return 0 ;
154+ }
155+ #endif /* ANY_RESET_GPIO */
156+
123157 /* Issue a soft reset */
124158 if (phy_mii_reg_write (dev , MII_BMCR , MII_BMCR_RESET ) < 0 ) {
125159 return - EIO ;
@@ -547,6 +581,18 @@ static DEVICE_API(ethphy, phy_mii_driver_api) = {
547581#endif
548582};
549583
584+ #if ANY_RESET_GPIO
585+ #define RESET_GPIO (n ) \
586+ .reset_gpio = GPIO_DT_SPEC_INST_GET_OR(n, \
587+ reset_gpios, {0}), \
588+ .reset_assert_duration_us = DT_INST_PROP_OR(n, \
589+ reset_assert_duration_us, 0), \
590+ .reset_deassertion_timeout_ms = DT_INST_PROP_OR(n, \
591+ reset_deassertion_timeout_ms, 0),
592+ #else
593+ #define RESET_GPIO (n )
594+ #endif /* ANY_RESET_GPIO */
595+
550596#define PHY_MII_CONFIG (n ) \
551597BUILD_ASSERT(PHY_INST_GENERATE_DEFAULT_SPEEDS(n) != 0, \
552598 "At least one valid speed must be configured for this driver"); \
@@ -558,7 +604,8 @@ static const struct phy_mii_dev_config phy_mii_dev_config_##n = { \
558604 .fixed_speed = DT_INST_ENUM_IDX_OR(n, fixed_link, 0), \
559605 .default_speeds = PHY_INST_GENERATE_DEFAULT_SPEEDS(n), \
560606 .mdio = UTIL_AND(UTIL_NOT(IS_FIXED_LINK(n)), \
561- DEVICE_DT_GET(DT_INST_BUS(n))) \
607+ DEVICE_DT_GET(DT_INST_BUS(n))), \
608+ RESET_GPIO(n) \
562609};
563610
564611#define PHY_MII_DATA (n ) \
0 commit comments