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>
20
21
21
22
LOG_MODULE_REGISTER (phy_adin , CONFIG_PHY_LOG_LEVEL );
22
23
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
+
23
32
/* PHYs out of reset check retry delay */
24
33
#define ADIN2111_PHY_AWAIT_DELAY_POLL_US 15U
25
34
/*
@@ -36,6 +45,7 @@ LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL);
36
45
37
46
/* Software reset, CLK_25 disabled time*/
38
47
#define ADIN1100_PHY_SFT_RESET_MS 25U
48
+ #define ADIN1100_PHY_HRD_RESET_MS 70U
39
49
40
50
/* PHYs autonegotiation complete timeout */
41
51
#define ADIN2111_AN_COMPLETE_AWAIT_TIMEOUT_MS 3000U
@@ -94,6 +104,9 @@ struct phy_adin2111_config {
94
104
bool led0_en ;
95
105
bool led1_en ;
96
106
bool tx_24v ;
107
+ #if ADIN2111_RST_GPIO_SUPPORT
108
+ const struct gpio_dt_spec reset_gpio ;
109
+ #endif /* ADIN2111_RST_GPIO_SUPPORT */
97
110
bool mii ;
98
111
};
99
112
@@ -352,6 +365,31 @@ static int phy_adin2111_reset(const struct device *dev)
352
365
{
353
366
int ret ;
354
367
368
+ #if ADIN2111_RST_GPIO_SUPPORT
369
+ const struct phy_adin2111_config * config = dev -> config ;
370
+
371
+ if (!config -> reset_gpio .port ) {
372
+ goto skip_reset_gpio ;
373
+ }
374
+
375
+ /* Assert reset (min. reset pulse width 10us) */
376
+ ret = gpio_pin_set_dt (& config -> reset_gpio , 1 );
377
+ if (ret < 0 ) {
378
+ return ret ;
379
+ }
380
+ k_busy_wait (50 );
381
+
382
+ /* Deassert reset */
383
+ ret = gpio_pin_set_dt (& config -> reset_gpio , 0 );
384
+ if (ret < 0 ) {
385
+ return ret ;
386
+ }
387
+
388
+ k_msleep (ADIN1100_PHY_HRD_RESET_MS );
389
+
390
+ return 0 ;
391
+ skip_reset_gpio :
392
+ #endif /* ADIN2111_RST_GPIO_SUPPORT */
355
393
ret = phy_adin2111_c22_write (dev , MII_BMCR , MII_BMCR_RESET );
356
394
if (ret < 0 ) {
357
395
return ret ;
@@ -439,6 +477,15 @@ static int phy_adin2111_init(const struct device *dev)
439
477
data -> state .is_up = false;
440
478
data -> state .speed = LINK_FULL_10BASE ;
441
479
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
+
442
489
/*
443
490
* For adin1100 and further mii stuff,
444
491
* reset may not be performed from the mac layer, doing a clean reset here.
@@ -617,13 +664,21 @@ static DEVICE_API(ethphy, phy_adin2111_api) = {
617
664
.write = phy_adin2111_reg_write ,
618
665
};
619
666
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
+
620
674
#define ADIN2111_PHY_INITIALIZE (n , model ) \
621
675
static const struct phy_adin2111_config phy_adin##model##_config_##n = { \
622
676
.mdio = DEVICE_DT_GET(DT_INST_BUS(n)), \
623
677
.phy_addr = DT_INST_REG_ADDR(n), \
624
678
.led0_en = DT_INST_PROP(n, led0_en), \
625
679
.led1_en = DT_INST_PROP(n, led1_en), \
626
680
.tx_24v = !(DT_INST_PROP(n, disable_tx_mode_24v)), \
681
+ RESET_GPIO(n) \
627
682
IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(adi_adin1100_phy), \
628
683
(.mii = 1)) \
629
684
}; \
0 commit comments