add newton rfkill,keeping on B23 power,for BT uart2 larkage
authoreddie <cf@rock-chips.com>
Thu, 1 Sep 2011 02:51:40 +0000 (10:51 +0800)
committereddie <cf@rock-chips.com>
Thu, 1 Sep 2011 02:51:40 +0000 (10:51 +0800)
arch/arm/mach-rk29/Makefile [changed mode: 0755->0644]
arch/arm/mach-rk29/board-newton-rfkill.c [new file with mode: 0644]
arch/arm/mach-rk29/board-rk29-newton.c

old mode 100755 (executable)
new mode 100644 (file)
index c3521e0..bc91143
@@ -22,5 +22,5 @@ obj-$(CONFIG_MACH_RK29_PHONESDK) += board-rk29-phonesdk.o board-rk29-phonesdk-ke
 obj-$(CONFIG_MACH_RK29FIH) += board-rk29-fih.o board-rk29-fih-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o
 obj-$(CONFIG_MACH_RK29_A22) += board-rk29-a22.o board-rk29-a22-key.o board-rk29-a22-rfkill.o
 obj-$(CONFIG_MACH_RK29_PHONEPADSDK) += board-rk29phonepadsdk.o board-rk29phonepadsdk-key.o board-rk29phonepadsdk-rfkill.o board-rk29phonepadsdk-power.o
-obj-$(CONFIG_MACH_RK29_newton) += board-rk29-newton.o board-rk29-newton-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o
+obj-$(CONFIG_MACH_RK29_newton) += board-rk29-newton.o board-rk29-newton-key.o board-newton-rfkill.o board-rk29sdk-power.o
 
