diff options
Diffstat (limited to 'drivers/net/phy/microchip.c')
| -rw-r--r-- | drivers/net/phy/microchip.c | 25 | 
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c index a97ac8c12c4c..2d67937866a3 100644 --- a/drivers/net/phy/microchip.c +++ b/drivers/net/phy/microchip.c @@ -21,6 +21,8 @@  #include <linux/phy.h>  #include <linux/microchipphy.h>  #include <linux/delay.h> +#include <linux/of.h> +#include <dt-bindings/net/microchip-lan78xx.h>  #define DRIVER_AUTHOR	"WOOJUNG HUH <woojung.huh@microchip.com>"  #define DRIVER_DESC	"Microchip LAN88XX PHY driver" @@ -225,6 +227,8 @@ static int lan88xx_probe(struct phy_device *phydev)  {  	struct device *dev = &phydev->mdio.dev;  	struct lan88xx_priv *priv; +	u32 led_modes[4]; +	int len;  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);  	if (!priv) @@ -232,6 +236,27 @@ static int lan88xx_probe(struct phy_device *phydev)  	priv->wolopts = 0; +	len = of_property_read_variable_u32_array(dev->of_node, +						  "microchip,led-modes", +						  led_modes, +						  0, +						  ARRAY_SIZE(led_modes)); +	if (len >= 0) { +		u32 reg = 0; +		int i; + +		for (i = 0; i < len; i++) { +			if (led_modes[i] > 15) +				return -EINVAL; +			reg |= led_modes[i] << (i * 4); +		} +		for (; i < ARRAY_SIZE(led_modes); i++) +			reg |= LAN78XX_FORCE_LED_OFF << (i * 4); +		(void)phy_write(phydev, LAN78XX_PHY_LED_MODE_SELECT, reg); +	} else if (len == -EOVERFLOW) { +		return -EINVAL; +	} +  	/* these values can be used to identify internal PHY */  	priv->chip_id = phy_read_mmd(phydev, 3, LAN88XX_MMD3_CHIP_ID);  	priv->chip_rev = phy_read_mmd(phydev, 3, LAN88XX_MMD3_CHIP_REV);  | 
