/*
 *  Copyright 2007, Google Inc.
 *  Copyright 2012, Intel Inc.
 *
 *  based on omap.c driver, which was
 *  Copyright (C) 2004 Nokia Corporation
 *  Written by Tuukka Tikkanen and Juha Yrjölä <juha.yrjola@nokia.com>
 *  Misc hacks here and there by Tony Lindgren <tony@atomide.com>
 *  Other hacks (DMA, SD, etc) by David Brownell
 *
 * 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.
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/major.h>

#include <linux/types.h>
#include <linux/pci.h>
#include <linux/interrupt.h>

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/hdreg.h>
#include <linux/kdev_t.h>
#include <linux/blkdev.h>
#include <linux/mutex.h>
#include <linux/scatterlist.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>

#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/clk.h>
#include <linux/scatterlist.h>

#include <asm/io.h>
#include <asm/irq.h>

#include <asm/types.h>
#include <asm/io.h>
#include <linux/uaccess.h>

#define DRIVER_NAME "goldfish_mmc"

#define BUFFER_SIZE   16384

#define GOLDFISH_MMC_READ(host, addr)   (readl(host->reg_base + addr))
#define GOLDFISH_MMC_WRITE(host, addr, x)   (writel(x, host->reg_base + addr))

enum {
	/* status register */
	MMC_INT_STATUS	        = 0x00,
	/* set this to enable IRQ */
	MMC_INT_ENABLE	        = 0x04,
	/* set this to specify buffer address */
	MMC_SET_BUFFER          = 0x08,

	/* MMC command number */
	MMC_CMD	                = 0x0C,

	/* MMC argument */
	MMC_ARG	                = 0x10,

	/* MMC response (or R2 bits 0 - 31) */
	MMC_RESP_0		        = 0x14,

	/* MMC R2 response bits 32 - 63 */
	MMC_RESP_1		        = 0x18,

	/* MMC R2 response bits 64 - 95 */
	MMC_RESP_2		        = 0x1C,

	/* MMC R2 response bits 96 - 127 */
	MMC_RESP_3		        = 0x20,

	MMC_BLOCK_LENGTH        = 0x24,
	MMC_BLOCK_COUNT         = 0x28,

	/* MMC state flags */
	MMC_STATE               = 0x2C,

	/* MMC_INT_STATUS bits */

	MMC_STAT_END_OF_CMD     = 1U << 0,
	MMC_STAT_END_OF_DATA    = 1U << 1,
	MMC_STAT_STATE_CHANGE   = 1U << 2,
	MMC_STAT_CMD_TIMEOUT    = 1U << 3,

	/* MMC_STATE bits */
	MMC_STATE_INSERTED     = 1U << 0,
	MMC_STATE_READ_ONLY    = 1U << 1,
};

/*
 * Command types
 */
#define OMAP_MMC_CMDTYPE_BC	0
#define OMAP_MMC_CMDTYPE_BCR	1
#define OMAP_MMC_CMDTYPE_AC	2
#define OMAP_MMC_CMDTYPE_ADTC	3


struct goldfish_mmc_host {
	struct mmc_request	*mrq;
	struct mmc_command	*cmd;
	struct mmc_data		*data;
	struct mmc_host		*mmc;
	struct device		*dev;
	unsigned char		id; /* 16xx chips have 2 MMC blocks */
	void			*virt_base;
	unsigned int		phys_base;
	int			irq;
	unsigned char		bus_mode;
	unsigned char		hw_bus_mode;

	unsigned int		sg_len;
	unsigned		dma_done:1;
	unsigned		dma_in_use:1;

	void __iomem		*reg_base;
};

static inline int
goldfish_mmc_cover_is_open(struct goldfish_mmc_host *host)
{
	return 0;
}

static ssize_t
goldfish_mmc_show_cover_switch(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct goldfish_mmc_host *host = dev_get_drvdata(dev);

	return sprintf(buf, "%s\n", goldfish_mmc_cover_is_open(host) ? "open" :
		       "closed");
}

static DEVICE_ATTR(cover_switch, S_IRUGO, goldfish_mmc_show_cover_switch, NULL);