diff --git a/arch/arm/mach-rk29/board-newton-rfkill.c b/arch/arm/mach-rk29/board-newton-rfkill.c
new file mode 100644 (file)
index 0000000..cd125e9
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2010 ROCKCHIP, Inc.
+ * Author: roger_chen <cz@rock-chips.com>
+ *
+ * This program is the bluetooth device bcm4329's driver,
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/rfkill.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/wakelock.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#include <mach/gpio.h>
+#include <asm/irq.h>
+#include <mach/iomux.h>
+#include <linux/wakelock.h>
+#include <linux/timer.h>
+
+#if 0
+#define DBG(x...)   printk(KERN_INFO x)
+#else
+#define DBG(x...)
+#endif
+
+#define BT_WAKE_HOST_SUPPORT 0
+
+struct bt_ctrl
+{
+    struct rfkill *bt_rfk;
+#if BT_WAKE_HOST_SUPPORT
+    struct timer_list tl;
+    bool b_HostWake;
+    struct wake_lock bt_wakelock;
+#endif
+};
+
+#define BT_GPIO_POWER           RK29_PIN5_PD6
+#define IOMUX_BT_GPIO_POWER     rk29_mux_api_set(GPIO5D6_SDMMC1PWREN_NAME, GPIO5H_GPIO5D6);
+#define BT_GPIO_RESET                  RK29_PIN6_PC4
+#define BT_GPIO_WAKE_UP         RK29_PIN6_PC5
+#define BT_GPIO_WAKE_UP_HOST    //RK2818_PIN_PA7
+#define IOMUX_BT_GPIO_WAKE_UP_HOST() //rk2818_mux_api_set(GPIOA7_FLASHCS3_SEL_NAME,0);
+
+#define BT_WAKE_LOCK_TIMEOUT    10 //s
+
+static const char bt_name[] = "bcm4329";
+extern int rk29sdk_bt_power_state;
+extern int rk29sdk_wifi_power_state;
+
+struct bt_ctrl gBtCtrl;
+    
+#if BT_WAKE_HOST_SUPPORT
+void resetBtHostSleepTimer(void)
+{
+    mod_timer(&(gBtCtrl.tl),jiffies + BT_WAKE_LOCK_TIMEOUT*HZ);//ÔÙÖØÐÂÉèÖó¬Ê±Öµ¡£    
+}
+
+void btWakeupHostLock(void)
+{
+    if(gBtCtrl.b_HostWake == false){
+        DBG("*************************Lock\n");
+        wake_lock(&(gBtCtrl.bt_wakelock));
+        gBtCtrl.b_HostWake = true;
+    }
+}
+
+void btWakeupHostUnlock(void)
+{
+    if(gBtCtrl.b_HostWake == true){        
+        DBG("*************************UnLock\n");
+        wake_unlock(&(gBtCtrl.bt_wakelock));  //ÈÃϵͳ˯Ãß    
+        gBtCtrl.b_HostWake = false;
+    }    
+}
+
+static void timer_hostSleep(unsigned long arg)
+{     
+       DBG("%s---b_HostWake=%d\n",__FUNCTION__,gBtCtrl.b_HostWake);
+    btWakeupHostUnlock();
+}
+
+
+#ifdef CONFIG_PM
+static int bcm4329_rfkill_suspend(struct platform_device *pdev, pm_message_t state)
+{   
+    DBG("%s\n",__FUNCTION__);          
+    return 0;
+}
+
+static int bcm4329_rfkill_resume(struct platform_device *pdev)
+{  
+    DBG("%s\n",__FUNCTION__);     
+    btWakeupHostLock();
+    resetBtHostSleepTimer();
+    return 0;
+}
+#else
+#define bcm4329_rfkill_suspend NULL
+#define bcm4329_rfkill_resume  NULL
+#endif
+
+static irqreturn_t bcm4329_wake_host_irq(int irq, void *dev)
+{
+    btWakeupHostLock();
+    resetBtHostSleepTimer();
+       return IRQ_HANDLED;
+}
+#endif
+
+#ifdef CONFIG_BT_HCIBCM4325
+int bcm4325_sleep(int bSleep)
+{
+//     printk("*************bt enter sleep***************\n");
+    if (bSleep)
+    gpio_set_value(BT_GPIO_WAKE_UP, GPIO_LOW);   //low represent bt device may enter sleep  
+    else
+    gpio_set_value(BT_GPIO_WAKE_UP, GPIO_HIGH);  //high represent bt device must be awake 
+
+       //printk("sleep=%d\n",bSleep);
+}
+#endif
+  
+static int bcm4329_set_block(void *data, bool blocked)
+{
+       DBG("%s---blocked :%d\n", __FUNCTION__, blocked);
+
+        IOMUX_BT_GPIO_POWER;
+
+       if (false == blocked) { 
+            gpio_set_value(BT_GPIO_POWER, GPIO_HIGH);  /* bt power on */
+            gpio_set_value(BT_GPIO_RESET, GPIO_LOW);
+            mdelay(200);
+            gpio_set_value(BT_GPIO_RESET, GPIO_HIGH);  /* bt reset deactive*/
+            mdelay(200);
+        
+#if BT_WAKE_HOST_SUPPORT     
+            btWakeupHostLock();
+#endif         
+               pr_info("bt turn on power\n");
+       }
+       else {
+#if BT_WAKE_HOST_SUPPORT     
+            btWakeupHostUnlock();
+#endif
+// cwz 0: close for bt uart2 larkage.
+#if 0
+               if (!rk29sdk_wifi_power_state) {
+                    gpio_set_value(BT_GPIO_POWER, GPIO_LOW);  /* bt power off */
+                    mdelay(20);        
+                    pr_info("bt shut off power\n");
+               }else {
+                    pr_info("bt shouldn't shut off power, wifi is using it!\n");
+               }
+#endif
+               gpio_set_value(BT_GPIO_RESET, GPIO_LOW);  /* bt reset active*/
+               mdelay(20);
+       }
+
+       rk29sdk_bt_power_state = !blocked;
+       return 0;
+}
+
+
+static const struct rfkill_ops bcm4329_rfk_ops = {
+       .set_block = bcm4329_set_block,
+};
+
+static int __devinit bcm4329_rfkill_probe(struct platform_device *pdev)
+{
+       int rc = 0;
+       bool default_state = true;
+       
+       DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
+       
+       /* default to bluetooth off */
+       bcm4329_set_block(NULL, default_state); /* blocked -> bt off */
+        
+       gBtCtrl.bt_rfk = rfkill_alloc(bt_name, 
+                NULL, 
+                RFKILL_TYPE_BLUETOOTH, 
+                &bcm4329_rfk_ops, 
+                NULL);
+
+       if (!gBtCtrl.bt_rfk)
+       {
+               printk("fail to rfkill_allocate************\n");
+               return -ENOMEM;
+       }
+       
+       rfkill_set_states(gBtCtrl.bt_rfk, default_state, false);
+
+       rc = rfkill_register(gBtCtrl.bt_rfk);
+       if (rc)
+       {
+               printk("failed to rfkill_register,rc=0x%x\n",rc);
+               rfkill_destroy(gBtCtrl.bt_rfk);
+       }
+       
+       gpio_request(BT_GPIO_POWER, NULL);
+       gpio_request(BT_GPIO_RESET, NULL);
+       gpio_request(BT_GPIO_WAKE_UP, NULL);
+
+#if BT_WAKE_HOST_SUPPORT
+    init_timer(&(gBtCtrl.tl));
+    gBtCtrl.tl.expires = jiffies + BT_WAKE_LOCK_TIMEOUT*HZ;        
+    gBtCtrl.tl.function = timer_hostSleep;        
+    add_timer(&(gBtCtrl.tl));
+    gBtCtrl.b_HostWake = false;
+    
+       wake_lock_init(&(gBtCtrl.bt_wakelock), WAKE_LOCK_SUSPEND, "bt_wake");
+       
+       rc = gpio_request(BT_GPIO_WAKE_UP_HOST, "bt_wake");
+       if (rc) {
+               printk("%s:failed to request RAHO_BT_WAKE_UP_HOST\n",__FUNCTION__);
+       }
+       
+       IOMUX_BT_GPIO_WAKE_UP_HOST();
+       gpio_pull_updown(BT_GPIO_WAKE_UP_HOST,GPIOPullUp);
+       rc = request_irq(gpio_to_irq(BT_GPIO_WAKE_UP_HOST),bcm4329_wake_host_irq,IRQF_TRIGGER_FALLING,NULL,NULL);
+       if(rc)
+       {
+               printk("%s:failed to request RAHO_BT_WAKE_UP_HOST irq\n",__FUNCTION__);
+               gpio_free(BT_GPIO_WAKE_UP_HOST);
+       }
+       enable_irq_wake(gpio_to_irq(BT_GPIO_WAKE_UP_HOST)); // so RAHO_BT_WAKE_UP_HOST can wake up system
+
+       printk(KERN_INFO "bcm4329 module has been initialized,rc=0x%x\n",rc);
+ #endif
+       return rc;
+
+       
+}
+
+
+static int __devexit bcm4329_rfkill_remove(struct platform_device *pdev)
+{
+       if (gBtCtrl.bt_rfk)
+               rfkill_unregister(gBtCtrl.bt_rfk);
+       gBtCtrl.bt_rfk = NULL;
+#if BT_WAKE_HOST_SUPPORT       
+    del_timer(&(gBtCtrl.tl));//ɾµô¶¨Ê±Æ÷
+    btWakeupHostUnlock();
+    wake_lock_destroy(&(gBtCtrl.bt_wakelock));
+#endif    
+       platform_set_drvdata(pdev, NULL);
+
+       DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
+       return 0;
+}
+
+static struct platform_driver bcm4329_rfkill_driver = {
+       .probe = bcm4329_rfkill_probe,
+       .remove = __devexit_p(bcm4329_rfkill_remove),
+       .driver = {
+               .name = "rk29sdk_rfkill", 
+               .owner = THIS_MODULE,
+       },      
+#if BT_WAKE_HOST_SUPPORT
+    .suspend = bcm4329_rfkill_suspend,
+    .resume = bcm4329_rfkill_resume,
+#endif
+};
+
+/*
+ * Module initialization
+ */
+static int __init bcm4329_mod_init(void)
+{
+       int ret;
+       DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
+       ret = platform_driver_register(&bcm4329_rfkill_driver);
+       printk("ret=0x%x\n", ret);
+       return ret;
+}
+
+static void __exit bcm4329_mod_exit(void)
+{
+       platform_driver_unregister(&bcm4329_rfkill_driver);
+}
+
+module_init(bcm4329_mod_init);
+module_exit(bcm4329_mod_exit);
+MODULE_DESCRIPTION("bcm4329 Bluetooth driver");
+MODULE_AUTHOR("roger_chen cz@rock-chips.com");
+MODULE_LICENSE("GPL");
+
index 9cc5a5c99073054e19c0186400d6b2b33930a76b..f47a92a24c2d8ebee57a1894de92787e93d54942 100644 (file)
@@ -1529,7 +1529,12 @@ static int rk29sdk_wifi_bt_gpio_control_init(void)
           return -1;
     }
 
+// cwz 0: close for bt uart2 larkage.
+#if 0
     gpio_direction_output(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW);
+#else
+    gpio_direction_output(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_HIGH);
+#endif
     gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N,    GPIO_LOW);
     gpio_direction_output(RK29SDK_BT_GPIO_RESET_N,      GPIO_LOW);
 
@@ -1547,6 +1552,8 @@ static int rk29sdk_wifi_power(int on)
                 mdelay(100);
                 pr_info("wifi turn on power\n");
         }else{
+// cwz 0: close for bt uart2 larkage.
+#if 0
                 if (!rk29sdk_bt_power_state){
                         gpio_set_value(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW);
                         mdelay(100);
@@ -1555,8 +1562,8 @@ static int rk29sdk_wifi_power(int on)
                 {
                         pr_info("wifi shouldn't shut off power, bt is using it!\n");
                 }
+#endif
                 gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW);
-
         }
 
         rk29sdk_wifi_power_state = on;