Root/
1 | /* |
2 | * Battery driver for wm8350 PMIC |
3 | * |
4 | * Copyright 2007, 2008 Wolfson Microelectronics PLC. |
5 | * |
6 | * Based on OLPC Battery Driver |
7 | * |
8 | * Copyright 2006 David Woodhouse <dwmw2@infradead.org> |
9 | * |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. |
13 | */ |
14 | |
15 | #include <linux/module.h> |
16 | #include <linux/err.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/power_supply.h> |
19 | #include <linux/mfd/wm8350/supply.h> |
20 | #include <linux/mfd/wm8350/core.h> |
21 | #include <linux/mfd/wm8350/comparator.h> |
22 | |
23 | static int wm8350_read_battery_uvolts(struct wm8350 *wm8350) |
24 | { |
25 | return wm8350_read_auxadc(wm8350, WM8350_AUXADC_BATT, 0, 0) |
26 | * WM8350_AUX_COEFF; |
27 | } |
28 | |
29 | static int wm8350_read_line_uvolts(struct wm8350 *wm8350) |
30 | { |
31 | return wm8350_read_auxadc(wm8350, WM8350_AUXADC_LINE, 0, 0) |
32 | * WM8350_AUX_COEFF; |
33 | } |
34 | |
35 | static int wm8350_read_usb_uvolts(struct wm8350 *wm8350) |
36 | { |
37 | return wm8350_read_auxadc(wm8350, WM8350_AUXADC_USB, 0, 0) |
38 | * WM8350_AUX_COEFF; |
39 | } |
40 | |
41 | #define WM8350_BATT_SUPPLY 1 |
42 | #define WM8350_USB_SUPPLY 2 |
43 | #define WM8350_LINE_SUPPLY 4 |
44 | |
45 | static inline int wm8350_charge_time_min(struct wm8350 *wm8350, int min) |
46 | { |
47 | if (!wm8350->power.rev_g_coeff) |
48 | return (((min - 30) / 15) & 0xf) << 8; |
49 | else |
50 | return (((min - 30) / 30) & 0xf) << 8; |
51 | } |
52 | |
53 | static int wm8350_get_supplies(struct wm8350 *wm8350) |
54 | { |
55 | u16 sm, ov, co, chrg; |
56 | int supplies = 0; |
57 | |
58 | sm = wm8350_reg_read(wm8350, WM8350_STATE_MACHINE_STATUS); |
59 | ov = wm8350_reg_read(wm8350, WM8350_MISC_OVERRIDES); |
60 | co = wm8350_reg_read(wm8350, WM8350_COMPARATOR_OVERRIDES); |
61 | chrg = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2); |
62 | |
63 | /* USB_SM */ |
64 | sm = (sm & WM8350_USB_SM_MASK) >> WM8350_USB_SM_SHIFT; |
65 | |
66 | /* CHG_ISEL */ |
67 | chrg &= WM8350_CHG_ISEL_MASK; |
68 | |
69 | /* If the USB state machine is active then we're using that with or |
70 | * without battery, otherwise check for wall supply */ |
71 | if (((sm == WM8350_USB_SM_100_SLV) || |
72 | (sm == WM8350_USB_SM_500_SLV) || |
73 | (sm == WM8350_USB_SM_STDBY_SLV)) |
74 | && !(ov & WM8350_USB_LIMIT_OVRDE)) |
75 | supplies = WM8350_USB_SUPPLY; |
76 | else if (((sm == WM8350_USB_SM_100_SLV) || |
77 | (sm == WM8350_USB_SM_500_SLV) || |
78 | (sm == WM8350_USB_SM_STDBY_SLV)) |
79 | && (ov & WM8350_USB_LIMIT_OVRDE) && (chrg == 0)) |
80 | supplies = WM8350_USB_SUPPLY | WM8350_BATT_SUPPLY; |
81 | else if (co & WM8350_WALL_FB_OVRDE) |
82 | supplies = WM8350_LINE_SUPPLY; |
83 | else |
84 | supplies = WM8350_BATT_SUPPLY; |
85 | |
86 | return supplies; |
87 | } |
88 | |
89 | static int wm8350_charger_config(struct wm8350 *wm8350, |
90 | struct wm8350_charger_policy *policy) |
91 | { |
92 | u16 reg, eoc_mA, fast_limit_mA; |
93 | |
94 | if (!policy) { |
95 | dev_warn(wm8350->dev, |
96 | "No charger policy, charger not configured.\n"); |
97 | return -EINVAL; |
98 | } |
99 | |
100 | /* make sure USB fast charge current is not > 500mA */ |
101 | if (policy->fast_limit_USB_mA > 500) { |
102 | dev_err(wm8350->dev, "USB fast charge > 500mA\n"); |
103 | return -EINVAL; |
104 | } |
105 | |
106 | eoc_mA = WM8350_CHG_EOC_mA(policy->eoc_mA); |
107 | |
108 | wm8350_reg_unlock(wm8350); |
109 | |
110 | reg = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_1) |
111 | & WM8350_CHG_ENA_R168; |
112 | wm8350_reg_write(wm8350, WM8350_BATTERY_CHARGER_CONTROL_1, |
113 | reg | eoc_mA | policy->trickle_start_mV | |
114 | WM8350_CHG_TRICKLE_TEMP_CHOKE | |
115 | WM8350_CHG_TRICKLE_USB_CHOKE | |
116 | WM8350_CHG_FAST_USB_THROTTLE); |
117 | |
118 | if (wm8350_get_supplies(wm8350) & WM8350_USB_SUPPLY) { |
119 | fast_limit_mA = |
120 | WM8350_CHG_FAST_LIMIT_mA(policy->fast_limit_USB_mA); |
121 | wm8350_reg_write(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2, |
122 | policy->charge_mV | policy->trickle_charge_USB_mA | |
123 | fast_limit_mA | wm8350_charge_time_min(wm8350, |
124 | policy->charge_timeout)); |
125 | |
126 | } else { |
127 | fast_limit_mA = |
128 | WM8350_CHG_FAST_LIMIT_mA(policy->fast_limit_mA); |
129 | wm8350_reg_write(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2, |
130 | policy->charge_mV | policy->trickle_charge_mA | |
131 | fast_limit_mA | wm8350_charge_time_min(wm8350, |
132 | policy->charge_timeout)); |
133 | } |
134 | |
135 | wm8350_reg_lock(wm8350); |
136 | return 0; |
137 | } |
138 | |
139 | static int wm8350_batt_status(struct wm8350 *wm8350) |
140 | { |
141 | u16 state; |
142 | |
143 | state = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2); |
144 | state &= WM8350_CHG_STS_MASK; |
145 | |
146 | switch (state) { |
147 | case WM8350_CHG_STS_OFF: |
148 | return POWER_SUPPLY_STATUS_DISCHARGING; |
149 | |
150 | case WM8350_CHG_STS_TRICKLE: |
151 | case WM8350_CHG_STS_FAST: |
152 | return POWER_SUPPLY_STATUS_CHARGING; |
153 | |
154 | default: |
155 | return POWER_SUPPLY_STATUS_UNKNOWN; |
156 | } |
157 | } |
158 | |
159 | static ssize_t charger_state_show(struct device *dev, |
160 | struct device_attribute *attr, char *buf) |
161 | { |
162 | struct wm8350 *wm8350 = dev_get_drvdata(dev); |
163 | char *charge; |
164 | int state; |
165 | |
166 | state = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2) & |
167 | WM8350_CHG_STS_MASK; |
168 | switch (state) { |
169 | case WM8350_CHG_STS_OFF: |
170 | charge = "Charger Off"; |
171 | break; |
172 | case WM8350_CHG_STS_TRICKLE: |
173 | charge = "Trickle Charging"; |
174 | break; |
175 | case WM8350_CHG_STS_FAST: |
176 | charge = "Fast Charging"; |
177 | break; |
178 | default: |
179 | return 0; |
180 | } |
181 | |
182 | return sprintf(buf, "%s\n", charge); |
183 | } |
184 | |
185 | static DEVICE_ATTR(charger_state, 0444, charger_state_show, NULL); |
186 | |
187 | static irqreturn_t wm8350_charger_handler(int irq, void *data) |
188 | { |
189 | struct wm8350 *wm8350 = data; |
190 | struct wm8350_power *power = &wm8350->power; |
191 | struct wm8350_charger_policy *policy = power->policy; |
192 | |
193 | switch (irq - wm8350->irq_base) { |
194 | case WM8350_IRQ_CHG_BAT_FAIL: |
195 | dev_err(wm8350->dev, "battery failed\n"); |
196 | break; |
197 | case WM8350_IRQ_CHG_TO: |
198 | dev_err(wm8350->dev, "charger timeout\n"); |
199 | power_supply_changed(&power->battery); |
200 | break; |
201 | |
202 | case WM8350_IRQ_CHG_BAT_HOT: |
203 | case WM8350_IRQ_CHG_BAT_COLD: |
204 | case WM8350_IRQ_CHG_START: |
205 | case WM8350_IRQ_CHG_END: |
206 | power_supply_changed(&power->battery); |
207 | break; |
208 | |
209 | case WM8350_IRQ_CHG_FAST_RDY: |
210 | dev_dbg(wm8350->dev, "fast charger ready\n"); |
211 | wm8350_charger_config(wm8350, policy); |
212 | wm8350_reg_unlock(wm8350); |
213 | wm8350_set_bits(wm8350, WM8350_BATTERY_CHARGER_CONTROL_1, |
214 | WM8350_CHG_FAST); |
215 | wm8350_reg_lock(wm8350); |
216 | break; |
217 | |
218 | case WM8350_IRQ_CHG_VBATT_LT_3P9: |
219 | dev_warn(wm8350->dev, "battery < 3.9V\n"); |
220 | break; |
221 | case WM8350_IRQ_CHG_VBATT_LT_3P1: |
222 | dev_warn(wm8350->dev, "battery < 3.1V\n"); |
223 | break; |
224 | case WM8350_IRQ_CHG_VBATT_LT_2P85: |
225 | dev_warn(wm8350->dev, "battery < 2.85V\n"); |
226 | break; |
227 | |
228 | /* Supply change. We will overnotify but it should do |
229 | * no harm. */ |
230 | case WM8350_IRQ_EXT_USB_FB: |
231 | case WM8350_IRQ_EXT_WALL_FB: |
232 | wm8350_charger_config(wm8350, policy); |
233 | case WM8350_IRQ_EXT_BAT_FB: /* Fall through */ |
234 | power_supply_changed(&power->battery); |
235 | power_supply_changed(&power->usb); |
236 | power_supply_changed(&power->ac); |
237 | break; |
238 | |
239 | default: |
240 | dev_err(wm8350->dev, "Unknown interrupt %d\n", irq); |
241 | } |
242 | |
243 | return IRQ_HANDLED; |
244 | } |
245 | |
246 | /********************************************************************* |
247 | * AC Power |
248 | *********************************************************************/ |
249 | static int wm8350_ac_get_prop(struct power_supply *psy, |
250 | enum power_supply_property psp, |
251 | union power_supply_propval *val) |
252 | { |
253 | struct wm8350 *wm8350 = dev_get_drvdata(psy->dev->parent); |
254 | int ret = 0; |
255 | |
256 | switch (psp) { |
257 | case POWER_SUPPLY_PROP_ONLINE: |
258 | val->intval = !!(wm8350_get_supplies(wm8350) & |
259 | WM8350_LINE_SUPPLY); |
260 | break; |
261 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
262 | val->intval = wm8350_read_line_uvolts(wm8350); |
263 | break; |
264 | default: |
265 | ret = -EINVAL; |
266 | break; |
267 | } |
268 | return ret; |
269 | } |
270 | |
271 | static enum power_supply_property wm8350_ac_props[] = { |
272 | POWER_SUPPLY_PROP_ONLINE, |
273 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
274 | }; |
275 | |
276 | /********************************************************************* |
277 | * USB Power |
278 | *********************************************************************/ |
279 | static int wm8350_usb_get_prop(struct power_supply *psy, |
280 | enum power_supply_property psp, |
281 | union power_supply_propval *val) |
282 | { |
283 | struct wm8350 *wm8350 = dev_get_drvdata(psy->dev->parent); |
284 | int ret = 0; |
285 | |
286 | switch (psp) { |
287 | case POWER_SUPPLY_PROP_ONLINE: |
288 | val->intval = !!(wm8350_get_supplies(wm8350) & |
289 | WM8350_USB_SUPPLY); |
290 | break; |
291 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
292 | val->intval = wm8350_read_usb_uvolts(wm8350); |
293 | break; |
294 | default: |
295 | ret = -EINVAL; |
296 | break; |
297 | } |
298 | return ret; |
299 | } |
300 | |
301 | static enum power_supply_property wm8350_usb_props[] = { |
302 | POWER_SUPPLY_PROP_ONLINE, |
303 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
304 | }; |
305 | |
306 | /********************************************************************* |
307 | * Battery properties |
308 | *********************************************************************/ |
309 | |
310 | static int wm8350_bat_check_health(struct wm8350 *wm8350) |
311 | { |
312 | u16 reg; |
313 | |
314 | if (wm8350_read_battery_uvolts(wm8350) < 2850000) |
315 | return POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; |
316 | |
317 | reg = wm8350_reg_read(wm8350, WM8350_CHARGER_OVERRIDES); |
318 | if (reg & WM8350_CHG_BATT_HOT_OVRDE) |
319 | return POWER_SUPPLY_HEALTH_OVERHEAT; |
320 | |
321 | if (reg & WM8350_CHG_BATT_COLD_OVRDE) |
322 | return POWER_SUPPLY_HEALTH_COLD; |
323 | |
324 | return POWER_SUPPLY_HEALTH_GOOD; |
325 | } |
326 | |
327 | static int wm8350_bat_get_charge_type(struct wm8350 *wm8350) |
328 | { |
329 | int state; |
330 | |
331 | state = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2) & |
332 | WM8350_CHG_STS_MASK; |
333 | switch (state) { |
334 | case WM8350_CHG_STS_OFF: |
335 | return POWER_SUPPLY_CHARGE_TYPE_NONE; |
336 | case WM8350_CHG_STS_TRICKLE: |
337 | return POWER_SUPPLY_CHARGE_TYPE_TRICKLE; |
338 | case WM8350_CHG_STS_FAST: |
339 | return POWER_SUPPLY_CHARGE_TYPE_FAST; |
340 | default: |
341 | return POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; |
342 | } |
343 | } |
344 | |
345 | static int wm8350_bat_get_property(struct power_supply *psy, |
346 | enum power_supply_property psp, |
347 | union power_supply_propval *val) |
348 | { |
349 | struct wm8350 *wm8350 = dev_get_drvdata(psy->dev->parent); |
350 | int ret = 0; |
351 | |
352 | switch (psp) { |
353 | case POWER_SUPPLY_PROP_STATUS: |
354 | val->intval = wm8350_batt_status(wm8350); |
355 | break; |
356 | case POWER_SUPPLY_PROP_ONLINE: |
357 | val->intval = !!(wm8350_get_supplies(wm8350) & |
358 | WM8350_BATT_SUPPLY); |
359 | break; |
360 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
361 | val->intval = wm8350_read_battery_uvolts(wm8350); |
362 | break; |
363 | case POWER_SUPPLY_PROP_HEALTH: |
364 | val->intval = wm8350_bat_check_health(wm8350); |
365 | break; |
366 | case POWER_SUPPLY_PROP_CHARGE_TYPE: |
367 | val->intval = wm8350_bat_get_charge_type(wm8350); |
368 | break; |
369 | default: |
370 | ret = -EINVAL; |
371 | break; |
372 | } |
373 | |
374 | return ret; |
375 | } |
376 | |
377 | static enum power_supply_property wm8350_bat_props[] = { |
378 | POWER_SUPPLY_PROP_STATUS, |
379 | POWER_SUPPLY_PROP_ONLINE, |
380 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
381 | POWER_SUPPLY_PROP_HEALTH, |
382 | POWER_SUPPLY_PROP_CHARGE_TYPE, |
383 | }; |
384 | |
385 | /********************************************************************* |
386 | * Initialisation |
387 | *********************************************************************/ |
388 | |
389 | static void wm8350_init_charger(struct wm8350 *wm8350) |
390 | { |
391 | /* register our interest in charger events */ |
392 | wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, |
393 | wm8350_charger_handler, 0, "Battery hot", wm8350); |
394 | wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, |
395 | wm8350_charger_handler, 0, "Battery cold", wm8350); |
396 | wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, |
397 | wm8350_charger_handler, 0, "Battery fail", wm8350); |
398 | wm8350_register_irq(wm8350, WM8350_IRQ_CHG_TO, |
399 | wm8350_charger_handler, 0, |
400 | "Charger timeout", wm8350); |
401 | wm8350_register_irq(wm8350, WM8350_IRQ_CHG_END, |
402 | wm8350_charger_handler, 0, |
403 | "Charge end", wm8350); |
404 | wm8350_register_irq(wm8350, WM8350_IRQ_CHG_START, |
405 | wm8350_charger_handler, 0, |
406 | "Charge start", wm8350); |
407 | wm8350_register_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY, |
408 | wm8350_charger_handler, 0, |
409 | "Fast charge ready", wm8350); |
410 | wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, |
411 | wm8350_charger_handler, 0, |
412 | "Battery <3.9V", wm8350); |
413 | wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, |
414 | wm8350_charger_handler, 0, |
415 | "Battery <3.1V", wm8350); |
416 | wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, |
417 | wm8350_charger_handler, 0, |
418 | "Battery <2.85V", wm8350); |
419 | |
420 | /* and supply change events */ |
421 | wm8350_register_irq(wm8350, WM8350_IRQ_EXT_USB_FB, |
422 | wm8350_charger_handler, 0, "USB", wm8350); |
423 | wm8350_register_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, |
424 | wm8350_charger_handler, 0, "Wall", wm8350); |
425 | wm8350_register_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, |
426 | wm8350_charger_handler, 0, "Battery", wm8350); |
427 | } |
428 | |
429 | static void free_charger_irq(struct wm8350 *wm8350) |
430 | { |
431 | wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, wm8350); |
432 | wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, wm8350); |
433 | wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, wm8350); |
434 | wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350); |
435 | wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END, wm8350); |
436 | wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START, wm8350); |
437 | wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350); |
438 | wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350); |
439 | wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350); |
440 | wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB, wm8350); |
441 | wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, wm8350); |
442 | wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, wm8350); |
443 | } |
444 | |
445 | static __devinit int wm8350_power_probe(struct platform_device *pdev) |
446 | { |
447 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); |
448 | struct wm8350_power *power = &wm8350->power; |
449 | struct wm8350_charger_policy *policy = power->policy; |
450 | struct power_supply *usb = &power->usb; |
451 | struct power_supply *battery = &power->battery; |
452 | struct power_supply *ac = &power->ac; |
453 | int ret; |
454 | |
455 | ac->name = "wm8350-ac"; |
456 | ac->type = POWER_SUPPLY_TYPE_MAINS; |
457 | ac->properties = wm8350_ac_props; |
458 | ac->num_properties = ARRAY_SIZE(wm8350_ac_props); |
459 | ac->get_property = wm8350_ac_get_prop; |
460 | ret = power_supply_register(&pdev->dev, ac); |
461 | if (ret) |
462 | return ret; |
463 | |
464 | battery->name = "wm8350-battery"; |
465 | battery->properties = wm8350_bat_props; |
466 | battery->num_properties = ARRAY_SIZE(wm8350_bat_props); |
467 | battery->get_property = wm8350_bat_get_property; |
468 | battery->use_for_apm = 1; |
469 | ret = power_supply_register(&pdev->dev, battery); |
470 | if (ret) |
471 | goto battery_failed; |
472 | |
473 | usb->name = "wm8350-usb", |
474 | usb->type = POWER_SUPPLY_TYPE_USB; |
475 | usb->properties = wm8350_usb_props; |
476 | usb->num_properties = ARRAY_SIZE(wm8350_usb_props); |
477 | usb->get_property = wm8350_usb_get_prop; |
478 | ret = power_supply_register(&pdev->dev, usb); |
479 | if (ret) |
480 | goto usb_failed; |
481 | |
482 | ret = device_create_file(&pdev->dev, &dev_attr_charger_state); |
483 | if (ret < 0) |
484 | dev_warn(wm8350->dev, "failed to add charge sysfs: %d\n", ret); |
485 | ret = 0; |
486 | |
487 | wm8350_init_charger(wm8350); |
488 | if (wm8350_charger_config(wm8350, policy) == 0) { |
489 | wm8350_reg_unlock(wm8350); |
490 | wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CHG_ENA); |
491 | wm8350_reg_lock(wm8350); |
492 | } |
493 | |
494 | return ret; |
495 | |
496 | usb_failed: |
497 | power_supply_unregister(battery); |
498 | battery_failed: |
499 | power_supply_unregister(ac); |
500 | |
501 | return ret; |
502 | } |
503 | |
504 | static __devexit int wm8350_power_remove(struct platform_device *pdev) |
505 | { |
506 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); |
507 | struct wm8350_power *power = &wm8350->power; |
508 | |
509 | free_charger_irq(wm8350); |
510 | device_remove_file(&pdev->dev, &dev_attr_charger_state); |
511 | power_supply_unregister(&power->battery); |
512 | power_supply_unregister(&power->ac); |
513 | power_supply_unregister(&power->usb); |
514 | return 0; |
515 | } |
516 | |
517 | static struct platform_driver wm8350_power_driver = { |
518 | .probe = wm8350_power_probe, |
519 | .remove = __devexit_p(wm8350_power_remove), |
520 | .driver = { |
521 | .name = "wm8350-power", |
522 | }, |
523 | }; |
524 | |
525 | module_platform_driver(wm8350_power_driver); |
526 | |
527 | MODULE_LICENSE("GPL"); |
528 | MODULE_DESCRIPTION("Power supply driver for WM8350"); |
529 | MODULE_ALIAS("platform:wm8350-power"); |
530 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9