toolchain: link ldd when using external toolchain
[openwrt/openwrt.git] / target / linux / mvebu / patches-6.1 / 102-leds-turris-omnia-support-HW-controlled-mode-via-pri.patch
1 From 80e643510cb14f116f687e992210c0008a09d869 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
3 Date: Mon, 4 Jul 2022 12:59:53 +0200
4 Subject: [PATCH] leds: turris-omnia: support HW controlled mode via
5 private trigger
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
9
10 Add support for enabling MCU controlled mode of the Turris Omnia LEDs
11 via a LED private trigger called "omnia-mcu".
12
13 When in MCU controlled mode, the user can still set LED color, but the
14 blinking is done by MCU, which does different things for various LEDs:
15 - WAN LED is blinked according to the LED[0] pin of the WAN PHY
16 - LAN LEDs are blinked according to the LED[0] output of corresponding
17 port of the LAN switch
18 - PCIe LEDs are blinked according to the logical OR of the MiniPCIe port
19 LED pins
20
21 For a long time I wanted to actually do this differently: I wanted to
22 make the netdev trigger to transparently offload the blinking to the HW
23 if user set compatible settings for the netdev trigger.
24 There was some work on this, and hopefully we will be able to complete
25 it sometime, but since there are various complications, it will probably
26 not be soon.
27
28 In the meantime let's support HW controlled mode via this private LED
29 trigger. If, in the future, we manage to complete the netdev trigger
30 offloading, we can still keep this private trigger for backwards
31 compatiblity, if needed.
32
33 We also set "omnia-mcu" to cdev->default_trigger, so that the MCU keeps
34 control until the user first wants to take over it. If a different
35 default trigger is specified in device-tree via the
36 `linux,default-trigger` property, LED class will overwrite
37 cdev->default_trigger, and so the DT property will be respected.
38
39 Signed-off-by: Marek BehĂșn <kabel@kernel.org>
40 ---
41 drivers/leds/Kconfig | 1 +
42 drivers/leds/leds-turris-omnia.c | 41 ++++++++++++++++++++++++++++++++
43 2 files changed, 42 insertions(+)
44
45 --- a/drivers/leds/Kconfig
46 +++ b/drivers/leds/Kconfig
47 @@ -163,6 +163,7 @@ config LEDS_TURRIS_OMNIA
48 depends on I2C
49 depends on MACH_ARMADA_38X || COMPILE_TEST
50 depends on OF
51 + select LEDS_TRIGGERS
52 help
53 This option enables basic support for the LEDs found on the front
54 side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the
55 --- a/drivers/leds/leds-turris-omnia.c
56 +++ b/drivers/leds/leds-turris-omnia.c
57 @@ -41,6 +41,39 @@ struct omnia_leds {
58 struct omnia_led leds[];
59 };
60
61 +static struct led_hw_trigger_type omnia_hw_trigger_type;
62 +
63 +static int omnia_hwtrig_activate(struct led_classdev *cdev)
64 +{
65 + struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
66 + struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev));
67 +
68 + /* put the LED into MCU controlled mode */
69 + return i2c_smbus_write_byte_data(leds->client, CMD_LED_MODE,
70 + CMD_LED_MODE_LED(led->reg));
71 +}
72 +
73 +static void omnia_hwtrig_deactivate(struct led_classdev *cdev)
74 +{
75 + struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
76 + struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev));
77 + int ret;
78 +
79 + /* put the LED into software mode */
80 + ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_MODE,
81 + CMD_LED_MODE_LED(led->reg) |
82 + CMD_LED_MODE_USER);
83 + if (ret < 0)
84 + dev_err(cdev->dev, "Cannot put to software mode: %i\n", ret);
85 +}
86 +
87 +static struct led_trigger omnia_hw_trigger = {
88 + .name = "omnia-mcu",
89 + .activate = omnia_hwtrig_activate,
90 + .deactivate = omnia_hwtrig_deactivate,
91 + .trigger_type = &omnia_hw_trigger_type,
92 +};
93 +
94 static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
95 enum led_brightness brightness)
96 {
97 @@ -112,6 +145,8 @@ static int omnia_led_register(struct i2c
98 cdev = &led->mc_cdev.led_cdev;
99 cdev->max_brightness = 255;
100 cdev->brightness_set_blocking = omnia_led_brightness_set_blocking;
101 + cdev->trigger_type = &omnia_hw_trigger_type;
102 + cdev->default_trigger = omnia_hw_trigger.name;
103
104 /* put the LED into software mode */
105 ret = i2c_smbus_write_byte_data(client, CMD_LED_MODE,
106 @@ -228,6 +263,12 @@ static int omnia_leds_probe(struct i2c_c
107
108 mutex_init(&leds->lock);
109
110 + ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
111 + if (ret < 0) {
112 + dev_err(dev, "Cannot register private LED trigger: %d\n", ret);
113 + return ret;
114 + }
115 +
116 led = &leds->leds[0];
117 for_each_available_child_of_node(np, child) {
118 ret = omnia_led_register(client, led, child);