mvebu: backport pending Turris Omnia LEDs improvements
It backports this patch series, which is currently on review:
https://lore.kernel.org/linux-leds/20220704105955.15474-1-kabel@kernel.org/T/#rb89a4ca5a836f17bdcc53d65549e0b1779bb6a18
It allows being able to configure LEDs in userspace.
This fixes issue described in Turris Build repository
https://gitlab.nic.cz/turris/os/build/-/issues/354
It happens in OpenWrt as well.
- Before
```
root@turris:/# ls /sys/class/leds/
ath10k-phy0  ath9k-phy1   mmc0::
```
 -After
```
root@turris:/# ls /sys/class/leds/
ath10k-phy0      rgb:indicator-2  rgb:lan-3        rgb:wlan-1
ath9k-phy1       rgb:lan-0        rgb:lan-4        rgb:wlan-2
mmc0::           rgb:lan-1        rgb:power        rgb:wlan-3
rgb:indicator-1  rgb:lan-2        rgb:wan
```
Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
(cherry picked from commit 049368b936)
			
			
This commit is contained in:
		
				
					committed by
					
						
						Petr Štetiar
					
				
			
			
				
	
			
			
			
						parent
						
							93ac163dea
						
					
				
				
					commit
					e06f97eb33
				
			@@ -0,0 +1,118 @@
 | 
			
		||||
From 80e643510cb14f116f687e992210c0008a09d869 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
 | 
			
		||||
Date: Mon, 4 Jul 2022 12:59:53 +0200
 | 
			
		||||
Subject: [PATCH] leds: turris-omnia: support HW controlled mode via
 | 
			
		||||
 private trigger
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
Add support for enabling MCU controlled mode of the Turris Omnia LEDs
 | 
			
		||||
via a LED private trigger called "omnia-mcu".
 | 
			
		||||
 | 
			
		||||
When in MCU controlled mode, the user can still set LED color, but the
 | 
			
		||||
blinking is done by MCU, which does different things for various LEDs:
 | 
			
		||||
- WAN LED is blinked according to the LED[0] pin of the WAN PHY
 | 
			
		||||
- LAN LEDs are blinked according to the LED[0] output of corresponding
 | 
			
		||||
  port of the LAN switch
 | 
			
		||||
- PCIe LEDs are blinked according to the logical OR of the MiniPCIe port
 | 
			
		||||
  LED pins
 | 
			
		||||
 | 
			
		||||
For a long time I wanted to actually do this differently: I wanted to
 | 
			
		||||
make the netdev trigger to transparently offload the blinking to the HW
 | 
			
		||||
if user set compatible settings for the netdev trigger.
 | 
			
		||||
There was some work on this, and hopefully we will be able to complete
 | 
			
		||||
it sometime, but since there are various complications, it will probably
 | 
			
		||||
not be soon.
 | 
			
		||||
 | 
			
		||||
In the meantime let's support HW controlled mode via this private LED
 | 
			
		||||
trigger. If, in the future, we manage to complete the netdev trigger
 | 
			
		||||
offloading, we can still keep this private trigger for backwards
 | 
			
		||||
compatiblity, if needed.
 | 
			
		||||
 | 
			
		||||
We also set "omnia-mcu" to cdev->default_trigger, so that the MCU keeps
 | 
			
		||||
control until the user first wants to take over it. If a different
 | 
			
		||||
default trigger is specified in device-tree via the
 | 
			
		||||
`linux,default-trigger` property, LED class will overwrite
 | 
			
		||||
cdev->default_trigger, and so the DT property will be respected.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Marek Behún <kabel@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/leds/Kconfig             |  1 +
 | 
			
		||||
 drivers/leds/leds-turris-omnia.c | 41 ++++++++++++++++++++++++++++++++
 | 
			
		||||
 2 files changed, 42 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/leds/Kconfig
 | 
			
		||||
+++ b/drivers/leds/Kconfig
 | 
			
		||||
