Skip to content

Commit 39bce9a

Browse files
185264646TravMurav
authored andcommitted
lk2nd: device: Add an LED driver
Signed-off-by: Yang Xiwen <[email protected]>
1 parent 46de1c1 commit 39bce9a

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

Documentation/dt-bindings.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,34 @@ new keycode to the actual key.
247247
};
248248
};
249249
```
250+
251+
### GPIO leds
252+
253+
lk2nd supports the `gpio-leds` node. This node follows upstream binding except
254+
that most properties are not supported. Currently only `gpios` and
255+
`default-state` are supported in lk2nd.
256+
257+
```
258+
gpio-leds {
259+
compatible = "gpio-leds";
260+
261+
red {
262+
gpios = <&tlmm 3 GPIO_ACTIVE_HIGH>;
263+
default-state = "on";
264+
};
265+
266+
green {
267+
gpios = <&tlmm 4 GPIO_ACTIVE_HIGH>;
268+
default-state = "off";
269+
};
270+
};
271+
```
272+
273+
This driver is mainly for lk1st since no previous boot-loader is capable to
274+
light up an LED in this case. This makes it unclear what state currently the
275+
device is in. If you wish to make sure some leds are enabled or disabled by
276+
lk1st on boot, you can use this driver.
277+
278+
lk2nd doesn't implement a fully-fledged led subsystem. The only purpose for
279+
this driver is for debugging and the LED behavior consistancy between lk1st
280+
and lk2nd.

lk2nd/device/leds.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
/* Copyright (c) 2025 Yang Xiwen <[email protected]> */
3+
4+
#include <debug.h>
5+
#include <libfdt.h>
6+
7+
#include <lk2nd/hw/gpio.h>
8+
9+
#include "device.h"
10+
11+
static int lk2nd_leds_init(const void *dtb, int node)
12+
{
13+
int i = 0, subnode, len;
14+
struct gpiol_desc desc;
15+
const char *state;
16+
17+
dprintf(SPEW, " Initializing LEDs\n");
18+
dprintf(SPEW, " | label | gpio | state |\n");
19+
20+
fdt_for_each_subnode(subnode, dtb, node) {
21+
state = fdt_getprop(dtb, subnode, "default-state", &len);
22+
if (len < 0 || state[len - 1] != '\0') {
23+
dprintf(CRITICAL, "leds: Failed to get property \"default-state\". Broken dtb?\n");
24+
continue;
25+
}
26+
27+
if (!strcmp(state, "on")) {
28+
gpiol_get(dtb, subnode, NULL, &desc, GPIOL_FLAGS_OUT_ASSERTED);
29+
} else if (!strcmp(state, "off")) {
30+
gpiol_get(dtb, subnode, NULL, &desc, GPIOL_FLAGS_OUT_DEASSERTED);
31+
} else if (!strcmp(state, "keep")) {
32+
/* do nothing */
33+
} else {
34+
dprintf(CRITICAL, "leds: Unknown \"default-state\" value: %s\n", state);
35+
continue;
36+
}
37+
38+
i++;
39+
40+
dprintf(SPEW, " | %5s | 0x%02x 0x%04x | %5s |\n",
41+
fdt_get_name(dtb, subnode, NULL), desc.dev, desc.pin, state);
42+
}
43+
dprintf(INFO, "leds: %d leds configured\n", i);
44+
45+
if (subnode < 0 && subnode != -FDT_ERR_NOTFOUND) {
46+
dprintf(CRITICAL, "leds: Failed to parse subnodes: %d\n", subnode);
47+
return subnode;
48+
}
49+
50+
return 0;
51+
}
52+
53+
LK2ND_DEVICE_INIT("gpio-leds", lk2nd_leds_init);

lk2nd/device/rules.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ OBJS += \
1818
$(LK2ND_DEVICE_OBJ) \
1919
$(LOCAL_DIR)/panel.o \
2020
$(LOCAL_DIR)/keys.o \
21+
$(LOCAL_DIR)/leds.o \
2122

2223
ifneq ($(LK2ND_COMPATIBLE),)
2324
DEFINES += LK2ND_COMPATIBLE="$(LK2ND_COMPATIBLE)"

0 commit comments

Comments
 (0)