/*
 * Copyright (C) 2016 MediaTek Inc.
 *
 * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details.
 */

#include <linux/spi/spi.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/platform_data/spi-mt65xx.h>
#include <linux/dma-mapping.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/clk.h>

#if 0
/* #ifdef CONFIG_TRUSTONIC_TEE_SUPPORT */
#define SPI_TRUSTONIC_TEE_SUPPORT
#endif

#ifdef SPI_TRUSTONIC_TEE_SUPPORT
#include <mobicore_driver_api.h>
#include <tlspi_Api.h>
#endif

static struct spi_device *spi_test;
u32 speed = 10000000;

struct mtk_spi {
	void __iomem *base;
	u32 state;
	int pad_num;
	u32 *pad_sel;
	struct clk *parent_clk, *sel_clk, *spi_clk;
	struct spi_transfer *cur_transfer;
	u32 xfer_len;
	u32 num_xfered;
	struct scatterlist *tx_sgl, *rx_sgl;
	u32 tx_sgl_len, rx_sgl_len;
	const struct mtk_spi_compatible *dev_comp;
};

static struct mtk_chip_config mtk_test_chip_info = {
	.rx_mlsb = 0,
	.tx_mlsb = 0,
	.sample_sel = 0,

	.cs_setuptime = 0,
	.cs_holdtime = 0,
	.cs_idletime = 0,
	.deassert_mode = 0,
	.tick_delay = 0,
};

#define SPI_CFG0_REG                      0x0000
#define SPI_CFG1_REG                      0x0004
#define SPI_TX_SRC_REG                    0x0008
#define SPI_RX_DST_REG                    0x000c
#define SPI_TX_DATA_REG                   0x0010
#define SPI_RX_DATA_REG                   0x0014
#define SPI_CMD_REG                       0x0018
#define SPI_STATUS0_REG                   0x001c
#define SPI_STATUS1_REG                   0x0020
#define SPI_PAD_SEL_REG                   0x0024
#define SPI_CFG2_REG                      0x0028
#define SPI_TX_SRC_REG_64                 0x002c
#define SPI_RX_DST_REG_64                 0x0030

#define SPI_CFG1_CS_IDLE_OFFSET           0
#define SPI_CFG1_GET_TICK_DLY_OFFSET      29

#ifdef SPI_TRUSTONIC_TEE_SUPPORT
#define DEFAULT_HANDLES_NUM (64)
#define MAX_OPEN_SESSIONS (0xffffffff - 1)
/*
 * Trustlet UUID.
 */
u8 spi_uuid[10][16] = {
	{0x09, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00},
	{0x09, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00},
	{0x09, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00},
	{0x09, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00},
	{0x09, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00},
	{0x09, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00},
	{0x09, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00},
	{0x09, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00},
	{0x09, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00},
	{0x09, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00} };

static struct mc_session_handle secspi_session = { 0 };

static u32 secspi_session_ref;
static u32 secspi_devid = MC_DEVICE_ID_DEFAULT;
static tciSpiMessage_t *secspi_tci;

static DEFINE_MUTEX(secspi_lock);