static void
goldfish_mmc_start_command(struct goldfish_mmc_host *host, struct mmc_command *cmd)
{
	u32 cmdreg;
	u32 resptype;
	u32 cmdtype;

	host->cmd = cmd;

	resptype = 0;
	cmdtype = 0;

	/* Our hardware needs to know exact type */
	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_NONE:
		break;
	case MMC_RSP_R1:
	case MMC_RSP_R1B:
		/* resp 1, 1b, 6, 7 */
		resptype = 1;
		break;
	case MMC_RSP_R2:
		resptype = 2;
		break;
	case MMC_RSP_R3:
		resptype = 3;
		break;
	default:
		dev_err(mmc_dev(host->mmc),
			"Invalid response type: %04x\n", mmc_resp_type(cmd));
		break;
	}

	if (mmc_cmd_type(cmd) == MMC_CMD_ADTC)
		cmdtype = OMAP_MMC_CMDTYPE_ADTC;
	else if (mmc_cmd_type(cmd) == MMC_CMD_BC)
		cmdtype = OMAP_MMC_CMDTYPE_BC;
	else if (mmc_cmd_type(cmd) == MMC_CMD_BCR)
		cmdtype = OMAP_MMC_CMDTYPE_BCR;
	else
		cmdtype = OMAP_MMC_CMDTYPE_AC;

	cmdreg = cmd->opcode | (resptype << 8) | (cmdtype << 12);

	if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
		cmdreg |= 1 << 6;

	if (cmd->flags & MMC_RSP_BUSY)
		cmdreg |= 1 << 11;

	if (host->data && !(host->data->flags & MMC_DATA_WRITE))
		cmdreg |= 1 << 15;

	GOLDFISH_MMC_WRITE(host, MMC_ARG, cmd->arg);
	GOLDFISH_MMC_WRITE(host, MMC_CMD, cmdreg);
}

static void goldfish_mmc_xfer_done(struct goldfish_mmc_host *host,
				   struct mmc_data *data)
{
	if (host->dma_in_use) {
		enum dma_data_direction dma_data_dir;

		dma_data_dir = mmc_get_dma_dir(data);

		if (dma_data_dir == DMA_FROM_DEVICE) {
			/*
			 * We don't really have DMA, so we need
			 * to copy from our platform driver buffer
			 */
			uint8_t *dest = (uint8_t *)sg_virt(data->sg);
			memcpy(dest, host->virt_base, data->sg->length);
		}
		host->data->bytes_xfered += data->sg->length;
		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len,
			     dma_data_dir);
	}

	host->data = NULL;
	host->sg_len = 0;

	/*
	 * NOTE:  MMC layer will sometimes poll-wait CMD13 next, issuing
	 * dozens of requests until the card finishes writing data.
	 * It'd be cheaper to just wait till an EOFB interrupt arrives...
	 */

	if (!data->stop) {
		host->mrq = NULL;
		mmc_request_done(host->mmc, data->mrq);
		return;
	}

	goldfish_mmc_start_command(host, data->stop);
}

static void goldfish_mmc_end_of_data(struct goldfish_mmc_host *host,
				     struct mmc_data *data)
{
	if (!host->dma_in_use) {
		goldfish_mmc_xfer_done(host, data);
		return;
	}
	if (host->dma_done)
		goldfish_mmc_xfer_done(host, data);
}

static void goldfish_mmc_cmd_done(struct goldfish_mmc_host *host,
				  struct mmc_command *cmd)
{
	host->cmd = NULL;
	if (cmd->flags & MMC_RSP_PRESENT) {
		if (cmd->flags & MMC_RSP_136) {
			/* response type 2 */
			cmd->resp[3] =
				GOLDFISH_MMC_READ(host, MMC_RESP_0);
			cmd->resp[2] =
				GOLDFISH_MMC_READ(host, MMC_RESP_1);
			cmd->resp[1] =
				GOLDFISH_MMC_READ(host, MMC_RESP_2);
			cmd->resp[0] =
				GOLDFISH_MMC_READ(host, MMC_RESP_3);
		} else {
			/* response types 1, 1b, 3, 4, 5, 6 */
			cmd->resp[0] =
				GOLDFISH_MMC_READ(host, MMC_RESP_0);
		}
	}

	if (host->data == NULL || cmd->error) {
		host->mrq = NULL;
		mmc_request_done(host->mmc, cmd->mrq);
	}
}

