Ejemplo n.º 1
0
static int __init gpio_test_init(void)
{
	const struct wl12xx_platform_data *wlan_data;
	wlan_data = wl12xx_get_platform_data();

	bt_enable_pin = wlan_data->bt_enable_gpio;

	/* Default to alpha EVM in case the element is not initialized */
	if (! bt_enable_pin)
	{
		pr_info("BT Enable pin is not initialized, defaulting to EVM Rev 1.0A.\n");
		bt_enable_pin = GPIO_TO_PIN(1, 31); 
	}

	/* Select pad conf register based on EVM board rev */
	if ( bt_enable_pin == GPIO_TO_PIN(3, 21) )	
		selected_pad = AM33XX_CONTROL_PADCONF_MCASP0_AHCLKX_OFFSET;
	else
		selected_pad = AM33XX_CONTROL_PADCONF_GPMC_CSN2_OFFSET;
 
	printk("Gpio value is :%d\n", bt_enable_pin);
	gpio_direction_output(bt_enable_pin, 0);
	msleep(1);
	printk("WL1271: BT Enable\n");
	gpio_direction_output(bt_enable_pin, 1);

	/* Enable pullup on the enable pin for keeping BT active during suspend */
	pad_mux_value = readl(AM33XX_CTRL_REGADDR(selected_pad));
	pad_mux_value &= (~AM33XX_PULL_DISA);
	writel(pad_mux_value, AM33XX_CTRL_REGADDR(selected_pad));

	return 0;
}
Ejemplo n.º 2
0
static struct wl12xx_platform_data *get_platform_data(struct device *dev)
{
	struct wl12xx_platform_data *pdata;
	struct device_node __maybe_unused *np;

	pdata = wl12xx_get_platform_data();
	if (!IS_ERR(pdata))
		return kmemdup(pdata, sizeof(*pdata), GFP_KERNEL);

#ifdef CONFIG_OF
	/* first, try looking for "upstream" dt */
	pdata = wlcore_probe_of(dev);
	if (pdata)
		return pdata;

	/* if not found, look for our deprecated dt */
	np = of_find_matching_node(NULL, wlcore_of_match);
	if (!np) {
		dev_err(dev, "No platform data set\n");
		return NULL;
	}

	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (!pdata) {
		dev_err(dev, "Can't allocate platform data\n");
		return NULL;
	}

	if (of_property_read_u32(np, "irq", &pdata->irq)) {
		u32 gpio;

		if (!of_property_read_u32(np, "gpio", &gpio) &&
		    !gpio_request_one(gpio, GPIOF_IN, "wlcore_irq"))
			pdata->gpio = gpio;
	}

	/* Optional fields */
	pdata->use_eeprom = of_property_read_bool(np, "use-eeprom");
	of_property_read_u32(np, "board-ref-clock", &pdata->board_ref_clock);
	of_property_read_u32(np, "board-tcxo-clock", &pdata->board_tcxo_clock);
	of_property_read_u32(np, "platform-quirks", &pdata->platform_quirks);
#endif

	if (IS_ERR(pdata))
		return NULL;

