/*
 * SDIO testing driver for wl12xx
 *
 * Copyright (C) 2010 Nokia Corporation
 *
 * Contact: Roger Quadros <roger.quadros@nokia.com>
 *
 * wl12xx read/write routines taken from the main module
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <linux/irq.h>
#include <linux/module.h>
#include <linux/crc7.h>
#include <linux/vmalloc.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/card.h>
#include <linux/gpio.h>
#include <linux/wl12xx.h>
#include <linux/kthread.h>
#include <linux/firmware.h>
#include <linux/pm_runtime.h>

#include "wl12xx.h"
#include "io.h"
#include "boot.h"

#ifndef SDIO_VENDOR_ID_TI
#define SDIO_VENDOR_ID_TI		0x0097
#endif

#ifndef SDIO_DEVICE_ID_TI_WL1271
#define SDIO_DEVICE_ID_TI_WL1271	0x4076
#endif

static bool rx, tx;

module_param(rx, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(rx, "Perform rx test. Default (0). "
	"This test continuously reads data from the SDIO device.\n");

module_param(tx, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(tx, "Perform tx test. Default (0). "
	"This test continuously writes data to the SDIO device.\n");

struct wl1271_test {
	struct wl1271 wl;
	struct task_struct *test_task;
};

static const struct sdio_device_id wl1271_devices[] = {
	{ SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
	{}
};

static inline struct sdio_func *wl_to_func(struct wl1271 *wl)
{
	return wl->if_priv;
}

static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl)
{
	return &(wl_to_func(wl)->dev);
}

static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
		size_t len, bool fixed)
{
	int ret = 0;
	struct sdio_func *func = wl_to_func(wl);

	if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
		((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
		wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x",
				addr, ((u8 *)buf)[0]);
	} else {
		if (fixed)
			ret = sdio_readsb(func, buf, addr, len);
		else
			ret = sdio_memcpy_fromio(func, buf, addr, len);

		wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %zu bytes",
				addr, len);
		wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
	}

	if (ret)
		wl1271_error("sdio read failed (%d)", ret);
}

static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
		size_t len, bool fixed)
{
	int ret = 0;
	struct sdio_func *func = wl_to_func(wl);

	if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
		sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
		wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
				addr, ((u8 *)buf)[0]);
	} else {
		wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %zu bytes",
				addr, len);
		wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);

		if (fixed)
			ret = sdio_writesb(func, addr, buf, len);
		else
			ret = sdio_memcpy_toio(func, addr, buf, len);
	}
	if (ret)
		wl1271_error("sdio write failed (%d)", ret);

}

static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
{
	struct sdio_func *func = wl_to_func(wl);
	int ret;

	/* Let the SDIO stack handle wlan_enable control, so we
	 * keep host claimed while wlan is in use to keep wl1271
	 * alive.
	 */
	if (enable) {
		/* Power up the card */
		ret = pm_runtime_get_sync(&func->dev);
		if (ret < 0)
			goto out;
		sdio_claim_host(func);
		sdio_enable_func(func);
		sdio_release_host(func);
	} else {
		sdio_claim_host(func);
		sdio_disable_func(func);
		sdio_release_host(func);

		/* Power down the card */
		ret = pm_runtime_put_sync(&func->dev);
	}

out:
	return ret;
}

static void wl1271_sdio_disable_interrupts(struct wl1271 *wl)
{
}

static void wl1271_sdio_enable_interrupts(struct wl1271 *wl)
{
}


static struct wl1271_if_operations sdio_ops = {
	.read		= wl1271_sdio_raw_read,
	.write		= wl1271_sdio_raw_write,
	.power		= wl1271_sdio_set_power,
	.dev		= wl1271_sdio_wl_to_dev,
	.enable_irq	= wl1271_sdio_enable_interrupts,
	.disable_irq	= wl1271_sdio_disable_interrupts,
};

static void wl1271_fw_wakeup(struct wl1271 *wl)
{
	u32 elp_reg;

	elp_reg = ELPCTRL_WAKE_UP;
	wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
}

static int wl1271_fetch_firmware(struct wl1271 *wl)
{
	const struct firmware *fw;
	int ret;

	ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl));

	if (ret < 0) {
		wl1271_error("could not get firmware: %d", ret);
		return ret;
	}

	if (fw->size % 4) {
		wl1271_error("firmware size is not multiple of 32 bits: %zu",
				fw->size);
		ret = -EILSEQ;
		goto out;
	}

	wl->fw_len = fw->size;
	wl->fw = vmalloc(wl->fw_len);

	if (!wl->fw) {
		wl1271_error("could not allocate memory for the firmware");
		ret = -ENOMEM;
		goto out;
	}

	memcpy(wl->fw, fw->data, wl->fw_len);

	ret = 0;

out:
	release_firmware(fw);

	return ret;
}

static int wl1271_fetch_nvs(struct wl1271 *wl)
{
	const struct firmware *fw;
	int ret;

	ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl));

	if (ret < 0) {
		wl1271_error("could not get nvs file: %d", ret);
		return ret;
	}

	wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);

	if (!wl->nvs) {
		wl1271_error("could not allocate memory for the nvs file");
		ret = -ENOMEM;
		goto out;
	}

	wl->nvs_len = fw->size;

