Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  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}