static irqreturn_t goldfish_mmc_irq(int irq, void *dev_id)
{
	struct goldfish_mmc_host *host = (struct goldfish_mmc_host *)dev_id;
	u16 status;
	int end_command = 0;
	int end_transfer = 0;
	int transfer_error = 0;
	int state_changed = 0;
	int cmd_timeout = 0;

	while ((status = GOLDFISH_MMC_READ(host, MMC_INT_STATUS)) != 0) {
		GOLDFISH_MMC_WRITE(host, MMC_INT_STATUS, status);

		if (status & MMC_STAT_END_OF_CMD)
			end_command = 1;

		if (status & MMC_STAT_END_OF_DATA)
			end_transfer = 1;

		if (status & MMC_STAT_STATE_CHANGE)
			state_changed = 1;

                if (status & MMC_STAT_CMD_TIMEOUT) {
			end_command = 0;
			cmd_timeout = 1;
                }
	}

	if (cmd_timeout) {
		struct mmc_request *mrq = host->mrq;
		mrq->cmd->error = -ETIMEDOUT;
		host->mrq = NULL;
		mmc_request_done(host->mmc, mrq);
	}

	if (end_command)
		goldfish_mmc_cmd_done(host, host->cmd);

	if (transfer_error)
		goldfish_mmc_xfer_done(host, host->data);
	else if (end_transfer) {
		host->dma_done = 1;
		goldfish_mmc_end_of_data(host, host->data);
	} else if (host->data != NULL) {
		/*
		 * WORKAROUND -- after porting this driver from 2.6 to 3.4,
		 * during device initialization, cases where host->data is
		 * non-null but end_transfer is false would occur. Doing
		 * nothing in such cases results in no further interrupts,
		 * and initialization failure.
		 * TODO -- find the real cause.
		 */
		host->dma_done = 1;
		goldfish_mmc_end_of_data(host, host->data);
	}

	if (state_changed) {
		u32 state = GOLDFISH_MMC_READ(host, MMC_STATE);
		pr_info("%s: Card detect now %d\n", __func__,
			(state & MMC_STATE_INSERTED));
		mmc_detect_change(host->mmc, 0);
	}

	if (!end_command && !end_transfer &&
	    !transfer_error && !state_changed && !cmd_timeout) {
		status = GOLDFISH_MMC_READ(host, MMC_INT_STATUS);
		dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status);
		if (status != 0) {
			GOLDFISH_MMC_WRITE(host, MMC_INT_STATUS, status);
			GOLDFISH_MMC_WRITE(host, MMC_INT_ENABLE, 0);
		}
	}

	return IRQ_HANDLED;
}

static void goldfish_mmc_prepare_data(struct goldfish_mmc_host *host,
				      struct mmc_request *req)
{
	struct mmc_data *data = req->data;
	int block_size;
	unsigned sg_len;
	enum dma_data_direction dma_data_dir;

	host->data = data;
	if (data == NULL) {
		GOLDFISH_MMC_WRITE(host, MMC_BLOCK_LENGTH, 0);
		GOLDFISH_MMC_WRITE(host, MMC_BLOCK_COUNT, 0);
		host->dma_in_use = 0;
		return;
	}

	block_size = data->blksz;

	GOLDFISH_MMC_WRITE(host, MMC_BLOCK_COUNT, data->blocks - 1);
	GOLDFISH_MMC_WRITE(host, MMC_BLOCK_LENGTH, block_size - 1);

	/*
	 * Cope with calling layer confusion; it issues "single
	 * block" writes using multi-block scatterlists.
	 */
	sg_len = (data->blocks == 1) ? 1 : data->sg_len;

	dma_data_dir = mmc_get_dma_dir(data);

	host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
				  sg_len, dma_data_dir);
	host->dma_done = 0;
	host->dma_in_use = 1;

	if (dma_data_dir == DMA_TO_DEVICE) {
		/*
		 * We don't really have DMA, so we need to copy to our
		 * platform driver buffer
		 */
		const uint8_t *src = (uint8_t *)sg_virt(data->sg);
		memcpy(host->virt_base, src, data->sg->length);
	}
}

static void goldfish_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
{
	struct goldfish_mmc_host *host = mmc_priv(mmc);

	WARN_ON(host->mrq != NULL);

	host->mrq = req;
	goldfish_mmc_prepare_data(host, req);
	goldfish_mmc_start_command(host, req->cmd);

	/*
	 * This is to avoid accidentally being detected as an SDIO card
	 * in mmc_attach_sdio().
	 */
	if (req->cmd->opcode == SD_IO_SEND_OP_COND &&
	    req->cmd->flags == (MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR))
		req->cmd->error = -EINVAL;
}

static void goldfish_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct goldfish_mmc_host *host = mmc_priv(mmc);

	host->bus_mode = ios->bus_mode;
	host->hw_bus_mode = host->bus_mode;
}

