Consummate bcm wifi oob on all platform(Wake gpio define).
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rk30 / board-rk30-ds1001b-rfkill.c
1 /*
2  * Copyright (C) 2010 ROCKCHIP, Inc.
3  * Author: roger_chen <cz@rock-chips.com>
4  *
5  * This program is the bluetooth device bcm4329's driver,
6  *
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/platform_device.h>
11 #include <linux/module.h>
12 #include <linux/device.h>
13 #include <linux/rfkill.h>
14 #include <linux/delay.h>
15 #include <linux/i2c.h>
16 #include <linux/init.h>
17 #include <linux/slab.h>
18 #include <linux/interrupt.h>
19 #include <linux/wakelock.h>
20 #include <linux/fs.h>
21 #include <asm/uaccess.h>
22 #include <mach/gpio.h>
23 #include <asm/irq.h>
24 #include <mach/iomux.h>
25 #include <linux/wakelock.h>
26 #include <linux/timer.h>
27 #include <mach/board.h>
28
29 #if 0
30 #define DBG(x...)   printk(KERN_INFO "[BT_RFKILL]: "x)
31 #else
32 #define DBG(x...)
33 #endif
34
35 #define LOG(x...)   printk(KERN_INFO "[BT_RFKILL]: "x)
36
37 #ifdef CONFIG_BCM4329
38 #define WIFI_BT_POWER_TOGGLE    1
39 #else
40 #define WIFI_BT_POWER_TOGGLE    0
41 #endif
42
43 #define BT_WAKE_LOCK_TIMEOUT    10 //s
44
45 #define BT_AUTO_SLEEP_TIMEOUT   3
46
47 /*
48  * IO Configuration for RK29
49  */
50 #ifdef CONFIG_ARCH_RK29
51
52 #define BT_WAKE_HOST_SUPPORT    0
53
54 /* IO configuration */
55 // BT power pin
56 #define BT_GPIO_POWER           RK29_PIN5_PD6
57 #define IOMUX_BT_GPIO_POWER()     rk29_mux_api_set(GPIO5D6_SDMMC1PWREN_NAME, GPIO5H_GPIO5D6);
58
59 // BT reset pin
60 #define BT_GPIO_RESET           RK29_PIN6_PC4
61 #define IOMUX_BT_GPIO_RESET()
62
63 // BT wakeup pin
64 #define BT_GPIO_WAKE_UP         RK29_PIN6_PC5
65 #define IOMUX_BT_GPIO_WAKE_UP()
66
67 // BT wakeup host pin
68 #define BT_GPIO_WAKE_UP_HOST
69 #define IOMUX_BT_GPIO_WAKE_UP_HOST()
70
71 //bt cts paired to uart rts
72 #define UART_RTS                RK29_PIN2_PA7
73 #define IOMUX_UART_RTS_GPIO()   rk29_mux_api_set(GPIO2A7_UART2RTSN_NAME, GPIO2L_GPIO2A7)
74 #define IOMUX_UART_RTS()        rk29_mux_api_set(GPIO2A7_UART2RTSN_NAME, GPIO2L_UART2_RTS_N)
75
76 /*
77  * IO Configuration for RK30
78  */
79 #elif defined (CONFIG_ARCH_RK30)
80
81 #define BT_WAKE_HOST_SUPPORT    1
82
83 /* IO configuration */
84 // BT power pin
85 #define BT_GPIO_POWER           RK30_PIN3_PC7
86 #define IOMUX_BT_GPIO_POWER()     rk30_mux_api_set(GPIO3C7_SDMMC1WRITEPRT_NAME, GPIO3C_GPIO3C7);
87
88 // BT reset pin
89 #define BT_GPIO_RESET           RK30_PIN3_PD1
90 #define IOMUX_BT_GPIO_RESET()     rk30_mux_api_set(GPIO3D1_SDMMC1BACKENDPWR_NAME, GPIO3D_GPIO3D1);
91
92 // BT wakeup pin
93 #define BT_GPIO_WAKE_UP         RK30_PIN3_PC6
94 #define IOMUX_BT_GPIO_WAKE_UP() rk30_mux_api_set(GPIO3C6_SDMMC1DETECTN_NAME, GPIO3C_GPIO3C6);
95
96 // BT wakeup host pin
97 #define BT_GPIO_WAKE_UP_HOST    RK30_PIN6_PA7
98 #define BT_IRQ_WAKE_UP_HOST     gpio_to_irq(BT_GPIO_WAKE_UP_HOST)
99 #define IOMUX_BT_GPIO_WAKE_UP_HOST()
100
101 //bt cts paired to uart rts
102 #define UART_RTS                RK30_PIN1_PA3
103 #define IOMUX_UART_RTS_GPIO()     rk30_mux_api_set(GPIO1A3_UART0RTSN_NAME, GPIO1A_GPIO1A3)
104 #define IOMUX_UART_RTS()          rk30_mux_api_set(GPIO1A3_UART0RTSN_NAME, GPIO1A_UART0_RTS_N)
105
106 #endif
107
108 struct bt_ctrl
109 {
110     struct rfkill *bt_rfk;
111 #if BT_WAKE_HOST_SUPPORT
112     struct timer_list tl;
113     bool b_HostWake;
114     struct wake_lock bt_wakelock;
115 #endif
116 };
117
118 static const char bt_name[] = 
119 #if defined(CONFIG_RKWIFI)
120     #if defined(CONFIG_RKWIFI_26M)
121         "rk903_26M"
122     #else
123         "rk903"
124     #endif
125 #elif defined(CONFIG_BCM4329)
126     "bcm4329"
127 #elif defined(CONFIG_MV8787)
128     "mv8787"
129 #else
130     "bt_default"
131 #endif
132 ;
133
134 #if WIFI_BT_POWER_TOGGLE
135 extern int rk29sdk_bt_power_state;
136 extern int rk29sdk_wifi_power_state;
137 #endif
138
139 struct bt_ctrl gBtCtrl;
140 struct timer_list bt_sleep_tl;
141
142
143 #if BT_WAKE_HOST_SUPPORT
144 void resetBtHostSleepTimer(void)
145 {
146     mod_timer(&(gBtCtrl.tl),jiffies + BT_WAKE_LOCK_TIMEOUT*HZ);//ÔÙÖØÐÂÉèÖó¬Ê±Öµ¡£    
147 }
148
149 void btWakeupHostLock(void)
150 {
151     if(gBtCtrl.b_HostWake == false){
152         DBG("** Lock **\n");
153         wake_lock(&(gBtCtrl.bt_wakelock));
154         gBtCtrl.b_HostWake = true;
155     }
156 }
157
158 void btWakeupHostUnlock(void)
159 {
160     if(gBtCtrl.b_HostWake == true){        
161         DBG("** UnLock **\n");
162         wake_unlock(&(gBtCtrl.bt_wakelock));  //ÈÃϵͳ˯Ãß    
163         gBtCtrl.b_HostWake = false;
164     }    
165 }
166
167 static void timer_hostSleep(unsigned long arg)
168 {     
169         DBG("b_HostWake=%d\n", gBtCtrl.b_HostWake);
170     btWakeupHostUnlock();
171 }
172
173 void bcm4325_sleep(unsigned long bSleep);
174
175 #ifdef CONFIG_PM
176 static irqreturn_t bcm4329_wake_host_irq(int irq, void *dev)
177 {
178     DBG("%s\n",__FUNCTION__);
179
180     btWakeupHostLock();
181     resetBtHostSleepTimer();
182         return IRQ_HANDLED;
183 }
184
185 static void rfkill_do_wakeup(struct work_struct *work)
186 {
187     // disable bt wakeup host
188     DBG("** free irq\n");
189     free_irq(BT_IRQ_WAKE_UP_HOST, NULL);
190
191     DBG("Enable UART_RTS\n");
192     gpio_set_value(UART_RTS, GPIO_LOW);
193     IOMUX_UART_RTS();
194 }
195
196 static DECLARE_DELAYED_WORK(wakeup_work, rfkill_do_wakeup);
197
198 static int bcm4329_rfkill_suspend(struct platform_device *pdev, pm_message_t state)
199 {
200     DBG("%s\n",__FUNCTION__);
201
202     cancel_delayed_work(&wakeup_work);
203
204 #ifdef CONFIG_BT_AUTOSLEEP
205     bcm4325_sleep(1);
206 #endif
207
208     DBG("Disable UART_RTS\n");
209         //To prevent uart to receive bt data when suspended
210         IOMUX_UART_RTS_GPIO();
211         gpio_request(UART_RTS, "uart_rts");
212         gpio_set_value(UART_RTS, GPIO_HIGH);
213
214     // enable bt wakeup host
215     DBG("Request irq for bt wakeup host\n");
216         if (0 == request_irq(BT_IRQ_WAKE_UP_HOST,
217                     bcm4329_wake_host_irq,
218                     IRQF_TRIGGER_FALLING,
219                     "bt_wake",
220                     NULL))
221         enable_irq_wake(BT_IRQ_WAKE_UP_HOST);
222     else
223                 LOG("Failed to request BT_WAKE_UP_HOST irq\n");
224
225 #ifdef CONFIG_RFKILL_RESET
226     extern void rfkill_set_block(struct rfkill *rfkill, bool blocked);
227     rfkill_set_block(gBtCtrl.bt_rfk, true);
228 #endif
229
230     return 0;
231 }
232
233 static int bcm4329_rfkill_resume(struct platform_device *pdev)
234 {  
235     DBG("%s\n",__FUNCTION__);
236
237     // ÏµÍ³Í˳ö¶þ¼¶Ë¯ÃߺóÐèÒªÀ­µÍRTS£¬´Ó¶ø²ÅÔÊÐíBT·¢Êý¾Ý¹ýÀ´
238     // µ«ÊÇÄ¿Ç°·¢ÏÖÔÚresumeº¯ÊýÖÐÖ±½ÓÀ­µÍRTS»áµ¼ÖÂBTÊý¾Ý¶ªÊ§
239     // ËùÒÔÑÓ³Ù1sºóÔÙÀ­µÍRTS
240     // ÏµÍ³Í˳ö¶þ¼¶Ë¯ÃßʱÊͷŵôBT_IRQ_WAKE_UP_HOST£¬ÔÚ˯ÃßʱºòÔÙ
241     // ´ÎÉêÇ룬Ŀǰ·¢ÏÖÖжϻص÷º¯Êý±Èresume¸üÍíÖ´ÐУ¬Èç¹ûresume
242     // Ê±Ö±½ÓfreeµôIRQ£¬»áµ¼ÖÂÖжϻص÷º¯Êý²»»á±»Ö´ÐУ¬
243     DBG("delay 1s\n");
244     schedule_delayed_work(&wakeup_work, HZ);
245
246     return 0;
247 }
248 #else
249 #define bcm4329_rfkill_suspend NULL
250 #define bcm4329_rfkill_resume  NULL
251 #endif
252
253 #endif
254
255 void bcm4325_sleep(unsigned long bSleep)
256 {
257     DBG("*** bt sleep: %d ***\n", bSleep);
258 #ifdef CONFIG_BT_AUTOSLEEP
259     del_timer(&bt_sleep_tl);// cmy: È·±£ÔÚ»½ÐÑBTʱ£¬²»»áÒò´¥·¢bt_sleep_tl¶øÂíÉÏ˯Ãß
260 #endif
261
262     IOMUX_BT_GPIO_WAKE_UP();
263     gpio_set_value(BT_GPIO_WAKE_UP, bSleep?GPIO_LOW:GPIO_HIGH);
264
265 #ifdef CONFIG_BT_AUTOSLEEP
266     if(!bSleep)
267         mod_timer(&bt_sleep_tl, jiffies + BT_AUTO_SLEEP_TIMEOUT*HZ);//ÔÙÖØÐÂÉèÖó¬Ê±Öµ¡£
268 #endif
269 }
270
271 static int bcm4329_set_block(void *data, bool blocked)
272 {
273         DBG("set blocked :%d\n", blocked);
274
275     IOMUX_BT_GPIO_POWER();
276     IOMUX_BT_GPIO_RESET();
277
278         if (false == blocked) { 
279                 gpio_set_value(BT_GPIO_POWER, GPIO_HIGH);  /* bt power on */
280                 mdelay(20);
281
282         gpio_set_value(BT_GPIO_RESET, GPIO_LOW);
283         mdelay(20);
284                 gpio_set_value(BT_GPIO_RESET, GPIO_HIGH);  /* bt reset deactive*/
285
286         mdelay(20);
287         bcm4325_sleep(0); // ensure bt is wakeup
288         
289         pr_info("bt turn on power\n");
290         } else {
291 #if WIFI_BT_POWER_TOGGLE
292                 if (!rk29sdk_wifi_power_state) {
293 #endif
294                         gpio_set_value(BT_GPIO_POWER, GPIO_LOW);  /* bt power off */
295                 mdelay(20);     
296                 pr_info("bt shut off power\n");
297 #if WIFI_BT_POWER_TOGGLE
298                 }else {
299                         pr_info("bt shouldn't shut off power, wifi is using it!\n");
300                 }
301 #endif
302
303         gpio_set_value(BT_GPIO_RESET, GPIO_LOW);  /* bt reset active*/
304         mdelay(20);
305         }
306
307 #if WIFI_BT_POWER_TOGGLE
308         rk29sdk_bt_power_state = !blocked;
309 #endif
310         return 0;
311 }
312
313 static const struct rfkill_ops bcm4329_rfk_ops = {
314         .set_block = bcm4329_set_block,
315 };
316
317 static int __devinit bcm4329_rfkill_probe(struct platform_device *pdev)
318 {
319         int rc = 0;
320         bool default_state = true;
321         
322         DBG("Enter %s\n",__FUNCTION__);
323         
324         /* default to bluetooth off */
325         bcm4329_set_block(NULL, default_state); /* blocked -> bt off */
326          
327         gBtCtrl.bt_rfk = rfkill_alloc(bt_name, 
328                 NULL, 
329                 RFKILL_TYPE_BLUETOOTH, 
330                 &bcm4329_rfk_ops, 
331                 NULL);
332
333         if (!gBtCtrl.bt_rfk)
334         {
335                 LOG("fail to rfkill_allocate\n");
336                 return -ENOMEM;
337         }
338         
339         rfkill_set_states(gBtCtrl.bt_rfk, default_state, false);
340
341         rc = rfkill_register(gBtCtrl.bt_rfk);
342         if (rc)
343         {
344                 LOG("failed to rfkill_register,rc=0x%x\n",rc);
345                 rfkill_destroy(gBtCtrl.bt_rfk);
346         }
347         
348         gpio_request(BT_GPIO_POWER, NULL);
349         gpio_request(BT_GPIO_RESET, NULL);
350         gpio_request(BT_GPIO_WAKE_UP, NULL);
351     
352 #ifdef CONFIG_BT_AUTOSLEEP
353     init_timer(&bt_sleep_tl);
354     bt_sleep_tl.expires = 0;
355     bt_sleep_tl.function = bcm4325_sleep;
356     bt_sleep_tl.data = 1;
357     add_timer(&bt_sleep_tl);
358 #endif
359
360 #if BT_WAKE_HOST_SUPPORT
361     init_timer(&(gBtCtrl.tl));
362     gBtCtrl.tl.expires = 0;
363     gBtCtrl.tl.function = timer_hostSleep;
364     add_timer(&(gBtCtrl.tl));
365     gBtCtrl.b_HostWake = false;
366     
367         wake_lock_init(&(gBtCtrl.bt_wakelock), WAKE_LOCK_SUSPEND, "bt_wake");
368         
369         rc = gpio_request(BT_GPIO_WAKE_UP_HOST, "bt_wake");
370         if (rc) {
371                 LOG("Failed to request BT_WAKE_UP_HOST\n");
372         }
373         
374         IOMUX_BT_GPIO_WAKE_UP_HOST();
375         gpio_pull_updown(BT_GPIO_WAKE_UP_HOST,GPIOPullUp);
376  #endif
377  
378     LOG("bcm4329 module has been initialized,rc=0x%x\n",rc);
379  
380         return rc;
381 }
382
383
384 static int __devexit bcm4329_rfkill_remove(struct platform_device *pdev)
385 {
386         if (gBtCtrl.bt_rfk)
387                 rfkill_unregister(gBtCtrl.bt_rfk);
388         gBtCtrl.bt_rfk = NULL;
389 #if BT_WAKE_HOST_SUPPORT
390     del_timer(&(gBtCtrl.tl));//ɾµô¶¨Ê±Æ÷
391     btWakeupHostUnlock();
392     wake_lock_destroy(&(gBtCtrl.bt_wakelock));
393 #endif
394 #ifdef CONFIG_BT_AUTOSLEEP
395     del_timer(&bt_sleep_tl);
396 #endif
397
398         platform_set_drvdata(pdev, NULL);
399
400         DBG("Enter %s\n",__FUNCTION__);
401         return 0;
402 }
403
404 static struct platform_driver bcm4329_rfkill_driver = {
405         .probe = bcm4329_rfkill_probe,
406         .remove = __devexit_p(bcm4329_rfkill_remove),
407         .driver = {
408                 .name = "rk29sdk_rfkill", 
409                 .owner = THIS_MODULE,
410         },      
411 #if BT_WAKE_HOST_SUPPORT
412     .suspend = bcm4329_rfkill_suspend,
413     .resume = bcm4329_rfkill_resume,
414 #endif
415 };
416
417 /*
418  * Module initialization
419  */
420 static int __init bcm4329_mod_init(void)
421 {
422         int ret;
423         DBG("Enter %s\n",__FUNCTION__);
424         ret = platform_driver_register(&bcm4329_rfkill_driver);
425         LOG("ret=0x%x\n", ret);
426         return ret;
427 }
428
429 static void __exit bcm4329_mod_exit(void)
430 {
431         platform_driver_unregister(&bcm4329_rfkill_driver);
432 }
433
434 module_init(bcm4329_mod_init);
435 module_exit(bcm4329_mod_exit);
436 MODULE_DESCRIPTION("bcm4329 Bluetooth driver");
437 MODULE_AUTHOR("roger_chen cz@rock-chips.com, cmy@rock-chips.com");
438 MODULE_LICENSE("GPL");
439