ADIN1300/1200 support software control over pin polarity for LINK_ST (link-status) pin. Configure the polarity during config_init based on device-tree property. Polarity is only set if specified in device-tree, otherwise the phy defaults to active-high during reset. Signed-off-by: Josua Mayer <josua@xxxxxxxxxxxxx> --- drivers/net/phy/adin.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c index 2e1a46e121d9..a533932afcb8 100644 --- a/drivers/net/phy/adin.c +++ b/drivers/net/phy/adin.c @@ -158,6 +158,9 @@ #define ADIN1300_RMII_20_BITS 0x0004 #define ADIN1300_RMII_24_BITS 0x0005 +#define ADIN1300_GE_LNK_STAT_INV_EN_REG 0xff3c +#define ADIN1300_GE_LNK_STAT_INV_EN BIT(0) + /** * struct adin_cfg_reg_map - map a config value to aregister value * @cfg: value in device configuration @@ -522,6 +525,28 @@ static int adin_config_clk_out(struct phy_device *phydev) ADIN1300_GE_CLK_CFG_MASK, sel); } +static int adin_config_link_status_pin_polarity(struct phy_device *phydev) +{ + struct device *dev = &phydev->mdio.dev; + int ret; + u32 val; + + if (!device_property_present(dev, "adi,link-st-polarity")) + return 0; + + ret = device_property_read_u32(dev, "adi,link-st-polarity", &val); + if (ret) { + return ret; + } else if (val > 1) { + phydev_err(phydev, "invalid adi,link-st-polarity\n"); + return -EINVAL; + } + + return phy_modify_mmd(phydev, MDIO_MMD_VEND1, + ADIN1300_GE_LNK_STAT_INV_EN_REG, + ADIN1300_GE_LNK_STAT_INV_EN, val); +} + static int adin_config_init(struct phy_device *phydev) { int rc; @@ -548,6 +573,10 @@ static int adin_config_init(struct phy_device *phydev) if (rc < 0) return rc; + rc = adin_config_link_status_pin_polarity(phydev); + if (rc < 0) + return rc; + phydev_dbg(phydev, "PHY is using mode '%s'\n", phy_modes(phydev->interface)); -- 2.35.3