@@ -182,6 +182,7 @@ config LEDS_TURRIS_OMNIA
 | 
			
		||||
 	depends on I2C
 | 
			
		||||
 	depends on MACH_ARMADA_38X || COMPILE_TEST
 | 
			
		||||
 	depends on OF
 | 
			
		||||
+	select LEDS_TRIGGERS
 | 
			
		||||
 	help
 | 
			
		||||
 	  This option enables basic support for the LEDs found on the front
 | 
			
		||||
 	  side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the
 | 
			
		||||
--- a/drivers/leds/leds-turris-omnia.c
 | 
			
		||||
+++ b/drivers/leds/leds-turris-omnia.c
 | 
			
		||||
@@ -49,6 +49,39 @@ struct omnia_leds {
 | 
			
		||||
 	struct omnia_led leds[];
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+static struct led_hw_trigger_type omnia_hw_trigger_type;
 | 
			
		||||
+
 | 
			
		||||
+static int omnia_hwtrig_activate(struct led_classdev *cdev)
 | 
			
		||||
+{
 | 
			
		||||
+	struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
 | 
			
		||||
+	struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev));
 | 
			
		||||
+
 | 
			
		||||
+	/* put the LED into MCU controlled mode */
 | 
			
		||||
+	return i2c_smbus_write_byte_data(leds->client, CMD_LED_MODE,
 | 
			
		||||
+					 CMD_LED_MODE_LED(led->reg));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void omnia_hwtrig_deactivate(struct led_classdev *cdev)
 | 
			
		||||
+{
 | 
			
		||||
+	struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
 | 
			
		||||
+	struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev));
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	/* put the LED into software mode */
 | 
			
		||||
+	ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_MODE,
 | 
			
		||||
+					CMD_LED_MODE_LED(led->reg) |
 | 
			
		||||
+					CMD_LED_MODE_USER);
 | 
			
		||||
+	if (ret < 0)
 | 
			
		||||
