59473f286b31f1ccbf6131e1b1da42f5b9144f68
[linux-2.6-block.git] / drivers / leds / led-core.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * LED Class Core
4  *
5  * Copyright 2005-2006 Openedhand Ltd.
6  *
7  * Author: Richard Purdie <rpurdie@openedhand.com>
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/led-class-multicolor.h>
12 #include <linux/leds.h>
13 #include <linux/list.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
16 #include <linux/of.h>
17 #include <linux/property.h>
18 #include <linux/rwsem.h>
19 #include <linux/slab.h>
20 #include <uapi/linux/uleds.h>
21 #include "leds.h"
22
23 DECLARE_RWSEM(leds_list_lock);
24 EXPORT_SYMBOL_GPL(leds_list_lock);
25
26 LIST_HEAD(leds_list);
27 EXPORT_SYMBOL_GPL(leds_list);
28
29 static const char * const led_colors[LED_COLOR_ID_MAX] = {
30         [LED_COLOR_ID_WHITE] = "white",
31         [LED_COLOR_ID_RED] = "red",
32         [LED_COLOR_ID_GREEN] = "green",
33         [LED_COLOR_ID_BLUE] = "blue",
34         [LED_COLOR_ID_AMBER] = "amber",
35         [LED_COLOR_ID_VIOLET] = "violet",
36         [LED_COLOR_ID_YELLOW] = "yellow",
37         [LED_COLOR_ID_IR] = "ir",
38         [LED_COLOR_ID_MULTI] = "multicolor",
39         [LED_COLOR_ID_RGB] = "rgb",
40         [LED_COLOR_ID_PURPLE] = "purple",
41         [LED_COLOR_ID_ORANGE] = "orange",
42         [LED_COLOR_ID_PINK] = "pink",
43         [LED_COLOR_ID_CYAN] = "cyan",
44         [LED_COLOR_ID_LIME] = "lime",
45 };
46
47 static int __led_set_brightness(struct led_classdev *led_cdev, unsigned int value)
48 {
49         if (!led_cdev->brightness_set)
50                 return -ENOTSUPP;
51
52         led_cdev->brightness_set(led_cdev, value);
53
54         return 0;
55 }
56
57 static int __led_set_brightness_blocking(struct led_classdev *led_cdev, unsigned int value)
58 {
59         if (!led_cdev->brightness_set_blocking)
60                 return -ENOTSUPP;
61
62         return led_cdev->brightness_set_blocking(led_cdev, value);
63 }
64
65 static void led_timer_function(struct timer_list *t)
66 {
67         struct led_classdev *led_cdev = timer_container_of(led_cdev, t,
68                                                            blink_timer);
69         unsigned long brightness;
70         unsigned long delay;
71
72         if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) {
73                 led_set_brightness_nosleep(led_cdev, LED_OFF);
74                 clear_bit(LED_BLINK_SW, &led_cdev->work_flags);
75                 return;
76         }
77
78         if (test_and_clear_bit(LED_BLINK_ONESHOT_STOP,
79                                &led_cdev->work_flags)) {
80                 clear_bit(LED_BLINK_SW, &led_cdev->work_flags);
81                 return;
82         }
83
84         brightness = led_get_brightness(led_cdev);
85         if (!brightness) {
86                 /* Time to switch the LED on. */
87                 if (test_and_clear_bit(LED_BLINK_BRIGHTNESS_CHANGE,
88                                         &led_cdev->work_flags))
89                         brightness = led_cdev->new_blink_brightness;
90                 else
91                         brightness = led_cdev->blink_brightness;
92                 delay = led_cdev->blink_delay_on;
93         } else {
94                 /* Store the current brightness value to be able
95                  * to restore it when the delay_off period is over.
96                  */
97                 led_cdev->blink_brightness = brightness;
98                 brightness = LED_OFF;
99                 delay = led_cdev->blink_delay_off;
100         }
101
102         led_set_brightness_nosleep(led_cdev, brightness);
103
104         /* Return in next iteration if led is in one-shot mode and we are in
105          * the final blink state so that the led is toggled each delay_on +
106          * delay_off milliseconds in worst case.
107          */
108         if (test_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags)) {
109                 if (test_bit(LED_BLINK_INVERT, &led_cdev->work_flags)) {
110                         if (brightness)
111                                 set_bit(LED_BLINK_ONESHOT_STOP,
112                                         &led_cdev->work_flags);
113                 } else {
114                         if (!brightness)
115                                 set_bit(LED_BLINK_ONESHOT_STOP,
116                                         &led_cdev->work_flags);
117                 }
118         }
119
120         mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
121 }
122
123 static void set_brightness_delayed_set_brightness(struct led_classdev *led_cdev,
124                                                   unsigned int value)
125 {
126         int ret;
127
128         ret = __led_set_brightness(led_cdev, value);
129         if (ret == -ENOTSUPP) {
130                 ret = __led_set_brightness_blocking(led_cdev, value);
131                 if (ret == -ENOTSUPP)
132                         /* No back-end support to set a fixed brightness value */
133                         return;
134         }
135
136         /* LED HW might have been unplugged, therefore don't warn */
137         if (ret == -ENODEV && led_cdev->flags & LED_UNREGISTERING &&
138             led_cdev->flags & LED_HW_PLUGGABLE)
139                 return;
140
141         if (ret < 0)
142                 dev_err(led_cdev->dev,
143                         "Setting an LED's brightness failed (%d)\n", ret);
144 }
145
146 static void set_brightness_delayed(struct work_struct *ws)
147 {
148         struct led_classdev *led_cdev =
149                 container_of(ws, struct led_classdev, set_brightness_work);
150
151         if (test_and_clear_bit(LED_BLINK_DISABLE, &led_cdev->work_flags)) {
152                 led_stop_software_blink(led_cdev);
153                 set_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags);
154         }
155
156         /*
157          * Triggers may call led_set_brightness(LED_OFF),
158          * led_set_brightness(LED_FULL) in quick succession to disable blinking
159          * and turn the LED on. Both actions may have been scheduled to run
160          * before this work item runs once. To make sure this works properly
161          * handle LED_SET_BRIGHTNESS_OFF first.
162          */
163         if (test_and_clear_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags)) {
164                 set_brightness_delayed_set_brightness(led_cdev, LED_OFF);
165                 /*
166                  * The consecutives led_set_brightness(LED_OFF),
167                  * led_set_brightness(LED_FULL) could have been executed out of
168                  * order (LED_FULL first), if the work_flags has been set
169                  * between LED_SET_BRIGHTNESS_OFF and LED_SET_BRIGHTNESS of this
170                  * work. To avoid ending with the LED turned off, turn the LED
171                  * on again.
172                  */
173                 if (led_cdev->delayed_set_value != LED_OFF)
174                         set_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags);
175         }
176
177         if (test_and_clear_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags))
178                 set_brightness_delayed_set_brightness(led_cdev, led_cdev->delayed_set_value);
179
180         if (test_and_clear_bit(LED_SET_BLINK, &led_cdev->work_flags)) {
181                 unsigned long delay_on = led_cdev->delayed_delay_on;
182                 unsigned long delay_off = led_cdev->delayed_delay_off;
183
184                 led_blink_set(led_cdev, &delay_on, &delay_off);
185         }
186 }
187
188 static void led_set_software_blink(struct led_classdev *led_cdev,
189                                    unsigned long delay_on,
190                                    unsigned long delay_off)
191 {
192         int current_brightness;
193
194         current_brightness = led_get_brightness(led_cdev);
195         if (current_brightness)
196                 led_cdev->blink_brightness = current_brightness;
197         if (!led_cdev->blink_brightness)
198                 led_cdev->blink_brightness = led_cdev->max_brightness;
199
200         led_cdev->blink_delay_on = delay_on;
201         led_cdev->blink_delay_off = delay_off;
202
203         /* never on - just set to off */
204         if (!delay_on) {
205                 led_set_brightness_nosleep(led_cdev, LED_OFF);
206                 return;
207         }
208
209         /* never off - just set to brightness */
210         if (!delay_off) {
211                 led_set_brightness_nosleep(led_cdev,
212                                            led_cdev->blink_brightness);
213                 return;
214         }
215
216         set_bit(LED_BLINK_SW, &led_cdev->work_flags);
217         mod_timer(&led_cdev->blink_timer, jiffies + 1);
218 }
219
220
221 static void led_blink_setup(struct led_classdev *led_cdev,
222                      unsigned long *delay_on,
223                      unsigned long *delay_off)
224 {
225         if (!test_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags) &&
226             led_cdev->blink_set &&
227             !led_cdev->blink_set(led_cdev, delay_on, delay_off))
228                 return;
229
230         /* blink with 1 Hz as default if nothing specified */
231         if (!*delay_on && !*delay_off)
232                 *delay_on = *delay_off = 500;
233
234         led_set_software_blink(led_cdev, *delay_on, *delay_off);
235 }
236
237 void led_init_core(struct led_classdev *led_cdev)
238 {
239         INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
240
241         timer_setup(&led_cdev->blink_timer, led_timer_function, 0);
242 }
243 EXPORT_SYMBOL_GPL(led_init_core);
244
245 void led_blink_set(struct led_classdev *led_cdev,
246                    unsigned long *delay_on,
247                    unsigned long *delay_off)
248 {
249         timer_delete_sync(&led_cdev->blink_timer);
250
251         clear_bit(LED_BLINK_SW, &led_cdev->work_flags);
252         clear_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags);
253         clear_bit(LED_BLINK_ONESHOT_STOP, &led_cdev->work_flags);
254
255         led_blink_setup(led_cdev, delay_on, delay_off);
256 }
257 EXPORT_SYMBOL_GPL(led_blink_set);
258
259 void led_blink_set_oneshot(struct led_classdev *led_cdev,
260                            unsigned long *delay_on,
261                            unsigned long *delay_off,
262                            int invert)
263 {
264         if (test_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags) &&
265              timer_pending(&led_cdev->blink_timer))
266                 return;
267
268         set_bit(LED_BLINK_ONESHOT, &led_cdev->work_flags);
269         clear_bit(LED_BLINK_ONESHOT_STOP, &led_cdev->work_flags);
270
271         if (invert)
272                 set_bit(LED_BLINK_INVERT, &led_cdev->work_flags);
273         else
274                 clear_bit(LED_BLINK_INVERT, &led_cdev->work_flags);
275
276         led_blink_setup(led_cdev, delay_on, delay_off);
277 }
278 EXPORT_SYMBOL_GPL(led_blink_set_oneshot);
279
280 void led_blink_set_nosleep(struct led_classdev *led_cdev, unsigned long delay_on,
281                            unsigned long delay_off)
282 {
283         /* If necessary delegate to a work queue task. */
284         if (led_cdev->blink_set && led_cdev->brightness_set_blocking) {
285                 led_cdev->delayed_delay_on = delay_on;
286                 led_cdev->delayed_delay_off = delay_off;
287                 set_bit(LED_SET_BLINK, &led_cdev->work_flags);
288                 queue_work(led_cdev->wq, &led_cdev->set_brightness_work);
289                 return;
290         }
291
292         led_blink_set(led_cdev, &delay_on, &delay_off);
293 }
294 EXPORT_SYMBOL_GPL(led_blink_set_nosleep);
295
296 void led_stop_software_blink(struct led_classdev *led_cdev)
297 {
298         timer_delete_sync(&led_cdev->blink_timer);
299         led_cdev->blink_delay_on = 0;
300         led_cdev->blink_delay_off = 0;
301         clear_bit(LED_BLINK_SW, &led_cdev->work_flags);
302 }
303 EXPORT_SYMBOL_GPL(led_stop_software_blink);
304
305 void led_set_brightness(struct led_classdev *led_cdev, unsigned int brightness)
306 {
307         /*
308          * If software blink is active, delay brightness setting
309          * until the next timer tick.
310          */
311         if (test_bit(LED_BLINK_SW, &led_cdev->work_flags)) {
312                 /*
313                  * If we need to disable soft blinking delegate this to the
314                  * work queue task to avoid problems in case we are called
315                  * from hard irq context.
316                  */
317                 if (!brightness) {
318                         set_bit(LED_BLINK_DISABLE, &led_cdev->work_flags);
319                         queue_work(led_cdev->wq, &led_cdev->set_brightness_work);
320                 } else {
321                         set_bit(LED_BLINK_BRIGHTNESS_CHANGE,
322                                 &led_cdev->work_flags);
323                         led_cdev->new_blink_brightness = brightness;
324                 }
325                 return;
326         }
327
328         led_set_brightness_nosleep(led_cdev, brightness);
329 }
330 EXPORT_SYMBOL_GPL(led_set_brightness);
331
332 void led_set_brightness_nopm(struct led_classdev *led_cdev, unsigned int value)
333 {
334         /* Use brightness_set op if available, it is guaranteed not to sleep */
335         if (!__led_set_brightness(led_cdev, value))
336                 return;
337
338         /*
339          * Brightness setting can sleep, delegate it to a work queue task.
340          * value 0 / LED_OFF is special, since it also disables hw-blinking
341          * (sw-blink disable is handled in led_set_brightness()).
342          * To avoid a hw-blink-disable getting lost when a second brightness
343          * change is done immediately afterwards (before the work runs),
344          * it uses a separate work_flag.
345          */
346         led_cdev->delayed_set_value = value;
347         /* Ensure delayed_set_value is seen before work_flags modification */
348         smp_mb__before_atomic();
349
350         if (value)
351                 set_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags);
352         else {
353                 clear_bit(LED_SET_BRIGHTNESS, &led_cdev->work_flags);
354                 clear_bit(LED_SET_BLINK, &led_cdev->work_flags);
355                 set_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags);
356         }
357
358         queue_work(led_cdev->wq, &led_cdev->set_brightness_work);
359 }
360 EXPORT_SYMBOL_GPL(led_set_brightness_nopm);
361
362 void led_set_brightness_nosleep(struct led_classdev *led_cdev, unsigned int value)
363 {
364         led_cdev->brightness = min(value, led_cdev->max_brightness);
365
366         if (led_cdev->flags & LED_SUSPENDED)
367                 return;
368
369         led_set_brightness_nopm(led_cdev, led_cdev->brightness);
370 }
371 EXPORT_SYMBOL_GPL(led_set_brightness_nosleep);
372
373 int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value)
374 {
375         if (led_cdev->blink_delay_on || led_cdev->blink_delay_off)
376                 return -EBUSY;
377
378         led_cdev->brightness = min(value, led_cdev->max_brightness);
379
380         if (led_cdev->flags & LED_SUSPENDED)
381                 return 0;
382
383         return __led_set_brightness_blocking(led_cdev, led_cdev->brightness);
384 }
385 EXPORT_SYMBOL_GPL(led_set_brightness_sync);
386
387 /*
388  * This is a led-core function because just like led_set_brightness()
389  * it is used in the kernel by e.g. triggers.
390  */
391 void led_mc_set_brightness(struct led_classdev *led_cdev,
392                            unsigned int *intensity_value, unsigned int num_colors,
393                            unsigned int brightness)
394 {
395         struct led_classdev_mc *mcled_cdev;
396         unsigned int i;
397
398         if (!(led_cdev->flags & LED_MULTI_COLOR)) {
399                 dev_err_once(led_cdev->dev, "error not a multi-color LED\n");
400                 return;
401         }
402
403         mcled_cdev = lcdev_to_mccdev(led_cdev);
404         if (num_colors != mcled_cdev->num_colors) {
405                 dev_err_once(led_cdev->dev, "error num_colors mismatch %u != %u\n",
406                              num_colors, mcled_cdev->num_colors);
407                 return;
408         }
409
410         for (i = 0; i < mcled_cdev->num_colors; i++)
411                 mcled_cdev->subled_info[i].intensity = intensity_value[i];
412
413         led_set_brightness(led_cdev, brightness);
414 }
415 EXPORT_SYMBOL_GPL(led_mc_set_brightness);
416
417 int led_update_brightness(struct led_classdev *led_cdev)
418 {
419         int ret;
420
421         if (led_cdev->brightness_get) {
422                 ret = led_cdev->brightness_get(led_cdev);
423                 if (ret < 0)
424                         return ret;
425
426                 led_cdev->brightness = ret;
427         }
428
429         return 0;
430 }
431 EXPORT_SYMBOL_GPL(led_update_brightness);
432
433 u32 *led_get_default_pattern(struct led_classdev *led_cdev, unsigned int *size)
434 {
435         struct fwnode_handle *fwnode = led_cdev->dev->fwnode;
436         u32 *pattern;
437         int count;
438
439         count = fwnode_property_count_u32(fwnode, "led-pattern");
440         if (count < 0)
441                 return NULL;
442
443         pattern = kcalloc(count, sizeof(*pattern), GFP_KERNEL);
444         if (!pattern)
445                 return NULL;
446
447         if (fwnode_property_read_u32_array(fwnode, "led-pattern", pattern, count)) {
448                 kfree(pattern);
449                 return NULL;
450         }
451
452         *size = count;
453
454         return pattern;
455 }
456 EXPORT_SYMBOL_GPL(led_get_default_pattern);
457
458 /* Caller must ensure led_cdev->led_access held */
459 void led_sysfs_disable(struct led_classdev *led_cdev)
460 {
461         lockdep_assert_held(&led_cdev->led_access);
462
463         led_cdev->flags |= LED_SYSFS_DISABLE;
464 }
465 EXPORT_SYMBOL_GPL(led_sysfs_disable);
466
467 /* Caller must ensure led_cdev->led_access held */
468 void led_sysfs_enable(struct led_classdev *led_cdev)
469 {
470         lockdep_assert_held(&led_cdev->led_access);
471
472         led_cdev->flags &= ~LED_SYSFS_DISABLE;
473 }
474 EXPORT_SYMBOL_GPL(led_sysfs_enable);
475
476 static void led_parse_fwnode_props(struct device *dev,
477                                    struct fwnode_handle *fwnode,
478                                    struct led_properties *props)
479 {
480         int ret;
481
482         if (!fwnode)
483                 return;
484
485         if (fwnode_property_present(fwnode, "label")) {
486                 ret = fwnode_property_read_string(fwnode, "label", &props->label);
487                 if (ret)
488                         dev_err(dev, "Error parsing 'label' property (%d)\n", ret);
489                 return;
490         }
491
492         if (fwnode_property_present(fwnode, "color")) {
493                 ret = fwnode_property_read_u32(fwnode, "color", &props->color);
494                 if (ret)
495                         dev_err(dev, "Error parsing 'color' property (%d)\n", ret);
496                 else if (props->color >= LED_COLOR_ID_MAX)
497                         dev_err(dev, "LED color identifier out of range\n");
498                 else
499                         props->color_present = true;
500         }
501
502
503         if (!fwnode_property_present(fwnode, "function"))
504                 return;
505
506         ret = fwnode_property_read_string(fwnode, "function", &props->function);
507         if (ret) {
508                 dev_err(dev,
509                         "Error parsing 'function' property (%d)\n",
510                         ret);
511         }
512
513         if (!fwnode_property_present(fwnode, "function-enumerator"))
514                 return;
515
516         ret = fwnode_property_read_u32(fwnode, "function-enumerator",
517                                        &props->func_enum);
518         if (ret) {
519                 dev_err(dev,
520                         "Error parsing 'function-enumerator' property (%d)\n",
521                         ret);
522         } else {
523                 props->func_enum_present = true;
524         }
525 }
526
527 int led_compose_name(struct device *dev, struct led_init_data *init_data,
528                      char *led_classdev_name)
529 {
530         struct led_properties props = {};
531         struct fwnode_handle *fwnode = init_data->fwnode;
532         const char *devicename = init_data->devicename;
533         int n;
534
535         if (!led_classdev_name)
536                 return -EINVAL;
537
538         led_parse_fwnode_props(dev, fwnode, &props);
539
540         if (props.label) {
541                 /*
542                  * If init_data.devicename is NULL, then it indicates that
543                  * DT label should be used as-is for LED class device name.
544                  * Otherwise the label is prepended with devicename to compose
545                  * the final LED class device name.
546                  */
547                 if (devicename) {
548                         n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
549                                      devicename, props.label);
550                 } else {
551                         n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s", props.label);
552                 }
553         } else if (props.function || props.color_present) {
554                 char tmp_buf[LED_MAX_NAME_SIZE];
555
556                 if (props.func_enum_present) {
557                         n = snprintf(tmp_buf, LED_MAX_NAME_SIZE, "%s:%s-%d",
558                                      props.color_present ? led_colors[props.color] : "",
559                                      props.function ?: "", props.func_enum);
560                 } else {
561                         n = snprintf(tmp_buf, LED_MAX_NAME_SIZE, "%s:%s",
562                                      props.color_present ? led_colors[props.color] : "",
563                                      props.function ?: "");
564                 }
565                 if (n >= LED_MAX_NAME_SIZE)
566                         return -E2BIG;
567
568                 if (init_data->devname_mandatory) {
569                         n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
570                                      devicename, tmp_buf);
571                 } else {
572                         n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s", tmp_buf);
573                 }
574         } else if (init_data->default_label) {
575                 if (!devicename) {
576                         dev_err(dev, "Legacy LED naming requires devicename segment");
577                         return -EINVAL;
578                 }
579                 n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
580                              devicename, init_data->default_label);
581         } else if (is_of_node(fwnode)) {
582                 n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s",
583                              to_of_node(fwnode)->name);
584         } else
585                 return -EINVAL;
586
587         if (n >= LED_MAX_NAME_SIZE)
588                 return -E2BIG;
589
590         return 0;
591 }
592 EXPORT_SYMBOL_GPL(led_compose_name);
593
594 const char *led_get_color_name(u8 color_id)
595 {
596         if (color_id >= ARRAY_SIZE(led_colors))
597                 return NULL;
598
599         return led_colors[color_id];
600 }
601 EXPORT_SYMBOL_GPL(led_get_color_name);
602
603 enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode)
604 {
605         const char *state = NULL;
606
607         if (!fwnode_property_read_string(fwnode, "default-state", &state)) {
608                 if (!strcmp(state, "keep"))
609                         return LEDS_DEFSTATE_KEEP;
610                 if (!strcmp(state, "on"))
611                         return LEDS_DEFSTATE_ON;
612         }
613
614         return LEDS_DEFSTATE_OFF;
615 }
616 EXPORT_SYMBOL_GPL(led_init_default_state_get);