From b6be512663a34f85e79bd6dd6caeece57d9f6fe0 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 21 Mar 2018 15:59:26 +0000 Subject: [PATCH 257/454] lan78xx: Read LED states from Device Tree Add support for DT property "microchip,led-modes", a vector of two cells (u32s) in the range 0-15, each of which sets the mode for one of the two LEDs. The possible values are: 0=link/activity 1=link1000/activity 2=link100/activity 3=link10/activity 4=link100/1000/activity 5=link10/1000/activity 6=link10/100/activity 14=off 15=on Signed-off-by: Phil Elwell --- drivers/net/usb/lan78xx.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -1999,7 +1999,9 @@ static int lan78xx_phy_init(struct lan78 { int ret; u32 mii_adv; - u32 led_modes; + u32 led_modes[2]; + u32 led_modes_reg; + int i; struct phy_device *phydev = dev->net->phydev; phydev = phy_find_first(dev->mdiobus); @@ -2072,18 +2074,27 @@ static int lan78xx_phy_init(struct lan78 mii_adv = (u32)mii_advertise_flowctrl(dev->fc_request_control); phydev->advertising |= mii_adv_to_ethtool_adv_t(mii_adv); - /* Change LED defaults: - * orange = link1000/activity - * green = link10/link100/activity + /* Set LED modes: * led: 0=link/activity 1=link1000/activity * 2=link100/activity 3=link10/activity * 4=link100/1000/activity 5=link10/1000/activity * 6=link10/100/activity 14=off 15=on */ - led_modes = phy_read(phydev, 0x1d); - led_modes &= ~0xff; - led_modes |= (1 << 0) | (6 << 4); - (void)phy_write(phydev, 0x1d, led_modes); + + memset(led_modes, ~0, sizeof(led_modes)); + + of_property_read_u32_array(dev->udev->dev.of_node, + "microchip,led-modes", + led_modes, ARRAY_SIZE(led_modes)); + + led_modes_reg = phy_read(phydev, 0x1d); + for (i = 0; i < ARRAY_SIZE(led_modes); i++) { + if (led_modes[i] != ~0) { + led_modes_reg &= ~(0xf << (i * 4)); + led_modes_reg |= (led_modes[i] & 0xf) << (i * 4); + } + } + (void)phy_write(phydev, 0x1d, led_modes_reg); genphy_config_aneg(phydev);