+		dev_err(cdev->dev, "Cannot put to software mode: %i\n", ret);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static struct led_trigger omnia_hw_trigger = {
 | 
			
		||||
+	.name		= "omnia-mcu",
 | 
			
		||||
+	.activate	= omnia_hwtrig_activate,
 | 
			
		||||
+	.deactivate	= omnia_hwtrig_deactivate,
 | 
			
		||||
+	.trigger_type	= &omnia_hw_trigger_type,
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
 | 
			
		||||
 					     enum led_brightness brightness)
 | 
			
		||||
 {
 | 
			
		||||
@@ -120,6 +153,8 @@ static int omnia_led_register(struct i2c
 | 
			
		||||
 	cdev = &led->mc_cdev.led_cdev;
 | 
			
		||||
 	cdev->max_brightness = 255;
 | 
			
		||||
 	cdev->brightness_set_blocking = omnia_led_brightness_set_blocking;
 | 
			
		||||
+	cdev->trigger_type = &omnia_hw_trigger_type;
 | 
			
		||||
+	cdev->default_trigger = omnia_hw_trigger.name;
 | 
			
		||||
 
 | 
			
		||||
 	/* put the LED into software mode */
 | 
			
		||||
 	ret = i2c_smbus_write_byte_data(client, CMD_LED_MODE,
 | 
			
		||||
@@ -231,6 +266,12 @@ static int omnia_leds_probe(struct i2c_c
 | 
			
		||||
 
 | 
			
		||||
 	mutex_init(&leds->lock);
 | 
			
		||||
 
 | 
			
		||||
+	ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
 | 
			
		||||
+	if (ret < 0) {
 | 
			
		||||
+		dev_err(dev, "Cannot register private LED trigger: %d\n", ret);
 | 
			
		||||
+		return ret;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	led = &leds->leds[0];
 | 
			
		||||
 	for_each_available_child_of_node(np, child) {
 | 
			
		||||
 		ret = omnia_led_register(client, led, child);
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
From bda176cceb735b9b46c1900658b6486c34e13ae6 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
 | 
			
		||||
Date: Mon, 4 Jul 2022 12:59:54 +0200
 | 
			
		||||
Subject: [PATCH] leds: turris-omnia: initialize multi-intensity to full
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
The default color of each LED before driver probe (255, 255, 255).
 | 
			
		||||
Initialize multi_intensity to this value, so that it corresponds to the
 | 
			
		||||
reality.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Marek Behún <kabel@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/leds/leds-turris-omnia.c | 3 +++
 | 
			
		||||
 1 file changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/leds/leds-turris-omnia.c
 | 
			
		||||
+++ b/drivers/leds/leds-turris-omnia.c
 | 
			
		||||
@@ -139,10 +139,13 @@ static int omnia_led_register(struct i2c
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	led->subled_info[0].color_index = LED_COLOR_ID_RED;
 | 
			
		||||
+	led->subled_info[0].intensity = 255;
 | 
			
		||||
 	led->subled_info[0].channel = 0;
 | 
			
		||||
 	led->subled_info[1].color_index = LED_COLOR_ID_GREEN;
 | 
			
		||||
+	led->subled_info[1].intensity = 255;
 | 
			
		||||
 	led->subled_info[1].channel = 1;
 | 
			
		||||
 	led->subled_info[2].color_index = LED_COLOR_ID_BLUE;
 | 
			
		||||
+	led->subled_info[2].intensity = 255;
 | 
			
		||||
 	led->subled_info[2].channel = 2;
 | 
			
		||||
 
 | 
			
		||||
 	led->mc_cdev.subled_info = led->subled_info;
 | 
			
		||||
@@ -0,0 +1,31 @@
 | 
			
		||||
From 349cbe949b9622cc05b148ecfa6268cbbae35b45 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
 | 
			
		||||
Date: Mon, 4 Jul 2022 12:59:55 +0200
 | 
			
		||||
Subject: [PATCH] leds: turris-omnia: change max brightness from 255 to 1
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
Using binary brightness makes more sense for this controller, because
 | 
			
		||||
internally in the MCU it works that way: the LED has a color, and a
 | 
			
		||||
state whether it is ON or OFF.
 | 
			
		||||
 | 
			
		||||
The resulting brightness computation with led_mc_calc_color_components()
 | 
			
		||||
will now always result in either (0, 0, 0) or the multi_intensity value.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Marek Behún <kabel@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/leds/leds-turris-omnia.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/leds/leds-turris-omnia.c
 | 
			
		||||
+++ b/drivers/leds/leds-turris-omnia.c
 | 
			
		||||
@@ -154,7 +154,7 @@ static int omnia_led_register(struct i2c
 | 
			
		||||
 	init_data.fwnode = &np->fwnode;
 | 
			
		||||
 
 | 
			
		||||
 	cdev = &led->mc_cdev.led_cdev;
 | 
			
		||||
-	cdev->max_brightness = 255;
 | 
			
		||||
+	cdev->max_brightness = 1;
 | 
			
		||||
 	cdev->brightness_set_blocking = omnia_led_brightness_set_blocking;
 | 
			
		||||
 	cdev->trigger_type = &omnia_hw_trigger_type;
 | 
			
		||||
 	cdev->default_trigger = omnia_hw_trigger.name;
 | 
			
		||||
@@ -30,7 +30,7 @@ Cc: Robert Marko <robert.marko@sartura.hr>
 | 
			
		||||
 | 
			
		||||
--- a/drivers/leds/Kconfig
 | 
			
		||||
+++ b/drivers/leds/Kconfig
 | 
			
		||||
@@ -333,6 +333,14 @@ config LEDS_IPAQ_MICRO
 | 
			
		||||
@@ -334,6 +334,14 @@ config LEDS_IPAQ_MICRO
 | 
			
		||||
 	  Choose this option if you want to use the notification LED on
 | 
			
		||||
 	  Compaq/HP iPAQ h3100 and h3600.
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user