#include <linux/interrupt.h>\r
#include <linux/gpio.h>\r
#include <mach/gpio.h>\r
+#include <mach/iomux.h>\r
//#include <plat/gpio-cfg.h>\r
\r
#include "bt_hwctl.h"\r
\r
+extern int mt6622_suspend_flag;\r
+\r
/****************************************************************************\r
* C O N S T A N T S *\r
*****************************************************************************/\r
\r
static int irq_num = -1;\r
\r
+#ifdef CONFIG_ARCH_RK29\r
+ #define rk_mux_api_set(name,mode) rk29_mux_api_set(name,mode)\r
+#elif defined (CONFIG_ARCH_RK30)\r
+ #define rk_mux_api_set(name,mode) rk30_mux_api_set(name,mode)\r
+#else\r
+ #define rk_mux_api_set(name,mode) rk30_mux_api_set(name,mode)\r
+#endif\r
+\r
+static int irq_num;\r
+// to avoid irq enable and disable not match\r
+static unsigned int irq_mask;\r
+//static spinlock_t bt_irq_lock;\r
+\r
/****************************************************************************\r
* I R Q F U N C T I O N S *\r
*****************************************************************************/\r
static int mt_bt_request_irq(void)\r
{\r
int iRet;\r
+ int trigger = IRQF_TRIGGER_RISING;\r
+ struct mt6622_platform_data *pdata = (struct mt6622_platform_data *)mt_bt_get_platform_data();\r
+ \r
+ irq_mask = 0;\r
+ if(pdata->irq_gpio.enable == GPIO_LOW)\r
+ trigger = IRQF_TRIGGER_FALLING;\r
+ \r
iRet = request_irq(irq_num, mt_bt_eirq_handler, \r
- /*IRQF_TRIGGER_RISING*/IRQF_TRIGGER_HIGH, "BT_INT_B", NULL);\r
+ trigger, "BT_INT_B", NULL);\r
if (iRet){\r
printk(KERN_ALERT MODULE_TAG "request_irq IRQ%d fails, errno %d\n", irq_num, iRet);\r
}\r
\r
static void mt_bt_free_irq(void)\r
{\r
- if(irq_num != -1) {\r
+ if(irq_num != -1)\r
free_irq(irq_num, NULL);\r
- irq_num = -1;\r
+ irq_mask = 0;\r
+ irq_num = -1;\r
+}\r
+\r
+int mt6622_suspend(struct platform_device *pdev, pm_message_t state)\r
+{\r
+ if(irq_num != -1) {\r
+ printk(KERN_INFO MODULE_TAG "mt6622_suspend\n");\r
+ mt6622_suspend_flag = 1;\r
+ enable_irq_wake(irq_num);\r
}\r
+ return 0;\r
}\r
\r
-void mt_bt_enable_irq(void)\r
+int mt6622_resume(struct platform_device *pdev)\r
{\r
if(irq_num != -1) {\r
+ printk(KERN_INFO MODULE_TAG "mt6622_resume\n");\r
+ disable_irq_wake(irq_num);\r
+ }\r
+ return 0;\r
+}\r
+\r
+void mt_bt_enable_irq(void)\r
+{\r
+ if (irq_mask){\r
+ irq_mask = 0;\r
enable_irq(irq_num);\r
}\r
}\r
\r
void mt_bt_disable_irq(void)\r
{\r
- if(irq_num != -1) { \r
+ if (!irq_mask){\r
+ irq_mask = 1;\r
disable_irq_nosync(irq_num);\r
- } \r
+ }\r
}\r
EXPORT_SYMBOL(mt_bt_disable_irq);\r
\r
* P O W E R C O N T R O L *\r
*****************************************************************************/\r
\r
+int mt_bt_power_init(void)\r
+{\r
+ struct mt6622_platform_data *pdata;\r
+ \r
+ printk(KERN_INFO MODULE_TAG "mt_bt_power_init\n");\r
+ \r
+ pdata = (struct mt6622_platform_data *)mt_bt_get_platform_data();\r
+ \r
+ if(pdata) {\r
+ \r
+ // PWR_EN and RESET\r
+ /* PWR_EN set to gpio output low */\r
+ if(pdata->power_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->power_gpio.io, 0);\r
+ /* RESET set to gpio output low */\r
+ if(pdata->reset_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->reset_gpio.io, 0);\r
+ msleep(200);\r
+ \r
+ /* PWR_EN pull up */\r
+ //if(pdata->power_gpio.io != INVALID_GPIO)\r
+ // gpio_direction_output(pdata->power_gpio.io, 0);\r
+ //msleep(200);\r
+ /* RESET pull up */\r
+ if(pdata->reset_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->reset_gpio.io, 1);\r
+ msleep(1000);\r
+ \r
+ //pdata->power_gpio.io = INVALID_GPIO;\r
+ pdata->reset_gpio.io = INVALID_GPIO;\r
+ }\r
+ \r
+ return 0;\r
+}\r
+EXPORT_SYMBOL(mt_bt_power_init);\r
+\r
int mt_bt_power_on(void)\r
{\r
int error;\r
// EINT\r
//--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(0));\r
//--s3c_gpio_setpull(GPIO_BT_EINT_PIN, S3C_GPIO_PULL_DOWN);\r
- gpio_direction_input(pdata->irq_gpio.io);\r
+ if(pdata->irq_gpio.io != INVALID_GPIO)\r
+ gpio_direction_input(pdata->irq_gpio.io);\r
//gpio_pull_updown(pdata->irq_gpio->io, GPIOPullDown);\r
/* set to EINT mode */\r
//--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(0xF));\r
/* get irq number */\r
- irq_num = gpio_to_irq(pdata->irq_gpio.io);\r
+ if(pdata->irq_gpio.io != INVALID_GPIO)\r
+ irq_num = gpio_to_irq(pdata->irq_gpio.io);\r
//mt_set_gpio_mode(GPIO_BT_EINT_PIN, GPIO_BT_EINT_PIN_M_GPIO);\r
//mt_set_gpio_pull_enable(GPIO_BT_EINT_PIN, 1);\r
//mt_set_gpio_pull_select(GPIO_BT_EINT_PIN, GPIO_PULL_DOWN);\r
// 32k CLK\r
//mt_set_gpio_mode(GPIO_BT_CLK_PIN , GPIO_BT_CLK_PIN_M_CLK);\r
//mt_set_clock_output(GPIO_BT_CLK_PIN_CLK, CLK_SRC_F32K, 1);\r
+ \r
+ if(gpio_is_valid(pdata->rts_gpio.io)) {\r
+ printk(KERN_INFO MODULE_TAG "mt_bt_power_on rts iomux\n");\r
+ rk_mux_api_set(pdata->rts_gpio.iomux.name, pdata->rts_gpio.iomux.fgpio);\r
+ gpio_direction_output(pdata->rts_gpio.io, 0);\r
+ } \r
\r
// PWR_EN and RESET\r
/* PWR_EN set to gpio output low */\r
- gpio_direction_output(pdata->power_gpio.io, 0);\r
+ if(pdata->power_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->power_gpio.io, 0);\r
/* RESET set to gpio output low */\r
- gpio_direction_output(pdata->reset_gpio.io, 0);\r
+ if(pdata->reset_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->reset_gpio.io, 0);\r
msleep(200);\r
\r
/* PWR_EN pull up */\r
- gpio_direction_output(pdata->power_gpio.io, 1);\r
+ if(pdata->power_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->power_gpio.io, 1);\r
msleep(200);\r
/* RESET pull up */\r
- gpio_direction_output(pdata->reset_gpio.io, 1);\r
+ if(pdata->reset_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->reset_gpio.io, 1);\r
msleep(1000);\r
+\r
+ if(gpio_is_valid(pdata->rts_gpio.io)) {\r
+ rk_mux_api_set(pdata->rts_gpio.iomux.name, pdata->rts_gpio.iomux.fmux);\r
+ }\r
\r
error = mt_bt_request_irq();\r
if (error){\r
- gpio_direction_output(pdata->power_gpio.io, 0);\r
- gpio_direction_output(pdata->reset_gpio.io, 0);\r
+ if(pdata->power_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->power_gpio.io, 0);\r
+ if(pdata->reset_gpio.io != INVALID_GPIO) \r
+ gpio_direction_output(pdata->reset_gpio.io, 0);\r
//--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(1));\r
- gpio_direction_output(pdata->irq_gpio.io, 0);\r
+ if(pdata->irq_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->irq_gpio.io, 0);\r
return error;\r
}\r
}\r
\r
if(pdata) {\r
// PWR_EN and RESET\r
- gpio_direction_output(pdata->power_gpio.io, 0);\r
- gpio_direction_output(pdata->reset_gpio.io, 0);\r
+ if(pdata->power_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->power_gpio.io, 0);\r
+ if(pdata->reset_gpio.io != INVALID_GPIO) \r
+ gpio_direction_output(pdata->reset_gpio.io, 0);\r
\r
// EINT\r
//--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(1));\r
- gpio_direction_output(pdata->irq_gpio.io, 0);\r
+ if(pdata->irq_gpio.io != INVALID_GPIO)\r
+ gpio_direction_output(pdata->irq_gpio.io, 0);\r
\r
mt_bt_free_irq();\r
}\r