net: phy: broadcom: Add support for setting LED brightness
authorFlorian Fainelli <florian.fainelli@broadcom.com>
Wed, 7 Jun 2023 18:34:53 +0000 (11:34 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 9 Jun 2023 09:38:43 +0000 (10:38 +0100)
Broadcom PHYs have two LEDs selector registers which allow us to control
the LED assignment, including how to turn them on/off.

Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/phy/bcm-phy-lib.c
drivers/net/phy/bcm-phy-lib.h
drivers/net/phy/broadcom.c
include/linux/brcmphy.h

index c6e2e5f636d49a29afba9f1e576bd535aa7bd87a..876f28fd82565da2b97ca6ecffc1cbc2006c45f2 100644 (file)
@@ -1039,6 +1039,33 @@ irqreturn_t bcm_phy_wol_isr(int irq, void *dev_id)
 }
 EXPORT_SYMBOL_GPL(bcm_phy_wol_isr);
 
+int bcm_phy_led_brightness_set(struct phy_device *phydev,
+                              u8 index, enum led_brightness value)
+{
+       u8 led_num;
+       int ret;
+       u16 reg;
+
+       if (index >= 4)
+               return -EINVAL;
+
+       /* Two LEDS per register */
+       led_num = index % 2;
+       reg = index >= 2 ? BCM54XX_SHD_LEDS2 : BCM54XX_SHD_LEDS1;
+
+       ret = bcm_phy_read_shadow(phydev, reg);
+       if (ret < 0)
+               return ret;
+
+       ret &= ~(BCM_LED_SRC_MASK << BCM54XX_SHD_LEDS_SHIFT(led_num));
+       if (value == LED_OFF)
+               ret |= BCM_LED_SRC_OFF << BCM54XX_SHD_LEDS_SHIFT(led_num);
+       else
+               ret |= BCM_LED_SRC_ON << BCM54XX_SHD_LEDS_SHIFT(led_num);
+       return bcm_phy_write_shadow(phydev, reg, ret);
+}
+EXPORT_SYMBOL_GPL(bcm_phy_led_brightness_set);
+
 MODULE_DESCRIPTION("Broadcom PHY Library");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Broadcom Corporation");
index 2f30ce0cab0e358889a130eac17ff67740f6e1c7..b52189e45a848199db559e74e3422a465e105175 100644 (file)
@@ -118,4 +118,7 @@ int bcm_phy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);
 void bcm_phy_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol);
 irqreturn_t bcm_phy_wol_isr(int irq, void *dev_id);
 
+int bcm_phy_led_brightness_set(struct phy_device *phydev,
+                              u8 index, enum led_brightness value);
+
 #endif /* _LINUX_BCM_PHY_LIB_H */
