• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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.
5  *
6  * Copyright © 2007 Anton Vorontsov <cbou@mail.ru>
7  *
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.
11  */
12 
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>
24 
get_irq_flags(struct resource * res)25 static inline unsigned int get_irq_flags(struct resource *res)
26 {
27 	return IRQF_SHARED | (res->flags & IRQF_TRIGGER_MASK);
28 }
29 
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;
36 static int polling;
37 static struct power_supply *pda_psy_ac, *pda_psy_usb;
38 
39 #if IS_ENABLED(CONFIG_USB_PHY)
40 static struct usb_phy *transceiver;
41 static struct notifier_block otg_nb;
42 #endif
43 
44 static struct regulator *ac_draw;
45 
46 enum {
47 	PDA_PSY_OFFLINE = 0,
48 	PDA_PSY_ONLINE = 1,
49 	PDA_PSY_TO_CHANGE,
50 };
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;
55 
pda_power_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)56 static int pda_power_get_property(struct power_supply *psy,
57 				  enum power_supply_property psp,
58 				  union power_supply_propval *val)
59 {
60 	switch (psp) {
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;
65 		else
66 			val->intval = pdata->is_usb_online ?
67 				      pdata->is_usb_online() : 0;
68 		break;
69 	default:
70 		return -EINVAL;
71 	}
72 	return 0;
73 }
74 
75 static enum power_supply_property pda_power_props[] = {
76 	POWER_SUPPLY_PROP_ONLINE,
77 };
78 
79 static char *pda_power_supplied_to[] = {
80 	"main-battery",
81 	"backup-battery",
82 };
83 
84 static const struct power_supply_desc pda_psy_ac_desc = {
85 	.name = "ac",
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,
90 };
91 
92 static const struct power_supply_desc pda_psy_usb_desc = {
93 	.name = "usb",
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,
98 };
99 
update_status(void)100 static void update_status(void)
101 {
102 	if (pdata->is_ac_online)
103 		new_ac_status = !!pdata->is_ac_online();
104 
105 	if (pdata->is_usb_online)
106 		new_usb_status = !!pdata->is_usb_online();
107 }
108 
update_charger(void)109 static void update_charger(void)
110 {
111 	static int regulator_enabled;
112 	int max_uA = pdata->ac_max_uA;
113 
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);
121 		} else {
122 			dev_dbg(dev, "charger off\n");
123 			pdata->set_charge(0);
124 		}
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;
132 			}
133 		} else {
134 			if (regulator_enabled) {
135 				dev_dbg(dev, "charger off\n");
136 				WARN_ON(regulator_disable(ac_draw));
137 				regulator_enabled = 0;
138 			}
139 		}
140 	}
141 }
142 
supply_work_func(struct work_struct * work)143 static void supply_work_func(struct work_struct *work)
144 {
145 	if (ac_status == PDA_PSY_TO_CHANGE) {
146 		ac_status = new_ac_status;
147 		power_supply_changed(pda_psy_ac);
148 	}
149 
150 	if (usb_status == PDA_PSY_TO_CHANGE) {
151 		usb_status = new_usb_status;
152 		power_supply_changed(pda_psy_usb);
153 	}
154 }
155 
psy_changed(void)156 static void psy_changed(void)
157 {
158 	update_charger();
159 
160 	/*
161 	 * Okay, charger set. Now wait a bit before notifying supplicants,
162 	 * charge power should stabilize.
163 	 */
164 	cancel_delayed_work(&supply_work);
165 	schedule_delayed_work(&supply_work,
166 			      msecs_to_jiffies(pdata->wait_for_charger));
167 }
168 
charger_work_func(struct work_struct * work)169 static void charger_work_func(struct work_struct *work)
170 {
171 	update_status();
172 	psy_changed();
173 }
174 
power_changed_isr(int irq,void * power_supply)175 static irqreturn_t power_changed_isr(int irq, void *power_supply)
176 {
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;
181 	else
182 		return IRQ_NONE;
183 
184 	/*
185 	 * Wait a bit before reading ac/usb line status and setting charger,
186 	 * because ac/usb status readings may lag from irq.
187 	 */
188 	cancel_delayed_work(&charger_work);
189 	schedule_delayed_work(&charger_work,
190 			      msecs_to_jiffies(pdata->wait_for_status));
191 
192 	return IRQ_HANDLED;
193 }
194 
polling_work_func(struct work_struct * work)195 static void polling_work_func(struct work_struct *work)
196 {
197 	int changed = 0;
198 
199 	dev_dbg(dev, "polling...\n");
200 
201 	update_status();
202 
203 	if (!ac_irq && new_ac_status != ac_status) {
204 		ac_status = PDA_PSY_TO_CHANGE;
205 		changed = 1;
206 	}
207 
208 	if (!usb_irq && new_usb_status != usb_status) {
209 		usb_status = PDA_PSY_TO_CHANGE;
210 		changed = 1;
211 	}
212 
213 	if (changed)
214 		psy_changed();
215 
216 	cancel_delayed_work(&polling_work);
217 	schedule_delayed_work(&polling_work,
218 			      msecs_to_jiffies(pdata->polling_interval));
219 }
220 
221 #if IS_ENABLED(CONFIG_USB_PHY)
otg_is_usb_online(void)222 static int otg_is_usb_online(void)
223 {
224 	return (transceiver->last_event == USB_EVENT_VBUS ||
225 		transceiver->last_event == USB_EVENT_ENUMERATED);
226 }
227 
otg_is_ac_online(void)228 static int otg_is_ac_online(void)
229 {
230 	return (transceiver->last_event == USB_EVENT_CHARGER);
231 }
232 
otg_handle_notification(struct notifier_block * nb,unsigned long event,void * unused)233 static int otg_handle_notification(struct notifier_block *nb,
234 		unsigned long event, void *unused)
235 {
236 	switch (event) {
237 	case USB_EVENT_CHARGER:
238 		ac_status = PDA_PSY_TO_CHANGE;
239 		break;
240 	case USB_EVENT_VBUS:
241 	case USB_EVENT_ENUMERATED:
242 		usb_status = PDA_PSY_TO_CHANGE;
243 		break;
244 	case USB_EVENT_NONE:
245 		ac_status = PDA_PSY_TO_CHANGE;
246 		usb_status = PDA_PSY_TO_CHANGE;
247 		break;
248 	default:
249 		return NOTIFY_OK;
250 	}
251 
252 	/*
253 	 * Wait a bit before reading ac/usb line status and setting charger,
254 	 * because ac/usb status readings may lag from irq.
255 	 */
256 	cancel_delayed_work(&charger_work);
257 	schedule_delayed_work(&charger_work,
258 			      msecs_to_jiffies(pdata->wait_for_status));
259 
260 	return NOTIFY_OK;
261 }
262 #endif
263 
pda_power_probe(struct platform_device * pdev)264 static int pda_power_probe(struct platform_device *pdev)
265 {
266 	struct power_supply_config psy_cfg = {};
267 	int ret = 0;
268 
269 	dev = &pdev->dev;
270 
271 	if (pdev->id != -1) {
272 		dev_err(dev, "it's meaningless to register several "
273 			"pda_powers; use id = -1\n");
274 		ret = -EINVAL;
275 		goto wrongid;
276 	}
277 
278 	pdata = pdev->dev.platform_data;
279 
280 	if (pdata->init) {
281 		ret = pdata->init(dev);
282 		if (ret < 0)
283 			goto init_failed;
284 	}
285 
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");
289 		ac_draw = NULL;
290 	}
291 
292 	update_status();
293 	update_charger();
294 
295 	if (!pdata->wait_for_status)
296 		pdata->wait_for_status = 500;
297 
298 	if (!pdata->wait_for_charger)
299 		pdata->wait_for_charger = 500;
300 
301 	if (!pdata->polling_interval)
302 		pdata->polling_interval = 2000;
303 
304 	if (!pdata->ac_max_uA)
305 		pdata->ac_max_uA = 500000;
306 
307 	INIT_DELAYED_WORK(&charger_work, charger_work_func);
308 	INIT_DELAYED_WORK(&supply_work, supply_work_func);
309 
310 	ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac");
311 	usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb");
312 
313 	if (pdata->supplied_to) {
314 		psy_cfg.supplied_to = pdata->supplied_to;
315 		psy_cfg.num_supplicants = pdata->num_supplicants;
316 	} else {
317 		psy_cfg.supplied_to = pda_power_supplied_to;
318 		psy_cfg.num_supplicants = ARRAY_SIZE(pda_power_supplied_to);
319 	}
320 
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;
328 	}
329 #endif
330 
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;
339 		}
340 
341 		if (ac_irq) {
342 			ret = request_irq(ac_irq->start, power_changed_isr,
343 					  get_irq_flags(ac_irq), ac_irq->name,
344 					  pda_psy_ac);
345 			if (ret) {
346 				dev_err(dev, "request ac irq failed\n");
347 				goto ac_irq_failed;
348 			}
349 		} else {
350 			polling = 1;
351 		}
352 	}
353 
354 	if (pdata->is_usb_online) {
355 		pda_psy_usb = power_supply_register(&pdev->dev,
356 						    &pda_psy_usb_desc,
357 						    &psy_cfg);
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;
363 		}
364 
365 		if (usb_irq) {
366 			ret = request_irq(usb_irq->start, power_changed_isr,
367 					  get_irq_flags(usb_irq),
368 					  usb_irq->name, pda_psy_usb);
369 			if (ret) {
370 				dev_err(dev, "request usb irq failed\n");
371 				goto usb_irq_failed;
372 			}
373 		} else {
374 			polling = 1;
375 		}
376 	}
377 
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);
382 		if (ret) {
383 			dev_err(dev, "failure to register otg notifier\n");
384 			goto otg_reg_notifier_failed;
385 		}
386 		polling = 0;
387 	}
388 #endif
389 
390 	if (polling) {
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));
396 	}
397 
398 	if (ac_irq || usb_irq)
399 		device_init_wakeup(&pdev->dev, 1);
400 
401 	return 0;
402 
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);
407 #endif
408 usb_irq_failed:
409 	if (pdata->is_usb_online)
410 		power_supply_unregister(pda_psy_usb);
411 usb_supply_failed:
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);
417 #endif
418 ac_irq_failed:
419 	if (pdata->is_ac_online)
420 		power_supply_unregister(pda_psy_ac);
421 ac_supply_failed:
422 	if (ac_draw) {
423 		regulator_put(ac_draw);
424 		ac_draw = NULL;
425 	}
426 	if (pdata->exit)
427 		pdata->exit(dev);
428 init_failed:
429 wrongid:
430 	return ret;
431 }
432 
pda_power_remove(struct platform_device * pdev)433 static int pda_power_remove(struct platform_device *pdev)
434 {
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);
439 
440 	if (polling)
441 		cancel_delayed_work_sync(&polling_work);
442 	cancel_delayed_work_sync(&charger_work);
443 	cancel_delayed_work_sync(&supply_work);
444 
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);
452 #endif
453 	if (ac_draw) {
454 		regulator_put(ac_draw);
455 		ac_draw = NULL;
456 	}
457 	if (pdata->exit)
458 		pdata->exit(dev);
459 
460 	return 0;
461 }
462 
463 #ifdef CONFIG_PM
464 static int ac_wakeup_enabled;
465 static int usb_wakeup_enabled;
466 
pda_power_suspend(struct platform_device * pdev,pm_message_t state)467 static int pda_power_suspend(struct platform_device *pdev, pm_message_t state)
468 {
469 	if (pdata->suspend) {
470 		int ret = pdata->suspend(state);
471 
472 		if (ret)
473 			return ret;
474 	}
475 
476 	if (device_may_wakeup(&pdev->dev)) {
477 		if (ac_irq)
478 			ac_wakeup_enabled = !enable_irq_wake(ac_irq->start);
479 		if (usb_irq)
480 			usb_wakeup_enabled = !enable_irq_wake(usb_irq->start);
481 	}
482 
483 	return 0;
484 }
485 
pda_power_resume(struct platform_device * pdev)486 static int pda_power_resume(struct platform_device *pdev)
487 {
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);
493 	}
494 
495 	if (pdata->resume)
496 		return pdata->resume();
497 
498 	return 0;
499 }
500 #else
501 #define pda_power_suspend NULL
502 #define pda_power_resume NULL
503 #endif /* CONFIG_PM */
504 
505 static struct platform_driver pda_power_pdrv = {
506 	.driver = {
507 		.name = "pda-power",
508 	},
509 	.probe = pda_power_probe,
510 	.remove = pda_power_remove,
511 	.suspend = pda_power_suspend,
512 	.resume = pda_power_resume,
513 };
514 
515 module_platform_driver(pda_power_pdrv);
516 
517 MODULE_LICENSE("GPL");
518 MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
519 MODULE_ALIAS("platform:pda-power");
520