2 * Bluetooth Broadcom GPIO and Low Power Mode control
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * Copyright (C) 2011 Google, Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/delay.h>
24 #include <linux/gpio.h>
25 #include <linux/hrtimer.h>
26 #include <linux/init.h>
27 #include <linux/interrupt.h>
28 #include <linux/irq.h>
29 #include <linux/module.h>
30 #include <linux/platform_device.h>
31 #include <linux/rfkill.h>
32 #include <linux/serial_core.h>
33 #include <linux/wakelock.h>
34 #include <linux/of_gpio.h>
39 static struct rfkill *bt_rfkill;
41 static int bt_wake_state = -1;
48 struct hrtimer enter_lpm_timer;
49 ktime_t enter_lpm_delay;
51 struct uart_port *uport;
53 struct wake_lock host_wake_lock;
54 struct wake_lock bt_wake_lock;
70 EXPORT_SYMBOL(check_bt_op);
72 static int bcm4343_bt_rfkill_set_power(void *data, bool blocked)
74 /* rfkill_ops callback. Turn transmitter on when blocked is false */
76 pr_info("[BT] Bluetooth Power On.\n");
79 gpio_set_value(bt_gpio.bt_wake, 1);
81 gpio_set_value(bt_gpio.bt_en, 1);
86 pr_info("[BT] Bluetooth Power Off.\n");
89 gpio_set_value(bt_gpio.bt_en, 0);
94 static const struct rfkill_ops bcm4343_bt_rfkill_ops = {
95 .set_block = bcm4343_bt_rfkill_set_power,
99 static void set_wake_locked(int wake)
102 wake_lock(&bt_lpm.bt_wake_lock);
104 gpio_set_value(bt_gpio.bt_wake, wake);
105 bt_lpm.dev_wake = wake;
107 if (bt_wake_state != wake)
109 pr_err("[BT] set_wake_locked value = %d\n", wake);
110 bt_wake_state = wake;
114 static enum hrtimer_restart enter_lpm(struct hrtimer *timer)
116 if (bt_lpm.uport != NULL)
121 wake_lock_timeout(&bt_lpm.bt_wake_lock, HZ/2);
123 return HRTIMER_NORESTART;
126 void bcm_bt_lpm_exit_lpm_locked(struct uart_port *uport)
128 bt_lpm.uport = uport;
130 hrtimer_try_to_cancel(&bt_lpm.enter_lpm_timer);
134 hrtimer_start(&bt_lpm.enter_lpm_timer, bt_lpm.enter_lpm_delay,
137 EXPORT_SYMBOL(bcm_bt_lpm_exit_lpm_locked);
140 static void update_host_wake_locked(int host_wake)
142 if (host_wake == bt_lpm.host_wake)
145 bt_lpm.host_wake = host_wake;
150 wake_lock(&bt_lpm.host_wake_lock);
152 /* Take a timed wakelock, so that upper layers can take it.
153 * The chipset deasserts the hostwake lock, when there is no
156 pr_err("[BT] update_host_wake_locked host_wake is deasserted. release wakelock in 1s\n");
157 wake_lock_timeout(&bt_lpm.host_wake_lock, HZ);
161 static irqreturn_t host_wake_isr(int irq, void *dev)
165 host_wake = gpio_get_value(bt_gpio.bt_hostwake);
166 irq_set_irq_type(irq, host_wake ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
169 bt_lpm.host_wake = host_wake;
170 pr_err("[BT] host_wake_isr uport is null\n");
174 update_host_wake_locked(host_wake);
179 static int bcm_bt_lpm_init(struct platform_device *pdev)
183 hrtimer_init(&bt_lpm.enter_lpm_timer, CLOCK_MONOTONIC,
185 bt_lpm.enter_lpm_delay = ktime_set(5, 0); /* 1 sec */ /*1->3*//*3->4*/
186 bt_lpm.enter_lpm_timer.function = enter_lpm;
188 bt_lpm.host_wake = 0;
190 wake_lock_init(&bt_lpm.host_wake_lock, WAKE_LOCK_SUSPEND,
192 wake_lock_init(&bt_lpm.bt_wake_lock, WAKE_LOCK_SUSPEND,
195 bt_gpio.irq = gpio_to_irq(bt_gpio.bt_hostwake);
196 ret = request_irq(bt_gpio.irq, host_wake_isr, IRQF_TRIGGER_HIGH|IRQF_NO_SUSPEND,
197 "bt_host_wake", NULL);
199 pr_err("[BT] Request_host wake irq failed.\n");
207 static int bcm4343_bluetooth_probe(struct platform_device *pdev)
213 pr_info("[BT] bcm4343_bluetooth_probe.\n");
215 bt_gpio.bt_en = of_get_gpio(pdev->dev.of_node, 0);
217 if (!gpio_is_valid(bt_gpio.bt_en)) {
218 pr_err("[BT] bt_gpio.bt_en get gpio failed.\n");
222 rc = gpio_request(bt_gpio.bt_en, "bten_gpio");
225 pr_err("[BT] bt_gpio.bt_en request failed.\n");
229 bt_gpio.bt_wake =of_get_gpio(pdev->dev.of_node, 1);
231 if (!gpio_is_valid(bt_gpio.bt_wake)) {
232 pr_err("[BT] bt_gpio.bt_wake get gpio failed.\n");
236 rc = gpio_request(bt_gpio.bt_wake, "btwake_gpio");
239 pr_err("[BT] bt_gpio.bt_wake request failed.\n");
240 gpio_free(bt_gpio.bt_en);
244 bt_gpio.bt_hostwake =of_get_gpio(pdev->dev.of_node, 2);
246 if (!gpio_is_valid(bt_gpio.bt_hostwake)) {
247 pr_err("[BT] bt_gpio.bt_hostwake get gpio failed.\n");
251 rc = gpio_request(bt_gpio.bt_hostwake,"bthostwake_gpio");
254 pr_err("[BT] bt_gpio.bt_hostwake request failed.\n");
255 gpio_free(bt_gpio.bt_wake);
256 gpio_free(bt_gpio.bt_en);
260 gpio_direction_input(bt_gpio.bt_hostwake);
261 gpio_direction_output(bt_gpio.bt_wake, 0);
262 gpio_direction_output(bt_gpio.bt_en, 0);
264 bt_rfkill = rfkill_alloc("bcm4343 Bluetooth", &pdev->dev,
265 RFKILL_TYPE_BLUETOOTH, &bcm4343_bt_rfkill_ops,
268 if (unlikely(!bt_rfkill)) {
269 pr_err("[BT] bt_rfkill alloc failed.\n");
270 gpio_free(bt_gpio.bt_hostwake);
271 gpio_free(bt_gpio.bt_wake);
272 gpio_free(bt_gpio.bt_en);
276 rfkill_init_sw_state(bt_rfkill, 0);
278 rc = rfkill_register(bt_rfkill);
281 pr_err("[BT] bt_rfkill register failed.\n");
282 rfkill_destroy(bt_rfkill);
283 gpio_free(bt_gpio.bt_hostwake);
284 gpio_free(bt_gpio.bt_wake);
285 gpio_free(bt_gpio.bt_en);
289 rfkill_set_sw_state(bt_rfkill, true);
292 ret = bcm_bt_lpm_init(pdev);
294 rfkill_unregister(bt_rfkill);
295 rfkill_destroy(bt_rfkill);
297 gpio_free(bt_gpio.bt_hostwake);
298 gpio_free(bt_gpio.bt_wake);
299 gpio_free(bt_gpio.bt_en);
302 pr_info("[BT] bcm4343_bluetooth_probe End \n");
306 static int bcm4343_bluetooth_remove(struct platform_device *pdev)
308 rfkill_unregister(bt_rfkill);
309 rfkill_destroy(bt_rfkill);
311 gpio_free(bt_gpio.bt_en);
312 gpio_free(bt_gpio.bt_wake);
313 gpio_free(bt_gpio.bt_hostwake);
315 wake_lock_destroy(&bt_lpm.host_wake_lock);
316 wake_lock_destroy(&bt_lpm.bt_wake_lock);
321 #if defined (CONFIG_OF)
322 static const struct of_device_id exynos_bluetooth_match[] = {
324 .compatible = "broadcom,bcm4343",
328 MODULE_DEVICE_TABLE(of, exynos_bluetooth_match);
330 static struct platform_driver bcm4343_bluetooth_platform_driver = {
331 .probe = bcm4343_bluetooth_probe,
332 .remove = bcm4343_bluetooth_remove,
334 .name = "bcm4343_bluetooth",
335 .owner = THIS_MODULE,
336 .of_match_table = exynos_bluetooth_match,
340 module_platform_driver(bcm4343_bluetooth_platform_driver);
342 MODULE_ALIAS("platform:bcm4343");
343 MODULE_DESCRIPTION("bcm4343_bluetooth");
344 MODULE_LICENSE("GPL");