OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 1 | From 766357a4f8476461035dcfe2c6b43f532366f533 Mon Sep 17 00:00:00 2001 |
2 | From: Phil Elwell <phil@raspberrypi.org> |
||
3 | Date: Fri, 6 Feb 2015 13:50:57 +0000 |
||
4 | Subject: [PATCH] BCM270x_DT: Add pwr_led, and the required "input" trigger |
||
5 | |||
6 | The "input" trigger makes the associated GPIO an input. This is to support |
||
7 | the Raspberry Pi PWR LED, which is driven by external hardware in normal use. |
||
8 | |||
9 | N.B. pwr_led is not available on Model A or B boards. |
||
10 | |||
11 | leds-gpio: Implement the brightness_get method |
||
12 | |||
13 | The power LED uses some clever logic that means it is driven |
||
14 | by a voltage measuring circuit when configured as input, otherwise |
||
15 | it is driven by the GPIO output value. This patch wires up the |
||
16 | brightness_get method for leds-gpio so that user-space can monitor |
||
17 | the LED value via /sys/class/gpio/led1/brightness. Using the input |
||
18 | trigger this returns an indication of the system power health, |
||
19 | otherwise it is just whatever value the trigger has written most |
||
20 | recently. |
||
21 | |||
22 | See: https://github.com/raspberrypi/linux/issues/1064 |
||
23 | --- |
||
24 | drivers/leds/leds-gpio.c | 18 +++++++++++- |
||
25 | drivers/leds/trigger/Kconfig | 7 +++++ |
||
26 | drivers/leds/trigger/Makefile | 1 + |
||
27 | drivers/leds/trigger/ledtrig-input.c | 54 ++++++++++++++++++++++++++++++++++++ |
||
28 | include/linux/leds.h | 3 ++ |
||
29 | 5 files changed, 82 insertions(+), 1 deletion(-) |
||
30 | create mode 100644 drivers/leds/trigger/ledtrig-input.c |
||
31 | |||
32 | --- a/drivers/leds/leds-gpio.c |
||
33 | +++ b/drivers/leds/leds-gpio.c |
||
34 | @@ -50,8 +50,15 @@ static void gpio_led_set(struct led_clas |
||
35 | led_dat->platform_gpio_blink_set(led_dat->gpiod, level, |
||
36 | NULL, NULL); |
||
37 | led_dat->blinking = 0; |
||
38 | + } else if (led_dat->cdev.flags & SET_GPIO_INPUT) { |
||
39 | + gpiod_direction_input(led_dat->gpiod); |
||
40 | + led_dat->cdev.flags &= ~SET_GPIO_INPUT; |
||
41 | + } else if (led_dat->cdev.flags & SET_GPIO_OUTPUT) { |
||
42 | + gpiod_direction_output(led_dat->gpiod, level); |
||
43 | + led_dat->cdev.flags &= ~SET_GPIO_OUTPUT; |
||
44 | } else { |
||
45 | - if (led_dat->can_sleep) |
||
46 | + if (led_dat->can_sleep || |
||
47 | + (led_dat->cdev.flags & (SET_GPIO_INPUT | SET_GPIO_OUTPUT) )) |
||
48 | gpiod_set_value_cansleep(led_dat->gpiod, level); |
||
49 | else |
||
50 | gpiod_set_value(led_dat->gpiod, level); |
||
51 | @@ -65,6 +72,13 @@ static int gpio_led_set_blocking(struct |
||
52 | return 0; |
||
53 | } |
||
54 | |||
55 | +static enum led_brightness gpio_led_get(struct led_classdev *led_cdev) |
||
56 | +{ |
||
57 | + struct gpio_led_data *led_dat = |
||
58 | + container_of(led_cdev, struct gpio_led_data, cdev); |
||
59 | + return gpiod_get_value_cansleep(led_dat->gpiod) ? LED_FULL : LED_OFF; |
||
60 | +} |
||
61 | + |
||
62 | static int gpio_blink_set(struct led_classdev *led_cdev, |
||
63 | unsigned long *delay_on, unsigned long *delay_off) |
||
64 | { |
||
65 | @@ -122,6 +136,8 @@ static int create_gpio_led(const struct |
||
66 | led_dat->platform_gpio_blink_set = blink_set; |
||
67 | led_dat->cdev.blink_set = gpio_blink_set; |
||
68 | } |
||
69 | + led_dat->cdev.brightness_set = gpio_led_set; |
||
70 | + led_dat->cdev.brightness_get = gpio_led_get; |
||
71 | if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) { |
||
72 | state = gpiod_get_value_cansleep(led_dat->gpiod); |
||
73 | if (state < 0) |
||
74 | --- a/drivers/leds/trigger/Kconfig |
||
75 | +++ b/drivers/leds/trigger/Kconfig |
||
76 | @@ -116,6 +116,13 @@ config LEDS_TRIGGER_CAMERA |
||
77 | This enables direct flash/torch on/off by the driver, kernel space. |
||
78 | If unsure, say Y. |
||
79 | |||
80 | +config LEDS_TRIGGER_INPUT |
||
81 | + tristate "LED Input Trigger" |
||
82 | + depends on LEDS_TRIGGERS |
||
83 | + help |
||
84 | + This allows the GPIOs assigned to be LEDs to be initialised to inputs. |
||
85 | + If unsure, say Y. |
||
86 | + |
||
87 | config LEDS_TRIGGER_PANIC |
||
88 | bool "LED Panic Trigger" |
||
89 | depends on LEDS_TRIGGERS |
||
90 | --- a/drivers/leds/trigger/Makefile |
||
91 | +++ b/drivers/leds/trigger/Makefile |
||
92 | @@ -9,4 +9,5 @@ obj-$(CONFIG_LEDS_TRIGGER_CPU) += ledtr |
||
93 | obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o |
||
94 | obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o |
||
95 | obj-$(CONFIG_LEDS_TRIGGER_CAMERA) += ledtrig-camera.o |
||
96 | +obj-$(CONFIG_LEDS_TRIGGER_INPUT) += ledtrig-input.o |
||
97 | obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledtrig-panic.o |
||
98 | --- /dev/null |
||
99 | +++ b/drivers/leds/trigger/ledtrig-input.c |
||
100 | @@ -0,0 +1,54 @@ |
||
101 | +/* |
||
102 | + * Set LED GPIO to Input "Trigger" |
||
103 | + * |
||
104 | + * Copyright 2015 Phil Elwell <phil@raspberrypi.org> |
||
105 | + * |
||
106 | + * Based on Nick Forbes's ledtrig-default-on.c. |
||
107 | + * |
||
108 | + * This program is free software; you can redistribute it and/or modify |
||
109 | + * it under the terms of the GNU General Public License version 2 as |
||
110 | + * published by the Free Software Foundation. |
||
111 | + * |
||
112 | + */ |
||
113 | + |
||
114 | +#include <linux/module.h> |
||
115 | +#include <linux/kernel.h> |
||
116 | +#include <linux/init.h> |
||
117 | +#include <linux/leds.h> |
||
118 | +#include <linux/gpio.h> |
||
119 | +#include "../leds.h" |
||
120 | + |
||
121 | +static void input_trig_activate(struct led_classdev *led_cdev) |
||
122 | +{ |
||
123 | + led_cdev->flags |= SET_GPIO_INPUT; |
||
124 | + led_set_brightness(led_cdev, 0); |
||
125 | +} |
||
126 | + |
||
127 | +static void input_trig_deactivate(struct led_classdev *led_cdev) |
||
128 | +{ |
||
129 | + led_cdev->flags |= SET_GPIO_OUTPUT; |
||
130 | + led_set_brightness(led_cdev, 0); |
||
131 | +} |
||
132 | + |
||
133 | +static struct led_trigger input_led_trigger = { |
||
134 | + .name = "input", |
||
135 | + .activate = input_trig_activate, |
||
136 | + .deactivate = input_trig_deactivate, |
||
137 | +}; |
||
138 | + |
||
139 | +static int __init input_trig_init(void) |
||
140 | +{ |
||
141 | + return led_trigger_register(&input_led_trigger); |
||
142 | +} |
||
143 | + |
||
144 | +static void __exit input_trig_exit(void) |
||
145 | +{ |
||
146 | + led_trigger_unregister(&input_led_trigger); |
||
147 | +} |
||
148 | + |
||
149 | +module_init(input_trig_init); |
||
150 | +module_exit(input_trig_exit); |
||
151 | + |
||
152 | +MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.org>"); |
||
153 | +MODULE_DESCRIPTION("Set LED GPIO to Input \"trigger\""); |
||
154 | +MODULE_LICENSE("GPL"); |
||
155 | --- a/include/linux/leds.h |
||
156 | +++ b/include/linux/leds.h |
||
157 | @@ -52,6 +52,9 @@ struct led_classdev { |
||
158 | #define LED_DEV_CAP_FLASH (1 << 24) |
||
159 | #define LED_HW_PLUGGABLE (1 << 25) |
||
160 | #define LED_PANIC_INDICATOR (1 << 26) |
||
161 | + /* Additions for Raspberry Pi PWR LED */ |
||
162 | +#define SET_GPIO_INPUT (1 << 30) |
||
163 | +#define SET_GPIO_OUTPUT (1 << 31) |
||
164 | |||
165 | /* Set LED brightness level |
||
166 | * Must not sleep. Use brightness_set_blocking for drivers |