index 57a865aa1fe5a58d80d2d9b6eb6faa3cdbd985ab..9f0a9c575bd771d6cb32ce57174d5decb25d0f6b 100644 (file)
@@ -1031,6 +1031,7 @@ static struct phy_driver broadcom_drivers[] = {
        .resume         = bcm54xx_resume,
        .get_wol        = bcm54xx_phy_get_wol,
        .set_wol        = bcm54xx_phy_set_wol,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM5461,
        .phy_id_mask    = 0xfffffff0,
@@ -1044,6 +1045,7 @@ static struct phy_driver broadcom_drivers[] = {
        .config_intr    = bcm_phy_config_intr,
        .handle_interrupt = bcm_phy_handle_interrupt,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM54612E,
        .phy_id_mask    = 0xfffffff0,
@@ -1057,6 +1059,7 @@ static struct phy_driver broadcom_drivers[] = {
        .config_intr    = bcm_phy_config_intr,
        .handle_interrupt = bcm_phy_handle_interrupt,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM54616S,
        .phy_id_mask    = 0xfffffff0,
@@ -1070,6 +1073,7 @@ static struct phy_driver broadcom_drivers[] = {
        .read_status    = bcm54616s_read_status,
        .probe          = bcm54616s_probe,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM5464,
        .phy_id_mask    = 0xfffffff0,
@@ -1085,6 +1089,7 @@ static struct phy_driver broadcom_drivers[] = {
        .suspend        = genphy_suspend,
        .resume         = genphy_resume,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM5481,
        .phy_id_mask    = 0xfffffff0,
@@ -1099,6 +1104,7 @@ static struct phy_driver broadcom_drivers[] = {
        .config_intr    = bcm_phy_config_intr,
        .handle_interrupt = bcm_phy_handle_interrupt,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM54810,
        .phy_id_mask    = 0xfffffff0,
@@ -1115,6 +1121,7 @@ static struct phy_driver broadcom_drivers[] = {
        .suspend        = bcm54xx_suspend,
        .resume         = bcm54xx_resume,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM54811,
        .phy_id_mask    = 0xfffffff0,
@@ -1131,6 +1138,7 @@ static struct phy_driver broadcom_drivers[] = {
        .suspend        = bcm54xx_suspend,
        .resume         = bcm54xx_resume,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM5482,
        .phy_id_mask    = 0xfffffff0,
@@ -1144,6 +1152,7 @@ static struct phy_driver broadcom_drivers[] = {
        .config_intr    = bcm_phy_config_intr,
        .handle_interrupt = bcm_phy_handle_interrupt,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM50610,
        .phy_id_mask    = 0xfffffff0,
@@ -1159,6 +1168,7 @@ static struct phy_driver broadcom_drivers[] = {
        .link_change_notify     = bcm54xx_link_change_notify,
        .suspend        = bcm54xx_suspend,
        .resume         = bcm54xx_resume,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM50610M,
        .phy_id_mask    = 0xfffffff0,
@@ -1174,6 +1184,7 @@ static struct phy_driver broadcom_drivers[] = {
        .link_change_notify     = bcm54xx_link_change_notify,
        .suspend        = bcm54xx_suspend,
        .resume         = bcm54xx_resume,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM57780,
        .phy_id_mask    = 0xfffffff0,
@@ -1187,6 +1198,7 @@ static struct phy_driver broadcom_drivers[] = {
        .config_intr    = bcm_phy_config_intr,
        .handle_interrupt = bcm_phy_handle_interrupt,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCMAC131,
        .phy_id_mask    = 0xfffffff0,
@@ -1218,6 +1230,7 @@ static struct phy_driver broadcom_drivers[] = {
        .get_stats      = bcm54xx_get_stats,
        .probe          = bcm54xx_phy_probe,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM53125,
        .phy_id_mask    = 0xfffffff0,
@@ -1232,6 +1245,7 @@ static struct phy_driver broadcom_drivers[] = {
        .config_intr    = bcm_phy_config_intr,
        .handle_interrupt = bcm_phy_handle_interrupt,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM53128,
        .phy_id_mask    = 0xfffffff0,
@@ -1246,6 +1260,7 @@ static struct phy_driver broadcom_drivers[] = {
        .config_intr    = bcm_phy_config_intr,
        .handle_interrupt = bcm_phy_handle_interrupt,
        .link_change_notify     = bcm54xx_link_change_notify,
+       .led_brightness_set     = bcm_phy_led_brightness_set,
 }, {
        .phy_id         = PHY_ID_BCM89610,
        .phy_id_mask    = 0xfffffff0,
index ab21b8a1b2c82c2c5909cf39f9d3352c10d4952c..5d732f48f78762c54d55c82b72fa8d5f4939768c 100644 (file)
 #define BCM_LED_SRC_OPENSHORT  0xb
 #define BCM_LED_SRC_OFF                0xe     /* Tied high */
 #define BCM_LED_SRC_ON         0xf     /* Tied low */
+#define BCM_LED_SRC_MASK       GENMASK(3, 0)
 
 /*
  * Broadcom Multicolor LED configurations (expansion register 4)
 
 #define BCM54XX_SHD_LEDS1      0x0d    /* 01101: LED Selector 1 */
                                        /* LED3 / ~LINKSPD[2] selector */
+#define BCM54XX_SHD_LEDS_SHIFT(led)    (4 * (led))
 #define BCM54XX_SHD_LEDS1_LED3(src)    ((src & 0xf) << 4)
                                        /* LED1 / ~LINKSPD[1] selector */
 #define BCM54XX_SHD_LEDS1_LED1(src)    ((src & 0xf) << 0)
+#define BCM54XX_SHD_LEDS2      0x0e    /* 01110: LED Selector 2 */
 #define BCM54XX_SHD_RGMII_MODE 0x0b    /* 01011: RGMII Mode Selector */
 #define BCM5482_SHD_SSD                0x14    /* 10100: Secondary SerDes control */
 #define BCM5482_SHD_SSD_LEDM   0x0008  /* SSD LED Mode enable */