static int goldfish_mmc_get_ro(struct mmc_host *mmc)
{
	uint32_t state;
	struct goldfish_mmc_host *host = mmc_priv(mmc);

	state = GOLDFISH_MMC_READ(host, MMC_STATE);
	return ((state & MMC_STATE_READ_ONLY) != 0);
}

static const struct mmc_host_ops goldfish_mmc_ops = {
	.request	= goldfish_mmc_request,
	.set_ios	= goldfish_mmc_set_ios,
	.get_ro		= goldfish_mmc_get_ro,
};

static int goldfish_mmc_probe(struct platform_device *pdev)
{
	struct mmc_host *mmc;
	struct goldfish_mmc_host *host = NULL;
	struct resource *res;
	int ret = 0;
	int irq;
	dma_addr_t buf_addr;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
	if (res == NULL || irq < 0)
		return -ENXIO;

	mmc = mmc_alloc_host(sizeof(struct goldfish_mmc_host), &pdev->dev);
	if (mmc == NULL) {
		ret = -ENOMEM;
		goto err_alloc_host_failed;
	}

	host = mmc_priv(mmc);
	host->mmc = mmc;

	pr_err("mmc: Mapping %lX to %lX\n", (long)res->start, (long)res->end);
	host->reg_base = ioremap(res->start, resource_size(res));
	if (host->reg_base == NULL) {
		ret = -ENOMEM;
		goto ioremap_failed;
	}
	host->virt_base = dma_alloc_coherent(&pdev->dev, BUFFER_SIZE,
					     &buf_addr, GFP_KERNEL);

	if (host->virt_base == 0) {
		ret = -ENOMEM;
		goto dma_alloc_failed;
	}
	host->phys_base = buf_addr;

	host->id = pdev->id;
	host->irq = irq;

	mmc->ops = &goldfish_mmc_ops;
	mmc->f_min = 400000;
	mmc->f_max = 24000000;
	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
	mmc->caps = MMC_CAP_4_BIT_DATA;

	/* Use scatterlist DMA to reduce per-transfer costs.
	 * NOTE max_seg_size assumption that small blocks aren't
	 * normally used (except e.g. for reading SD registers).
	 */
	mmc->max_segs = 32;
	mmc->max_blk_size = 2048;	/* MMC_BLOCK_LENGTH is 11 bits (+1) */
	mmc->max_blk_count = 2048;	/* MMC_BLOCK_COUNT is 11 bits (+1) */
	mmc->max_req_size = BUFFER_SIZE;
	mmc->max_seg_size = mmc->max_req_size;

	ret = request_irq(host->irq, goldfish_mmc_irq, 0, DRIVER_NAME, host);
	if (ret) {
		dev_err(&pdev->dev, "Failed IRQ Adding goldfish MMC\n");
		goto err_request_irq_failed;
	}

	host->dev = &pdev->dev;
	platform_set_drvdata(pdev, host);

	ret = device_create_file(&pdev->dev, &dev_attr_cover_switch);
	if (ret)
		dev_warn(mmc_dev(host->mmc),
			 "Unable to create sysfs attributes\n");

	GOLDFISH_MMC_WRITE(host, MMC_SET_BUFFER, host->phys_base);
	GOLDFISH_MMC_WRITE(host, MMC_INT_ENABLE,
			   MMC_STAT_END_OF_CMD | MMC_STAT_END_OF_DATA |
			   MMC_STAT_STATE_CHANGE | MMC_STAT_CMD_TIMEOUT);

	mmc_add_host(mmc);
	return 0;

err_request_irq_failed:
	dma_free_coherent(&pdev->dev, BUFFER_SIZE, host->virt_base,
			  host->phys_base);
dma_alloc_failed:
	iounmap(host->reg_base);
ioremap_failed:
	mmc_free_host(host->mmc);
err_alloc_host_failed:
	return ret;
}

static int goldfish_mmc_remove(struct platform_device *pdev)
{
	struct goldfish_mmc_host *host = platform_get_drvdata(pdev);

	BUG_ON(host == NULL);

	mmc_remove_host(host->mmc);
	free_irq(host->irq, host);
	dma_free_coherent(&pdev->dev, BUFFER_SIZE, host->virt_base, host->phys_base);
	iounmap(host->reg_base);
	mmc_free_host(host->mmc);
	return 0;
}

static struct platform_driver goldfish_mmc_driver = {
	.probe		= goldfish_mmc_probe,
	.remove		= goldfish_mmc_remove,
	.driver		= {
		.name	= DRIVER_NAME,
	},
};

module_platform_driver(goldfish_mmc_driver);
MODULE_LICENSE("GPL v2");
