Re: [PATCH v7 10/11] net: dsa: qca8k: add LEDs support
From: <Arun.Ramadoss@microchip.com>
Date: 2022-12-15 03:54:37
Also in:
linux-devicetree, linux-doc, linux-leds, lkml
Hi Christian, On Thu, 2022-12-15 at 00:54 +0100, Christian Marangi wrote:
quoted hunk ↗ jump to hunk
Add LEDs support for qca8k Switch Family. This will provide the LEDs hardware API to permit the PHY LED to support hardware mode. Each port have at least 3 LEDs and they can HW blink, set on/off or follow blink modes configured with the LED in hardware mode. Adds support for leds netdev trigger to support hardware triggers. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> --- drivers/net/dsa/qca/Kconfig | 9 + drivers/net/dsa/qca/Makefile | 1 + drivers/net/dsa/qca/qca8k-8xxx.c | 4 + drivers/net/dsa/qca/qca8k-leds.c | 406 +++++++++++++++++++++++++++++++ drivers/net/dsa/qca/qca8k.h | 62 +++++ 5 files changed, 482 insertions(+) create mode 100644 drivers/net/dsa/qca/qca8k-leds.cdiff --git a/drivers/net/dsa/qca/qca8k-leds.cb/drivers/net/dsa/qca/qca8k-leds.c new file mode 100644 index 000000000000..b51cdcae31b2--- /dev/null +++ b/drivers/net/dsa/qca/qca8k-leds.c@@ -0,0 +1,406 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <net/dsa.h> +#include <linux/regmap.h>
Alphabatical order
+
+#include "qca8k.h"
+
+static int
+qca8k_get_enable_led_reg(int port_num, int led_num, struct
qca8k_led_pattern_en *reg_info)
+{
+ int shift;
+
+ switch (port_num) {
+ case 0:
+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num);
+ reg_info->shift = 14;Any macros other than magic number for 14, 30
+ break; + case 1: + case 2: + case 3: + reg_info->reg = QCA8K_LED_CTRL_REG(3); + shift = 2 * led_num + (6 * (port_num - 1)); + + reg_info->shift = 8 + shift; + + break; + case 4: + reg_info->reg = QCA8K_LED_CTRL_REG(led_num); + reg_info->shift = 30; + break; + default: + return -EINVAL; + } + + return 0; +} + + +static void +qca8k_led_brightness_set(struct qca8k_led *led, + enum led_brightness b)
variable name other than b to have readability in code
+{
+ struct qca8k_led_pattern_en reg_info;
+ struct qca8k_priv *priv = led->priv;
+ u32 val = QCA8K_LED_ALWAYS_OFF;
+
+ qca8k_get_enable_led_reg(led->port_num, led->led_num,
®_info);
+
+ if (b)
+ val = QCA8K_LED_ALWAYS_ON;
+
+ regmap_update_bits(priv->regmap, reg_info.reg,
+ GENMASK(1, 0) << reg_info.shift,GENMASK(1, 0) used in multiple place, replace with macro for readability
+ val << reg_info.shift);
+}
+
+
+static int
+qca8k_cled_trigger_offload(struct led_classdev *ldev, bool enable)
+{
+ struct qca8k_led *led = container_of(ldev, struct qca8k_led,
cdev);
+Blank line
+ struct qca8k_led_pattern_en reg_info;
+ struct qca8k_priv *priv = led->priv;
+ u32 val = QCA8K_LED_ALWAYS_OFF;
+
+ qca8k_get_enable_led_reg(led->port_num, led->led_num,
®_info);
+
+ if (enable)
+ val = QCA8K_LED_RULE_CONTROLLED;
+
+ return regmap_update_bits(priv->regmap, reg_info.reg,
+ GENMASK(1, 0) << reg_info.shift,
+ val << reg_info.shift);
+}
+
+static bool
+qca8k_cled_hw_control_status(struct led_classdev *ldev)
+{
+ struct qca8k_led *led = container_of(ldev, struct qca8k_led,
cdev);
+Blank line
+ struct qca8k_led_pattern_en reg_info; + struct qca8k_priv *priv = led->priv; + u32 val; + + qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); + + regmap_read(priv->regmap, reg_info.reg, &val); + + val >>= reg_info.shift; + val &= GENMASK(1, 0); + + return val == QCA8K_LED_RULE_CONTROLLED; +} +