Blame view

drivers/power/power_supply_leds.c 4.76 KB
4a11b59d8   Anton Vorontsov   [BATTERY] Univers...
1
2
3
4
5
6
7
8
9
10
11
  /*
   *  LEDs triggers for power supply class
   *
   *  Copyright © 2007  Anton Vorontsov <cbou@mail.ru>
   *  Copyright © 2004  Szabolcs Gyurko
   *  Copyright © 2003  Ian Molton <spyro@f2s.com>
   *
   *  Modified: 2004, Oct     Szabolcs Gyurko
   *
   *  You may use this code as per GPL version 2
   */
4d24473c4   Akinobu Mita   [BATTERY] power_s...
12
  #include <linux/kernel.h>
4a11b59d8   Anton Vorontsov   [BATTERY] Univers...
13
  #include <linux/power_supply.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
14
  #include <linux/slab.h>
4a11b59d8   Anton Vorontsov   [BATTERY] Univers...
15

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