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 delayed_work charger_work
;
34 static struct delayed_work polling_work
;
35 static struct delayed_work supply_work
;
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_work_func(struct work_struct
*work
)
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 cancel_delayed_work(&supply_work
);
165 schedule_delayed_work(&supply_work
,
166 msecs_to_jiffies(pdata
->wait_for_charger
));
169 static void charger_work_func(struct work_struct
*work
)
175 static irqreturn_t
power_changed_isr(int irq
, void *power_supply
)
177 if (power_supply
== pda_psy_ac
)
178 ac_status
= PDA_PSY_TO_CHANGE
;
179 else if (power_supply
== pda_psy_usb
)
180 usb_status
= PDA_PSY_TO_CHANGE
;
185 * Wait a bit before reading ac/usb line status and setting charger,
186 * because ac/usb status readings may lag from irq.
188 cancel_delayed_work(&charger_work
);
189 schedule_delayed_work(&charger_work
,
190 msecs_to_jiffies(pdata
->wait_for_status
));
195 static void polling_work_func(struct work_struct
*work
)
199 dev_dbg(dev
, "polling...\n");
203 if (!ac_irq
&& new_ac_status
!= ac_status
) {
204 ac_status
= PDA_PSY_TO_CHANGE
;
208 if (!usb_irq
&& new_usb_status
!= usb_status
) {
209 usb_status
= PDA_PSY_TO_CHANGE
;
216 cancel_delayed_work(&polling_work
);
217 schedule_delayed_work(&polling_work
,
218 msecs_to_jiffies(pdata
->polling_interval
));
221 #if IS_ENABLED(CONFIG_USB_PHY)
222 static int otg_is_usb_online(void)
224 return (transceiver
->last_event
== USB_EVENT_VBUS
||
225 transceiver
->last_event
== USB_EVENT_ENUMERATED
);
228 static int otg_is_ac_online(void)
230 return (transceiver
->last_event
== USB_EVENT_CHARGER
);
233 static int otg_handle_notification(struct notifier_block
*nb
,
234 unsigned long event
, void *unused
)
237 case USB_EVENT_CHARGER
:
238 ac_status
= PDA_PSY_TO_CHANGE
;
241 case USB_EVENT_ENUMERATED
:
242 usb_status
= PDA_PSY_TO_CHANGE
;
245 ac_status
= PDA_PSY_TO_CHANGE
;
246 usb_status
= PDA_PSY_TO_CHANGE
;
253 * Wait a bit before reading ac/usb line status and setting charger,
254 * because ac/usb status readings may lag from irq.
256 cancel_delayed_work(&charger_work
);
257 schedule_delayed_work(&charger_work
,
258 msecs_to_jiffies(pdata
->wait_for_status
));
264 static int pda_power_probe(struct platform_device
*pdev
)
266 struct power_supply_config psy_cfg
= {};
271 if (pdev
->id
!= -1) {
272 dev_err(dev
, "it's meaningless to register several "
273 "pda_powers; use id = -1\n");
278 pdata
= pdev
->dev
.platform_data
;
281 ret
= pdata
->init(dev
);
286 ac_draw
= regulator_get(dev
, "ac_draw");
287 if (IS_ERR(ac_draw
)) {
288 dev_dbg(dev
, "couldn't get ac_draw regulator\n");
295 if (!pdata
->wait_for_status
)
296 pdata
->wait_for_status
= 500;
298 if (!pdata
->wait_for_charger
)
299 pdata
->wait_for_charger
= 500;
301 if (!pdata
->polling_interval
)
302 pdata
->polling_interval
= 2000;
304 if (!pdata
->ac_max_uA
)
305 pdata
->ac_max_uA
= 500000;
307 INIT_DELAYED_WORK(&charger_work
, charger_work_func
);
308 INIT_DELAYED_WORK(&supply_work
, supply_work_func
);
310 ac_irq
= platform_get_resource_byname(pdev
, IORESOURCE_IRQ
, "ac");
311 usb_irq
= platform_get_resource_byname(pdev
, IORESOURCE_IRQ
, "usb");
313 if (pdata
->supplied_to
) {
314 psy_cfg
.supplied_to
= pdata
->supplied_to
;
315 psy_cfg
.num_supplicants
= pdata
->num_supplicants
;
317 psy_cfg
.supplied_to
= pda_power_supplied_to
;
318 psy_cfg
.num_supplicants
= ARRAY_SIZE(pda_power_supplied_to
);
321 #if IS_ENABLED(CONFIG_USB_PHY)
322 transceiver
= usb_get_phy(USB_PHY_TYPE_USB2
);
323 if (!IS_ERR_OR_NULL(transceiver
)) {
324 if (!pdata
->is_usb_online
)
325 pdata
->is_usb_online
= otg_is_usb_online
;
326 if (!pdata
->is_ac_online
)
327 pdata
->is_ac_online
= otg_is_ac_online
;
331 if (pdata
->is_ac_online
) {
332 pda_psy_ac
= power_supply_register(&pdev
->dev
,
333 &pda_psy_ac_desc
, &psy_cfg
);
334 if (IS_ERR(pda_psy_ac
)) {
335 dev_err(dev
, "failed to register %s power supply\n",
336 pda_psy_ac_desc
.name
);
337 ret
= PTR_ERR(pda_psy_ac
);
338 goto ac_supply_failed
;
342 ret
= request_irq(ac_irq
->start
, power_changed_isr
,
343 get_irq_flags(ac_irq
), ac_irq
->name
,
346 dev_err(dev
, "request ac irq failed\n");
354 if (pdata
->is_usb_online
) {
355 pda_psy_usb
= power_supply_register(&pdev
->dev
,
358 if (IS_ERR(pda_psy_usb
)) {
359 dev_err(dev
, "failed to register %s power supply\n",
360 pda_psy_usb_desc
.name
);
361 ret
= PTR_ERR(pda_psy_usb
);
362 goto usb_supply_failed
;
366 ret
= request_irq(usb_irq
->start
, power_changed_isr
,
367 get_irq_flags(usb_irq
),
368 usb_irq
->name
, pda_psy_usb
);
370 dev_err(dev
, "request usb irq failed\n");
378 #if IS_ENABLED(CONFIG_USB_PHY)
379 if (!IS_ERR_OR_NULL(transceiver
) && pdata
->use_otg_notifier
) {
380 otg_nb
.notifier_call
= otg_handle_notification
;
381 ret
= usb_register_notifier(transceiver
, &otg_nb
);
383 dev_err(dev
, "failure to register otg notifier\n");
384 goto otg_reg_notifier_failed
;
391 dev_dbg(dev
, "will poll for status\n");
392 INIT_DELAYED_WORK(&polling_work
, polling_work_func
);
393 cancel_delayed_work(&polling_work
);
394 schedule_delayed_work(&polling_work
,
395 msecs_to_jiffies(pdata
->polling_interval
));
398 if (ac_irq
|| usb_irq
)
399 device_init_wakeup(&pdev
->dev
, 1);
403 #if IS_ENABLED(CONFIG_USB_PHY)
404 otg_reg_notifier_failed
:
405 if (pdata
->is_usb_online
&& usb_irq
)
406 free_irq(usb_irq
->start
, pda_psy_usb
);
409 if (pdata
->is_usb_online
)
410 power_supply_unregister(pda_psy_usb
);
412 if (pdata
->is_ac_online
&& ac_irq
)
413 free_irq(ac_irq
->start
, pda_psy_ac
);
414 #if IS_ENABLED(CONFIG_USB_PHY)
415 if (!IS_ERR_OR_NULL(transceiver
))
416 usb_put_phy(transceiver
);
419 if (pdata
->is_ac_online
)
420 power_supply_unregister(pda_psy_ac
);
423 regulator_put(ac_draw
);
433 static int pda_power_remove(struct platform_device
*pdev
)
435 if (pdata
->is_usb_online
&& usb_irq
)
436 free_irq(usb_irq
->start
, pda_psy_usb
);
437 if (pdata
->is_ac_online
&& ac_irq
)
438 free_irq(ac_irq
->start
, pda_psy_ac
);
441 cancel_delayed_work_sync(&polling_work
);
442 cancel_delayed_work_sync(&charger_work
);
443 cancel_delayed_work_sync(&supply_work
);
445 if (pdata
->is_usb_online
)
446 power_supply_unregister(pda_psy_usb
);
447 if (pdata
->is_ac_online
)
448 power_supply_unregister(pda_psy_ac
);
449 #if IS_ENABLED(CONFIG_USB_PHY)
450 if (!IS_ERR_OR_NULL(transceiver
))
451 usb_put_phy(transceiver
);
454 regulator_put(ac_draw
);
464 static int ac_wakeup_enabled
;
465 static int usb_wakeup_enabled
;
467 static int pda_power_suspend(struct platform_device
*pdev
, pm_message_t state
)
469 if (pdata
->suspend
) {
470 int ret
= pdata
->suspend(state
);
476 if (device_may_wakeup(&pdev
->dev
)) {
478 ac_wakeup_enabled
= !enable_irq_wake(ac_irq
->start
);
480 usb_wakeup_enabled
= !enable_irq_wake(usb_irq
->start
);
486 static int pda_power_resume(struct platform_device
*pdev
)
488 if (device_may_wakeup(&pdev
->dev
)) {
489 if (usb_irq
&& usb_wakeup_enabled
)
490 disable_irq_wake(usb_irq
->start
);
491 if (ac_irq
&& ac_wakeup_enabled
)
492 disable_irq_wake(ac_irq
->start
);
496 return pdata
->resume();
501 #define pda_power_suspend NULL
502 #define pda_power_resume NULL
503 #endif /* CONFIG_PM */
505 static struct platform_driver pda_power_pdrv
= {
509 .probe
= pda_power_probe
,
510 .remove
= pda_power_remove
,
511 .suspend
= pda_power_suspend
,
512 .resume
= pda_power_resume
,
515 module_platform_driver(pda_power_pdrv
);
517 MODULE_LICENSE("GPL");
518 MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
519 MODULE_ALIAS("platform:pda-power");