int secspi_session_open(u32 spinum)
{
	enum mc_result mc_ret = MC_DRV_OK;

	mutex_lock(&secspi_lock);


	pr_info("%s() start\n", __func__);
	do {
		/* sessions reach max numbers ? */

		if (secspi_session_ref > MAX_OPEN_SESSIONS) {
			pr_notice("%s() err: secspi_session(0x%x)>MAX(0x%x)\n",
			__func__, secspi_session_ref, MAX_OPEN_SESSIONS);
			break;
		}

		if (secspi_session_ref > 0) {
			secspi_session_ref++;
			break;
		}

		/* open device */
		mc_ret = mc_open_device(secspi_devid);
		if (mc_ret != MC_DRV_OK) {
			pr_notice("%s() mc_open_device failed: %d\n", __func__,
				mc_ret);
			break;
		}

		/* allocating WSM for DCI */
		mc_ret = mc_malloc_wsm(secspi_devid, 0,
			sizeof(tciSpiMessage_t), (uint8_t **) &secspi_tci, 0);
		if (mc_ret != MC_DRV_OK) {
			pr_notice("%s() mc_malloc_wsm failed: %d\n", __func__,
				mc_ret);
			mc_close_device(secspi_devid);
			break;
		}

		/* open session */
		secspi_session.device_id = secspi_devid;
		mc_ret = mc_open_session(&secspi_session,
			(struct mc_uuid_t *)&spi_uuid[spinum][0],
			(uint8_t *)secspi_tci, sizeof(tciSpiMessage_t));
		if (mc_ret != MC_DRV_OK) {
			pr_notice("%s() mc_open_session fail: %d\n", __func__,
				mc_ret);
			mc_free_wsm(secspi_devid, (uint8_t *) secspi_tci);
			mc_close_device(secspi_devid);
			secspi_tci = NULL;
			break;
		}
		secspi_session_ref = 1;

	} while (0);

	mutex_unlock(&secspi_lock);

	if (mc_ret != MC_DRV_OK) {
		pr_notice("%s() Done. Fail! ret=%d, ref=%d\n", __func__,
			mc_ret, secspi_session_ref);
		return -ENXIO;
	}

	pr_info("%s() Done. Success! ret=%d, ref=%d\n", __func__, mc_ret,
				secspi_session_ref);
	return 0;
}

static int secspi_session_close(void)
{
	enum mc_result mc_ret = MC_DRV_OK;

	mutex_lock(&secspi_lock);

	do {
		/* session is already closed ? */
		if (secspi_session_ref == 0) {
			pr_notice("%s() spi_session already closed\n",
				__func__);
			break;
		}

		if (secspi_session_ref > 1) {
			secspi_session_ref--;
			break;
		}

		/* close session */
		mc_ret = mc_close_session(&secspi_session);
		if (mc_ret != MC_DRV_OK) {
			pr_notice("%s() mc_close_session failed: %d\n",
				__func__, mc_ret);
			break;
		}

		/* free WSM for DCI */
		mc_ret = mc_free_wsm(secspi_devid, (uint8_t *) secspi_tci);
		if (mc_ret != MC_DRV_OK) {
			pr_notice("%s() mc_free_wsm failed: %d\n", __func__,
				mc_ret);
			break;
		}
		secspi_tci = NULL;
		secspi_session_ref = 0;

		/* close device */
		mc_ret = mc_close_device(secspi_devid);
		if (mc_ret != MC_DRV_OK)
			pr_notice("%s() mc_close_device failed: %d\n",
				__func__, mc_ret);

	} while (0);

	mutex_unlock(&secspi_lock);

	if (mc_ret != MC_DRV_OK) {
		pr_notice("%s() Done. Fail! ret=%d, ref=%d\n", __func__,
			mc_ret, secspi_session_ref);
		return -ENXIO;
	}

	pr_info("%s() Done. Success! ret=%d, ref=%d\n", __func__, mc_ret,
			secspi_session_ref);
	return 0;

}

void secspi_enable_clk(struct spi_device *spidev)
{
	int ret;
	struct spi_master *master;
	struct mtk_spi *ms;

	master = spidev->master;
	ms = spi_master_get_devdata(master);
	/*
	 * prepare the clock source
	 */
	ret = clk_prepare_enable(ms->spi_clk);
}

