power_supply: Add support TI BQ25703 charger chip
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_bt / bt_plat_smdk.c
index 1d829883c0df404590e1860269fd503819c921e1..eb928d16cf713193b1c391f2cc93647b6de0425e 100755 (executable)
 #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
@@ -74,15 +97,35 @@ static int mt_bt_request_irq(void)
 \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
@@ -90,9 +133,10 @@ EXPORT_SYMBOL(mt_bt_enable_irq);
 \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
@@ -100,6 +144,42 @@ EXPORT_SYMBOL(mt_bt_disable_irq);
  *                      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
@@ -117,12 +197,14 @@ int mt_bt_power_on(void)
            // 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
@@ -131,27 +213,44 @@ int mt_bt_power_on(void)
            // 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
@@ -173,12 +272,15 @@ void mt_bt_power_off(void)
     \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