linux/drivers/power/power_supply_leds.c
<<
>>
Prefs
   1/*
   2 *  LEDs triggers for power supply class
   3 *
   4 *  Copyright © 2007  Anton Vorontsov <cbou@mail.ru>
   5 *  Copyright © 2004  Szabolcs Gyurko
   6 *  Copyright © 2003  Ian Molton <spyro@f2s.com>
   7 *
   8 *  Modified: 2004, Oct     Szabolcs Gyurko
   9 *
  10 *  You may use this code as per GPL version 2
  11 */
  12
  13#include <linux/kernel.h>
  14#include <linux/device.h>
  15#include <linux/power_supply.h>
  16#include <linux/slab.h>
  17
  18#include "power_supply.h"
  19
  20/* Battery specific LEDs triggers. */
  21
  22static void power_supply_update_bat_leds(struct power_supply *psy)
  23{
  24        union power_supply_propval status;
  25        unsigned long delay_on = 0;
  26        unsigned long delay_off = 0;
  27
  28        if (psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &status))
  29                return;
  30
  31        dev_dbg(psy->dev, "%s %d\n", __func__, status.intval);
  32
  33        switch (status.intval) {
  34        case POWER_SUPPLY_STATUS_FULL:
  35                led_trigger_event(psy->charging_full_trig, LED_FULL);
  36                led_trigger_event(psy->charging_trig, LED_OFF);
  37                led_trigger_event(psy->full_trig, LED_FULL);
  38                led_trigger_event(psy->charging_blink_full_solid_trig,
  39                        LED_FULL);
  40                break;
  41        case POWER_SUPPLY_STATUS_CHARGING:
  42                led_trigger_event(psy->charging_full_trig, LED_FULL);
  43                led_trigger_event(psy->charging_trig, LED_FULL);
  44                led_trigger_event(psy->full_trig, LED_OFF);
  45                led_trigger_blink(psy->charging_blink_full_solid_trig,
  46                        &delay_on, &delay_off);
  47                break;
  48        default:
  49                led_trigger_event(psy->charging_full_trig, LED_OFF);
  50                led_trigger_event(psy->charging_trig, LED_OFF);
  51                led_trigger_event(psy->full_trig, LED_OFF);
  52                led_trigger_event(psy->charging_blink_full_solid_trig,
  53                        LED_OFF);
  54                break;
  55        }
  56}
  57
  58static int power_supply_create_bat_triggers(struct power_supply *psy)
  59{
  60        psy->charging_full_trig_name = kasprintf(GFP_KERNEL,
  61                                        "%s-charging-or-full", psy->name);
  62        if (!psy->charging_full_trig_name)
  63                goto charging_full_failed;
  64
  65        psy->charging_trig_name = kasprintf(GFP_KERNEL,
  66                                        "%s-charging", psy->name);
  67        if (!psy->charging_trig_name)
  68                goto charging_failed;
  69
  70        psy->full_trig_name = kasprintf(GFP_KERNEL, "%s-full", psy->name);
  71        if (!psy->full_trig_name)
  72                goto full_failed;
  73
  74        psy->charging_blink_full_solid_trig_name = kasprintf(GFP_KERNEL,
  75                "%s-charging-blink-full-solid", psy->name);
  76        if (!psy->charging_blink_full_solid_trig_name)
  77                goto charging_blink_full_solid_failed;
  78
  79        led_trigger_register_simple(psy->charging_full_trig_name,
  80                                    &psy->charging_full_trig);
  81        led_trigger_register_simple(psy->charging_trig_name,
  82                                    &psy->charging_trig);
  83        led_trigger_register_simple(psy->full_trig_name,
  84                                    &psy->full_trig);
  85        led_trigger_register_simple(psy->charging_blink_full_solid_trig_name,
  86                                    &psy->charging_blink_full_solid_trig);
  87
  88        return 0;
  89
  90charging_blink_full_solid_failed:
  91        kfree(psy->full_trig_name);
  92full_failed:
  93        kfree(psy->charging_trig_name);
  94charging_failed:
  95        kfree(psy->charging_full_trig_name);
  96charging_full_failed:
  97        return -ENOMEM;
  98}
  99
 100static void power_supply_remove_bat_triggers(struct power_supply *psy)
 101{
 102        led_trigger_unregister_simple(psy->charging_full_trig);
 103        led_trigger_unregister_simple(psy->charging_trig);
 104        led_trigger_unregister_simple(psy->full_trig);
 105        led_trigger_unregister_simple(psy->charging_blink_full_solid_trig);
 106        kfree(psy->charging_blink_full_solid_trig_name);
 107        kfree(psy->full_trig_name);
 108        kfree(psy->charging_trig_name);
 109        kfree(psy->charging_full_trig_name);
 110}
 111
 112/* Generated power specific LEDs triggers. */
 113
 114static void power_supply_update_gen_leds(struct power_supply *psy)
 115{
 116        union power_supply_propval online;
 117
 118        if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online))
 119                return;
 120
 121        dev_dbg(psy->dev, "%s %d\n", __func__, online.intval);
 122
 123        if (online.intval)
 124                led_trigger_event(psy->online_trig, LED_FULL);
 125        else
 126                led_trigger_event(psy->online_trig, LED_OFF);
 127}
 128
 129static int power_supply_create_gen_triggers(struct power_supply *psy)
 130{
 131        psy->online_trig_name = kasprintf(GFP_KERNEL, "%s-online", psy->name);
 132        if (!psy->online_trig_name)
 133                return -ENOMEM;
 134
 135        led_trigger_register_simple(psy->online_trig_name, &psy->online_trig);
 136
 137        return 0;
 138}
 139
 140static void power_supply_remove_gen_triggers(struct power_supply *psy)
 141{
 142        led_trigger_unregister_simple(psy->online_trig);
 143        kfree(psy->online_trig_name);
 144}
 145
 146/* Choice what triggers to create&update. */
 147
 148void power_supply_update_leds(struct power_supply *psy)
 149{
 150        if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
 151                power_supply_update_bat_leds(psy);
 152        else
 153                power_supply_update_gen_leds(psy);
 154}
 155
 156int power_supply_create_triggers(struct power_supply *psy)
 157{
 158        if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
 159                return power_supply_create_bat_triggers(psy);
 160        return power_supply_create_gen_triggers(psy);
 161}
 162
 163void power_supply_remove_triggers(struct power_supply *psy)
 164{
 165        if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
 166                power_supply_remove_bat_triggers(psy);
 167        else
 168                power_supply_remove_gen_triggers(psy);
 169}
 170