int secspi_execute(u32 cmd, tciSpiMessage_t *param)
{
	enum mc_result mc_ret;

	pr_info("%s() start.\n", __func__);
	mutex_lock(&secspi_lock);

	if (secspi_tci == NULL) {
		mutex_unlock(&secspi_lock);
		pr_notice("%s() secspi_tci not exist\n", __func__);
		return -ENODEV;
	}

	/*set transfer data para */
	if (param == NULL) {
		pr_notice("%s() parameter is NULL !!\n", __func__);
	} else {
		secspi_tci->tx_buf = param->tx_buf;
		secspi_tci->rx_buf = param->rx_buf;
		secspi_tci->len = param->len;
		secspi_tci->is_dma_used = param->is_dma_used;
		secspi_tci->tx_dma = param->tx_dma;
		secspi_tci->rx_dma = param->rx_dma;
		secspi_tci->tl_chip_config = param->tl_chip_config;
	}

	secspi_tci->cmd_spi.header.commandId = (tciCommandId_t) cmd;
	secspi_tci->cmd_spi.len = 0;

	/* enable_clock(MT_CG_PERI_SPI0, "spi"); */
	/* enable_clk(ms); */

	mc_ret = mc_notify(&secspi_session);

	if (mc_ret != MC_DRV_OK) {
		pr_notice("%s() mc_notify failed: %d", __func__, mc_ret);
		goto exit;
	}

	mc_ret = mc_wait_notification(&secspi_session, -1);
	if (mc_ret != MC_DRV_OK) {
		pr_notice("%s() SPI mc_wait_notification failed: %d", __func__,
			mc_ret);
		goto exit;
	}

exit:
	mutex_unlock(&secspi_lock);

	if (mc_ret != MC_DRV_OK) {
		pr_notice("%s() Done. Fail. ret:%d\n", __func__, mc_ret);
		return -ENOSPC;
	}

	pr_info("%s() Done. Success. ret:%d\n", __func__, mc_ret);
	return 0;
}

/*used for REE to detach IRQ of TEE*/
void spi_detach_irq_tee(u32 spinum)
{
	secspi_session_open(spinum);
	secspi_execute(2, NULL);
	pr_info("%s() Done.\n", __func__);
}
#endif

void mt_spi_disable_master_clk(struct spi_device *spidev)
{
	struct mtk_spi *ms;

	ms = spi_master_get_devdata(spidev->master);

	clk_disable_unprepare(ms->spi_clk);
}
EXPORT_SYMBOL(mt_spi_disable_master_clk);

void mt_spi_enable_master_clk(struct spi_device *spidev)
{
	int ret;
	struct mtk_spi *ms;

	ms = spi_master_get_devdata(spidev->master);

	ret = clk_prepare_enable(ms->spi_clk);
}
EXPORT_SYMBOL(mt_spi_enable_master_clk);

static int spi_setup_xfer(struct device *dev, struct spi_transfer *xfer,
		u32 len, u32 flag)
{
	u32 tx_buffer = 0x12345678;
	u32 cnt, i;

	xfer->speed_hz = speed;
	pr_info("%s()  flag:%d speed:%d\n", __func__, flag, xfer->speed_hz);

	/* Instead of using kzalloc, if using below
	 * dma_alloc_coherent to allocate tx_dma/rx_dma, remember:
	 * 1. remove kfree in spi_recv_check_all, otherwise KE reboot
	 * 2. set msg.is_dma_mapped = 1 before calling spi_sync();
	 */

	if ((xfer->tx_buf == NULL) || (xfer->rx_buf == NULL))
		return -1;

	cnt = (len%4)?(len/4 + 1):(len/4);

	if (flag == 0)
		for (i = 0; i < cnt; i++)
			*((u32 *)xfer->tx_buf + i) = tx_buffer;
	else if (flag == 1)
		for (i = 0; i < cnt; i++)
			*((u32 *)xfer->tx_buf + i) = tx_buffer + i;
	else
		return -EINVAL;

	return 0;

}