out:
	release_firmware(fw);

	return ret;
}

static int wl1271_chip_wakeup(struct wl1271 *wl)
{
	struct wl1271_partition_set partition;
	int ret;

	msleep(WL1271_PRE_POWER_ON_SLEEP);
	ret = wl1271_power_on(wl);
	if (ret)
		return ret;

	msleep(WL1271_POWER_ON_SLEEP);

	/* We don't need a real memory partition here, because we only want
	 * to use the registers at this point. */
	memset(&partition, 0, sizeof(partition));
	partition.reg.start = REGISTERS_BASE;
	partition.reg.size = REGISTERS_DOWN_SIZE;
	wl1271_set_partition(wl, &partition);

	/* ELP module wake up */
	wl1271_fw_wakeup(wl);

	/* whal_FwCtrl_BootSm() */

	/* 0. read chip id from CHIP_ID */
	wl->chip.id = wl1271_read32(wl, CHIP_ID_B);

	/* 1. check if chip id is valid */

	switch (wl->chip.id) {
	case CHIP_ID_1271_PG10:
		wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
				wl->chip.id);
		break;
	case CHIP_ID_1271_PG20:
		wl1271_notice("chip id 0x%x (1271 PG20)",
				wl->chip.id);
		break;
	default:
		wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
		return -ENODEV;
	}

	return ret;
}

static struct wl1271_partition_set part_down = {
	.mem = {
		.start = 0x00000000,
		.size  = 0x000177c0
	},
	.reg = {
		.start = REGISTERS_BASE,
		.size  = 0x00008800
	},
	.mem2 = {
		.start = 0x00000000,
		.size  = 0x00000000
	},
	.mem3 = {
		.start = 0x00000000,
		.size  = 0x00000000
	},
};

static int tester(void *data)
{
	struct wl1271 *wl = data;
	struct sdio_func *func = wl_to_func(wl);
	struct device *pdev = &func->dev;
	int ret = 0;
	bool rx_started = 0;
	bool tx_started = 0;
	uint8_t *tx_buf, *rx_buf;
	int test_size = PAGE_SIZE;
	u32 addr = 0;
	struct wl1271_partition_set partition;

	/* We assume chip is powered up and firmware fetched */

	memcpy(&partition, &part_down, sizeof(partition));
	partition.mem.start = addr;
	wl1271_set_partition(wl, &partition);

	tx_buf = kmalloc(test_size, GFP_KERNEL);
	rx_buf = kmalloc(test_size, GFP_KERNEL);
	if (!tx_buf || !rx_buf) {
		dev_err(pdev,
			"Could not allocate memory. Test will not run.\n");
		ret = -ENOMEM;
		goto free;
	}

	memset(tx_buf, 0x5a, test_size);

	/* write something in data area so we can read it back */
	wl1271_write(wl, addr, tx_buf, test_size, false);

	while (!kthread_should_stop()) {
		if (rx && !rx_started) {
			dev_info(pdev, "starting rx test\n");
			rx_started = 1;
		} else if (!rx && rx_started) {
			dev_info(pdev, "stopping rx test\n");
			rx_started = 0;
		}

		if (tx && !tx_started) {
			dev_info(pdev, "starting tx test\n");
			tx_started = 1;
		} else if (!tx && tx_started) {
			dev_info(pdev, "stopping tx test\n");
			tx_started = 0;
		}

		if (rx_started)
			wl1271_read(wl, addr, rx_buf, test_size, false);

		if (tx_started)
			wl1271_write(wl, addr, tx_buf, test_size, false);

		if (!rx_started && !tx_started)
			msleep(100);
	}

free:
	kfree(tx_buf);
	kfree(rx_buf);
	return ret;
}

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;

	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;

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

static void __devexit wl1271_remove(struct sdio_func *func)
{
	struct wl1271_test *wl_test = sdio_get_drvdata(func);

	/* stop the I/O test thread */
	kthread_stop(wl_test->test_task);

	/* power off the chip */
	wl1271_power_off(&wl_test->wl);

	vfree(wl_test->wl.fw);
	wl_test->wl.fw = NULL;
	kfree(wl_test->wl.nvs);
	wl_test->wl.nvs = NULL;

	kfree(wl_test);
}

static struct sdio_driver wl1271_sdio_driver = {
	.name		= "wl12xx_sdio_test",
	.id_table	= wl1271_devices,
	.probe		= wl1271_probe,
	.remove		= __devexit_p(wl1271_remove),
};

static int __init wl1271_init(void)
{
	int ret;

	ret = sdio_register_driver(&wl1271_sdio_driver);
	if (ret < 0)
		pr_err("failed to register sdio driver: %d\n", ret);

	return ret;
}
module_init(wl1271_init);

static void __exit wl1271_exit(void)
{
	sdio_unregister_driver(&wl1271_sdio_driver);
}
module_exit(wl1271_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Roger Quadros <roger.quadros@nokia.com>");

