Example #1
0
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);
        }
    }
}
Example #2
0
/*
 * 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;
}
Example #3
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;
}
Example #4
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;
}