diff --git a/Documentation/devicetree/bindings/net/adi,adin.yaml b/Documentation/devicetree/bindings/net/adi,adin.yaml index c425a9f1886d..f594055c2b15 100644 --- a/Documentation/devicetree/bindings/net/adi,adin.yaml +++ b/Documentation/devicetree/bindings/net/adi,adin.yaml @@ -52,6 +52,20 @@ properties: description: Enable 25MHz reference clock output on CLK25_REF pin. type: boolean + adi,low-cmode-impedance: + description: | + Configure PHY for the lowest common-mode impedance on the receive pair + for 100BASE-TX. This is suited for capacitive coupled applications and + other applications where there may be a path for high common-mode noise + to reach the PHY. + If not present, by default the PHY is configured for normal termination + (zero-power termination) mode. + + Note: There is a trade-off of 12 mW increased power consumption with + the lowest common-mode impedance setting, but in all cases the + differential impedance is 100 ohms. + type: boolean + unevaluatedProperties: false examples: diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c index 7fa713ca8d45..3a934051b574 100644 --- a/drivers/net/phy/adin.c +++ b/drivers/net/phy/adin.c @@ -89,6 +89,9 @@ #define ADIN1300_CLOCK_STOP_REG 0x9400 #define ADIN1300_LPI_WAKE_ERR_CNT_REG 0xa000 +#define ADIN1300_B_100_ZPTM_DIMRX 0xB685 +#define ADIN1300_B_100_ZPTM_EN_DIMRX BIT(0) + #define ADIN1300_CDIAG_RUN 0xba1b #define ADIN1300_CDIAG_RUN_EN BIT(0) @@ -522,6 +525,19 @@ static int adin_config_clk_out(struct phy_device *phydev) ADIN1300_GE_CLK_CFG_MASK, sel); } +static int adin_config_zptm100(struct phy_device *phydev) +{ + struct device *dev = &phydev->mdio.dev; + + if (!(device_property_read_bool(dev, "adi,low-cmode-impedance"))) + return 0; + + /* clear bit 0 to configure for lowest common-mode impedance */ + return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, + ADIN1300_B_100_ZPTM_DIMRX, + ADIN1300_B_100_ZPTM_EN_DIMRX); +} + static int adin_config_init(struct phy_device *phydev) { int rc; @@ -548,6 +564,10 @@ static int adin_config_init(struct phy_device *phydev) if (rc < 0) return rc; + rc = adin_config_zptm100(phydev); + if (rc < 0) + return rc; + phydev_dbg(phydev, "PHY is using mode '%s'\n", phy_modes(phydev->interface));