/* Realtek PCI-Express Memstick Card Interface driver
 *
 * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * Author:
 *   Wei WANG <wei_wang@realsil.com.cn>
 *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
 */

#include <linux/module.h>
#include <linux/highmem.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/memstick.h>
#include <linux/mfd/rtsx_pci.h>
#include <asm/unaligned.h>

struct realtek_pci_ms {
	struct platform_device	*pdev;
	struct rtsx_pcr		*pcr;
	struct memstick_host	*msh;
	struct memstick_request	*req;

	struct mutex		host_mutex;
	struct work_struct	handle_req;

	u8			ssc_depth;
	unsigned int		clock;
	unsigned char           ifmode;
	bool			eject;
};

static inline struct device *ms_dev(struct realtek_pci_ms *host)
{
	return &(host->pdev->dev);
}

static inline void ms_clear_error(struct realtek_pci_ms *host)
{
	rtsx_pci_write_register(host->pcr, CARD_STOP,
			MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR);
}

#ifdef DEBUG

static void ms_print_debug_regs(struct realtek_pci_ms *host)
{
	struct rtsx_pcr *pcr = host->pcr;
	u16 i;
	u8 *ptr;

	/* Print MS host internal registers */
	rtsx_pci_init_cmd(pcr);
	for (i = 0xFD40; i <= 0xFD44; i++)
		rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
	for (i = 0xFD52; i <= 0xFD69; i++)
		rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0);
	rtsx_pci_send_cmd(pcr, 100);

	ptr = rtsx_pci_get_cmd_data(pcr);
	for (i = 0xFD40; i <= 0xFD44; i++)
		dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
	for (i = 0xFD52; i <= 0xFD69; i++)
		dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++));
}

#else

#define ms_print_debug_regs(host)

#endif

static int ms_power_on(struct realtek_pci_ms *host)
{
	struct rtsx_pcr *pcr = host->pcr;
	int err;

	rtsx_pci_init_cmd(pcr);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SELECT, 0x07, MS_MOD_SEL);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SHARE_MODE,
			CARD_SHARE_MASK, CARD_SHARE_48_MS);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN,
			MS_CLK_EN, MS_CLK_EN);
	err = rtsx_pci_send_cmd(pcr, 100);
	if (err < 0)
		return err;

	err = rtsx_pci_card_pull_ctl_enable(pcr, RTSX_MS_CARD);
	if (err < 0)
		return err;

	err = rtsx_pci_card_power_on(pcr, RTSX_MS_CARD);
	if (err < 0)
		return err;

	/* Wait ms power stable */
	msleep(150);

	err = rtsx_pci_write_register(pcr, CARD_OE,
			MS_OUTPUT_EN, MS_OUTPUT_EN);
	if (err < 0)
		return err;

	return 0;
}

static int ms_power_off(struct realtek_pci_ms *host)
{
	struct rtsx_pcr *pcr = host->pcr;
	int err;

	rtsx_pci_init_cmd(pcr);

	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0);

	err = rtsx_pci_send_cmd(pcr, 100);
	if (err < 0)
		return err;

	err = rtsx_pci_card_power_off(pcr, RTSX_MS_CARD);
	if (err < 0)
		return err;

	return rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD);
}

static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir,
		u8 tpc, u8 cfg, struct scatterlist *sg)
{
	struct rtsx_pcr *pcr = host->pcr;
	int err;
	unsigned int length = sg->length;
	u16 sec_cnt = (u16)(length / 512);
	u8 val, trans_mode, dma_dir;

	dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n",
			__func__, tpc, (data_dir == READ) ? "READ" : "WRITE",
			length);

	if (data_dir == READ) {
		dma_dir = DMA_DIR_FROM_CARD;
		trans_mode = MS_TM_AUTO_READ;
	} else {
		dma_dir = DMA_DIR_TO_CARD;
		trans_mode = MS_TM_AUTO_WRITE;
	}

	rtsx_pci_init_cmd(pcr);

	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H,
			0xFF, (u8)(sec_cnt >> 8));
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L,
			0xFF, (u8)sec_cnt);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);

	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0,
			DMA_DONE_INT, DMA_DONE_INT);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(length >> 24));
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(length >> 16));
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(length >> 8));
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)length);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL,
			0x03 | DMA_PACK_SIZE_MASK, dma_dir | DMA_EN | DMA_512);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
			0x01, RING_BUFFER);

	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER,
			0xFF, MS_TRANSFER_START | trans_mode);
	rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER,
			MS_TRANSFER_END, MS_TRANSFER_END);

	rtsx_pci_send_cmd_no_wait(pcr);

	err = rtsx_pci_transfer_data(pcr, sg, 1, data_dir == READ, 10000);
	if (err < 0) {
		ms_clear_error(host);
		return err;
	}

	rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
	if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT))
		return -EIO;

	return 0;
}

static int ms_write_bytes(struct realtek_pci_ms *host, u8 tpc,
		u8 cfg, u8 cnt, u8 *data, u8 *int_reg)
{
	struct rtsx_pcr *pcr = host->pcr;
	int err, i;

	dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc);

	if (!data)
		return -EINVAL;

	rtsx_pci_init_cmd(pcr);

	for (i = 0; i < cnt; i++)
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
				PPBUF_BASE2 + i, 0xFF, data[i]);
	if (cnt % 2)
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
				PPBUF_BASE2 + i, 0xFF, 0xFF);

	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
			0x01, PINGPONG_BUFFER);

	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER,
			0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES);
	rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER,
			MS_TRANSFER_END, MS_TRANSFER_END);
	if (int_reg)
		rtsx_pci_add_cmd(pcr, READ_REG_CMD, MS_TRANS_CFG, 0, 0);

	err = rtsx_pci_send_cmd(pcr, 5000);
	if (err < 0) {
		u8 val;

		rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
		dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val);

		if (int_reg)
			*int_reg = val & 0x0F;

		ms_print_debug_regs(host);

		ms_clear_error(host);

		if (!(tpc & 0x08)) {
			if (val & MS_CRC16_ERR)
				return -EIO;
		} else {
			if (!(val & 0x80)) {
				if (val & (MS_INT_ERR | MS_INT_CMDNK))
					return -EIO;
			}
		}

		return -ETIMEDOUT;
	}

	if (int_reg) {
		u8 *ptr = rtsx_pci_get_cmd_data(pcr) + 1;
		*int_reg = *ptr & 0x0F;
	}

	return 0;
}

static int ms_read_bytes(struct realtek_pci_ms *host, u8 tpc,
		u8 cfg, u8 cnt, u8 *data, u8 *int_reg)
{
	struct rtsx_pcr *pcr = host->pcr;
	int err, i;
	u8 *ptr;

	dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc);

	if (!data)
		return -EINVAL;

	rtsx_pci_init_cmd(pcr);

	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
			0x01, PINGPONG_BUFFER);

	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER,
			0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES);
	rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER,
			MS_TRANSFER_END, MS_TRANSFER_END);
	for (i = 0; i < cnt - 1; i++)
		rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0);
	if (cnt % 2)
		rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + cnt, 0, 0);
	else
		rtsx_pci_add_cmd(pcr, READ_REG_CMD,
				PPBUF_BASE2 + cnt - 1, 0, 0);
	if (int_reg)
		rtsx_pci_add_cmd(pcr, READ_REG_CMD, MS_TRANS_CFG, 0, 0);

	err = rtsx_pci_send_cmd(pcr, 5000);
	if (err < 0) {
		u8 val;

		rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
		dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val);

		if (int_reg)
			*int_reg = val & 0x0F;

		ms_print_debug_regs(host);

		ms_clear_error(host);

		if (!(tpc & 0x08)) {
			if (val & MS_CRC16_ERR)
				return -EIO;
		} else {
			if (!(val & 0x80)) {
				if (val & (MS_INT_ERR | MS_INT_CMDNK))
					return -EIO;
			}
		}

		return -ETIMEDOUT;
	}

	ptr = rtsx_pci_get_cmd_data(pcr) + 1;
	for (i = 0; i < cnt; i++)
		data[i] = *ptr++;

	if (int_reg)
		*int_reg = *ptr & 0x0F;

	return 0;
}

static int rtsx_pci_ms_issue_cmd(struct realtek_pci_ms *host)
{
	struct memstick_request *req = host->req;
	int err = 0;
	u8 cfg = 0, int_reg;

	dev_dbg(ms_dev(host), "%s\n", __func__);

	if (req->need_card_int) {
		if (host->ifmode != MEMSTICK_SERIAL)
			cfg = WAIT_INT;
	}

	if (req->long_data) {
		err = ms_transfer_data(host, req->data_dir,
				req->tpc, cfg, &(req->sg));
	} else {
		if (req->data_dir == READ) {
			err = ms_read_bytes(host, req->tpc, cfg,
					req->data_len, req->data, &int_reg);
		} else {
			err = ms_write_bytes(host, req->tpc, cfg,
					req->data_len, req->data, &int_reg);
		}
	}
	if (err < 0)
		return err;

	if (req->need_card_int && (host->ifmode == MEMSTICK_SERIAL)) {
		err = ms_read_bytes(host, MS_TPC_GET_INT,
				NO_WAIT_INT, 1, &int_reg, NULL);
		if (err < 0)
			return err;
	}

	if (req->need_card_int) {
		dev_dbg(ms_dev(host), "int_reg: 0x%02x\n", int_reg);

		if (int_reg & MS_INT_CMDNK)
			req->int_reg |= MEMSTICK_INT_CMDNAK;
		if (int_reg & MS_INT_BREQ)
			req->int_reg |= MEMSTICK_INT_BREQ;
		if (int_reg & MS_INT_ERR)
			req->int_reg |= MEMSTICK_INT_ERR;
		if (int_reg & MS_INT_CED)
			req->int_reg |= MEMSTICK_INT_CED;
	}

	return 0;
}

static void rtsx_pci_ms_handle_req(struct work_struct *work)
{
	struct realtek_pci_ms *host = container_of(work,
			struct realtek_pci_ms, handle_req);
	struct rtsx_pcr *pcr = host->pcr;
	struct memstick_host *msh = host->msh;
	int rc;

	mutex_lock(&pcr->pcr_mutex);

	rtsx_pci_start_run(pcr);

	rtsx_pci_switch_clock(host->pcr, host->clock, host->ssc_depth,
			false, true, false);
	rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, MS_MOD_SEL);
	rtsx_pci_write_register(pcr, CARD_SHARE_MODE,
			CARD_SHARE_MASK, CARD_SHARE_48_MS);

	if (!host->req) {
		do {
			rc = memstick_next_req(msh, &host->req);
			dev_dbg(ms_dev(host), "next req %d\n", rc);

			if (!rc)
				host->req->error = rtsx_pci_ms_issue_cmd(host);
		} while (!rc);
	}

	mutex_unlock(&pcr->pcr_mutex);
}

static void rtsx_pci_ms_request(struct memstick_host *msh)
{
	struct realtek_pci_ms *host = memstick_priv(msh);

	dev_dbg(ms_dev(host), "--> %s\n", __func__);

	schedule_work(&host->handle_req);
}

static int rtsx_pci_ms_set_param(struct memstick_host *msh,
		enum memstick_param param, int value)
{
	struct realtek_pci_ms *host = memstick_priv(msh);
	struct rtsx_pcr *pcr = host->pcr;
	unsigned int clock = 0;
	u8 ssc_depth = 0;
	int err;

	dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n",
			__func__, param, value);

	switch (param) {
	case MEMSTICK_POWER:
		if (value == MEMSTICK_POWER_ON)
			err = ms_power_on(host);
		else if (value == MEMSTICK_POWER_OFF)
			err = ms_power_off(host);
		else
			return -EINVAL;
		break;

	case MEMSTICK_INTERFACE:
		if (value == MEMSTICK_SERIAL) {
			clock = 19000000;
			ssc_depth = RTSX_SSC_DEPTH_500K;

			err = rtsx_pci_write_register(pcr, MS_CFG,
					0x18, MS_BUS_WIDTH_1);
			if (err < 0)
				return err;
		} else if (value == MEMSTICK_PAR4) {
			clock = 39000000;
			ssc_depth = RTSX_SSC_DEPTH_1M;

			err = rtsx_pci_write_register(pcr, MS_CFG,
					0x58, MS_BUS_WIDTH_4 | PUSH_TIME_ODD);
			if (err < 0)
				return err;
		} else {
			return -EINVAL;
		}

		err = rtsx_pci_switch_clock(pcr, clock,
				ssc_depth, false, true, false);
		if (err < 0)
			return err;

		host->ssc_depth = ssc_depth;
		host->clock = clock;
		host->ifmode = value;
		break;
	}

	return 0;
}

#ifdef CONFIG_PM

static int rtsx_pci_ms_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct realtek_pci_ms *host = platform_get_drvdata(pdev);
	struct memstick_host *msh = host->msh;

	dev_dbg(ms_dev(host), "--> %s\n", __func__);

	memstick_suspend_host(msh);
	return 0;
}

static int rtsx_pci_ms_resume(struct platform_device *pdev)
{
	struct realtek_pci_ms *host = platform_get_drvdata(pdev);
	struct memstick_host *msh = host->msh;

	dev_dbg(ms_dev(host), "--> %s\n", __func__);

	memstick_resume_host(msh);
	return 0;
}

#else /* CONFIG_PM */

#define rtsx_pci_ms_suspend NULL
#define rtsx_pci_ms_resume NULL

#endif /* CONFIG_PM */

static void rtsx_pci_ms_card_event(struct platform_device *pdev)
{
	struct realtek_pci_ms *host = platform_get_drvdata(pdev);

	memstick_detect_change(host->msh);
}

static int rtsx_pci_ms_drv_probe(struct platform_device *pdev)
{
	struct memstick_host *msh;
	struct realtek_pci_ms *host;
	struct rtsx_pcr *pcr;
	struct pcr_handle *handle = pdev->dev.platform_data;
	int rc;

	if (!handle)
		return -ENXIO;

	pcr = handle->pcr;
	if (!pcr)
		return -ENXIO;

	dev_dbg(&(pdev->dev),
			": Realtek PCI-E Memstick controller found\n");

	msh = memstick_alloc_host(sizeof(*host), &pdev->dev);
	if (!msh)
		return -ENOMEM;

	host = memstick_priv(msh);
	host->pcr = pcr;
	host->msh = msh;
	host->pdev = pdev;
	platform_set_drvdata(pdev, host);
	pcr->slots[RTSX_MS_CARD].p_dev = pdev;
	pcr->slots[RTSX_MS_CARD].card_event = rtsx_pci_ms_card_event;

	mutex_init(&host->host_mutex);

	INIT_WORK(&host->handle_req, rtsx_pci_ms_handle_req);
	msh->request = rtsx_pci_ms_request;
	msh->set_param = rtsx_pci_ms_set_param;
	msh->caps = MEMSTICK_CAP_PAR4;

	rc = memstick_add_host(msh);
	if (rc) {
		memstick_free_host(msh);
		return rc;
	}

	return 0;
}

static int rtsx_pci_ms_drv_remove(struct platform_device *pdev)
{
	struct realtek_pci_ms *host = platform_get_drvdata(pdev);
	struct rtsx_pcr *pcr;
	struct memstick_host *msh;
	int rc;

	if (!host)
		return 0;

	pcr = host->pcr;
	pcr->slots[RTSX_MS_CARD].p_dev = NULL;
	pcr->slots[RTSX_MS_CARD].card_event = NULL;
	msh = host->msh;
	host->eject = true;

	mutex_lock(&host->host_mutex);
	if (host->req) {
		dev_dbg(&(pdev->dev),
			"%s: Controller removed during transfer\n",
			dev_name(&msh->dev));

		rtsx_pci_complete_unfinished_transfer(pcr);

		host->req->error = -ENOMEDIUM;
		do {
			rc = memstick_next_req(msh, &host->req);
			if (!rc)
				host->req->error = -ENOMEDIUM;
		} while (!rc);
	}
	mutex_unlock(&host->host_mutex);

	memstick_remove_host(msh);
	memstick_free_host(msh);

	platform_set_drvdata(pdev, NULL);

	dev_dbg(&(pdev->dev),
		": Realtek PCI-E Memstick controller has been removed\n");

	return 0;
}

static struct platform_device_id rtsx_pci_ms_ids[] = {
	{
		.name = DRV_NAME_RTSX_PCI_MS,
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(platform, rtsx_pci_ms_ids);

static struct platform_driver rtsx_pci_ms_driver = {
	.probe		= rtsx_pci_ms_drv_probe,
	.remove		= rtsx_pci_ms_drv_remove,
	.id_table       = rtsx_pci_ms_ids,
	.suspend	= rtsx_pci_ms_suspend,
	.resume		= rtsx_pci_ms_resume,
	.driver		= {
		.owner	= THIS_MODULE,
		.name	= DRV_NAME_RTSX_PCI_MS,
	},
};
module_platform_driver(rtsx_pci_ms_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Wei WANG <wei_wang@realsil.com.cn>");
MODULE_DESCRIPTION("Realtek PCI-E Memstick Card Host Driver");