	return pdata;
}
Ejemplo n.º 3
0
static int wl1271_probe(struct sdio_func *func,
				  const struct sdio_device_id *id)
{
	struct wlcore_platdev_data pdev_data;
	struct wl12xx_sdio_glue *glue;
	struct resource res[1];
	mmc_pm_flag_t mmcflags;
	int ret = -ENOMEM;
	const char *chip_family;

	/* We are only able to handle the wlan function */
	if (func->num != 0x02)
		return -ENODEV;

	memset(&pdev_data, 0x00, sizeof(pdev_data));
	pdev_data.if_ops = &sdio_ops;

	glue = kzalloc(sizeof(*glue), GFP_KERNEL);
	if (!glue) {
		dev_err(&func->dev, "can't allocate glue\n");
		goto out;
	}

	glue->dev = &func->dev;

	/* Grab access to FN0 for ELP reg. */
	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;

	/* Use block mode for transferring over one block size of data */
	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;

	pdev_data.pdata = wl12xx_get_platform_data();
	if (IS_ERR(pdev_data.pdata)) {
		ret = PTR_ERR(pdev_data.pdata);
		dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
		goto out_free_glue;
	}

	/* if sdio can keep power while host is suspended, enable wow */
	mmcflags = sdio_get_host_pm_caps(func);
	dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);

	if (mmcflags & MMC_PM_KEEP_POWER)
		pdev_data.pdata->pwr_in_suspend = true;

	sdio_set_drvdata(func, glue);

	/* Tell PM core that we don't need the card to be powered now */
	pm_runtime_put_noidle(&func->dev);

	/*
	 * Due to a hardware bug, we can't differentiate wl18xx from
	 * wl12xx, because both report the same device ID.  The only
	 * way to differentiate is by checking the SDIO revision,
	 * which is 3.00 on the wl18xx chips.
	 */
	if (func->card->cccr.sdio_vsn == SDIO_SDIO_REV_3_00)
		chip_family = "wl18xx";
	else
		chip_family = "wl12xx";

	glue->core = platform_device_alloc(chip_family, PLATFORM_DEVID_AUTO);
	if (!glue->core) {
		dev_err(glue->dev, "can't allocate platform_device");
		ret = -ENOMEM;
		goto out_free_glue;
	}

	glue->core->dev.parent = &func->dev;

	memset(res, 0x00, sizeof(res));

	res[0].start = pdev_data.pdata->irq;
	res[0].flags = IORESOURCE_IRQ;
	res[0].name = "irq";

	ret = platform_device_add_resources(glue->core, res, ARRAY_SIZE(res));
	if (ret) {
		dev_err(glue->dev, "can't add resources\n");
		goto out_dev_put;
	}

	ret = platform_device_add_data(glue->core, &pdev_data,
				       sizeof(pdev_data));
	if (ret) {
		dev_err(glue->dev, "can't add platform data\n");
		goto out_dev_put;
	}

	ret = platform_device_add(glue->core);
	if (ret) {
		dev_err(glue->dev, "can't add platform device\n");
		goto out_dev_put;
	}
	return 0;

out_dev_put:
	platform_device_put(glue->core);

out_free_glue:
	kfree(glue);

out:
	return ret;
}
Ejemplo n.º 4
0
static int __devinit wl1271_probe(struct sdio_func *func,
				  const struct sdio_device_id *id)
{
	struct ieee80211_hw *hw;
	const struct wl12xx_platform_data *wlan_data;
	struct wl1271 *wl;
	unsigned long irqflags;
	int ret;

	/* We are only able to handle the wlan function */
	if (func->num != 0x02)
		return -ENODEV;

	hw = wl1271_alloc_hw();
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	wl = hw->priv;

	wl->if_priv = func;
	wl->if_ops = &sdio_ops;

	/* Grab access to FN0 for ELP reg. */
	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;

	/* Use block mode for transferring over one block size of data */
	//func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;

	wlan_data = wl12xx_get_platform_data();
	if (IS_ERR(wlan_data)) {
		ret = PTR_ERR(wlan_data);
		wl1271_error("missing wlan platform data: %d", ret);
		goto out_free;
	}

	wl->irq = wlan_data->irq;
	if (wl->ref_clock < 0)
		wl->ref_clock = wlan_data->board_ref_clock;
	if (wl->tcxo_clock < 0)
		wl->tcxo_clock = wlan_data->board_tcxo_clock;
	wl->platform_quirks = wlan_data->platform_quirks;

	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
		irqflags = IRQF_TRIGGER_RISING;
	else
		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;

	ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
				   irqflags,
				   DRIVER_NAME, wl);
	if (ret < 0) {
		wl1271_error("request_irq() failed: %d", ret);
		goto out_free;
	}

	disable_irq(wl->irq);

	sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);

	ret = wl1271_init_ieee80211(wl);
	if (ret)
		goto out_irq;

	ret = wl1271_register_hw(wl);
	if (ret)
		goto out_irq;

	sdio_set_drvdata(func, wl);

	/* Tell PM core that we don't need the card to be powered now */
	pm_runtime_put_noidle(&func->dev);
	mmc_power_save_host(func->card->host);

	return 0;

 out_irq:
	free_irq(wl->irq, wl);

 out_free:
	wl1271_free_hw(wl);

	return ret;
}
Ejemplo n.º 5
0
static int wl1251_sdio_probe(struct sdio_func *func,
			     const struct sdio_device_id *id)
{
	int ret, t;
	struct wl1251 *wl;
	struct ieee80211_hw *hw;
	struct wl1251_sdio *wl_sdio;
	const struct wl12xx_platform_data *wl12xx_board_data;

	hw = wl1251_alloc_hw();
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	wl = hw->priv;

	wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL);
	if (wl_sdio == NULL) {
		ret = -ENOMEM;
		goto out_free_hw;
	}

	sdio_claim_host(func);
	ret = sdio_enable_func(func);
	if (ret)
		goto release;

	sdio_set_block_size(func, 512);
	sdio_release_host(func);

	SET_IEEE80211_DEV(hw, &func->dev);
	wl_sdio->func = func;
	wl->if_priv = wl_sdio;
	wl->if_ops = &wl1251_sdio_ops;

	wl12xx_board_data = wl12xx_get_platform_data();
	if (!IS_ERR(wl12xx_board_data)) {
		wl->set_power = wl12xx_board_data->set_power;
		wl->irq = wl12xx_board_data->irq;
		wl->use_eeprom = wl12xx_board_data->use_eeprom;
	}

	if (force_nvs_file)
		wl->use_eeprom = false;
	wl->dump_eeprom = dump_eeprom;

	if (wl->irq) {
		irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);

		ret = request_threaded_irq(wl->irq, NULL, wl1251_irq,
			IRQF_ONESHOT, "wl1251", wl);
		if (ret < 0) {
			wl1251_error("request_irq() failed: %d", ret);
			goto disable;
		}

		irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);

		wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
		wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;

		wl1251_info("using dedicated interrupt line");
	} else {
		wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
		wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;

		wl1251_info("using SDIO interrupt");
	}

	ret = wl1251_init_ieee80211(wl);
	if (ret)
		goto out_free_irq;

	sdio_set_drvdata(func, wl);

	for (t = 0; t < ARRAY_SIZE(wl1251_attrs); t++) {
		ret = device_create_file(&func->dev, &wl1251_attrs[t]);
		if (ret) {
			while (--t >= 0)
				device_remove_file(&func->dev,
						   &wl1251_attrs[t]);
			goto out_free_irq;
		}
	}

	/* Tell PM core that we don't need the card to be powered now */
	pm_runtime_put_noidle(&func->dev);

	return ret;

