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,8 @@ 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
49
+ #define ADIN1100_PHY_HRD_RESET_PULSE_WIDTH_US 50U
39
50
40
51
/* PHYs autonegotiation complete timeout */
41
52
#define ADIN2111_AN_COMPLETE_AWAIT_TIMEOUT_MS 3000U
@@ -90,6 +101,9 @@ LOG_MODULE_REGISTER(phy_adin, CONFIG_PHY_LOG_LEVEL);
90
101
91
102
struct phy_adin2111_config {
92
103
const struct device * mdio ;
104
+ #if ADIN2111_RST_GPIO_SUPPORT
105
+ const struct gpio_dt_spec reset_gpio ;
106
+ #endif /* ADIN2111_RST_GPIO_SUPPORT */
93
107
uint8_t phy_addr ;
94
108
bool led0_en ;
95
109
bool led1_en ;
@@ -352,6 +366,30 @@ static int phy_adin2111_reset(const struct device *dev)
352
366
{
353
367
int ret ;
354
368
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 */
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,9 +664,17 @@ 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)), \
677
+ RESET_GPIO(n) \
623
678
.phy_addr = DT_INST_REG_ADDR(n), \
624
679
.led0_en = DT_INST_PROP(n, led0_en), \
625
680
.led1_en = DT_INST_PROP(n, led1_en), \
0 commit comments