10
10
#include <stdbool.h>
11
11
#include <zephyr/kernel.h>
12
12
#include <zephyr/device.h>
13
+ #include <zephyr/drivers/gpio.h>
13
14
#include <zephyr/drivers/mdio.h>
14
15
#include <zephyr/logging/log.h>
15
16
#include <zephyr/net/mdio.h>
@@ -36,6 +37,8 @@ LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL);
36
37
37
38
/* Software reset, CLK_25 disabled time*/
38
39
#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
39
42
40
43
/* PHYs autonegotiation complete timeout */
41
44
#define ADIN2111_AN_COMPLETE_AWAIT_TIMEOUT_MS 3000U
@@ -90,6 +93,9 @@ LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL);
90
93
91
94
struct phy_adin2111_config {
92
95
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) */
93
99
uint8_t phy_addr ;
94
100
bool led0_en ;
95
101
bool led1_en ;
@@ -352,6 +358,30 @@ static int phy_adin2111_reset(const struct device *dev)
352
358
{
353
359
int ret ;
354
360
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 ) {
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 */
355
385
ret = phy_adin2111_c22_write (dev , MII_BMCR , MII_BMCR_RESET );
356
386
if (ret < 0 ) {
357
387
return ret ;
@@ -439,6 +469,15 @@ static int phy_adin2111_init(const struct device *dev)
439
469
data -> state .is_up = false;
440
470
data -> state .speed = LINK_FULL_10BASE ;
441
471
472
+ #if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY (adi_adin1100_phy , reset_gpios )
473
+ if (cfg -> reset_gpio .port ) {
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
+
442
481
/*
443
482
* For adin1100 and further mii stuff,
444
483
* 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) = {
617
656
.write = phy_adin2111_reg_write ,
618
657
};
619
658
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
+
620
666
#define ADIN2111_PHY_INITIALIZE (n , model ) \
621
667
static const struct phy_adin2111_config phy_adin##model##_config_##n = { \
622
668
.mdio = DEVICE_DT_GET(DT_INST_BUS(n)), \
669
+ RESET_GPIO(n) \
623
670
.phy_addr = DT_INST_REG_ADDR(n), \
624
671
.led0_en = DT_INST_PROP(n, led0_en), \
625
672
.led1_en = DT_INST_PROP(n, led1_en), \
0 commit comments