From 9156c0f0a1f7f39d141c394ad85984a0a4b53bdb Mon Sep 17 00:00:00 2001 From: eddie Date: Thu, 1 Sep 2011 10:51:40 +0800 Subject: [PATCH] add newton rfkill,keeping on B23 power,for BT uart2 larkage --- arch/arm/mach-rk29/Makefile | 2 +- arch/arm/mach-rk29/board-newton-rfkill.c | 296 +++++++++++++++++++++++ arch/arm/mach-rk29/board-rk29-newton.c | 9 +- 3 files changed, 305 insertions(+), 2 deletions(-) mode change 100755 => 100644 arch/arm/mach-rk29/Makefile create mode 100644 arch/arm/mach-rk29/board-newton-rfkill.c diff --git a/arch/arm/mach-rk29/Makefile b/arch/arm/mach-rk29/Makefile old mode 100755 new mode 100644 index c3521e0db7e5..bc91143c770d --- a/arch/arm/mach-rk29/Makefile +++ b/arch/arm/mach-rk29/Makefile @@ -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 index 000000000000..cd125e93b278 --- /dev/null +++ b/arch/arm/mach-rk29/board-newton-rfkill.c @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2010 ROCKCHIP, Inc. + * Author: roger_chen + * + * This program is the bluetooth device bcm4329's driver, + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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"); + diff --git a/arch/arm/mach-rk29/board-rk29-newton.c b/arch/arm/mach-rk29/board-rk29-newton.c index 9cc5a5c99073..f47a92a24c2d 100644 --- a/arch/arm/mach-rk29/board-rk29-newton.c +++ b/arch/arm/mach-rk29/board-rk29-newton.c @@ -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; -- 2.34.1