diff options
author | Christian Marangi <ansuelsmth@gmail.com> | 2023-04-17 18:17:25 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-04-19 14:59:15 +0300 |
commit | 91acadcc6e599dfc62717abcdad58a459cfb1684 (patch) | |
tree | a85125f88181e75e069ba712c4e2cf61ce0f155e /drivers/net | |
parent | 1e264f9d2918b5737023c44a23ae04def1095210 (diff) | |
download | linux-91acadcc6e599dfc62717abcdad58a459cfb1684.tar.xz |
net: dsa: qca8k: add LEDs blink_set() support
Add LEDs blink_set() support to qca8k Switch Family.
These LEDs support hw accellerated blinking at a fixed rate
of 4Hz.
Reject any other value since not supported by the LEDs switch.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/dsa/qca/qca8k-leds.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/net/dsa/qca/qca8k-leds.c b/drivers/net/dsa/qca/qca8k-leds.c index 0146ee12d34c..b883692b7d86 100644 --- a/drivers/net/dsa/qca/qca8k-leds.c +++ b/drivers/net/dsa/qca/qca8k-leds.c @@ -128,6 +128,43 @@ qca8k_led_brightness_get(struct qca8k_led *led) } static int +qca8k_cled_blink_set(struct led_classdev *ldev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); + u32 mask, val = QCA8K_LED_ALWAYS_BLINK_4HZ; + struct qca8k_led_pattern_en reg_info; + struct qca8k_priv *priv = led->priv; + + if (*delay_on == 0 && *delay_off == 0) { + *delay_on = 125; + *delay_off = 125; + } + + if (*delay_on != 125 || *delay_off != 125) { + /* The hardware only supports blinking at 4Hz. Fall back + * to software implementation in other cases. + */ + return -EINVAL; + } + + qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); + + if (led->port_num == 0 || led->port_num == 4) { + mask = QCA8K_LED_PATTERN_EN_MASK; + val <<= QCA8K_LED_PATTERN_EN_SHIFT; + } else { + mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; + } + + regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift, + val << reg_info.shift); + + return 0; +} + +static int qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) { struct fwnode_handle *led = NULL, *leds = NULL; @@ -186,6 +223,7 @@ qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int p port_led->cdev.max_brightness = 1; port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; + port_led->cdev.blink_set = qca8k_cled_blink_set; init_data.default_label = ":port"; init_data.fwnode = led; init_data.devname_mandatory = true; |