Example #1
0
int hci_uart_tx_wakeup(struct hci_uart *hu)
{
	struct tty_struct *tty = hu->tty;
	struct hci_dev *hdev = hu->hdev;
	struct sk_buff *skb;

	if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
		set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
		return 0;
	}

	BT_DBG("");

restart:
	clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
#if !defined(CONFIG_MT5931_MT6622)
/*added by Barry,for broadcom 4325*/
#ifdef CONFIG_BT_AUTOSLEEP
#ifdef CONFIG_RFKILL_RK
    extern int rfkill_rk_sleep_bt(bool bSleep);
    rfkill_rk_sleep_bt(false);
#else
    //extern void bcm4325_sleep(unsigned long bSleep);
    //bcm4325_sleep(0);
#endif
#endif
#endif
	while ((skb = hci_uart_dequeue(hu))) {
		int len;

		set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
		len = tty->ops->write(tty, skb->data, skb->len);
		hdev->stat.byte_tx += len;

		skb_pull(skb, len);
		if (skb->len) {
			hu->tx_skb = skb;
			break;
		}

		hci_uart_tx_complete(hu, bt_cb(skb)->pkt_type);
		kfree_skb(skb);
	}

	if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
		goto restart;

	clear_bit(HCI_UART_SENDING, &hu->tx_state);

#if defined(CONFIG_MT5931_MT6622)
	/* Host can enter sleep after 5s no UART data */
	wake_lock_timeout(&bt_wake_lock, WAKE_LOCK_TIMEOUT);
#endif
	return 0;
}
Example #2
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;

    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);
        }

    	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;
}
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 bluesleep_write_proc_btwrite(struct file *file, const char *buffer,
					unsigned long count, void *data)
{
    char b;

    if (count < 1)
        return -EINVAL;

    if (copy_from_user(&b, buffer, 1))
        return -EFAULT;

    DBG("btwrite %c\n", b);
    /* HCI_DEV_WRITE */
    if (b != '0') {
        rfkill_rk_sleep_bt(BT_WAKEUP);
    }

    return count;
}
Example #5
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 0//defined(CONFIG_AP6210)
        if (gpio_is_valid(rts->io))
        {
            if (rts->iomux.name)
            {
                rk_mux_api_set(rts->iomux.name, rts->iomux.fgpio);
            }
            DBG("ENABLE UART_RTS\n");
            gpio_direction_output(rts->io, rts->enable);
            msleep(20);
        }
#endif

		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);
            }
            DBG("ENABLE UART_RTS\n");
            gpio_direction_output(rts->io, rts->enable);

            msleep(100);

            DBG("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

#if 0//defined(CONFIG_AP6210)
        if (gpio_is_valid(rts->io))
        {
            DBG("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;
}