33 * ledtrig-gio.c - LED Trigger Based on GPIO events
44 *
55 * Copyright 2009 Felipe Balbi <me@felipebalbi.com>
6+ * Copyright 2023 Linus Walleij <linus.walleij@linaro.org>
67 */
78
89#include <linux/module.h>
910#include <linux/kernel.h>
1011#include <linux/init.h>
11- #include <linux/gpio.h>
12+ #include <linux/gpio/consumer .h>
1213#include <linux/interrupt.h>
1314#include <linux/leds.h>
1415#include <linux/slab.h>
1516#include "../leds.h"
1617
1718struct gpio_trig_data {
1819 struct led_classdev * led ;
19-
2020 unsigned desired_brightness ; /* desired brightness when led is on */
21- unsigned inverted ; /* true when gpio is inverted */
22- unsigned gpio ; /* gpio that triggers the leds */
21+ struct gpio_desc * gpiod ; /* gpio that triggers the led */
2322};
2423
2524static irqreturn_t gpio_trig_irq (int irq , void * _led )
@@ -28,10 +27,7 @@ static irqreturn_t gpio_trig_irq(int irq, void *_led)
2827 struct gpio_trig_data * gpio_data = led_get_trigger_data (led );
2928 int tmp ;
3029
31- tmp = gpio_get_value_cansleep (gpio_data -> gpio );
32- if (gpio_data -> inverted )
33- tmp = !tmp ;
34-
30+ tmp = gpiod_get_value_cansleep (gpio_data -> gpiod );
3531 if (tmp ) {
3632 if (gpio_data -> desired_brightness )
3733 led_set_brightness_nosleep (gpio_data -> led ,
@@ -73,119 +69,66 @@ static ssize_t gpio_trig_brightness_store(struct device *dev,
7369static DEVICE_ATTR (desired_brightness , 0644 , gpio_trig_brightness_show ,
7470 gpio_trig_brightness_store ) ;
7571
76- static ssize_t gpio_trig_inverted_show (struct device * dev ,
77- struct device_attribute * attr , char * buf )
78- {
79- struct gpio_trig_data * gpio_data = led_trigger_get_drvdata (dev );
80-
81- return sprintf (buf , "%u\n" , gpio_data -> inverted );
82- }
83-
84- static ssize_t gpio_trig_inverted_store (struct device * dev ,
85- struct device_attribute * attr , const char * buf , size_t n )
86- {
87- struct led_classdev * led = led_trigger_get_led (dev );
88- struct gpio_trig_data * gpio_data = led_trigger_get_drvdata (dev );
89- unsigned long inverted ;
90- int ret ;
91-
92- ret = kstrtoul (buf , 10 , & inverted );
93- if (ret < 0 )
94- return ret ;
95-
96- if (inverted > 1 )
97- return - EINVAL ;
98-
99- gpio_data -> inverted = inverted ;
100-
101- /* After inverting, we need to update the LED. */
102- if (gpio_is_valid (gpio_data -> gpio ))
103- gpio_trig_irq (0 , led );
104-
105- return n ;
106- }
107- static DEVICE_ATTR (inverted , 0644 , gpio_trig_inverted_show ,
108- gpio_trig_inverted_store ) ;
109-
110- static ssize_t gpio_trig_gpio_show (struct device * dev ,
111- struct device_attribute * attr , char * buf )
112- {
113- struct gpio_trig_data * gpio_data = led_trigger_get_drvdata (dev );
114-
115- return sprintf (buf , "%u\n" , gpio_data -> gpio );
116- }
117-
118- static ssize_t gpio_trig_gpio_store (struct device * dev ,
119- struct device_attribute * attr , const char * buf , size_t n )
120- {
121- struct led_classdev * led = led_trigger_get_led (dev );
122- struct gpio_trig_data * gpio_data = led_trigger_get_drvdata (dev );
123- unsigned gpio ;
124- int ret ;
125-
126- ret = sscanf (buf , "%u" , & gpio );
127- if (ret < 1 ) {
128- dev_err (dev , "couldn't read gpio number\n" );
129- return - EINVAL ;
130- }
131-
132- if (gpio_data -> gpio == gpio )
133- return n ;
134-
135- if (!gpio_is_valid (gpio )) {
136- if (gpio_is_valid (gpio_data -> gpio ))
137- free_irq (gpio_to_irq (gpio_data -> gpio ), led );
138- gpio_data -> gpio = gpio ;
139- return n ;
140- }
141-
142- ret = request_threaded_irq (gpio_to_irq (gpio ), NULL , gpio_trig_irq ,
143- IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING
144- | IRQF_TRIGGER_FALLING , "ledtrig-gpio" , led );
145- if (ret ) {
146- dev_err (dev , "request_irq failed with error %d\n" , ret );
147- } else {
148- if (gpio_is_valid (gpio_data -> gpio ))
149- free_irq (gpio_to_irq (gpio_data -> gpio ), led );
150- gpio_data -> gpio = gpio ;
151- /* After changing the GPIO, we need to update the LED. */
152- gpio_trig_irq (0 , led );
153- }
154-
155- return ret ? ret : n ;
156- }
157- static DEVICE_ATTR (gpio , 0644 , gpio_trig_gpio_show , gpio_trig_gpio_store ) ;
158-
15972static struct attribute * gpio_trig_attrs [] = {
16073 & dev_attr_desired_brightness .attr ,
161- & dev_attr_inverted .attr ,
162- & dev_attr_gpio .attr ,
16374 NULL
16475};
16576ATTRIBUTE_GROUPS (gpio_trig );
16677
16778static int gpio_trig_activate (struct led_classdev * led )
16879{
16980 struct gpio_trig_data * gpio_data ;
81+ struct device * dev = led -> dev ;
82+ int ret ;
17083
17184 gpio_data = kzalloc (sizeof (* gpio_data ), GFP_KERNEL );
17285 if (!gpio_data )
17386 return - ENOMEM ;
17487
175- gpio_data -> led = led ;
176- gpio_data -> gpio = - ENOENT ;
88+ /*
89+ * The generic property "trigger-sources" is followed,
90+ * and we hope that this is a GPIO.
91+ */
92+ gpio_data -> gpiod = fwnode_gpiod_get_index (dev -> fwnode ,
93+ "trigger-sources" ,
94+ 0 , GPIOD_IN ,
95+ "led-trigger" );
96+ if (IS_ERR (gpio_data -> gpiod )) {
97+ ret = PTR_ERR (gpio_data -> gpiod );
98+ kfree (gpio_data );
99+ return ret ;
100+ }
101+ if (!gpio_data -> gpiod ) {
102+ dev_err (dev , "no valid GPIO for the trigger\n" );
103+ kfree (gpio_data );
104+ return - EINVAL ;
105+ }
177106
107+ gpio_data -> led = led ;
178108 led_set_trigger_data (led , gpio_data );
179109
110+ ret = request_threaded_irq (gpiod_to_irq (gpio_data -> gpiod ), NULL , gpio_trig_irq ,
111+ IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_RISING
112+ | IRQF_TRIGGER_FALLING , "ledtrig-gpio" , led );
113+ if (ret ) {
114+ dev_err (dev , "request_irq failed with error %d\n" , ret );
115+ gpiod_put (gpio_data -> gpiod );
116+ kfree (gpio_data );
117+ return ret ;
118+ }
119+
120+ /* Finally update the LED to initial status */
121+ gpio_trig_irq (0 , led );
122+
180123 return 0 ;
181124}
182125
183126static void gpio_trig_deactivate (struct led_classdev * led )
184127{
185128 struct gpio_trig_data * gpio_data = led_get_trigger_data (led );
186129
187- if ( gpio_is_valid (gpio_data -> gpio ))
188- free_irq ( gpio_to_irq ( gpio_data -> gpio ), led );
130+ free_irq ( gpiod_to_irq (gpio_data -> gpiod ), led );
131+ gpiod_put ( gpio_data -> gpiod );
189132 kfree (gpio_data );
190133}
191134
0 commit comments