static int spi_recv_check(struct spi_device *spi, struct spi_message *msg)
{
	struct mtk_chip_config *chip_config;
	struct spi_transfer *xfer;
	u32 i, err = 0;
	int j;
	u8 t, rec_cac;

	chip_config = (struct mtk_chip_config *) spi->controller_data;

	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
		if (!xfer) {
			pr_notice("%s() rv msg is NULL.\n", __func__);
			return -1;
		}

		pr_info("%s xfer->len:%d chip_config->tx_mlsb:%d rx_mlsb:%d\n",
				__func__, xfer->len, chip_config->tx_mlsb,
				chip_config->rx_mlsb);
		for (i = 0; i < xfer->len; i++) {
			if (chip_config->tx_mlsb ^ chip_config->rx_mlsb) {
				rec_cac = 0;
				for (j = 7; j >= 0; j--) {
					t = *((u8 *)xfer->tx_buf + i) & (1<<j);
					t = (t >> j) << (7-j);
					rec_cac |= t;
				}
			} else
				rec_cac = *((u8 *) xfer->tx_buf + i);

			if (*((u8 *) xfer->rx_buf + i) != rec_cac) {
				pr_notice("%s() tx xfer %d is:%x\n", __func__,
					i, *((u8 *) xfer->tx_buf + i));
				pr_notice("%s() rx xfer %d is:%x\n", __func__,
					i, *((u8 *) xfer->rx_buf + i));
				err++;
			}
		}
	}

	pr_info("%s() Done. error %d,actual xfer len:%d\n", __func__, err,
		msg->actual_length);

	return err;
}

