• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  TI Bluesleep driver
3  *	Kernel module responsible for Wake up of Host
4  *  Copyright (C) 2009-2010 Texas Instruments
5 
6 
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * for more details.
15  *
16  * Copyright (C) 2006-2007 - Motorola
17  * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
18  *
19  *  Date         Author           Comment
20  * -----------  --------------   --------------------------------
21  * 2006-Apr-28  Motorola         The kernel module for running the Bluetooth(R)
22  *                               Sleep-Mode Protocol from the Host side
23  * 2006-Sep-08  Motorola         Added workqueue for handling sleep work.
24  * 2007-Jan-24  Motorola         Added mbm_handle_ioi() call to ISR.
25  * 2009-Aug-10  Motorola         Changed "add_timer" to "mod_timer" to solve
26  *                               race when flurry of queued work comes in.
27 */
28 #define DEBUG
29 
30 #include <linux/module.h>       /* kernel module definitions */
31 #include <linux/init.h>
32 #include <linux/interrupt.h>
33 #include <linux/platform_device.h>
34 #include <linux/serial_core.h>
35 #include <linux/proc_fs.h>
36 #include <linux/version.h>
37 
38 #include <linux/gpio.h>
39 #include <linux/of_gpio.h>
40 #include <linux/of_platform.h>
41 #include <linux/pm_wakeirq.h>
42 
43 #include <net/bluetooth/bluetooth.h>
44 
45 /*
46  * #define BT_SLEEP_DBG
47  */
48 #undef BT_DBG
49 #undef BT_ERR
50 #ifdef BT_SLEEP_DBG
51 #define BT_DBG(fmt, arg...) pr_debug("[BT_LPM] %s: " fmt "\n",\
52 				__func__, ## arg)
53 #else
54 #define BT_DBG(fmt, arg...)
55 #endif
56 #define BT_ERR(fmt, arg...) pr_err("[BT_LPM] %s: " fmt "\n",\
57 				__func__, ## arg)
58 
59 /*
60  * Defines
61  */
62 #define VERSION	 "1.2.3"
63 #define PROC_DIR	"bluetooth/sleep"
64 
65 #define DEFAULT_UART_INDEX   1
66 
67 
68 static void bluesleep_stop(void);
69 static int bluesleep_start(void);
70 
71 struct bluesleep_info {
72 	unsigned int wakeup_enable;
73 	unsigned host_wake;
74 	unsigned ext_wake;
75 	unsigned host_wake_irq;
76 	struct wakeup_source *ws;
77 	struct uart_port *uport;
78 	unsigned host_wake_assert:1;
79 	unsigned ext_wake_assert:1;
80 	struct platform_device *pdev;
81 };
82 
83 /* work function */
84 static void bluesleep_sleep_work(struct work_struct *work);
85 
86 /* work queue */
87 DECLARE_DELAYED_WORK(sleep_workqueue, bluesleep_sleep_work);
88 
89 /* Macros for handling sleep work */
90 #define bluesleep_rx_busy()     schedule_delayed_work(&sleep_workqueue, 0)
91 #define bluesleep_tx_busy()     schedule_delayed_work(&sleep_workqueue, 0)
92 #define bluesleep_rx_idle()     schedule_delayed_work(&sleep_workqueue, 0)
93 #define bluesleep_tx_idle()     schedule_delayed_work(&sleep_workqueue, 0)
94 
95 /* 10 second timeout */
96 #define TX_TIMER_INTERVAL	10
97 
98 /* state variable names and bit positions */
99 #define BT_PROTO	0x01
100 #define BT_TXDATA	0x02
101 #define BT_ASLEEP	0x04
102 
103 /* variable use indicate lpm modle */
104 static bool has_lpm_enabled;
105 
106 /* struct use save platform_device from uart */
107 static struct platform_device *bluesleep_uart_dev;
108 
109 static struct bluesleep_info *bsi;
110 
111 /* module usage */
112 static atomic_t open_count = ATOMIC_INIT(1);
113 
114 /*
115  * Global variables
116  */
117 
118 /** Global state flags */
119 static unsigned long flags;
120 
121 /** Tasklet to respond to change in hostwake line */
122 static struct tasklet_struct hostwake_task;
123 
124 /** Transmission timer */
125 static struct timer_list tx_timer;
126 
127 /** Lock for state transitions */
128 static spinlock_t rw_lock;
129 
130 
131 struct proc_dir_entry *bluetooth_dir, *sleep_dir;
132 
133 /*
134  * Local functions
135  */
136 
137 /**
138  * @return 1 if the Host can go to sleep, 0 otherwise.
139  */
bluesleep_can_sleep(void)140 static inline int bluesleep_can_sleep(void)
141 {
142 	/* check if BT_WAKE_HOST_GPIO deasserted */
143 	return (gpio_get_value(bsi->host_wake) != bsi->host_wake_assert) &&
144 		(bsi->uport != NULL);
145 }
146 
147 /*
148  * after bt wakeup should clean BT_ASLEEP flag and start time.
149  */
bluesleep_sleep_wakeup(void)150 void bluesleep_sleep_wakeup(void)
151 {
152 	if (test_bit(BT_ASLEEP, &flags)) {
153 		BT_DBG("waking up...");
154 		/* Start the timer */
155 		mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ));
156 		clear_bit(BT_ASLEEP, &flags);
157 	}
158 }
159 
160 /**
161  * @brief@  main sleep work handling function which update the flags
162  * and activate and deactivate UART ,check FIFO.
163  */
bluesleep_sleep_work(struct work_struct * work)164 static void bluesleep_sleep_work(struct work_struct *work)
165 {
166 	if (bluesleep_can_sleep()) {
167 		/* already asleep, this is an error case */
168 		if (test_bit(BT_ASLEEP, &flags)) {
169 			BT_DBG("already asleep");
170 			return;
171 		}
172 		if (bsi->uport->ops->tx_empty(bsi->uport)) {
173 			BT_DBG("going to sleep...");
174 			set_bit(BT_ASLEEP, &flags);
175 			__pm_wakeup_event(bsi->ws, HZ / 2);
176 		} else {
177 			mod_timer(&tx_timer,
178 					jiffies + (TX_TIMER_INTERVAL * HZ));
179 			return;
180 		}
181 	} else if (!test_bit(BT_ASLEEP, &flags)) {
182 		mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ));
183 	} else {
184 		bluesleep_sleep_wakeup();
185 	}
186 }
187 
188 /**
189  * A tasklet function that runs in tasklet context and reads the value
190  * of the HOST_WAKE GPIO pin and further defer the work.
191  * @param data Not used.
192  */
bluesleep_hostwake_task(unsigned long data)193 static void bluesleep_hostwake_task(unsigned long data)
194 {
195 	BT_DBG("hostwake line change");
196 	spin_lock(&rw_lock);
197 
198 	if (gpio_get_value(bsi->host_wake) == bsi->host_wake_assert)
199 		bluesleep_rx_busy();
200 	else
201 		bluesleep_rx_idle();
202 
203 	spin_unlock(&rw_lock);
204 }
205 
bluesleep_get_uart_port(void)206 static struct uart_port *bluesleep_get_uart_port(void)
207 {
208 	struct uart_port *uport = NULL;
209 
210 	if (bluesleep_uart_dev) {
211 		uport = platform_get_drvdata(bluesleep_uart_dev);
212 		if (uport)
213 			BT_DBG(
214 			"%s get uart_port from blusleep_uart_dev: %s, port irq: %d",
215 					__func__, bluesleep_uart_dev->name,
216 					uport->irq);
217 	}
218 	return uport;
219 }
220 
bluesleep_lpm_proc_show(struct seq_file * m,void * v)221 static int bluesleep_lpm_proc_show(struct seq_file *m, void *v)
222 {
223 	seq_printf(m, "lpm enable: %d\n", has_lpm_enabled);
224 	return 0;
225 }
226 
bluesleep_lpm_proc_open(struct inode * inode,struct file * file)227 static int bluesleep_lpm_proc_open(struct inode *inode, struct file *file)
228 {
229 	return single_open(file, bluesleep_lpm_proc_show, NULL);
230 }
231 
bluesleep_write_proc_lpm(struct file * file,const char __user * buffer,size_t count,loff_t * pos)232 static ssize_t bluesleep_write_proc_lpm(struct file *file,
233 				const char __user *buffer,
234 				size_t count, loff_t *pos)
235 {
236 	char b;
237 
238 	if (count < 1)
239 		return -EINVAL;
240 
241 	if (copy_from_user(&b, buffer, 1))
242 		return -EFAULT;
243 
244 	if (b == '0') {
245 		/* HCI_DEV_UNREG */
246 		bluesleep_stop();
247 		has_lpm_enabled = false;
248 		bsi->uport = NULL;
249 	} else {
250 		/* HCI_DEV_REG */
251 		if (!has_lpm_enabled) {
252 			has_lpm_enabled = true;
253 			if (bluesleep_uart_dev)
254 				bsi->uport = bluesleep_get_uart_port();
255 
256 			/* if bluetooth started, start bluesleep*/
257 			bluesleep_start();
258 		}
259 	}
260 
261 	return count;
262 }
263 
264 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
265 static const struct proc_ops lpm_fops = {
266 	.proc_open    = bluesleep_lpm_proc_open,
267 	.proc_read    = seq_read,
268 	.proc_lseek   = seq_lseek,
269 	.proc_release = single_release,
270 	.proc_write   = bluesleep_write_proc_lpm,
271 };
272 
273 #else
274 
275 static const struct file_operations lpm_fops = {
276 	.owner		= THIS_MODULE,
277 	.open		= bluesleep_lpm_proc_open,
278 	.read		= seq_read,
279 	.llseek		= seq_lseek,
280 	.release	= single_release,
281 	.write		= bluesleep_write_proc_lpm,
282 };
283 #endif
284 
285 /**
286  * Handles transmission timer expiration.
287  * @param data Not used.
288  */
bluesleep_tx_timer_expire(struct timer_list * t)289 static void bluesleep_tx_timer_expire(struct timer_list *t)
290 {
291 	unsigned long irq_flags;
292 
293 	spin_lock_irqsave(&rw_lock, irq_flags);
294 
295 	BT_DBG("Tx timer expired");
296 
297 	/* were we silent during the last timeout */
298 	if (!test_bit(BT_TXDATA, &flags)) {
299 		BT_DBG("Tx has been idle");
300 		bluesleep_tx_idle();
301 	} else {
302 		BT_DBG("Tx data during last period");
303 		mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL*HZ));
304 	}
305 
306 	/* clear the incoming data flag */
307 	clear_bit(BT_TXDATA, &flags);
308 
309 	spin_unlock_irqrestore(&rw_lock, irq_flags);
310 }
311 
312 /**
313  * Schedules a tasklet to run when receiving an interrupt on the
314  * <code>HOST_WAKE</code> GPIO pin.
315  * @param irq Not used.
316  * @param dev_id Not used.
317  */
bluesleep_hostwake_isr(int irq,void * dev_id)318 static irqreturn_t bluesleep_hostwake_isr(int irq, void *dev_id)
319 {
320 	/* schedule a tasklet to handle the change in the host wake line */
321 	tasklet_schedule(&hostwake_task);
322 	__pm_stay_awake(bsi->ws);
323 	return IRQ_HANDLED;
324 }
325 
326 /**
327  * Starts the Sleep-Mode Protocol on the Host.
328  * @return On success, 0. On error, -1, and <code>errno</code> is set
329  * appropriately.
330  */
bluesleep_start(void)331 static int bluesleep_start(void)
332 {
333 	int retval;
334 	unsigned long irq_flags;
335 
336 	spin_lock_irqsave(&rw_lock, irq_flags);
337 
338 	if (test_bit(BT_PROTO, &flags)) {
339 		spin_unlock_irqrestore(&rw_lock, irq_flags);
340 		return 0;
341 	}
342 
343 	spin_unlock_irqrestore(&rw_lock, irq_flags);
344 
345 	if (!atomic_dec_and_test(&open_count)) {
346 		atomic_inc(&open_count);
347 		return -EBUSY;
348 	}
349 
350 	/* start the timer */
351 	mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL*HZ));
352 
353 	retval = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr,
354 				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
355 				"bluetooth hostwake", &bsi->pdev->dev);
356 	if (retval  < 0) {
357 		BT_ERR("Couldn't acquire BT_HOST_WAKE IRQ");
358 		goto fail;
359 	}
360 
361 	set_bit(BT_PROTO, &flags);
362 	__pm_stay_awake(bsi->ws);
363 
364 	return 0;
365 fail:
366 	del_timer(&tx_timer);
367 	atomic_inc(&open_count);
368 
369 	return retval;
370 }
371 
372 /**
373  * Stops the Sleep-Mode Protocol on the Host.
374  */
bluesleep_stop(void)375 static void bluesleep_stop(void)
376 {
377 	unsigned long irq_flags;
378 
379 	spin_lock_irqsave(&rw_lock, irq_flags);
380 
381 	if (!test_bit(BT_PROTO, &flags)) {
382 		spin_unlock_irqrestore(&rw_lock, irq_flags);
383 		return;
384 	}
385 
386 	del_timer(&tx_timer);
387 	clear_bit(BT_PROTO, &flags);
388 
389 	if (test_bit(BT_ASLEEP, &flags))
390 		clear_bit(BT_ASLEEP, &flags);
391 
392 	atomic_inc(&open_count);
393 
394 	spin_unlock_irqrestore(&rw_lock, irq_flags);
395 	free_irq(bsi->host_wake_irq, &bsi->pdev->dev);
396 	__pm_wakeup_event(bsi->ws, HZ / 2);
397 }
398 
399 static int assert_level = -1;
400 module_param(assert_level, int, S_IRUGO);
401 MODULE_PARM_DESC(assert_level, "BT_LPM hostwake/btwake assert level");
402 
sw_uart_get_pdev(int id)403 static struct platform_device *sw_uart_get_pdev(int id)
404 {
405 	struct device_node *np;
406 	char match[20];
407 	sprintf(match, "uart%d", id);
408 	np = of_find_node_by_type(NULL, match);
409 	return of_find_device_by_node(np);
410 }
411 
bluesleep_probe(struct platform_device * pdev)412 static int __init bluesleep_probe(struct platform_device *pdev)
413 {
414 	struct device_node *np = pdev->dev.of_node;
415 	struct device *dev = &pdev->dev;
416 	enum of_gpio_flags config;
417 	int ret, uart_index;
418 	u32 val;
419 
420 	bsi = devm_kzalloc(&pdev->dev, sizeof(struct bluesleep_info),
421 			GFP_KERNEL);
422 	if (!bsi)
423 		return -ENOMEM;
424 
425 	bsi->host_wake = of_get_named_gpio_flags(np, "bt_hostwake", 0, &config);
426 	if (!gpio_is_valid(bsi->host_wake)) {
427 		BT_ERR("get gpio bt_hostwake failed\n");
428 		return -EINVAL;
429 	}
430 
431 	/* set host_wake_assert */
432 	bsi->host_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1;
433 	BT_DBG("bt_hostwake gpio=%d assert=%d\n", bsi->host_wake, bsi->host_wake_assert);
434 
435 	if (assert_level != -1) {
436 		bsi->host_wake_assert = (assert_level & 0x02) > 0;
437 		BT_DBG("override host_wake assert to %d", bsi->host_wake_assert);
438 	}
439 
440 	ret = devm_gpio_request(dev, bsi->host_wake, "bt_hostwake");
441 	if (ret < 0) {
442 		BT_ERR("can't request bt_hostwake gpio %d\n",
443 			bsi->host_wake);
444 		return ret;
445 	}
446 	ret = gpio_direction_input(bsi->host_wake);
447 	if (ret < 0) {
448 		BT_ERR("can't request input direction bt_wake gpio %d\n",
449 			bsi->host_wake);
450 		return ret;
451 	}
452 
453 	if (!of_property_read_bool(np, "wakeup-source")) {
454 		BT_DBG("wakeup source is disabled!\n");
455 	} else {
456 		ret = device_init_wakeup(dev, true);
457 		if (ret < 0) {
458 			BT_ERR("device init wakeup failed!\n");
459 			return ret;
460 		}
461 		ret = dev_pm_set_wake_irq(dev, gpio_to_irq(bsi->host_wake));
462 		if (ret < 0) {
463 			BT_ERR("can't enable wakeup src for bt_hostwake %d\n",
464 				bsi->host_wake);
465 			return ret;
466 		}
467 		bsi->wakeup_enable = 1;
468 	}
469 
470 	bsi->ext_wake = of_get_named_gpio_flags(np, "bt_wake",
471 			0, (enum of_gpio_flags *)&config);
472 	if (!gpio_is_valid(bsi->ext_wake)) {
473 		BT_ERR("get gpio bt_wake failed\n");
474 		return -EINVAL;
475 	}
476 
477 	ret = devm_gpio_request(dev, bsi->ext_wake, "bt_wake");
478 	if (ret < 0) {
479 		BT_ERR("can't request bt_wake gpio %d\n",
480 			bsi->ext_wake);
481 		return ret;
482 	}
483 
484 	/* set ext_wake_assert */
485 	bsi->ext_wake_assert = (config == OF_GPIO_ACTIVE_LOW) ? 0 : 1;
486 	BT_DBG("bt_wake gpio=%d assert=%d\n", bsi->ext_wake, bsi->ext_wake_assert);
487 
488 	if (assert_level != -1) {
489 		bsi->ext_wake_assert = (assert_level & 0x01) > 0;
490 		BT_DBG("override ext_wake assert to %d", bsi->ext_wake_assert);
491 	}
492 
493 	/* 1.set bt_wake as output and the level is assert, assert bt wake */
494 	ret = gpio_direction_output(bsi->ext_wake, bsi->ext_wake_assert);
495 	if (ret < 0) {
496 		BT_ERR("can't request output direction bt_wake gpio %d\n",
497 			bsi->ext_wake);
498 		return ret;
499 	}
500 
501 	/* 2.get bt_host_wake gpio irq */
502 	bsi->host_wake_irq = gpio_to_irq(bsi->host_wake);
503 	if (bsi->host_wake_irq < 0) {
504 		BT_ERR("map gpio [%d] to virq failed, errno = %d\n",
505 				bsi->host_wake, bsi->host_wake_irq);
506 		ret = -ENODEV;
507 		return ret;
508 	}
509 
510 	uart_index = DEFAULT_UART_INDEX;
511 	if (!of_property_read_u32(np, "uart_index", &val)) {
512 		switch (val) {
513 		case 0:
514 		case 1:
515 		case 2:
516 			uart_index = val;
517 			break;
518 		default:
519 			BT_ERR("unsupported uart_index (%u)\n", val);
520 		}
521 	}
522 	BT_DBG("uart_index (%u)\n", uart_index);
523 	bluesleep_uart_dev = sw_uart_get_pdev(uart_index);
524 
525 	bsi->ws = wakeup_source_register(dev, "bluesleep");
526 	bsi->pdev = pdev;
527 	return 0;
528 }
529 
bluesleep_remove(struct platform_device * pdev)530 static int bluesleep_remove(struct platform_device *pdev)
531 {
532 	if (test_bit(BT_PROTO, &flags)) {
533 		if (disable_irq_wake(bsi->host_wake_irq))
534 			BT_ERR("Couldn't disable hostwake IRQ wakeup mode\n");
535 		free_irq(bsi->host_wake_irq, &bsi->pdev->dev);
536 		del_timer(&tx_timer);
537 	}
538 
539 	wakeup_source_unregister(bsi->ws);
540 	if (bsi->wakeup_enable) {
541 		BT_DBG("Deinit wakeup source");
542 		device_init_wakeup(&pdev->dev, false);
543 		dev_pm_clear_wake_irq(&pdev->dev);
544 	}
545 
546 	return 0;
547 }
548 
bluesleep_resume(struct platform_device * pdev)549 static int bluesleep_resume(struct platform_device *pdev)
550 {
551 	BT_DBG("%s", __func__);
552 
553 	return 0;
554 }
555 
bluesleep_suspend(struct platform_device * pdev,pm_message_t state)556 static int bluesleep_suspend(struct platform_device *pdev, pm_message_t state)
557 {
558 	BT_DBG("%s", __func__);
559 
560 	return 0;
561 }
562 
563 static const struct of_device_id sunxi_btlpm_ids[] = {
564 	{ .compatible = "allwinner,sunxi-btlpm" },
565 	{ /* Sentinel */ }
566 };
567 
568 static struct platform_driver bluesleep_driver = {
569 	.remove	= bluesleep_remove,
570 	.suspend = bluesleep_suspend,
571 	.resume = bluesleep_resume,
572 	.driver	= {
573 		.owner	= THIS_MODULE,
574 		.name	= "sunxi-btlpm",
575 		.of_match_table	= sunxi_btlpm_ids,
576 	},
577 };
578 
579 /**
580  * Initializes the module.
581  * @return On success, 0. On error, -1, and <code>errno</code> is set
582  * appropriately.
583  */
bluesleep_init(void)584 static int __init bluesleep_init(void)
585 {
586 	int retval;
587 	struct proc_dir_entry *ent;
588 
589 	BT_DBG("BlueSleep Mode Driver Ver %s", VERSION);
590 
591 	retval = platform_driver_probe(&bluesleep_driver, bluesleep_probe);
592 	if (retval)
593 		return retval;
594 
595 	bluetooth_dir = proc_mkdir("bluetooth", NULL);
596 	if (bluetooth_dir == NULL) {
597 		BT_ERR("Unable to create /proc/bluetooth directory");
598 		return -ENOMEM;
599 	}
600 
601 	sleep_dir = proc_mkdir("sleep", bluetooth_dir);
602 	if (sleep_dir == NULL) {
603 		BT_ERR("Unable to create /proc/%s directory", PROC_DIR);
604 		return -ENOMEM;
605 	}
606 	/* read/write proc entries */
607 	ent = proc_create("lpm", 0660, sleep_dir, &lpm_fops);
608 	if (ent == NULL) {
609 		BT_ERR("Unable to create /proc/%s/lpm entry", PROC_DIR);
610 		retval = -ENOMEM;
611 		goto fail;
612 	}
613 
614 	flags = 0; /* clear all status bits */
615 
616 	/* Initialize spinlock. */
617 	spin_lock_init(&rw_lock);
618 
619 	/* Initialize timer */
620 	timer_setup(&tx_timer, bluesleep_tx_timer_expire, 0);
621 
622 	/* initialize host wake tasklet */
623 	tasklet_init(&hostwake_task, bluesleep_hostwake_task, 0);
624 
625 	return 0;
626 
627 fail:
628 	remove_proc_entry("lpm", sleep_dir);
629 	remove_proc_entry("sleep", bluetooth_dir);
630 	remove_proc_entry("bluetooth", 0);
631 	return retval;
632 }
633 
634 /**
635  * Cleans up the module.
636  */
bluesleep_exit(void)637 static void __exit bluesleep_exit(void)
638 {
639 	platform_driver_unregister(&bluesleep_driver);
640 
641 	remove_proc_entry("lpm", sleep_dir);
642 	remove_proc_entry("sleep", bluetooth_dir);
643 	remove_proc_entry("bluetooth", 0);
644 }
645 
646 module_init(bluesleep_init);
647 module_exit(bluesleep_exit);
648 
649 MODULE_DESCRIPTION("Bluetooth Sleep Mode Driver ver %s " VERSION);
650 #ifdef MODULE_LICENSE
651 MODULE_LICENSE("GPL");
652 #endif
653