1 // SPDX-License-Identifier: GPL-2.0-only
3 * Common power driver for PDAs and phones with one or two external
4 * power supplies (AC/USB) connected to main and backup batteries,
5 * and optional builtin charger.
7 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/err.h>
13 #include <linux/interrupt.h>
14 #include <linux/notifier.h>
15 #include <linux/power_supply.h>
16 #include <linux/pda_power.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/timer.h>
19 #include <linux/jiffies.h>
20 #include <linux/usb/otg.h>
22 static inline unsigned int get_irq_flags(struct resource
*res
)
24 return IRQF_SHARED
| (res
->flags
& IRQF_TRIGGER_MASK
);
27 static struct device
*dev
;
28 static struct pda_power_pdata
*pdata
;
29 static struct resource
*ac_irq
, *usb_irq
;
30 static struct delayed_work charger_work
;
31 static struct delayed_work polling_work
;
32 static struct delayed_work supply_work
;
34 static struct power_supply
*pda_psy_ac
, *pda_psy_usb
;
36 #if IS_ENABLED(CONFIG_USB_PHY)
37 static struct usb_phy
*transceiver
;
38 static struct notifier_block otg_nb
;
41 static struct regulator
*ac_draw
;
48 static int new_ac_status
= -1;
49 static int new_usb_status
= -1;
50 static int ac_status
= -1;
51 static int usb_status
= -1;
53 static int pda_power_get_property(struct power_supply
*psy
,
54 enum power_supply_property psp
,
55 union power_supply_propval
*val
)
58 case POWER_SUPPLY_PROP_ONLINE
:
59 if (psy
->desc
->type
== POWER_SUPPLY_TYPE_MAINS
)
60 val
->intval
= pdata
->is_ac_online
?
61 pdata
->is_ac_online() : 0;
63 val
->intval
= pdata
->is_usb_online
?
64 pdata
->is_usb_online() : 0;
72 static enum power_supply_property pda_power_props
[] = {
73 POWER_SUPPLY_PROP_ONLINE
,
76 static char *pda_power_supplied_to
[] = {
81 static const struct power_supply_desc pda_psy_ac_desc
= {
83 .type
= POWER_SUPPLY_TYPE_MAINS
,
84 .properties
= pda_power_props
,
85 .num_properties
= ARRAY_SIZE(pda_power_props
),
86 .get_property
= pda_power_get_property
,
89 static const struct power_supply_desc pda_psy_usb_desc
= {
91 .type
= POWER_SUPPLY_TYPE_USB
,
92 .properties
= pda_power_props
,
93 .num_properties
= ARRAY_SIZE(pda_power_props
),
94 .get_property
= pda_power_get_property
,
97 static void update_status(void)
99 if (pdata
->is_ac_online
)
100 new_ac_status
= !!pdata
->is_ac_online();
102 if (pdata
->is_usb_online
)
103 new_usb_status
= !!pdata
->is_usb_online();
106 static void update_charger(void)
108 static int regulator_enabled
;
109 int max_uA
= pdata
->ac_max_uA
;
111 if (pdata
->set_charge
) {
112 if (new_ac_status
> 0) {
113 dev_dbg(dev
, "charger on (AC)\n");
114 pdata
->set_charge(PDA_POWER_CHARGE_AC
);
115 } else if (new_usb_status
> 0) {
116 dev_dbg(dev
, "charger on (USB)\n");
117 pdata
->set_charge(PDA_POWER_CHARGE_USB
);
119 dev_dbg(dev
, "charger off\n");
120 pdata
->set_charge(0);
122 } else if (ac_draw
) {
123 if (new_ac_status
> 0) {
124 regulator_set_current_limit(ac_draw
, max_uA
, max_uA
);
125 if (!regulator_enabled
) {
126 dev_dbg(dev
, "charger on (AC)\n");
127 WARN_ON(regulator_enable(ac_draw
));
128 regulator_enabled
= 1;
131 if (regulator_enabled
) {
132 dev_dbg(dev
, "charger off\n");
133 WARN_ON(regulator_disable(ac_draw
));
134 regulator_enabled
= 0;
140 static void supply_work_func(struct work_struct
*work
)
142 if (ac_status
== PDA_PSY_TO_CHANGE
) {
143 ac_status
= new_ac_status
;
144 power_supply_changed(pda_psy_ac
);
147 if (usb_status
== PDA_PSY_TO_CHANGE
) {
148 usb_status
= new_usb_status
;
149 power_supply_changed(pda_psy_usb
);
153 static void psy_changed(void)
158 * Okay, charger set. Now wait a bit before notifying supplicants,
159 * charge power should stabilize.
161 cancel_delayed_work(&supply_work
);
162 schedule_delayed_work(&supply_work
,
163 msecs_to_jiffies(pdata
->wait_for_charger
));
166 static void charger_work_func(struct work_struct
*work
)
172 static irqreturn_t
power_changed_isr(int irq
, void *power_supply
)
174 if (power_supply
== pda_psy_ac
)
175 ac_status
= PDA_PSY_TO_CHANGE
;
176 else if (power_supply
== pda_psy_usb
)
177 usb_status
= PDA_PSY_TO_CHANGE
;
182 * Wait a bit before reading ac/usb line status and setting charger,
183 * because ac/usb status readings may lag from irq.
185 cancel_delayed_work(&charger_work
);
186 schedule_delayed_work(&charger_work
,
187 msecs_to_jiffies(pdata
->wait_for_status
));
192 static void polling_work_func(struct work_struct
*work
)
196 dev_dbg(dev
, "polling...\n");
200 if (!ac_irq
&& new_ac_status
!= ac_status
) {
201 ac_status
= PDA_PSY_TO_CHANGE
;
205 if (!usb_irq
&& new_usb_status
!= usb_status
) {
206 usb_status
= PDA_PSY_TO_CHANGE
;
213 cancel_delayed_work(&polling_work
);
214 schedule_delayed_work(&polling_work
,
215 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 cancel_delayed_work(&charger_work
);
254 schedule_delayed_work(&charger_work
,
255 msecs_to_jiffies(pdata
->wait_for_status
));
261 static int pda_power_probe(struct platform_device
*pdev
)
263 struct power_supply_config psy_cfg
= {};
268 if (pdev
->id
!= -1) {
269 dev_err(dev
, "it's meaningless to register several "
270 "pda_powers; use id = -1\n");
275 pdata
= pdev
->dev
.platform_data
;
278 ret
= pdata
->init(dev
);
283 ac_draw
= regulator_get(dev
, "ac_draw");
284 if (IS_ERR(ac_draw
)) {
285 dev_dbg(dev
, "couldn't get ac_draw regulator\n");
292 if (!pdata
->wait_for_status
)
293 pdata
->wait_for_status
= 500;
295 if (!pdata
->wait_for_charger
)
296 pdata
->wait_for_charger
= 500;
298 if (!pdata
->polling_interval
)
299 pdata
->polling_interval
= 2000;
301 if (!pdata
->ac_max_uA
)
302 pdata
->ac_max_uA
= 500000;
304 INIT_DELAYED_WORK(&charger_work
, charger_work_func
);
305 INIT_DELAYED_WORK(&supply_work
, supply_work_func
);
307 ac_irq
= platform_get_resource_byname(pdev
, IORESOURCE_IRQ
, "ac");
308 usb_irq
= platform_get_resource_byname(pdev
, IORESOURCE_IRQ
, "usb");
310 if (pdata
->supplied_to
) {
311 psy_cfg
.supplied_to
= pdata
->supplied_to
;
312 psy_cfg
.num_supplicants
= pdata
->num_supplicants
;
314 psy_cfg
.supplied_to
= pda_power_supplied_to
;
315 psy_cfg
.num_supplicants
= ARRAY_SIZE(pda_power_supplied_to
);
318 #if IS_ENABLED(CONFIG_USB_PHY)
319 transceiver
= usb_get_phy(USB_PHY_TYPE_USB2
);
320 if (!IS_ERR_OR_NULL(transceiver
)) {
321 if (!pdata
->is_usb_online
)
322 pdata
->is_usb_online
= otg_is_usb_online
;
323 if (!pdata
->is_ac_online
)
324 pdata
->is_ac_online
= otg_is_ac_online
;
328 if (pdata
->is_ac_online
) {
329 pda_psy_ac
= power_supply_register(&pdev
->dev
,
330 &pda_psy_ac_desc
, &psy_cfg
);
331 if (IS_ERR(pda_psy_ac
)) {
332 dev_err(dev
, "failed to register %s power supply\n",
333 pda_psy_ac_desc
.name
);
334 ret
= PTR_ERR(pda_psy_ac
);
335 goto ac_supply_failed
;
339 ret
= request_irq(ac_irq
->start
, power_changed_isr
,
340 get_irq_flags(ac_irq
), ac_irq
->name
,
343 dev_err(dev
, "request ac irq failed\n");
351 if (pdata
->is_usb_online
) {
352 pda_psy_usb
= power_supply_register(&pdev
->dev
,
355 if (IS_ERR(pda_psy_usb
)) {
356 dev_err(dev
, "failed to register %s power supply\n",
357 pda_psy_usb_desc
.name
);
358 ret
= PTR_ERR(pda_psy_usb
);
359 goto usb_supply_failed
;
363 ret
= request_irq(usb_irq
->start
, power_changed_isr
,
364 get_irq_flags(usb_irq
),
365 usb_irq
->name
, pda_psy_usb
);
367 dev_err(dev
, "request usb irq failed\n");
375 #if IS_ENABLED(CONFIG_USB_PHY)
376 if (!IS_ERR_OR_NULL(transceiver
) && pdata
->use_otg_notifier
) {
377 otg_nb
.notifier_call
= otg_handle_notification
;
378 ret
= usb_register_notifier(transceiver
, &otg_nb
);
380 dev_err(dev
, "failure to register otg notifier\n");
381 goto otg_reg_notifier_failed
;
388 dev_dbg(dev
, "will poll for status\n");
389 INIT_DELAYED_WORK(&polling_work
, polling_work_func
);
390 cancel_delayed_work(&polling_work
);
391 schedule_delayed_work(&polling_work
,
392 msecs_to_jiffies(pdata
->polling_interval
));
395 if (ac_irq
|| usb_irq
)
396 device_init_wakeup(&pdev
->dev
, 1);
400 #if IS_ENABLED(CONFIG_USB_PHY)
401 otg_reg_notifier_failed
:
402 if (pdata
->is_usb_online
&& usb_irq
)
403 free_irq(usb_irq
->start
, pda_psy_usb
);
406 if (pdata
->is_usb_online
)
407 power_supply_unregister(pda_psy_usb
);
409 if (pdata
->is_ac_online
&& ac_irq
)
410 free_irq(ac_irq
->start
, pda_psy_ac
);
411 #if IS_ENABLED(CONFIG_USB_PHY)
412 if (!IS_ERR_OR_NULL(transceiver
))
413 usb_put_phy(transceiver
);
416 if (pdata
->is_ac_online
)
417 power_supply_unregister(pda_psy_ac
);
420 regulator_put(ac_draw
);
430 static int pda_power_remove(struct platform_device
*pdev
)
432 #if IS_ENABLED(CONFIG_USB_PHY)
433 if (!IS_ERR_OR_NULL(transceiver
) && pdata
->use_otg_notifier
)
434 usb_unregister_notifier(transceiver
, &otg_nb
);
436 if (pdata
->is_usb_online
&& usb_irq
)
437 free_irq(usb_irq
->start
, pda_psy_usb
);
438 if (pdata
->is_ac_online
&& ac_irq
)
439 free_irq(ac_irq
->start
, pda_psy_ac
);
442 cancel_delayed_work_sync(&polling_work
);
443 cancel_delayed_work_sync(&charger_work
);
444 cancel_delayed_work_sync(&supply_work
);
446 if (pdata
->is_usb_online
)
447 power_supply_unregister(pda_psy_usb
);
448 if (pdata
->is_ac_online
)
449 power_supply_unregister(pda_psy_ac
);
450 #if IS_ENABLED(CONFIG_USB_PHY)
451 if (!IS_ERR_OR_NULL(transceiver
))
452 usb_put_phy(transceiver
);
455 regulator_put(ac_draw
);
465 static int ac_wakeup_enabled
;
466 static int usb_wakeup_enabled
;
468 static int pda_power_suspend(struct platform_device
*pdev
, pm_message_t state
)
470 if (pdata
->suspend
) {
471 int ret
= pdata
->suspend(state
);
477 if (device_may_wakeup(&pdev
->dev
)) {
479 ac_wakeup_enabled
= !enable_irq_wake(ac_irq
->start
);
481 usb_wakeup_enabled
= !enable_irq_wake(usb_irq
->start
);
487 static int pda_power_resume(struct platform_device
*pdev
)
489 if (device_may_wakeup(&pdev
->dev
)) {
490 if (usb_irq
&& usb_wakeup_enabled
)
491 disable_irq_wake(usb_irq
->start
);
492 if (ac_irq
&& ac_wakeup_enabled
)
493 disable_irq_wake(ac_irq
->start
);
497 return pdata
->resume();
502 #define pda_power_suspend NULL
503 #define pda_power_resume NULL
504 #endif /* CONFIG_PM */
506 static struct platform_driver pda_power_pdrv
= {
510 .probe
= pda_power_probe
,
511 .remove
= pda_power_remove
,
512 .suspend
= pda_power_suspend
,
513 .resume
= pda_power_resume
,
516 module_platform_driver(pda_power_pdrv
);
518 MODULE_LICENSE("GPL");
519 MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
520 MODULE_ALIAS("platform:pda-power");