Messages in this thread Patch in this message | | | From | Frieder Schrempf <> | Subject | [PATCH 1/3] net: phy: mscc: Add possibilty to disable combined LED mode | Date | Thu, 30 Sep 2021 14:57:43 +0200 |
| |
From: Frieder Schrempf <frieder.schrempf@kontron.de>
By default the LED modes offer to combine two indicators like speed/link and activity in one LED. In order to use a LED only for the first of the two modes, the combined feature needs to be disabled.
In order to do this we introduce a boolean devicetree property 'vsc8531,led-[N]-combine-disable' and wire it up to the matching bits in the LED behavior register.
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de> --- drivers/net/phy/mscc/mscc.h | 5 ++++ drivers/net/phy/mscc/mscc_main.c | 47 ++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h index a50235fdf7d9..114b087fc89a 100644 --- a/drivers/net/phy/mscc/mscc.h +++ b/drivers/net/phy/mscc/mscc.h @@ -85,6 +85,10 @@ enum rgmii_clock_delay { #define LED_MODE_SEL_MASK(x) (GENMASK(3, 0) << LED_MODE_SEL_POS(x)) #define LED_MODE_SEL(x, mode) (((mode) << LED_MODE_SEL_POS(x)) & LED_MODE_SEL_MASK(x)) +#define MSCC_PHY_LED_BEHAVIOR 30 +#define LED_COMBINE_DIS_MASK(x) (1 << (x)) +#define LED_COMBINE_DIS(x, dis) (((dis) ? 1 : 0) << (x)) + #define MSCC_EXT_PAGE_CSR_CNTL_17 17 #define MSCC_EXT_PAGE_CSR_CNTL_18 18 @@ -363,6 +367,7 @@ struct vsc8531_private { int rate_magic; u16 supp_led_modes; u32 leds_mode[MAX_LEDS]; + bool leds_combine[MAX_LEDS]; u8 nleds; const struct vsc85xx_hw_stat *hw_stats; u64 *stats; diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c index 6e32da28e138..d42723e04c98 100644 --- a/drivers/net/phy/mscc/mscc_main.c +++ b/drivers/net/phy/mscc/mscc_main.c @@ -171,7 +171,8 @@ static void vsc85xx_get_stats(struct phy_device *phydev, static int vsc85xx_led_cntl_set(struct phy_device *phydev, u8 led_num, - u8 mode) + u8 mode, + bool combine_disable) { int rc; u16 reg_val; @@ -181,6 +182,10 @@ static int vsc85xx_led_cntl_set(struct phy_device *phydev, reg_val &= ~LED_MODE_SEL_MASK(led_num); reg_val |= LED_MODE_SEL(led_num, (u16)mode); rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val); + reg_val = phy_read(phydev, MSCC_PHY_LED_BEHAVIOR); + reg_val &= ~LED_COMBINE_DIS_MASK(led_num); + reg_val |= LED_COMBINE_DIS(led_num, combine_disable); + rc = phy_write(phydev, MSCC_PHY_LED_BEHAVIOR, reg_val); mutex_unlock(&phydev->lock); return rc; @@ -432,6 +437,21 @@ static int vsc85xx_dt_led_mode_get(struct phy_device *phydev, return led_mode; } +static bool vsc85xx_dt_led_combine_get(struct phy_device *phydev, + char *led) +{ + struct vsc8531_private *priv = phydev->priv; + struct device *dev = &phydev->mdio.dev; + struct device_node *of_node = dev->of_node; + bool led_combine = false; + int err; + + if (!of_node) + return false; + + return of_property_read_bool(of_node, led); +} + #else static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev) { @@ -444,13 +464,19 @@ static int vsc85xx_dt_led_mode_get(struct phy_device *phydev, { return default_mode; } + +static bool vsc85xx_dt_led_combine_get(struct phy_device *phydev, + char *led) +{ + return false; +} #endif /* CONFIG_OF_MDIO */ static int vsc85xx_dt_led_modes_get(struct phy_device *phydev, u32 *default_mode) { struct vsc8531_private *priv = phydev->priv; - char led_dt_prop[28]; + char led_dt_prop[32]; int i, ret; for (i = 0; i < priv->nleds; i++) { @@ -463,6 +489,14 @@ static int vsc85xx_dt_led_modes_get(struct phy_device *phydev, if (ret < 0) return ret; priv->leds_mode[i] = ret; + + ret = sprintf(led_dt_prop, + "vsc8531,led-%d-combine-disable", i); + if (ret < 0) + return ret; + + priv->leds_combine[i] = + vsc85xx_dt_led_combine_get(phydev, led_dt_prop); } return 0; @@ -1779,7 +1813,8 @@ static int vsc8584_config_init(struct phy_device *phydev) return ret; for (i = 0; i < vsc8531->nleds; i++) { - ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]); + ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i], + vsc8531->leds_combine[i]); if (ret) return ret; } @@ -1846,7 +1881,8 @@ static int vsc85xx_config_init(struct phy_device *phydev) return rc; for (i = 0; i < vsc8531->nleds; i++) { - rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]); + rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i], + vsc8531->leds_combine[i]); if (rc) return rc; } @@ -2099,7 +2135,8 @@ static int vsc8514_config_init(struct phy_device *phydev) return ret; for (i = 0; i < vsc8531->nleds; i++) { - ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]); + ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i], + vsc8531->leds_combine[i]); if (ret) return ret; } -- 2.33.0
| |