Skip to content

Commit 5607ca9

Browse files
jwrdegoedelag-linaro
authored andcommitted
leds: core: Add led_mc_set_brightness() function
Add a new led_mc_set_brightness() function for in kernel color/brightness changing of multi-color LEDs. led-class-multicolor can be build as a module and led_mc_set_brightness() will have the builtin callers, so put led_mc_set_brightness() inside led-core instead, just like how led_set_brightness() is part of the core and not of the led-class object. This also adds a new LED_MULTI_COLOR led_classdev flag to allow led_mc_set_brightness() to verify that it is operating on a multi-color LED classdev, avoiding casting the passed in LED classdev to a multi-color LED classdev, when it actually is not a multi-color LED. Signed-off-by: Hans de Goede <[email protected]> Reviewed-by: Jacek Anaszewski <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Lee Jones <[email protected]>
1 parent e1b08c6 commit 5607ca9

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

drivers/leds/led-class-multicolor.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ int led_classdev_multicolor_register_ext(struct device *parent,
134134
return -EINVAL;
135135

136136
led_cdev = &mcled_cdev->led_cdev;
137+
led_cdev->flags |= LED_MULTI_COLOR;
137138
mcled_cdev->led_cdev.groups = led_multicolor_groups;
138139

139140
return led_classdev_register_ext(parent, led_cdev, init_data);

drivers/leds/led-core.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include <linux/kernel.h>
11+
#include <linux/led-class-multicolor.h>
1112
#include <linux/leds.h>
1213
#include <linux/list.h>
1314
#include <linux/module.h>
@@ -362,6 +363,36 @@ int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value)
362363
}
363364
EXPORT_SYMBOL_GPL(led_set_brightness_sync);
364365

366+
/*
367+
* This is a led-core function because just like led_set_brightness()
368+
* it is used in the kernel by e.g. triggers.
369+
*/
370+
void led_mc_set_brightness(struct led_classdev *led_cdev,
371+
unsigned int *intensity_value, unsigned int num_colors,
372+
unsigned int brightness)
373+
{
374+
struct led_classdev_mc *mcled_cdev;
375+
unsigned int i;
376+
377+
if (!(led_cdev->flags & LED_MULTI_COLOR)) {
378+
dev_err_once(led_cdev->dev, "error not a multi-color LED\n");
379+
return;
380+
}
381+
382+
mcled_cdev = lcdev_to_mccdev(led_cdev);
383+
if (num_colors != mcled_cdev->num_colors) {
384+
dev_err_once(led_cdev->dev, "error num_colors mismatch %u != %u\n",
385+
num_colors, mcled_cdev->num_colors);
386+
return;
387+
}
388+
389+
for (i = 0; i < mcled_cdev->num_colors; i++)
390+
mcled_cdev->subled_info[i].intensity = intensity_value[i];
391+
392+
led_set_brightness(led_cdev, brightness);
393+
}
394+
EXPORT_SYMBOL_GPL(led_mc_set_brightness);
395+
365396
int led_update_brightness(struct led_classdev *led_cdev)
366397
{
367398
int ret;

include/linux/leds.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ struct led_classdev {
107107
#define LED_BRIGHT_HW_CHANGED BIT(21)
108108
#define LED_RETAIN_AT_SHUTDOWN BIT(22)
109109
#define LED_INIT_DEFAULT_TRIGGER BIT(23)
110+
#define LED_MULTI_COLOR BIT(24)
110111

111112
/* set_brightness_work / blink_timer flags, atomic, private. */
112113
unsigned long work_flags;
@@ -373,6 +374,25 @@ void led_set_brightness(struct led_classdev *led_cdev, unsigned int brightness);
373374
*/
374375
int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value);
375376

377+
/**
378+
* led_mc_set_brightness - set mc LED color intensity values and brightness
379+
* @led_cdev: the LED to set
380+
* @intensity_value: array of per color intensity values to set
381+
* @num_colors: amount of entries in intensity_value array
382+
* @brightness: the brightness to set the LED to
383+
*
384+
* Set a multi-color LED's per color intensity values and brightness.
385+
* If necessary, this cancels the software blink timer. This function is
386+
* guaranteed not to sleep.
387+
*
388+
* Calling this function on a non multi-color led_classdev or with the wrong
389+
* num_colors value is an error. In this case an error will be logged once
390+
* and the call will do nothing.
391+
*/
392+
void led_mc_set_brightness(struct led_classdev *led_cdev,
393+
unsigned int *intensity_value, unsigned int num_colors,
394+
unsigned int brightness);
395+
376396
/**
377397
* led_update_brightness - update LED brightness
378398
* @led_cdev: the LED to query

0 commit comments

Comments
 (0)