out_free_irq:
	if (wl->irq)
		free_irq(wl->irq, wl);
disable:
	sdio_claim_host(func);
	sdio_disable_func(func);
release:
	sdio_release_host(func);
	kfree(wl_sdio);
out_free_hw:
	wl1251_free_hw(wl);
	return ret;
}
Ejemplo n.º 6
0
static int __devinit wl1271_probe(struct sdio_func *func,
				  const struct sdio_device_id *id)
{
	struct ieee80211_hw *hw;
	const struct wl12xx_platform_data *wlan_data;
	struct wl1271 *wl;
	unsigned long irqflags;
	mmc_pm_flag_t mmcflags;
	int ret;

	/* We are only able to handle the wlan function */
	if (func->num != 0x02)
		return -ENODEV;

	hw = wl1271_alloc_hw();
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	wl = hw->priv;

	wl->if_priv = func;
	wl->if_ops = &sdio_ops;

	/* Grab access to FN0 for ELP reg. */
	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;

	/* Use block mode for transferring over one block size of data */
	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;

	wlan_data = wl12xx_get_platform_data();
	if (IS_ERR(wlan_data)) {
		ret = PTR_ERR(wlan_data);
		wl1271_error("missing wlan platform data: %d", ret);
		goto out_free;
	}

	wl->irq = wlan_data->irq;
	wl->ref_clock = wlan_data->board_ref_clock;
	wl->tcxo_clock = wlan_data->board_tcxo_clock;
	wl->platform_quirks = wlan_data->platform_quirks;

	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
		irqflags = IRQF_TRIGGER_RISING;
	else
		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;

	ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
				   irqflags,
				   DRIVER_NAME, wl);
	if (ret < 0) {
		wl1271_error("request_irq() failed: %d", ret);
		goto out_free;
	}

	enable_irq_wake(wl->irq);
	device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 1);

	disable_irq(wl->irq);

	/* if sdio can keep power while host is suspended, enable wow */
	mmcflags = sdio_get_host_pm_caps(func);
	wl1271_debug(DEBUG_SDIO, "sdio PM caps = 0x%x", mmcflags);

	if (mmcflags & MMC_PM_KEEP_POWER)
		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;

	ret = wl1271_init_ieee80211(wl);
	if (ret)
		goto out_irq;

	ret = wl1271_register_hw(wl);
	if (ret)
		goto out_irq;

	sdio_set_drvdata(func, wl);

	/* Tell PM core that we don't need the card to be powered now */
	pm_runtime_put_noidle(&func->dev);

	wl->set_power = wlan_data->set_power;
	wl1271_notice("initialized");

	return 0;

 out_irq:
	free_irq(wl->irq, wl);

 out_free:
	wl1271_free_hw(wl);

	return ret;
}
Ejemplo n.º 7
0
static int __devinit wl1271_probe(struct sdio_func *func,
				  const struct sdio_device_id *id)
{
	struct ieee80211_hw *hw;
	const struct wl12xx_platform_data *wlan_data;
	struct wl1271 *wl;
	int ret;

	/* We are only able to handle the wlan function */
	if (func->num != 0x02)
		return -ENODEV;

	hw = wl1271_alloc_hw();
	if (IS_ERR(hw))
		return PTR_ERR(hw);

	wl = hw->priv;

	wl->if_priv = func;
	wl->if_ops = &sdio_ops;

	/* Grab access to FN0 for ELP reg. */
	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;

	wlan_data = wl12xx_get_platform_data();
	if (IS_ERR(wlan_data)) {
		ret = PTR_ERR(wlan_data);
		wl1271_error("missing wlan platform data: %d", ret);
		goto out_free;
	}

	wl->irq = wlan_data->irq;
	wl->ref_clock = wlan_data->board_ref_clock;

	ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
	if (ret < 0) {
		wl1271_error("request_irq() failed: %d", ret);
		goto out_free;
	}

	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);

	disable_irq(wl->irq);

	ret = wl1271_init_ieee80211(wl);
	if (ret)
		goto out_irq;

	ret = wl1271_register_hw(wl);
	if (ret)
		goto out_irq;

	sdio_set_drvdata(func, wl);

	/* Tell PM core that we don't need the card to be powered now */
	pm_runtime_put_noidle(&func->dev);

	wl1271_notice("initialized");

	return 0;

 out_irq:
	free_irq(wl->irq, wl);


 out_free:
	wl1271_free_hw(wl);

	return ret;
}
Ejemplo n.º 8
0
static int __devinit wl1271_probe(struct sdio_func *func,
		const struct sdio_device_id *id)
{
	const struct wl12xx_platform_data *wlan_data;
	struct wl1271 *wl;
	struct wl1271_test *wl_test;
	int ret = 0;

	/* wl1271 has 2 sdio functions we handle just the wlan part */
	if (func->num != 0x02)
		return -ENODEV;

	wl_test = kzalloc(sizeof(struct wl1271_test), GFP_KERNEL);
	if (!wl_test) {
		dev_err(&func->dev, "Could not allocate memory\n");
		return -ENOMEM;
	}

	wl = &wl_test->wl;

	wl->if_priv = func;
	wl->if_ops = &sdio_ops;

	/* Grab access to FN0 for ELP reg. */
	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;

	/* Use block mode for transferring over one block size of data */
	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;

	wlan_data = wl12xx_get_platform_data();
	if (IS_ERR(wlan_data)) {
		ret = PTR_ERR(wlan_data);
		dev_err(&func->dev, "missing wlan platform data: %d\n", ret);
		goto out_free;
	}

	wl->irq = wlan_data->irq;
	wl->ref_clock = wlan_data->board_ref_clock;
	wl->tcxo_clock = wlan_data->board_tcxo_clock;

	sdio_set_drvdata(func, wl_test);


	/* power up the device */
	ret = wl1271_chip_wakeup(wl);
	if (ret) {
		dev_err(&func->dev, "could not wake up chip\n");
		goto out_free;
	}

	if (wl->fw == NULL) {
		ret = wl1271_fetch_firmware(wl);
		if (ret < 0) {
			dev_err(&func->dev, "firmware fetch error\n");
			goto out_off;
		}
	}

	/* fetch NVS */
	if (wl->nvs == NULL) {
		ret = wl1271_fetch_nvs(wl);
		if (ret < 0) {
			dev_err(&func->dev, "NVS fetch error\n");
			goto out_off;
		}
	}

	ret = wl1271_load_firmware(wl);
	if (ret < 0) {
		dev_err(&func->dev, "firmware load error: %d\n", ret);
		goto out_free;
	}

	dev_info(&func->dev, "initialized\n");

	/* I/O testing will be done in the tester thread */

	wl_test->test_task = kthread_run(tester, wl, "sdio_tester");
	if (IS_ERR(wl_test->test_task)) {
		dev_err(&func->dev, "unable to create kernel thread\n");
		ret = PTR_ERR(wl_test->test_task);
		goto out_free;
	}

	return 0;

out_off:
	/* power off the chip */
	wl1271_power_off(wl);

out_free:
	kfree(wl_test);
	return ret;
}