leds: triggers: add led_trigger_range_event for RGB triggers
PATCH v2 2/3 leds: triggers: add led_trigger_range_event for RGB triggers
Add led_trigger_range_event() and supporting struct led_rgb_range allowing to map a value within a value range to a color within a color range.
Simple example would be to map a temperature with in a range to a color between green and red.
Signed-off-by Heiner Kallweit <[email protected]>
---
v2:
- moved the actual mapping to a helper in led-rgb-core.c
- adjusted commit message
- renamed struct led_trigger_range to led_rgb_range
--- drivers/leds/led-rgb-core.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/linux/leds.h | 25 +++++++++++++++++++++++++ 2 files changed, 65 insertions(+)
drivers/leds/led-rgb-core.c +40 -0
@@ -73,3 +73,43 @@ enum led_brightness led_hsv_to_rgb(enum led_brightness hsv)return (r <<16 ) + (g <<8 ) + b; }EXPORT_SYMBOL_GPL (led_hsv_to_rgb); + +static inline int led_range_interpolate (int value, +const struct led_rgb_range *range, +int x_start,int x_end) +{ +return x_start +DIV_ROUND_CLOSEST ((value - range->start) * + (x_end - x_start), range->end - range->start); +} + +enum led_brightness led_val_to_rgb_range (const struct led_rgb_range *range, +int value) +{ +int h, s, v, hs, he, ss, se, vs, ve, hdiff; + +if (WARN_ON (range->start >= range->end)) +return LED_OFF ; + + hs = range->color_start >>16 &0xff ; + he = range->color_end >>16 &0xff ; + ss = range->color_start >>8 &0xff ; + se = range->color_end >>8 &0xff ; + vs = range->color_start &0xff ; + ve = range->color_end &0xff ; + hdiff = (252 + he - hs) %252 ; + +/* on color circle, choose shortest way from start to end */ +if (hdiff <=126 && he < hs) + he +=252 ; +else if (hdiff >126 && he > hs) + hs +=252 ; + + value =clamp (value, range->start, range->end); + + h =led_range_interpolate (value, range, hs, he) %252 ; + s =led_range_interpolate (value, range, ss, se); + v =led_range_interpolate (value, range, vs, ve); + +return LED_SET_HUE_SAT | h <<16 | s <<8 | v; +} +EXPORT_SYMBOL_GPL (led_val_to_rgb_range);
include/linux/leds.h +25 -0
@@ -234,6 +234,23 @@ static inline bool led_sysfs_is_disabled(struct led_classdev *led_cdev)*/ enum led_brightness led_hsv_to_rgb (enum led_brightness hsv); +struct led_rgb_range { +int start; +int end; +/* HSV color model */ +u32 color_start; +u32 color_end; +}; + +#if IS_ENABLED (CONFIG_LEDS_CLASS_RGB ) +enum led_brightness led_val_to_rgb_range (const struct led_rgb_range *range, +int value); +#else +static inline enum led_brightness led_val_to_rgb_range ( +const struct led_rgb_range *range, +int value) {return LED_OFF ; } +#endif /* CONFIG_LEDS_CLASS_RGB */ +/* * LED Triggers */
@@ -342,6 +359,14 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev)#endif /* CONFIG_LEDS_TRIGGERS */ +static inline void led_trigger_range_event (struct led_trigger *trigger, +const struct led_rgb_range *range, +int value) +{ +enum led_brightness brightness =led_val_to_rgb_range (range, value); +led_trigger_event (trigger, brightness); +} +/* Trigger specific functions */ #ifdef CONFIG_LEDS_TRIGGER_IDE_DISK extern void ledtrig_ide_activity (void );
Signature · 1 line
2.7.3