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/power_supply.h> 15#include <linux/slab.h> 16 17#include "power_supply.h" 18 19/* Battery specific LEDs triggers. */ 20 21static void power_supply_update_bat_leds(struct power_supply *psy) 22{ 23 union power_supply_propval status; 24 25 if (psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &status)) 26 return; 27 28 dev_dbg(psy->dev, "%s %d\n", __func__, status.intval); 29 30 switch (status.intval) { 31 case POWER_SUPPLY_STATUS_FULL: 32 led_trigger_event(psy->charging_full_trig, LED_FULL); 33 led_trigger_event(psy->charging_trig, LED_OFF); 34 led_trigger_event(psy->full_trig, LED_FULL); 35 break; 36 case POWER_SUPPLY_STATUS_CHARGING: 37 led_trigger_event(psy->charging_full_trig, LED_FULL); 38 led_trigger_event(psy->charging_trig, LED_FULL); 39 led_trigger_event(psy->full_trig, LED_OFF); 40 break; 41 default: 42 led_trigger_event(psy->charging_full_trig, LED_OFF); 43 led_trigger_event(psy->charging_trig, LED_OFF); 44 led_trigger_event(psy->full_trig, LED_OFF); 45 break; 46 } 47} 48 49static int power_supply_create_bat_triggers(struct power_supply *psy) 50{ 51 int rc = 0; 52 53 psy->charging_full_trig_name = kasprintf(GFP_KERNEL, 54 "%s-charging-or-full", psy->name); 55 if (!psy->charging_full_trig_name) 56 goto charging_full_failed; 57 58 psy->charging_trig_name = kasprintf(GFP_KERNEL, 59 "%s-charging", psy->name); 60 if (!psy->charging_trig_name) 61 goto charging_failed; 62 63 psy->full_trig_name = kasprintf(GFP_KERNEL, "%s-full", psy->name); 64 if (!psy->full_trig_name) 65 goto full_failed; 66 67 led_trigger_register_simple(psy->charging_full_trig_name, 68 &psy->charging_full_trig); 69 led_trigger_register_simple(psy->charging_trig_name, 70 &psy->charging_trig); 71 led_trigger_register_simple(psy->full_trig_name, 72 &psy->full_trig); 73 74 goto success; 75 76full_failed: 77 kfree(psy->charging_trig_name); 78charging_failed: 79 kfree(psy->charging_full_trig_name); 80charging_full_failed: 81 rc = -ENOMEM; 82success: 83 return rc; 84} 85 86static void power_supply_remove_bat_triggers(struct power_supply *psy) 87{ 88 led_trigger_unregister_simple(psy->charging_full_trig); 89 led_trigger_unregister_simple(psy->charging_trig); 90 led_trigger_unregister_simple(psy->full_trig); 91 kfree(psy->full_trig_name); 92 kfree(psy->charging_trig_name); 93 kfree(psy->charging_full_trig_name); 94} 95 96/* Generated power specific LEDs triggers. */ 97 98static void power_supply_update_gen_leds(struct power_supply *psy) 99{ 100 union power_supply_propval online; 101 102 if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &online)) 103 return; 104 105 dev_dbg(psy->dev, "%s %d\n", __func__, online.intval); 106 107 if (online.intval) 108 led_trigger_event(psy->online_trig, LED_FULL); 109 else 110 led_trigger_event(psy->online_trig, LED_OFF); 111} 112 113static int power_supply_create_gen_triggers(struct power_supply *psy) 114{ 115 int rc = 0; 116 117 psy->online_trig_name = kasprintf(GFP_KERNEL, "%s-online", psy->name); 118 if (!psy->online_trig_name) 119 goto online_failed; 120 121 led_trigger_register_simple(psy->online_trig_name, &psy->online_trig); 122 123 goto success; 124 125online_failed: 126 rc = -ENOMEM; 127success: 128 return rc; 129} 130 131static void power_supply_remove_gen_triggers(struct power_supply *psy) 132{ 133 led_trigger_unregister_simple(psy->online_trig); 134 kfree(psy->online_trig_name); 135} 136 137/* Choice what triggers to create&update. */ 138 139void power_supply_update_leds(struct power_supply *psy) 140{ 141 if (psy->type == POWER_SUPPLY_TYPE_BATTERY) 142 power_supply_update_bat_leds(psy); 143 else 144 power_supply_update_gen_leds(psy); 145} 146 147int power_supply_create_triggers(struct power_supply *psy) 148{ 149 if (psy->type == POWER_SUPPLY_TYPE_BATTERY) 150 return power_supply_create_bat_triggers(psy); 151 return power_supply_create_gen_triggers(psy); 152} 153 154void power_supply_remove_triggers(struct power_supply *psy) 155{ 156 if (psy->type == POWER_SUPPLY_TYPE_BATTERY) 157 power_supply_remove_bat_triggers(psy); 158 else 159 power_supply_remove_gen_triggers(psy); 160} 161