static ssize_t spi_store(struct device *dev, struct device_attribute *attr,
	const char *buf, size_t count)
{
	struct spi_device *spi;
	struct mtk_spi *mdata = NULL;
	struct mtk_chip_config *chip_config;
	u32 cs_idletime, pad_sel;
	int cpol, cpha, tx_mlsb, rx_mlsb;
	int sample_sel, tckdly;
	u32 reg_val;
	int dump_all, dump;
	int index;
#if 0
/* #ifdef CONFIG_TRUSTONIC_TEE_SUPPORT */
	u32 spinum;
#endif

	spi = container_of(dev, struct spi_device, dev);
	pr_info("%s() SPIDEV name is:%s\n", __func__, spi->modalias);

	chip_config = (struct mtk_chip_config *) spi->controller_data;

	if (!chip_config) {
		pr_notice("%s() chip_config is NULL.\n", __func__);
		chip_config = kzalloc(sizeof(struct mtk_chip_config),
			GFP_KERNEL);
		if (!chip_config)
			return -ENOMEM;
	}

	if (!buf) {
		pr_notice("%s() buf is NULL.Exit!\n", __func__);
		goto out;
	}

#if 0
/* #ifdef CONFIG_TRUSTONIC_TEE_SUPPORT */
	if (!strncmp(buf, "send", 4)) {
		if (sscanf(buf + 4, "%d", &spinum) == 1) {
			pr_info("%s() start to access TL SPI driver.\n",
				__func__);
			secspi_session_open(spinum);
			secspi_enable_clk(spi);
			secspi_execute(1, NULL);
			secspi_session_close();
			pr_info("%s() secspi_execute 1 finished!\n", __func__);
		}
	} else if (!strncmp(buf, "config", 6)) {
		if (sscanf(buf + 6, "%d", &spinum) == 1) {
			pr_info("start to access TL SPI driver.\n");
			secspi_session_open(spinum);
			secspi_execute(2, NULL);
			secspi_session_close();
			pr_info("secspi_execute 2 finished!!!\n");
		}
	} else if (!strncmp(buf, "debug", 5)) {
		if (sscanf(buf + 5, "%d", &spinum) == 1) {
			pr_info("start to access TL SPI driver.\n");
			secspi_session_open(spinum);
			secspi_execute(3, NULL);
			secspi_session_close();
			pr_info("secspi_execute 3 finished!!!\n");
		}
	} else if (!strncmp(buf, "test", 4)) {
		if (sscanf(buf + 4, "%d", &spinum) == 1) {
			pr_info("start to access TL SPI driver.\n");
			secspi_session_open(spinum);
			secspi_execute(4, NULL);
			secspi_session_close();
			pr_info("secspi_execute 4 finished!!!\n");
		}
	}
#endif
	else if (!strncmp(buf, "-w", 2))
		goto set;
	else
		goto out;

set:
	buf += 3;
	mdata = spi_master_get_devdata(spi->master);
	mt_spi_enable_master_clk(spi);
	if (!strncmp(buf, "setuptime=", 10))
		pr_info("%s() setuptime cannot be set by cmd.\n", __func__);
	else if (!strncmp(buf, "holdtime=", 9))
		pr_info("%s() holdtime cannot be set by cmd.\n", __func__);
	else if (!strncmp(buf, "high_time=", 10))
		pr_info("%s() high_time cannot be set by cmd.\n", __func__);
	else if (!strncmp(buf, "low_time=", 9))
		pr_info("%s() low_time cannot be set by cmd.\n", __func__);
	else if (!strncmp(buf, "tckdly=", 7)) {
		if (sscanf(buf+7, "%d", &tckdly) == 1) {
			pr_info("%s() set tckdly=%d to SPI_CFG1_REG.\n",
				__func__, tckdly);
			reg_val = readl(mdata->base + SPI_CFG1_REG);
			reg_val &= 0x1FFFFFFF;
			reg_val |= (tckdly << SPI_CFG1_GET_TICK_DLY_OFFSET);
			writel(reg_val, mdata->base + SPI_CFG1_REG);
			reg_val = readl(mdata->base + SPI_CFG1_REG);
			pr_info("%s() now SPI_CFG1_REG=0x%x.\n", __func__,
				reg_val);
		}
	} else if (!strncmp(buf, "cs_idletime=", 12)) {
		if (sscanf(buf+12, "%d", &cs_idletime) == 1) {
			pr_info("%s() set cs_idletime=%d to SPI_CFG1_REG\n",
				__func__, cs_idletime);
			reg_val = readl(mdata->base + SPI_CFG1_REG);
			reg_val &= 0xFFFFFF00;
			reg_val |= (cs_idletime << SPI_CFG1_CS_IDLE_OFFSET);
			writel(reg_val, mdata->base + SPI_CFG1_REG);
			reg_val = readl(mdata->base + SPI_CFG1_REG);
			pr_info("%s() now SPI_CFG1_REG=0x%x.\n", __func__,
				reg_val);
		}
	} else if (!strncmp(buf, "cpol=", 5)) {
		if (sscanf(buf+5, "%d", &cpol) == 1) {
			pr_info("%s() Set cpol=%d to spi->mode.\n", __func__,
				cpol);
			spi->mode &= 0xFD;
			spi->mode |= cpol<<1;
			pr_info("%s() mow spi->mode:0x%.4x\n", __func__,
				spi->mode);
		}
	} else if (!strncmp(buf, "cpha=", 5)) {
		if (sscanf(buf+5, "%d", &cpha) == 1) {
			pr_info("%s() Set cpha=%d to spi->mode.\n", __func__,
				cpha);
			spi->mode &= 0xFE;
			spi->mode |= cpha;
			pr_info("%s() mow spi->mode:0x%.4x\n", __func__,
				spi->mode);
		}
	} else if (!strncmp(buf, "tx_mlsb=", 8)) {
		if (sscanf(buf+8, "%d", &tx_mlsb) == 1) {
			pr_info("%s() Set tx_mlsb=%d to chip_config\n",
				__func__, tx_mlsb);
			chip_config->tx_mlsb = tx_mlsb;
		}
	} else if (!strncmp(buf, "rx_mlsb=", 8)) {
		if (sscanf(buf+8, "%d", &rx_mlsb) == 1) {
			pr_info("%s() Set rx_mlsb=%d to chip_config\n",
				__func__, rx_mlsb);
			chip_config->rx_mlsb = rx_mlsb;
		}
	} else if (!strncmp(buf, "tx_endian=", 10))
		pr_info("%s() tx_endian cannot be set.See __LTTTLE_ENDIAN\n",
			__func__);
	else if (!strncmp(buf, "rx_endian=", 10))
		pr_info("%s() rx_endian cannot be set.See __LTTTLE_ENDIAN\n",
			__func__);
	else if (!strncmp(buf, "pause=", 6))
		pr_info("%s() pause cannot be set due to sw auto select\n",
			__func__);
	else if (!strncmp(buf, "deassert=", 9))
		pr_info("%s() deassert cannot be set, sw default disable\n",
			__func__);
	else if (!strncmp(buf, "sample_sel=", 11)) {
		if (sscanf(buf + 11, "%d", &sample_sel) == 1) {
			pr_info("%s() Set sample_sel=%d to chip_config\n",
				__func__, sample_sel);
			chip_config->sample_sel = sample_sel;
		}
	} else if (!strncmp(buf, "pad_sel=", 8)) {
		if (sscanf(buf + 8, "%d", &pad_sel) == 1) {
			pr_info("%s() Set pad select=%d to mdata->pad_sel.\n",
				__func__, pad_sel);
			mdata->pad_sel[spi->chip_select] = pad_sel;
		}
	} else if (!strncmp(buf, "speed=", 6)) {
		if (sscanf(buf + 6, "%d", &speed) == 1)
			pr_info("%s() Set speed=%d as global parameter.\n",
				__func__, speed);
	} else if (!strncmp(buf, "dump_all=", 9)) {
		if (sscanf(buf + 9, "%d", &dump_all) == 1) {
			pr_info("%s() dump all register.\n", __func__);
			pr_info("||* spi_dump_reg *******************||\n");
			pr_info("cfg0:0x%.8x\n",
				readl(mdata->base + SPI_CFG0_REG));
			pr_info("cfg1:0x%.8x\n",
				readl(mdata->base + SPI_CFG1_REG));
			pr_info("tx_s:0x%.8x\n",
				readl(mdata->base + SPI_TX_SRC_REG));
			pr_info("rx_d:0x%.8x\n",
				readl(mdata->base + SPI_RX_DST_REG));
			pr_info("tx_data:0x%.8x\n",
				readl(mdata->base + SPI_TX_DATA_REG));
			pr_info("rx_data:0x%.8x\n",
				readl(mdata->base + SPI_RX_DATA_REG));
			pr_info("cmd :0x%.8x\n",
				readl(mdata->base + SPI_CMD_REG));
			pr_info("status0:0x%.8x\n",
				readl(mdata->base + SPI_STATUS0_REG));
			pr_info("status1:0x%.8x\n",
				readl(mdata->base + SPI_STATUS1_REG));
			pr_info("pad_sel:0x%.8x\n",
				readl(mdata->base + SPI_PAD_SEL_REG));
			pr_info("cfg2:0x%.8x\n",
				readl(mdata->base + SPI_CFG2_REG));
			pr_info("tx_s64:0x%.8x\n",
				readl(mdata->base + SPI_TX_SRC_REG_64));
			pr_info("rx_d64:0x%.8x\n",
				readl(mdata->base + SPI_RX_DST_REG_64));
			pr_info("||*****************************************||\n");
		}
	} else if (!strncmp(buf, "dump=", 5)) {
		if (sscanf(buf + 5, "%d", &dump) == 1) {
			pr_info("%s() dump TX FIFO.\n", __func__);
			for (index = 1; index <= 8; index++)
				pr_info("%d tx_data:0x%.8x\n",
				index, readl(mdata->base + SPI_TX_DATA_REG));
			pr_info("%s() dump RX FIFO.\n", __func__);
			for (index = 1; index <= 8; index++)
				pr_info("%d rx_data:0x%.8x\n",
				index, readl(mdata->base + SPI_RX_DATA_REG));
		}
	} else {
		pr_notice("%s() Wrong parameters.Do nothing.\n", __func__);
		mt_spi_disable_master_clk(spi);
		goto out;
	}
	mt_spi_disable_master_clk(spi);
out:
	if (!spi->controller_data)
		kfree(chip_config);
	return count;
}

