Commit 5607ca92 authored by Hans de Goede's avatar Hans de Goede Committed by Lee Jones

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: default avatarHans de Goede <hdegoede@redhat.com>
Reviewed-by: default avatarJacek Anaszewski <jacek.anaszewski@gmail.com>
Reviewed-by: default avatarAndy Shevchenko <andy@kernel.org>
Link: https://lore.kernel.org/r/20240531114124.45346-5-hdegoede@redhat.comSigned-off-by: default avatarLee Jones <lee@kernel.org>
parent e1b08c6f
...@@ -134,6 +134,7 @@ int led_classdev_multicolor_register_ext(struct device *parent, ...@@ -134,6 +134,7 @@ int led_classdev_multicolor_register_ext(struct device *parent,
return -EINVAL; return -EINVAL;
led_cdev = &mcled_cdev->led_cdev; led_cdev = &mcled_cdev->led_cdev;
led_cdev->flags |= LED_MULTI_COLOR;
mcled_cdev->led_cdev.groups = led_multicolor_groups; mcled_cdev->led_cdev.groups = led_multicolor_groups;
return led_classdev_register_ext(parent, led_cdev, init_data); return led_classdev_register_ext(parent, led_cdev, init_data);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/led-class-multicolor.h>
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -362,6 +363,36 @@ int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value) ...@@ -362,6 +363,36 @@ int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value)
} }
EXPORT_SYMBOL_GPL(led_set_brightness_sync); EXPORT_SYMBOL_GPL(led_set_brightness_sync);
/*
* This is a led-core function because just like led_set_brightness()
* it is used in the kernel by e.g. triggers.
*/
void led_mc_set_brightness(struct led_classdev *led_cdev,
unsigned int *intensity_value, unsigned int num_colors,
unsigned int brightness)
{
struct led_classdev_mc *mcled_cdev;
unsigned int i;
if (!(led_cdev->flags & LED_MULTI_COLOR)) {
dev_err_once(led_cdev->dev, "error not a multi-color LED\n");
return;
}
mcled_cdev = lcdev_to_mccdev(led_cdev);
if (num_colors != mcled_cdev->num_colors) {
dev_err_once(led_cdev->dev, "error num_colors mismatch %u != %u\n",
num_colors, mcled_cdev->num_colors);
return;
}
for (i = 0; i < mcled_cdev->num_colors; i++)
mcled_cdev->subled_info[i].intensity = intensity_value[i];
led_set_brightness(led_cdev, brightness);
}
EXPORT_SYMBOL_GPL(led_mc_set_brightness);
int led_update_brightness(struct led_classdev *led_cdev) int led_update_brightness(struct led_classdev *led_cdev)
{ {
int ret; int ret;
......
...@@ -107,6 +107,7 @@ struct led_classdev { ...@@ -107,6 +107,7 @@ struct led_classdev {
#define LED_BRIGHT_HW_CHANGED BIT(21) #define LED_BRIGHT_HW_CHANGED BIT(21)
#define LED_RETAIN_AT_SHUTDOWN BIT(22) #define LED_RETAIN_AT_SHUTDOWN BIT(22)
#define LED_INIT_DEFAULT_TRIGGER BIT(23) #define LED_INIT_DEFAULT_TRIGGER BIT(23)
#define LED_MULTI_COLOR BIT(24)
/* set_brightness_work / blink_timer flags, atomic, private. */ /* set_brightness_work / blink_timer flags, atomic, private. */
unsigned long work_flags; unsigned long work_flags;
...@@ -373,6 +374,25 @@ void led_set_brightness(struct led_classdev *led_cdev, unsigned int brightness); ...@@ -373,6 +374,25 @@ void led_set_brightness(struct led_classdev *led_cdev, unsigned int brightness);
*/ */
int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value); int led_set_brightness_sync(struct led_classdev *led_cdev, unsigned int value);
/**
* led_mc_set_brightness - set mc LED color intensity values and brightness
* @led_cdev: the LED to set
* @intensity_value: array of per color intensity values to set
* @num_colors: amount of entries in intensity_value array
* @brightness: the brightness to set the LED to
*
* Set a multi-color LED's per color intensity values and brightness.
* If necessary, this cancels the software blink timer. This function is
* guaranteed not to sleep.
*
* Calling this function on a non multi-color led_classdev or with the wrong
* num_colors value is an error. In this case an error will be logged once
* and the call will do nothing.
*/
void led_mc_set_brightness(struct led_classdev *led_cdev,
unsigned int *intensity_value, unsigned int num_colors,
unsigned int brightness);
/** /**
* led_update_brightness - update LED brightness * led_update_brightness - update LED brightness
* @led_cdev: the LED to query * @led_cdev: the LED to query
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment