static void rfkill_rk_pm_complete(struct device *dev) { struct rfkill_rk_data *rfkill = g_rfkill; struct rfkill_rk_irq* wake_host_irq; struct rfkill_rk_gpio* rts; DBG("Enter %s\n",__FUNCTION__); if (!rfkill) return; wake_host_irq = &rfkill->pdata->wake_host_irq; rts = &rfkill->pdata->rts_gpio; if (gpio_is_valid(wake_host_irq->gpio.io)) { // 禁用掉 BT_WAKE_HOST IRQ,确保在系统唤醒后不会因BT的操作 // 而多次触发该中断 LOG("** disable irq\n"); disable_irq(wake_host_irq->irq); } /* 使用UART_RTS,此时蓝牙如果有数据就会送到UART * 上层分析送来的数据并做出相应的动作,比如: 送来的是 * 配对请求,则上层将会亮屏并弹出配对界面 */ if (gpio_is_valid(rts->io)) { DBG("Enable UART_RTS\n"); gpio_direction_output(rts->io, rts->enable); if (rts->iomux.name) { rk_mux_api_set(rts->iomux.name, rts->iomux.fmux); } } }
/* * rfkill_rk_setup_gpio - 设置GPIO * gpio - 要设置的GPIO * mux - iomux 什么功能 * prefix,name - 组成该IO的名称 * 返回值 * 返回值与 gpio_request 相同 */ static int rfkill_rk_setup_gpio(struct rfkill_rk_gpio* gpio, int mux, const char* prefix, const char* name) { if (gpio_is_valid(gpio->io)) { int ret=0; sprintf(gpio->name, "%s_%s", prefix, name); ret = gpio_request(gpio->io, gpio->name); if (ret) { LOG("Failed to get %s gpio.\n", gpio->name); return -1; } if (gpio->iomux.name) { if (mux==1) rk_mux_api_set(gpio->iomux.name, gpio->iomux.fgpio); else if (mux==2) rk_mux_api_set(gpio->iomux.name, gpio->iomux.fmux); else ;// do nothing } } return 0; }
static int rfkill_rk_pm_prepare(struct device *dev) { struct rfkill_rk_data *rfkill = g_rfkill; struct rfkill_rk_gpio* rts; struct rfkill_rk_irq* wake_host_irq; DBG("Enter %s\n",__FUNCTION__); if (!rfkill) return 0; rts = &rfkill->pdata->rts_gpio; wake_host_irq = &rfkill->pdata->wake_host_irq; //To prevent uart to receive bt data when suspended if (gpio_is_valid(rts->io)) { DBG("Disable UART_RTS\n"); if (rts->iomux.name) { rk_mux_api_set(rts->iomux.name, rts->iomux.fgpio); } gpio_direction_output(rts->io, !rts->enable); } #ifdef CONFIG_BT_AUTOSLEEP // BT进入睡眠状态,不接收主控数据 rfkill_rk_sleep_bt(BT_SLEEP); #endif /* 至此,蓝牙不再送数据到UART,也不再接收主控的UART数据 * 接着调用enable_irq使能 bt_wake_host irq,当远端设备有数据 * 到来时,将通过该IRQ唤醒主控 */ // enable bt wakeup host if (gpio_is_valid(wake_host_irq->gpio.io)) { DBG("enable irq for bt wakeup host\n"); enable_irq(wake_host_irq->irq); } #ifdef CONFIG_RFKILL_RESET rfkill_set_states(rfkill->rfkill_dev, BT_BLOCKED, false); rfkill_rk_set_power(rfkill, BT_BLOCKED); #endif return 0; }
static int rfkill_rk_set_power(void *data, bool blocked) { struct rfkill_rk_data *rfkill = data; struct rfkill_rk_gpio *poweron = &rfkill->pdata->poweron_gpio; struct rfkill_rk_gpio *reset = &rfkill->pdata->reset_gpio; struct rfkill_rk_gpio* rts = &rfkill->pdata->rts_gpio; DBG("Enter %s\n", __func__); DBG("Set blocked:%d\n", blocked); if (false == blocked) { rfkill_rk_sleep_bt(BT_WAKEUP); // ensure bt is wakeup if (gpio_is_valid(poweron->io)) { gpio_direction_output(poweron->io, poweron->enable); msleep(20); } if (gpio_is_valid(reset->io)) { gpio_direction_output(reset->io, reset->enable); msleep(20); gpio_direction_output(reset->io, !reset->enable); msleep(20); } #if defined(CONFIG_AP6210) if (gpio_is_valid(rts->io)) { if (rts->iomux.name) { rk_mux_api_set(rts->iomux.name, rts->iomux.fgpio); } LOG("ENABLE UART_RTS\n"); gpio_direction_output(rts->io, rts->enable); msleep(100); LOG("DISABLE UART_RTS\n"); gpio_direction_output(rts->io, !rts->enable); if (rts->iomux.name) { rk_mux_api_set(rts->iomux.name, rts->iomux.fmux); } } #endif LOG("bt turn on power\n"); } else { #if WIFI_BT_POWER_TOGGLE if (!rk29sdk_wifi_power_state) { #endif if (gpio_is_valid(poweron->io)) { gpio_direction_output(poweron->io, !poweron->enable); msleep(20); } LOG("bt shut off power\n"); #if WIFI_BT_POWER_TOGGLE }else { LOG("bt shouldn't shut off power, wifi is using it!\n"); } #endif if (gpio_is_valid(reset->io)) { gpio_direction_output(reset->io, reset->enable);/* bt reset active*/ msleep(20); } } #if WIFI_BT_POWER_TOGGLE rk29sdk_bt_power_state = !blocked; #endif return 0; }
int mt_bt_power_on(void) { int error; struct mt6622_platform_data *pdata; printk(KERN_INFO MODULE_TAG "mt_bt_power_on ++\n"); pdata = (struct mt6622_platform_data *)mt_bt_get_platform_data(); if(pdata) { // UART TX/RX // PCMIN, PCMOUT, PCMCLK, PCMSYNC // EINT //--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(0)); //--s3c_gpio_setpull(GPIO_BT_EINT_PIN, S3C_GPIO_PULL_DOWN); if(pdata->irq_gpio.io != INVALID_GPIO) gpio_direction_input(pdata->irq_gpio.io); //gpio_pull_updown(pdata->irq_gpio->io, GPIOPullDown); /* set to EINT mode */ //--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(0xF)); /* get irq number */ if(pdata->irq_gpio.io != INVALID_GPIO) irq_num = gpio_to_irq(pdata->irq_gpio.io); //mt_set_gpio_mode(GPIO_BT_EINT_PIN, GPIO_BT_EINT_PIN_M_GPIO); //mt_set_gpio_pull_enable(GPIO_BT_EINT_PIN, 1); //mt_set_gpio_pull_select(GPIO_BT_EINT_PIN, GPIO_PULL_DOWN); //mt_set_gpio_mode(GPIO_BT_EINT_PIN, GPIO_BT_EINT_PIN_M_EINT); // 32k CLK //mt_set_gpio_mode(GPIO_BT_CLK_PIN , GPIO_BT_CLK_PIN_M_CLK); //mt_set_clock_output(GPIO_BT_CLK_PIN_CLK, CLK_SRC_F32K, 1); if(gpio_is_valid(pdata->rts_gpio.io)) { printk(KERN_INFO MODULE_TAG "mt_bt_power_on rts iomux\n"); rk_mux_api_set(pdata->rts_gpio.iomux.name, pdata->rts_gpio.iomux.fgpio); gpio_direction_output(pdata->rts_gpio.io, 0); } // PWR_EN and RESET /* PWR_EN set to gpio output low */ if(pdata->power_gpio.io != INVALID_GPIO) gpio_direction_output(pdata->power_gpio.io, 0); /* RESET set to gpio output low */ if(pdata->reset_gpio.io != INVALID_GPIO) gpio_direction_output(pdata->reset_gpio.io, 0); msleep(200); /* PWR_EN pull up */ if(pdata->power_gpio.io != INVALID_GPIO) gpio_direction_output(pdata->power_gpio.io, 1); msleep(200); /* RESET pull up */ if(pdata->reset_gpio.io != INVALID_GPIO) gpio_direction_output(pdata->reset_gpio.io, 1); msleep(1000); if(gpio_is_valid(pdata->rts_gpio.io)) { rk_mux_api_set(pdata->rts_gpio.iomux.name, pdata->rts_gpio.iomux.fmux); } error = mt_bt_request_irq(); if (error){ if(pdata->power_gpio.io != INVALID_GPIO) gpio_direction_output(pdata->power_gpio.io, 0); if(pdata->reset_gpio.io != INVALID_GPIO) gpio_direction_output(pdata->reset_gpio.io, 0); //--s3c_gpio_cfgpin(GPIO_BT_EINT_PIN, S3C_GPIO_SFN(1)); if(pdata->irq_gpio.io != INVALID_GPIO) gpio_direction_output(pdata->irq_gpio.io, 0); return error; } } printk(KERN_INFO MODULE_TAG "mt_bt_power_on --\n"); return 0; }