static ssize_t
spi_msg_store(struct device *dev, struct device_attribute *attr,
				const char *buf, size_t count)
{
	int ret = 0;
	struct spi_device *spi;

	struct spi_transfer transfer = {0,};
	struct spi_message msg;
	u32 len = 4;

	spi = container_of(dev, struct spi_device, dev);

	if (unlikely(!spi)) {
		pr_notice("%s() spi device is invalid\n", __func__);
		goto out;
	}
	if (unlikely(!buf)) {
		pr_notice("%s() buf is invalid\n", __func__);
		goto out;
	}
	spi_message_init(&msg);

	if (strncmp(buf, "-func", 5)) {
		pr_notice("%s() Wrong parameters.Do nothing.\n", __func__);
		ret = -1;
		goto out;
	}

	buf += 6;
	if (!strncmp(buf, "len=", 4) && 1 == sscanf(buf + 4, "%d", &len)) {
		pr_info("%s() start transfer,dataLen=%d.-----------------\n",
				__func__, len);
		transfer.len = len;
		transfer.tx_buf = kzalloc(len, GFP_KERNEL);
		transfer.rx_buf = kzalloc(len, GFP_KERNEL);
		pr_info("%s() transfer.tx_buf:%p, transfer.rx_buf:%p\n",
				__func__, transfer.tx_buf, transfer.rx_buf);

		spi_setup_xfer(&spi->dev, &transfer, len, 1);
		spi_message_add_tail(&transfer, &msg);
		ret = spi_sync(spi, &msg);
		if (ret < 0) {
			pr_notice("%s() spi_sync err:%d\n", __func__, ret);
		} else {
			ret = spi_recv_check(spi, &msg);
			kfree(transfer.tx_buf);
			kfree(transfer.rx_buf);
			if (ret != 0) {
				ret = -ret;
				pr_notice("%s Message transfer err:%d\n",
					__func__, ret);
				goto out;
			}
		}
		pr_info("%s() spi transfer Done.-----------------\n",
				__func__);
	}

	ret = count;

out:
	return count;
	//return ret;

}

