示例#1
0
文件: rfkill-rk.c 项目: gopal02/aio
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;
}
示例#2
0
文件: rfkill-rk.c 项目: gopal02/aio
static int rfkill_rk_probe(struct platform_device *pdev)
{
	struct rfkill_rk_data *rfkill;
	struct rfkill_rk_platform_data *pdata = pdev->dev.platform_data;
	int ret = 0;
    struct proc_dir_entry *ent;

    DBG("Enter %s\n", __func__);

	if (!pdata) {
		LOG("%s: No platform data specified\n", __func__);
		return -EINVAL;
	}

    pdata->name = (char*)bt_name;

	rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
	if (!rfkill)
		return -ENOMEM;

	rfkill->pdata = pdata;
    g_rfkill = rfkill;

    bluetooth_dir = proc_mkdir("bluetooth", NULL);
    if (bluetooth_dir == NULL) {
        LOG("Unable to create /proc/bluetooth directory");
        return -ENOMEM;
    }

    sleep_dir = proc_mkdir("sleep", bluetooth_dir);
    if (sleep_dir == NULL) {
        LOG("Unable to create /proc/%s directory", PROC_DIR);
        return -ENOMEM;
    }

	/* read/write proc entries */
    ent = create_proc_entry("lpm", 0, sleep_dir);
    if (ent == NULL) {
        LOG("Unable to create /proc/%s/lpm entry", PROC_DIR);
        ret = -ENOMEM;
        goto fail_alloc;
    }
    ent->read_proc = bluesleep_read_proc_lpm;
    ent->write_proc = bluesleep_write_proc_lpm;

    /* read/write proc entries */
    ent = create_proc_entry("btwrite", 0, sleep_dir);
    if (ent == NULL) {
        LOG("Unable to create /proc/%s/btwrite entry", PROC_DIR);
        ret = -ENOMEM;
        goto fail_alloc;
    }
    ent->read_proc = bluesleep_read_proc_btwrite;
    ent->write_proc = bluesleep_write_proc_btwrite;

    // 申请GPIO以及IRQ
    DBG("init gpio\n");
    // 对于RK29 BCM4329,它的poweron io与wifi共用,在boad文件中已经request
    // 此处不用去申请
#if !WIFI_BT_POWER_TOGGLE
    ret = rfkill_rk_setup_gpio(&pdata->poweron_gpio, IOMUX_FGPIO, pdata->name, "poweron");
    if (ret) goto fail_alloc;
#endif

    ret = rfkill_rk_setup_gpio(&pdata->reset_gpio, IOMUX_FGPIO, pdata->name, "reset");
    if (ret) goto fail_poweron;

    ret = rfkill_rk_setup_gpio(&pdata->wake_gpio, IOMUX_FGPIO, pdata->name, "wake");
    if (ret) goto fail_reset;

    ret = rfkill_rk_setup_wake_irq(rfkill);
    if (ret) goto fail_wake;

    ret = rfkill_rk_setup_gpio(&pdata->rts_gpio, IOMUX_FMUX, rfkill->pdata->name, "rts"); 
    if (ret) goto fail_wake_host_irq;

    // 创建并注册RFKILL设备
    DBG("setup rfkill\n");
	rfkill->rfkill_dev = rfkill_alloc(pdata->name, &pdev->dev, pdata->type,
				&rfkill_rk_ops, rfkill);
	if (!rfkill->rfkill_dev)
		goto fail_rts;

    // cmy: 设置rfkill初始状态为blocked,在注册时不会调用 set_blocked函数
    rfkill_set_states(rfkill->rfkill_dev, BT_BLOCKED, false);
	ret = rfkill_register(rfkill->rfkill_dev);
	if (ret < 0)
		goto fail_rfkill;

    wake_lock_init(&(rfkill->bt_irq_wl), WAKE_LOCK_SUSPEND, "rfkill_rk_irq_wl");
    INIT_DELAYED_WORK(&rfkill->bt_sleep_delay_work, rfkill_rk_delay_sleep_bt);

    // cmy: 设置蓝牙电源的状态为 blocked
    rfkill_rk_set_power(rfkill, BT_BLOCKED);

	platform_set_drvdata(pdev, rfkill);

    LOG("%s device registered.\n", pdata->name);

	return 0;

fail_rfkill:
	rfkill_destroy(rfkill->rfkill_dev);
fail_rts:
    if (gpio_is_valid(pdata->rts_gpio.io))
        gpio_free(pdata->rts_gpio.io);
fail_wake_host_irq:
    if (gpio_is_valid(pdata->wake_host_irq.gpio.io)){
        free_irq(pdata->wake_host_irq.irq, rfkill);
        gpio_free(pdata->wake_host_irq.gpio.io);
    }
fail_wake:
    if (gpio_is_valid(pdata->wake_gpio.io))
        gpio_free(pdata->wake_gpio.io);
fail_reset:
	if (gpio_is_valid(pdata->reset_gpio.io))
		gpio_free(pdata->reset_gpio.io);
fail_poweron:
#if !WIFI_BT_POWER_TOGGLE
    if (gpio_is_valid(pdata->poweron_gpio.io))
        gpio_free(pdata->poweron_gpio.io);
#endif
fail_alloc:
	kfree(rfkill);
    g_rfkill = NULL;

	remove_proc_entry("btwrite", sleep_dir);
	remove_proc_entry("lpm", sleep_dir);

	return ret;
}
示例#3
0
static int rfkill_rk_probe(struct platform_device *pdev)
{
	struct rfkill_rk_data *rfkill;
	struct rfkill_rk_platform_data *pdata = pdev->dev.platform_data;
	int ret = 0;

    DBG("Enter %s\n", __func__);

	if (!pdata) {
		LOG("%s: No platform data specified\n", __func__);
		return -EINVAL;
	}

    pdata->name = (char*)bt_name;

	rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
	if (!rfkill)
		return -ENOMEM;

	rfkill->pdata = pdata;
    g_rfkill = rfkill;

    // 申请GPIO以及IRQ
    DBG("init gpio\n");
    // 对于RK29 BCM4329,它的poweron io与wifi共用,在boad文件中已经request
    // 此处不用去申请
#if !WIFI_BT_POWER_TOGGLE
    ret = rfkill_rk_setup_gpio(&pdata->poweron_gpio, IOMUX_FGPIO, pdata->name, "poweron");
    if (ret) goto fail_alloc;
#endif

    ret = rfkill_rk_setup_gpio(&pdata->reset_gpio, IOMUX_FGPIO, pdata->name, "reset");
    if (ret) goto fail_poweron;

    ret = rfkill_rk_setup_gpio(&pdata->wake_gpio, IOMUX_FGPIO, pdata->name, "wake");
    if (ret) goto fail_reset;

    ret = rfkill_rk_setup_wake_irq(rfkill);
    if (ret) goto fail_wake;

    ret = rfkill_rk_setup_gpio(&(pdata->rts_gpio), IOMUX_FNORMAL, rfkill->pdata->name, "rts");
    if (ret) goto fail_wake_host_irq;

    // 创建并注册RFKILL设备
    DBG("setup rfkill\n");
	rfkill->rfkill_dev = rfkill_alloc(pdata->name, &pdev->dev, pdata->type,
				&rfkill_rk_ops, rfkill);
	if (!rfkill->rfkill_dev)
		goto fail_rts;

    // cmy: 设置rfkill初始状态为blocked,在注册时不会调用 set_blocked函数
    rfkill_set_states(rfkill->rfkill_dev, BT_BLOCKED, false);
	ret = rfkill_register(rfkill->rfkill_dev);
	if (ret < 0)
		goto fail_rfkill;

    wake_lock_init(&(rfkill->bt_irq_wl), WAKE_LOCK_SUSPEND, "rfkill_rk_irq_wl");
    INIT_DELAYED_WORK(&rfkill->bt_sleep_delay_work, rfkill_rk_delay_sleep_bt);

    // cmy: 设置蓝牙电源的状态为 blocked
    rfkill_rk_set_power(rfkill, BT_BLOCKED);

	platform_set_drvdata(pdev, rfkill);

    LOG("%s device registered.\n", pdata->name);

	return 0;

fail_rfkill:
	rfkill_destroy(rfkill->rfkill_dev);
fail_rts:
    if (gpio_is_valid(pdata->rts_gpio.io))
        gpio_free(pdata->rts_gpio.io);
fail_wake_host_irq:
    if (gpio_is_valid(pdata->wake_host_irq.gpio.io)){
        free_irq(pdata->wake_host_irq.irq, rfkill);
        gpio_free(pdata->wake_host_irq.gpio.io);
    }
fail_wake:
    if (gpio_is_valid(pdata->wake_gpio.io))
        gpio_free(pdata->wake_gpio.io);
fail_reset:
	if (gpio_is_valid(pdata->reset_gpio.io))
		gpio_free(pdata->reset_gpio.io);
fail_poweron:
#if !WIFI_BT_POWER_TOGGLE
    if (gpio_is_valid(pdata->poweron_gpio.io))
        gpio_free(pdata->poweron_gpio.io);
#endif
fail_alloc:
	kfree(rfkill);
    g_rfkill = NULL;

	return ret;
}