2 * Common power driver for PDAs and phones with one or two external
3 * power supplies (AC/USB) connected to main and backup batteries,
4 * and optional builtin charger.
6 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/err.h>
16 #include <linux/interrupt.h>
17 #include <linux/notifier.h>
18 #include <linux/power_supply.h>
19 #include <linux/pda_power.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/timer.h>
22 #include <linux/jiffies.h>
23 #include <linux/usb/otg.h>
25 static inline unsigned int get_irq_flags(struct resource
*res
)
27 return IRQF_SHARED
| (res
->flags
& IRQF_TRIGGER_MASK
);
30 static struct device
*dev
;
31 static struct pda_power_pdata
*pdata
;
32 static struct resource
*ac_irq
, *usb_irq
;
33 static struct timer_list charger_timer
;
34 static struct timer_list supply_timer
;
35 static struct timer_list polling_timer
;
37 static struct power_supply
*pda_psy_ac
, *pda_psy_usb
;
39 #if IS_ENABLED(CONFIG_USB_PHY)
40 static struct usb_phy
*transceiver
;
41 static struct notifier_block otg_nb
;
44 static struct regulator
*ac_draw
;
51 static int new_ac_status
= -1;
52 static int new_usb_status
= -1;
53 static int ac_status
= -1;
54 static int usb_status
= -1;
56 static int pda_power_get_property(struct power_supply
*psy
,
57 enum power_supply_property psp
,
58 union power_supply_propval
*val
)
61 case POWER_SUPPLY_PROP_ONLINE
:
62 if (psy
->desc
->type
== POWER_SUPPLY_TYPE_MAINS
)
63 val
->intval
= pdata
->is_ac_online
?
64 pdata
->is_ac_online() : 0;
66 val
->intval
= pdata
->is_usb_online
?
67 pdata
->is_usb_online() : 0;
75 static enum power_supply_property pda_power_props
[] = {
76 POWER_SUPPLY_PROP_ONLINE
,
79 static char *pda_power_supplied_to
[] = {
84 static const struct power_supply_desc pda_psy_ac_desc
= {
86 .type
= POWER_SUPPLY_TYPE_MAINS
,
87 .properties
= pda_power_props
,
88 .num_properties
= ARRAY_SIZE(pda_power_props
),
89 .get_property
= pda_power_get_property
,
92 static const struct power_supply_desc pda_psy_usb_desc
= {
94 .type
= POWER_SUPPLY_TYPE_USB
,
95 .properties
= pda_power_props
,
96 .num_properties
= ARRAY_SIZE(pda_power_props
),
97 .get_property
= pda_power_get_property
,
100 static void update_status(void)
102 if (pdata
->is_ac_online
)
103 new_ac_status
= !!pdata
->is_ac_online();
105 if (pdata
->is_usb_online
)
106 new_usb_status
= !!pdata
->is_usb_online();
109 static void update_charger(void)
111 static int regulator_enabled
;
112 int max_uA
= pdata
->ac_max_uA
;
114 if (pdata
->set_charge
) {
115 if (new_ac_status
> 0) {
116 dev_dbg(dev
, "charger on (AC)\n");
117 pdata
->set_charge(PDA_POWER_CHARGE_AC
);
118 } else if (new_usb_status
> 0) {
119 dev_dbg(dev
, "charger on (USB)\n");
120 pdata
->set_charge(PDA_POWER_CHARGE_USB
);
122 dev_dbg(dev
, "charger off\n");
123 pdata
->set_charge(0);
125 } else if (ac_draw
) {
126 if (new_ac_status
> 0) {
127 regulator_set_current_limit(ac_draw
, max_uA
, max_uA
);
128 if (!regulator_enabled
) {
129 dev_dbg(dev
, "charger on (AC)\n");
130 WARN_ON(regulator_enable(ac_draw
));
131 regulator_enabled
= 1;
134 if (regulator_enabled
) {
135 dev_dbg(dev
, "charger off\n");
136 WARN_ON(regulator_disable(ac_draw
));
137 regulator_enabled
= 0;
143 static void supply_timer_func(unsigned long unused
)
145 if (ac_status
== PDA_PSY_TO_CHANGE
) {
146 ac_status
= new_ac_status
;
147 power_supply_changed(pda_psy_ac
);
150 if (usb_status
== PDA_PSY_TO_CHANGE
) {
151 usb_status
= new_usb_status
;
152 power_supply_changed(pda_psy_usb
);
156 static void psy_changed(void)
161 * Okay, charger set. Now wait a bit before notifying supplicants,
162 * charge power should stabilize.
164 mod_timer(&supply_timer
,
165 jiffies
+ msecs_to_jiffies(pdata
->wait_for_charger
));
168 static void charger_timer_func(unsigned long unused
)
174 static irqreturn_t
power_changed_isr(int irq
, void *power_supply
)
176 if (power_supply
== pda_psy_ac
)
177 ac_status
= PDA_PSY_TO_CHANGE
;
178 else if (power_supply
== pda_psy_usb
)
179 usb_status
= PDA_PSY_TO_CHANGE
;
184 * Wait a bit before reading ac/usb line status and setting charger,
185 * because ac/usb status readings may lag from irq.
187 mod_timer(&charger_timer
,
188 jiffies
+ msecs_to_jiffies(pdata
->wait_for_status
));
193 static void polling_timer_func(unsigned long unused
)
197 dev_dbg(dev
, "polling...\n");
201 if (!ac_irq
&& new_ac_status
!= ac_status
) {
202 ac_status
= PDA_PSY_TO_CHANGE
;
206 if (!usb_irq
&& new_usb_status
!= usb_status
) {
207 usb_status
= PDA_PSY_TO_CHANGE
;
214 mod_timer(&polling_timer
,
215 jiffies
+ msecs_to_jiffies(pdata
->polling_interval
));
218 #if IS_ENABLED(CONFIG_USB_PHY)
219 static int otg_is_usb_online(void)
221 return (transceiver
->last_event
== USB_EVENT_VBUS
||
222 transceiver
->last_event
== USB_EVENT_ENUMERATED
);
225 static int otg_is_ac_online(void)
227 return (transceiver
->last_event
== USB_EVENT_CHARGER
);
230 static int otg_handle_notification(struct notifier_block
*nb
,
231 unsigned long event
, void *unused
)
234 case USB_EVENT_CHARGER
:
235 ac_status
= PDA_PSY_TO_CHANGE
;
238 case USB_EVENT_ENUMERATED
:
239 usb_status
= PDA_PSY_TO_CHANGE
;
242 ac_status
= PDA_PSY_TO_CHANGE
;
243 usb_status
= PDA_PSY_TO_CHANGE
;
250 * Wait a bit before reading ac/usb line status and setting charger,
251 * because ac/usb status readings may lag from irq.
253 mod_timer(&charger_timer
,
254 jiffies
+ msecs_to_jiffies(pdata
->wait_for_status
));
260 static int pda_power_probe(struct platform_device
*pdev
)
262 struct power_supply_config psy_cfg
= {};
267 if (pdev
->id
!= -1) {
268 dev_err(dev
, "it's meaningless to register several "
269 "pda_powers; use id = -1\n");
274 pdata
= pdev
->dev
.platform_data
;
277 ret
= pdata
->init(dev
);
282 ac_draw
= regulator_get(dev
, "ac_draw");
283 if (IS_ERR(ac_draw
)) {
284 dev_dbg(dev
, "couldn't get ac_draw regulator\n");
291 if (!pdata
->wait_for_status
)
292 pdata
->wait_for_status
= 500;
294 if (!pdata
->wait_for_charger
)
295 pdata
->wait_for_charger
= 500;
297 if (!pdata
->polling_interval
)
298 pdata
->polling_interval
= 2000;
300 if (!pdata
->ac_max_uA
)
301 pdata
->ac_max_uA
= 500000;
303 setup_timer(&charger_timer
, charger_timer_func
, 0);
304 setup_timer(&supply_timer
, supply_timer_func
, 0);
306 ac_irq
= platform_get_resource_byname(pdev
, IORESOURCE_IRQ
, "ac");
307 usb_irq
= platform_get_resource_byname(pdev
, IORESOURCE_IRQ
, "usb");
309 if (pdata
->supplied_to
) {
310 psy_cfg
.supplied_to
= pdata
->supplied_to
;
311 psy_cfg
.num_supplicants
= pdata
->num_supplicants
;
313 psy_cfg
.supplied_to
= pda_power_supplied_to
;
314 psy_cfg
.num_supplicants
= ARRAY_SIZE(pda_power_supplied_to
);
317 #if IS_ENABLED(CONFIG_USB_PHY)
318 transceiver
= usb_get_phy(USB_PHY_TYPE_USB2
);
319 if (!IS_ERR_OR_NULL(transceiver
)) {
320 if (!pdata
->is_usb_online
)
321 pdata
->is_usb_online
= otg_is_usb_online
;
322 if (!pdata
->is_ac_online
)
323 pdata
->is_ac_online
= otg_is_ac_online
;
327 if (pdata
->is_ac_online
) {
328 pda_psy_ac
= power_supply_register(&pdev
->dev
,
329 &pda_psy_ac_desc
, &psy_cfg
);
330 if (IS_ERR(pda_psy_ac
)) {
331 dev_err(dev
, "failed to register %s power supply\n",
332 pda_psy_ac_desc
.name
);
333 ret
= PTR_ERR(pda_psy_ac
);
334 goto ac_supply_failed
;
338 ret
= request_irq(ac_irq
->start
, power_changed_isr
,
339 get_irq_flags(ac_irq
), ac_irq
->name
,
342 dev_err(dev
, "request ac irq failed\n");
350 if (pdata
->is_usb_online
) {
351 pda_psy_usb
= power_supply_register(&pdev
->dev
,
354 if (IS_ERR(pda_psy_usb
)) {
355 dev_err(dev
, "failed to register %s power supply\n",
356 pda_psy_usb_desc
.name
);
357 ret
= PTR_ERR(pda_psy_usb
);
358 goto usb_supply_failed
;
362 ret
= request_irq(usb_irq
->start
, power_changed_isr
,
363 get_irq_flags(usb_irq
),
364 usb_irq
->name
, pda_psy_usb
);
366 dev_err(dev
, "request usb irq failed\n");
374 #if IS_ENABLED(CONFIG_USB_PHY)
375 if (!IS_ERR_OR_NULL(transceiver
) && pdata
->use_otg_notifier
) {
376 otg_nb
.notifier_call
= otg_handle_notification
;
377 ret
= usb_register_notifier(transceiver
, &otg_nb
);
379 dev_err(dev
, "failure to register otg notifier\n");
380 goto otg_reg_notifier_failed
;
387 dev_dbg(dev
, "will poll for status\n");
388 setup_timer(&polling_timer
, polling_timer_func
, 0);
389 mod_timer(&polling_timer
,
390 jiffies
+ msecs_to_jiffies(pdata
->polling_interval
));
393 if (ac_irq
|| usb_irq
)
394 device_init_wakeup(&pdev
->dev
, 1);
398 #if IS_ENABLED(CONFIG_USB_PHY)
399 otg_reg_notifier_failed
:
400 if (pdata
->is_usb_online
&& usb_irq
)
401 free_irq(usb_irq
->start
, pda_psy_usb
);
404 if (pdata
->is_usb_online
)
405 power_supply_unregister(pda_psy_usb
);
407 if (pdata
->is_ac_online
&& ac_irq
)
408 free_irq(ac_irq
->start
, pda_psy_ac
);
409 #if IS_ENABLED(CONFIG_USB_PHY)
410 if (!IS_ERR_OR_NULL(transceiver
))
411 usb_put_phy(transceiver
);
414 if (pdata
->is_ac_online
)
415 power_supply_unregister(pda_psy_ac
);
418 regulator_put(ac_draw
);
428 static int pda_power_remove(struct platform_device
*pdev
)
430 if (pdata
->is_usb_online
&& usb_irq
)
431 free_irq(usb_irq
->start
, pda_psy_usb
);
432 if (pdata
->is_ac_online
&& ac_irq
)
433 free_irq(ac_irq
->start
, pda_psy_ac
);
436 del_timer_sync(&polling_timer
);
437 del_timer_sync(&charger_timer
);
438 del_timer_sync(&supply_timer
);
440 if (pdata
->is_usb_online
)
441 power_supply_unregister(pda_psy_usb
);
442 if (pdata
->is_ac_online
)
443 power_supply_unregister(pda_psy_ac
);
444 #if IS_ENABLED(CONFIG_USB_PHY)
445 if (!IS_ERR_OR_NULL(transceiver
))
446 usb_put_phy(transceiver
);
449 regulator_put(ac_draw
);
459 static int ac_wakeup_enabled
;
460 static int usb_wakeup_enabled
;
462 static int pda_power_suspend(struct platform_device
*pdev
, pm_message_t state
)
464 if (pdata
->suspend
) {
465 int ret
= pdata
->suspend(state
);
471 if (device_may_wakeup(&pdev
->dev
)) {
473 ac_wakeup_enabled
= !enable_irq_wake(ac_irq
->start
);
475 usb_wakeup_enabled
= !enable_irq_wake(usb_irq
->start
);
481 static int pda_power_resume(struct platform_device
*pdev
)
483 if (device_may_wakeup(&pdev
->dev
)) {
484 if (usb_irq
&& usb_wakeup_enabled
)
485 disable_irq_wake(usb_irq
->start
);
486 if (ac_irq
&& ac_wakeup_enabled
)
487 disable_irq_wake(ac_irq
->start
);
491 return pdata
->resume();
496 #define pda_power_suspend NULL
497 #define pda_power_resume NULL
498 #endif /* CONFIG_PM */
500 static struct platform_driver pda_power_pdrv
= {
504 .probe
= pda_power_probe
,
505 .remove
= pda_power_remove
,
506 .suspend
= pda_power_suspend
,
507 .resume
= pda_power_resume
,
510 module_platform_driver(pda_power_pdrv
);
512 MODULE_LICENSE("GPL");
513 MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
514 MODULE_ALIAS("platform:pda-power");