Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  LEDs triggers for power supply class
0004  *
0005  *  Copyright © 2007  Anton Vorontsov <cbou@mail.ru>
0006  *  Copyright © 2004  Szabolcs Gyurko
0007  *  Copyright © 2003  Ian Molton <spyro@f2s.com>
0008  *
0009  *  Modified: 2004, Oct     Szabolcs Gyurko
0010  */
0011 
0012 #include <linux/kernel.h>
0013 #include <linux/device.h>
0014 #include <linux/power_supply.h>
0015 #include <linux/slab.h>
0016 
0017 #include "power_supply.h"
0018 
0019 /* Battery specific LEDs triggers. */
0020 
0021 static void power_supply_update_bat_leds(struct power_supply *psy)
0022 {
0023     union power_supply_propval status;
0024     unsigned long delay_on = 0;
0025     unsigned long delay_off = 0;
0026 
0027     if (power_supply_get_property(psy, POWER_SUPPLY_PROP_STATUS, &status))
0028         return;
0029 
0030     dev_dbg(&psy->dev, "%s %d\n", __func__, status.intval);
0031 
0032     switch (status.intval) {
0033     case POWER_SUPPLY_STATUS_FULL:
0034         led_trigger_event(psy->charging_full_trig, LED_FULL);
0035         led_trigger_event(psy->charging_trig, LED_OFF);
0036         led_trigger_event(psy->full_trig, LED_FULL);
0037         led_trigger_event(psy->charging_blink_full_solid_trig,
0038             LED_FULL);
0039         break;
0040     case POWER_SUPPLY_STATUS_CHARGING:
0041         led_trigger_event(psy->charging_full_trig, LED_FULL);
0042         led_trigger_event(psy->charging_trig, LED_FULL);
0043         led_trigger_event(psy->full_trig, LED_OFF);
0044         led_trigger_blink(psy->charging_blink_full_solid_trig,
0045             &delay_on, &delay_off);
0046         break;
0047     default:
0048         led_trigger_event(psy->charging_full_trig, LED_OFF);
0049         led_trigger_event(psy->charging_trig, LED_OFF);
0050         led_trigger_event(psy->full_trig, LED_OFF);
0051         led_trigger_event(psy->charging_blink_full_solid_trig,
0052             LED_OFF);
0053         break;
0054     }
0055 }
0056 
0057 static int power_supply_create_bat_triggers(struct power_supply *psy)
0058 {
0059     psy->charging_full_trig_name = kasprintf(GFP_KERNEL,
0060                     "%s-charging-or-full", psy->desc->name);
0061     if (!psy->charging_full_trig_name)
0062         goto charging_full_failed;
0063 
0064     psy->charging_trig_name = kasprintf(GFP_KERNEL,
0065                     "%s-charging", psy->desc->name);
0066     if (!psy->charging_trig_name)
0067         goto charging_failed;
0068 
0069     psy->full_trig_name = kasprintf(GFP_KERNEL, "%s-full", psy->desc->name);
0070     if (!psy->full_trig_name)
0071         goto full_failed;
0072 
0073     psy->charging_blink_full_solid_trig_name = kasprintf(GFP_KERNEL,
0074         "%s-charging-blink-full-solid", psy->desc->name);
0075     if (!psy->charging_blink_full_solid_trig_name)
0076         goto charging_blink_full_solid_failed;
0077 
0078     led_trigger_register_simple(psy->charging_full_trig_name,
0079                     &psy->charging_full_trig);
0080     led_trigger_register_simple(psy->charging_trig_name,
0081                     &psy->charging_trig);
0082     led_trigger_register_simple(psy->full_trig_name,
0083                     &psy->full_trig);
0084     led_trigger_register_simple(psy->charging_blink_full_solid_trig_name,
0085                     &psy->charging_blink_full_solid_trig);
0086 
0087     return 0;
0088 
0089 charging_blink_full_solid_failed:
0090     kfree(psy->full_trig_name);
0091 full_failed:
0092     kfree(psy->charging_trig_name);
0093 charging_failed:
0094     kfree(psy->charging_full_trig_name);
0095 charging_full_failed:
0096     return -ENOMEM;
0097 }
0098 
0099 static void power_supply_remove_bat_triggers(struct power_supply *psy)
0100 {
0101     led_trigger_unregister_simple(psy->charging_full_trig);
0102     led_trigger_unregister_simple(psy->charging_trig);
0103     led_trigger_unregister_simple(psy->full_trig);
0104     led_trigger_unregister_simple(psy->charging_blink_full_solid_trig);
0105     kfree(psy->charging_blink_full_solid_trig_name);
0106     kfree(psy->full_trig_name);
0107     kfree(psy->charging_trig_name);
0108     kfree(psy->charging_full_trig_name);
0109 }
0110 
0111 /* Generated power specific LEDs triggers. */
0112 
0113 static void power_supply_update_gen_leds(struct power_supply *psy)
0114 {
0115     union power_supply_propval online;
0116 
0117     if (power_supply_get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online))
0118         return;
0119 
0120     dev_dbg(&psy->dev, "%s %d\n", __func__, online.intval);
0121 
0122     if (online.intval)
0123         led_trigger_event(psy->online_trig, LED_FULL);
0124     else
0125         led_trigger_event(psy->online_trig, LED_OFF);
0126 }
0127 
0128 static int power_supply_create_gen_triggers(struct power_supply *psy)
0129 {
0130     psy->online_trig_name = kasprintf(GFP_KERNEL, "%s-online",
0131                       psy->desc->name);
0132     if (!psy->online_trig_name)
0133         return -ENOMEM;
0134 
0135     led_trigger_register_simple(psy->online_trig_name, &psy->online_trig);
0136 
0137     return 0;
0138 }
0139 
0140 static void power_supply_remove_gen_triggers(struct power_supply *psy)
0141 {
0142     led_trigger_unregister_simple(psy->online_trig);
0143     kfree(psy->online_trig_name);
0144 }
0145 
0146 /* Choice what triggers to create&update. */
0147 
0148 void power_supply_update_leds(struct power_supply *psy)
0149 {
0150     if (psy->desc->type == POWER_SUPPLY_TYPE_BATTERY)
0151         power_supply_update_bat_leds(psy);
0152     else
0153         power_supply_update_gen_leds(psy);
0154 }
0155 
0156 int power_supply_create_triggers(struct power_supply *psy)
0157 {
0158     if (psy->desc->type == POWER_SUPPLY_TYPE_BATTERY)
0159         return power_supply_create_bat_triggers(psy);
0160     return power_supply_create_gen_triggers(psy);
0161 }
0162 
0163 void power_supply_remove_triggers(struct power_supply *psy)
0164 {
0165     if (psy->desc->type == POWER_SUPPLY_TYPE_BATTERY)
0166         power_supply_remove_bat_triggers(psy);
0167     else
0168         power_supply_remove_gen_triggers(psy);
0169 }