power: supply: power-supply-leds: Add charging_orange_full_green trigger for RGB LED
authorKate Hsuan <hpa@redhat.com>
Fri, 31 May 2024 11:41:24 +0000 (13:41 +0200)
committerLee Jones <lee@kernel.org>
Fri, 31 May 2024 11:57:43 +0000 (12:57 +0100)
Add a charging_orange_full_green LED trigger and the trigger is based on
led_mc_trigger_event() which can set an RGB LED when the trigger is
triggered. The LED will show orange when the battery status is charging.
The LED will show green when the battery status is full.

Link: https://lore.kernel.org/linux-leds/f40a0b1a-ceac-e269-c2dd-0158c5b4a1ad@gmail.com/
Signed-off-by: Kate Hsuan <hpa@redhat.com>
Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
[hdegoede@redhat.com change color order to RGB]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20240531114124.45346-7-hdegoede@redhat.com
Signed-off-by: Lee Jones <lee@kernel.org>
drivers/power/supply/power_supply_leds.c
include/linux/power_supply.h

index c7db29d5fcb80567edb4749c89ef4f8724dd67e5..73935de844d9756a2f5e5da7cad73ce0b212def6 100644 (file)
@@ -22,6 +22,8 @@
 static void power_supply_update_bat_leds(struct power_supply *psy)
 {
        union power_supply_propval status;
+       unsigned int intensity_green[3] = { 0, 255, 0 };
+       unsigned int intensity_orange[3] = { 255, 128, 0 };
 
        if (power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, &status))
                return;
@@ -36,12 +38,20 @@ static void power_supply_update_bat_leds(struct power_supply *psy)
                /* Going from blink to LED on requires a LED_OFF event to stop blink */
                led_trigger_event(psy->charging_blink_full_solid_trig, LED_OFF);
                led_trigger_event(psy->charging_blink_full_solid_trig, LED_FULL);
+               led_mc_trigger_event(psy->charging_orange_full_green_trig,
+                                    intensity_green,
+                                    ARRAY_SIZE(intensity_green),
+                                    LED_FULL);
                break;
        case POWER_SUPPLY_STATUS_CHARGING:
                led_trigger_event(psy->charging_full_trig, LED_FULL);
                led_trigger_event(psy->charging_trig, LED_FULL);
                led_trigger_event(psy->full_trig, LED_OFF);
                led_trigger_blink(psy->charging_blink_full_solid_trig, 0, 0);
+               led_mc_trigger_event(psy->charging_orange_full_green_trig,
+                                    intensity_orange,
+                                    ARRAY_SIZE(intensity_orange),
+                                    LED_FULL);
                break;
        default:
                led_trigger_event(psy->charging_full_trig, LED_OFF);
@@ -49,6 +59,8 @@ static void power_supply_update_bat_leds(struct power_supply *psy)
                led_trigger_event(psy->full_trig, LED_OFF);
                led_trigger_event(psy->charging_blink_full_solid_trig,
                        LED_OFF);
+               led_trigger_event(psy->charging_orange_full_green_trig,
+                       LED_OFF);
                break;
        }
 }
@@ -74,6 +86,11 @@ static int power_supply_create_bat_triggers(struct power_supply *psy)
        if (!psy->charging_blink_full_solid_trig_name)
                goto charging_blink_full_solid_failed;
 
+       psy->charging_orange_full_green_trig_name = kasprintf(GFP_KERNEL,
+               "%s-charging-orange-full-green", psy->desc->name);
+       if (!psy->charging_orange_full_green_trig_name)
+               goto charging_red_full_green_failed;
+
        led_trigger_register_simple(psy->charging_full_trig_name,
                                    &psy->charging_full_trig);
        led_trigger_register_simple(psy->charging_trig_name,
@@ -82,9 +99,13 @@ static int power_supply_create_bat_triggers(struct power_supply *psy)
                                    &psy->full_trig);
        led_trigger_register_simple(psy->charging_blink_full_solid_trig_name,
                                    &psy->charging_blink_full_solid_trig);
+       led_trigger_register_simple(psy->charging_orange_full_green_trig_name,
+                                   &psy->charging_orange_full_green_trig);
 
        return 0;
 
+charging_red_full_green_failed:
+       kfree(psy->charging_blink_full_solid_trig_name);
 charging_blink_full_solid_failed:
        kfree(psy->full_trig_name);
 full_failed:
@@ -101,10 +122,12 @@ static void power_supply_remove_bat_triggers(struct power_supply *psy)
        led_trigger_unregister_simple(psy->charging_trig);
        led_trigger_unregister_simple(psy->full_trig);
        led_trigger_unregister_simple(psy->charging_blink_full_solid_trig);
+       led_trigger_unregister_simple(psy->charging_orange_full_green_trig);
        kfree(psy->charging_blink_full_solid_trig_name);
        kfree(psy->full_trig_name);
        kfree(psy->charging_trig_name);
        kfree(psy->charging_full_trig_name);
+       kfree(psy->charging_orange_full_green_trig_name);
 }
 
 /* Generated power specific LEDs triggers. */
index 8e5705a56b85feee415e4c3051d2f86e78fb8fc9..c852cc882501571cbbd885de7ec03d79c98e7cdb 100644 (file)
@@ -319,6 +319,8 @@ struct power_supply {
        char *online_trig_name;
        struct led_trigger *charging_blink_full_solid_trig;
        char *charging_blink_full_solid_trig_name;
+       struct led_trigger *charging_orange_full_green_trig;
+       char *charging_orange_full_green_trig_name;
 #endif
 };