static DEVICE_ATTR(spi, 0200, NULL, spi_store);
static DEVICE_ATTR(spi_msg, 0200, NULL, spi_msg_store);

static struct device_attribute *spi_attribute[] = {
	&dev_attr_spi,
	&dev_attr_spi_msg,
};

static int spi_create_attribute(struct device *dev)
{
	int num, idx;
	int err = 0;

	num = (int)ARRAY_SIZE(spi_attribute);
	for (idx = 0; idx < num; idx++) {
		err = device_create_file(dev, spi_attribute[idx]);
		if (err)
			break;
	}
	return err;

}

static void spi_remove_attribute(struct device *dev)
{
	int num, idx;

	num = (int)ARRAY_SIZE(spi_attribute);
	for (idx = 0; idx < num; idx++)
		device_remove_file(dev, spi_attribute[idx]);
}

static int spi_test_remove(struct spi_device *spi)
{

	pr_info("%s().\n", __func__);
	spi_remove_attribute(&spi->dev);
	return 0;
}

static int spi_test_probe(struct spi_device *spi)
{
	pr_info("%s() enter.\n", __func__);
	spi_test = spi;
	spi->mode = SPI_MODE_3;
	spi->bits_per_word = 8;
	spi->controller_data = (void *)&mtk_test_chip_info;
	return spi_create_attribute(&spi->dev);
}

struct spi_device_id spi_id_table[] = {
	{"spi-ut", 0},
	{},
};

static const struct of_device_id spidev_dt_ids[] = {
	{ .compatible = "mediatek,spi-mt65xx-test" },
	{},
};
MODULE_DEVICE_TABLE(of, spidev_dt_ids);

static struct spi_driver spi_test_driver = {
	.driver = {
		.name = "test_spi",
		.bus = &spi_bus_type,
		.owner = THIS_MODULE,
		.of_match_table = spidev_dt_ids,
	},
	.probe = spi_test_probe,
	.remove = spi_test_remove,
	.id_table = spi_id_table,
};

static int __init spi_dev_init(void)
{
	pr_info("%s().\n", __func__);
	return spi_register_driver(&spi_test_driver);
}

static void __exit spi_test_exit(void)
{
	pr_info("%s().\n", __func__);
	spi_unregister_driver(&spi_test_driver);
}

module_init(spi_dev_init);
module_exit(spi_test_exit);

MODULE_DESCRIPTION("mt SPI test device driver");
MODULE_AUTHOR("ZH Chen <zh.chen@mediatek.com>");
MODULE_LICENSE("GPL");
