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        int rc = 0;
  61
  62        psy->charging_full_trig_name = kasprintf(GFP_KERNEL,
  63                                        "%s-charging-or-full", psy->name);
  64        if (!psy->charging_full_trig_name)
  65                goto charging_full_failed;
  66
  67        psy->charging_trig_name = kasprintf(GFP_KERNEL,
  68                                        "%s-charging", psy->name);
  69        if (!psy->charging_trig_name)
  70                goto charging_failed;
  71
  72        psy->full_trig_name = kasprintf(GFP_KERNEL, "%s-full", psy->name);
  73        if (!psy->full_trig_name)
  74                goto full_failed;
  75
  76        psy->charging_blink_full_solid_trig_name = kasprintf(GFP_KERNEL,
  77                "%s-charging-blink-full-solid", psy->name);
  78        if (!psy->charging_blink_full_solid_trig_name)
  79                goto charging_blink_full_solid_failed;
  80
  81        led_trigger_register_simple(psy->charging_full_trig_name,
  82                                    &psy->charging_full_trig);
  83        led_trigger_register_simple(psy->charging_trig_name,
  84                                    &psy->charging_trig);
  85        led_trigger_register_simple(psy->full_trig_name,
  86                                    &psy->full_trig);
  87        led_trigger_register_simple(psy->charging_blink_full_solid_trig_name,
  88                                    &psy->charging_blink_full_solid_trig);
  89
  90        goto success;
  91
  92charging_blink_full_solid_failed:
  93        kfree(psy->full_trig_name);
  94full_failed:
  95        kfree(psy->charging_trig_name);
  96charging_failed:
  97        kfree(psy->charging_full_trig_name);
  98charging_full_failed:
  99        rc = -ENOMEM;
 100success:
 101        return rc;
 102}
 103
 104static void power_supply_remove_bat_triggers(struct power_supply *psy)
 105{
 106        led_trigger_unregister_simple(psy->charging_full_trig);
 107        led_trigger_unregister_simple(psy->charging_trig);
 108        led_trigger_unregister_simple(psy->full_trig);
 109        led_trigger_unregister_simple(psy->charging_blink_full_solid_trig);
 110        kfree(psy->charging_blink_full_solid_trig_name);
 111        kfree(psy->full_trig_name);
 112        kfree(psy->charging_trig_name);
 113        kfree(psy->charging_full_trig_name);
 114}
 115
 116/* Generated power specific LEDs triggers. */
 117
 118static void power_supply_update_gen_leds(struct power_supply *psy)
 119{
 120        union power_supply_propval online;
 121
 122        if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online))
 123                return;
 124
 125        dev_dbg(psy->dev, "%s %d\n", __func__, online.intval);
 126
 127        if (online.intval)
 128                led_trigger_event(psy->online_trig, LED_FULL);
 129        else
 130                led_trigger_event(psy->online_trig, LED_OFF);
 131}
 132
 133static int power_supply_create_gen_triggers(struct power_supply *psy)
 134{
 135        int rc = 0;
 136
 137        psy->online_trig_name = kasprintf(GFP_KERNEL, "%s-online", psy->name);
 138        if (!psy->online_trig_name)
 139                goto online_failed;
 140
 141        led_trigger_register_simple(psy->online_trig_name, &psy->online_trig);
 142
 143        goto success;
 144
 145online_failed:
 146        rc = -ENOMEM;
 147success:
 148        return rc;
 149}
 150
 151static void power_supply_remove_gen_triggers(struct power_supply *psy)
 152{
 153        led_trigger_unregister_simple(psy->online_trig);
 154        kfree(psy->online_trig_name);
 155}
 156
 157/* Choice what triggers to create&update. */
 158
 159void power_supply_update_leds(struct power_supply *psy)
 160{
 161        if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
 162                power_supply_update_bat_leds(psy);
 163        else
 164                power_supply_update_gen_leds(psy);
 165}
 166
 167int power_supply_create_triggers(struct power_supply *psy)
 168{
 169        if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
 170                return power_supply_create_bat_triggers(psy);
 171        return power_supply_create_gen_triggers(psy);
 172}
 173
 174void power_supply_remove_triggers(struct power_supply *psy)
 175{
 176        if (psy->type == POWER_SUPPLY_TYPE_BATTERY)
 177                power_supply_remove_bat_triggers(psy);
 178        else
 179                power_supply_remove_gen_triggers(psy);
 180}
 181