video: sprdfd: disable ESD feature
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / bluetooth / bcm4343.c
1 /*
2  * Bluetooth Broadcom GPIO and Low Power Mode control
3  *
4  *  Copyright (C) 2011 Samsung Electronics Co., Ltd.
5  *  Copyright (C) 2011 Google, Inc.
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 as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
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.
16  *
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
20  *
21  */
22
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>
35 #include <linux/of.h>
36
37 #define BT_LPM_ENABLE
38
39 static struct rfkill *bt_rfkill;
40 #ifdef BT_LPM_ENABLE
41 static int bt_wake_state = -1;
42 #endif
43
44 struct bcm_bt_lpm {
45         int host_wake;
46         int dev_wake;
47
48         struct hrtimer enter_lpm_timer;
49         ktime_t enter_lpm_delay;
50
51         struct uart_port *uport;
52
53         struct wake_lock host_wake_lock;
54         struct wake_lock bt_wake_lock;
55 } bt_lpm;
56
57 struct bcm_bt_gpio {
58         int bt_en;
59         int bt_wake;
60         int bt_hostwake;
61         int irq;
62 } bt_gpio;
63
64 int bt_is_running=0;
65
66 int check_bt_op(void)
67 {
68         return bt_is_running;
69 }
70 EXPORT_SYMBOL(check_bt_op);
71
72 static int bcm4343_bt_rfkill_set_power(void *data, bool blocked)
73 {
74         /* rfkill_ops callback. Turn transmitter on when blocked is false */
75         if (!blocked) {
76                 pr_info("[BT] Bluetooth Power On.\n");
77
78 #ifndef BT_LPM_ENABLE
79                 gpio_set_value(bt_gpio.bt_wake, 1);
80 #endif
81                 gpio_set_value(bt_gpio.bt_en, 1);
82                 bt_is_running = 1;
83                 msleep(100);
84
85         } else {
86                 pr_info("[BT] Bluetooth Power Off.\n");
87
88                 bt_is_running = 0;
89                 gpio_set_value(bt_gpio.bt_en, 0);
90         }
91         return 0;
92 }
93
94 static const struct rfkill_ops bcm4343_bt_rfkill_ops = {
95         .set_block = bcm4343_bt_rfkill_set_power,
96 };
97
98 #ifdef BT_LPM_ENABLE
99 static void set_wake_locked(int wake)
100 {
101         if (wake)
102                 wake_lock(&bt_lpm.bt_wake_lock);
103
104         gpio_set_value(bt_gpio.bt_wake, wake);
105         bt_lpm.dev_wake = wake;
106
107         if (bt_wake_state != wake)
108         {
109                 pr_err("[BT] set_wake_locked value = %d\n", wake);
110                 bt_wake_state = wake;
111         }
112 }
113
114 static enum hrtimer_restart enter_lpm(struct hrtimer *timer)
115 {
116         if (bt_lpm.uport != NULL)
117                 set_wake_locked(0);
118
119         bt_is_running = 0;
120
121         wake_lock_timeout(&bt_lpm.bt_wake_lock, HZ/2);
122
123         return HRTIMER_NORESTART;
124 }
125
126 void bcm_bt_lpm_exit_lpm_locked(struct uart_port *uport)
127 {
128         bt_lpm.uport = uport;
129
130         hrtimer_try_to_cancel(&bt_lpm.enter_lpm_timer);
131         bt_is_running = 1;
132         set_wake_locked(1);
133
134         hrtimer_start(&bt_lpm.enter_lpm_timer, bt_lpm.enter_lpm_delay,
135                 HRTIMER_MODE_REL);
136 }
137 EXPORT_SYMBOL(bcm_bt_lpm_exit_lpm_locked);
138
139
140 static void update_host_wake_locked(int host_wake)
141 {
142         if (host_wake == bt_lpm.host_wake)
143                 return;
144
145         bt_lpm.host_wake = host_wake;
146
147         bt_is_running = 1;
148
149         if (host_wake) {
150                 wake_lock(&bt_lpm.host_wake_lock);
151         } else  {
152                 /* Take a timed wakelock, so that upper layers can take it.
153                  * The chipset deasserts the hostwake lock, when there is no
154                  * more data to send.
155                  */
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);
158         }
159 }
160
161 static irqreturn_t host_wake_isr(int irq, void *dev)
162 {
163         int host_wake;
164
165         host_wake = gpio_get_value(bt_gpio.bt_hostwake);
166         irq_set_irq_type(irq, host_wake ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
167
168         if (!bt_lpm.uport) {
169                 bt_lpm.host_wake = host_wake;
170                 pr_err("[BT] host_wake_isr uport is null\n");
171                 return IRQ_HANDLED;
172         }
173
174         update_host_wake_locked(host_wake);
175
176         return IRQ_HANDLED;
177 }
178
179 static int bcm_bt_lpm_init(struct platform_device *pdev)
180 {
181         int ret;
182
183         hrtimer_init(&bt_lpm.enter_lpm_timer, CLOCK_MONOTONIC,
184                         HRTIMER_MODE_REL);
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;
187
188         bt_lpm.host_wake = 0;
189
190         wake_lock_init(&bt_lpm.host_wake_lock, WAKE_LOCK_SUSPEND,
191                          "BT_host_wake");
192         wake_lock_init(&bt_lpm.bt_wake_lock, WAKE_LOCK_SUSPEND,
193                          "BT_bt_wake");
194
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);
198         if (ret) {
199                 pr_err("[BT] Request_host wake irq failed.\n");
200                 return ret;
201         }
202
203         return 0;
204 }
205 #endif
206
207 static int bcm4343_bluetooth_probe(struct platform_device *pdev)
208 {
209         int rc = 0;
210 #ifdef BT_LPM_ENABLE
211         int ret;
212 #endif
213         pr_info("[BT] bcm4343_bluetooth_probe.\n");
214
215         bt_gpio.bt_en = of_get_gpio(pdev->dev.of_node, 0);
216
217         if (!gpio_is_valid(bt_gpio.bt_en)) {
218                 pr_err("[BT] bt_gpio.bt_en get gpio failed.\n");
219                 return -EINVAL;
220         }
221
222         rc = gpio_request(bt_gpio.bt_en, "bten_gpio");
223
224         if (unlikely(rc)) {
225                 pr_err("[BT] bt_gpio.bt_en request failed.\n");
226                 return rc;
227         }
228
229         bt_gpio.bt_wake =of_get_gpio(pdev->dev.of_node, 1);
230
231         if (!gpio_is_valid(bt_gpio.bt_wake)) {
232                 pr_err("[BT] bt_gpio.bt_wake get gpio failed.\n");
233                 return -EINVAL;
234         }
235
236         rc = gpio_request(bt_gpio.bt_wake, "btwake_gpio");
237
238         if (unlikely(rc)) {
239                 pr_err("[BT] bt_gpio.bt_wake request failed.\n");
240                 gpio_free(bt_gpio.bt_en);
241                 return rc;
242         }
243
244         bt_gpio.bt_hostwake =of_get_gpio(pdev->dev.of_node, 2);
245
246         if (!gpio_is_valid(bt_gpio.bt_hostwake)) {
247                 pr_err("[BT] bt_gpio.bt_hostwake get gpio failed.\n");
248                 return -EINVAL;
249         }
250
251         rc = gpio_request(bt_gpio.bt_hostwake,"bthostwake_gpio");
252
253         if (unlikely(rc)) {
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);
257                 return rc;
258         }
259
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);
263
264         bt_rfkill = rfkill_alloc("bcm4343 Bluetooth", &pdev->dev,
265                                 RFKILL_TYPE_BLUETOOTH, &bcm4343_bt_rfkill_ops,
266                                 NULL);
267
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);
273                 return -ENOMEM;
274         }
275
276         rfkill_init_sw_state(bt_rfkill, 0);
277
278         rc = rfkill_register(bt_rfkill);
279
280         if (unlikely(rc)) {
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);
286                 return -1;
287         }
288
289         rfkill_set_sw_state(bt_rfkill, true);
290
291 #ifdef BT_LPM_ENABLE
292         ret = bcm_bt_lpm_init(pdev);
293         if (ret) {
294                 rfkill_unregister(bt_rfkill);
295                 rfkill_destroy(bt_rfkill);
296
297                 gpio_free(bt_gpio.bt_hostwake);
298                 gpio_free(bt_gpio.bt_wake);
299                 gpio_free(bt_gpio.bt_en);
300         }
301 #endif
302         pr_info("[BT] bcm4343_bluetooth_probe End \n");
303         return rc;
304 }
305
306 static int bcm4343_bluetooth_remove(struct platform_device *pdev)
307 {
308         rfkill_unregister(bt_rfkill);
309         rfkill_destroy(bt_rfkill);
310
311         gpio_free(bt_gpio.bt_en);
312         gpio_free(bt_gpio.bt_wake);
313         gpio_free(bt_gpio.bt_hostwake);
314
315         wake_lock_destroy(&bt_lpm.host_wake_lock);
316         wake_lock_destroy(&bt_lpm.bt_wake_lock);
317
318         return 0;
319 }
320
321 #if defined (CONFIG_OF)
322 static const struct of_device_id exynos_bluetooth_match[] = {
323         {
324                 .compatible = "broadcom,bcm4343",
325         },
326         {},
327 };
328 MODULE_DEVICE_TABLE(of, exynos_bluetooth_match);
329
330 static struct platform_driver bcm4343_bluetooth_platform_driver = {
331         .probe = bcm4343_bluetooth_probe,
332         .remove = bcm4343_bluetooth_remove,
333         .driver = {
334                    .name = "bcm4343_bluetooth",
335                    .owner = THIS_MODULE,
336                    .of_match_table = exynos_bluetooth_match,
337                    },
338 };
339
340 module_platform_driver(bcm4343_bluetooth_platform_driver);
341 #endif
342 MODULE_ALIAS("platform:bcm4343");
343 MODULE_DESCRIPTION("bcm4343_bluetooth");
344 MODULE_LICENSE("GPL");