/*
 * Copyright (C) 2010 Juergen Beisert, Pengutronix <jbe@pengutronix.de>
 *
 * This code is based on:
 *
 * Copyright (C) 2007 SigmaTel, Inc., Ioannis Kappas <ikappas@sigmatel.com>
 *
 * Portions copyright (C) 2003 Russell King, PXA MMCI Driver
 * Portions copyright (C) 2004-2005 Pierre Ossman, W83L51xD SD/MMC driver
 *
 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright 2008 Embedded Alley Solutions, Inc 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 of
 * the License, 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/**
 * @file
 * @brief MCI card host interface for i.MX23 CPU
 */

/* #define DEBUG */

#include <common.h>
#include <init.h>
#include <mci.h>
#include <errno.h>
#include <clock.h>
#include <asm/io.h>
#include <asm/bitops.h>
#include <mach/imx-regs.h>
#include <mach/mci.h>
#include <mach/clock.h>

#define CLOCKRATE_MIN (1 * 1000 * 1000)
#define CLOCKRATE_MAX (480 * 1000 * 1000)

#define HW_SSP_CTRL0 0x000
# define SSP_CTRL0_SFTRST (1 << 31)
# define SSP_CTRL0_CLKGATE (1 << 30)
# define SSP_CTRL0_RUN (1 << 29)
# define SSP_CTRL0_LOCK_CS (1 << 27)
# define SSP_CTRL0_READ (1 << 25)
# define SSP_CTRL0_IGNORE_CRC (1 << 26)
# define SSP_CTRL0_DATA_XFER (1 << 24)
# define SSP_CTRL0_BUS_WIDTH(x) (((x) & 0x3) << 22)
# define SSP_CTRL0_WAIT_FOR_IRQ (1 << 21)
# define SSP_CTRL0_LONG_RESP (1 << 19)
# define SSP_CTRL0_GET_RESP (1 << 17)
# define SSP_CTRL0_ENABLE (1 << 16)
#ifdef CONFIG_ARCH_IMX23
# define SSP_CTRL0_XFER_COUNT(x) ((x) & 0xffff)
#endif

#define HW_SSP_CMD0 0x010
# define SSP_CMD0_SLOW_CLK (1 << 22)
# define SSP_CMD0_CONT_CLK (1 << 21)
# define SSP_CMD0_APPEND_8CYC (1 << 20)
#ifdef CONFIG_ARCH_IMX23
# define SSP_CMD0_BLOCK_SIZE(x) (((x) & 0xf) << 16)
# define SSP_CMD0_BLOCK_COUNT(x) (((x) & 0xff) << 8)
#endif
# define SSP_CMD0_CMD(x) ((x) & 0xff)

#define HW_SSP_CMD1 0x020

#ifdef CONFIG_ARCH_IMX23
# define HW_SSP_COMPREF 0x030
# define HW_SSP_COMPMASK 0x040
# define HW_SSP_TIMING 0x050
# define HW_SSP_CTRL1 0x060
# define HW_SSP_DATA 0x070
#endif
#ifdef CONFIG_ARCH_IMX28
# define HW_SSP_XFER_COUNT 0x30
# define HW_SSP_BLOCK_SIZE 0x40
#  define SSP_BLOCK_SIZE(x) ((x) & 0xf)
#  define SSP_BLOCK_COUNT(x) (((x) & 0xffffff) << 4)
# define HW_SSP_COMPREF 0x050
# define HW_SSP_COMPMASK 0x060
# define HW_SSP_TIMING 0x070
# define HW_SSP_CTRL1 0x080
# define HW_SSP_DATA 0x090
#endif
/* bit definition for register HW_SSP_TIMING */
# define SSP_TIMING_TIMEOUT_MASK (0xffff0000)
# define SSP_TIMING_TIMEOUT(x) ((x) << 16)
# define SSP_TIMING_CLOCK_DIVIDE(x) (((x) & 0xff) << 8)
# define SSP_TIMING_CLOCK_RATE(x) ((x) & 0xff)

/* bit definition for register HW_SSP_CTRL1 */
# define SSP_CTRL1_POLARITY (1 << 9)
# define SSP_CTRL1_WORD_LENGTH(x) (((x) & 0xf) << 4)
# define SSP_CTRL1_SSP_MODE(x) ((x) & 0xf)

#ifdef CONFIG_ARCH_IMX23
# define HW_SSP_SDRESP0 0x080
# define HW_SSP_SDRESP1 0x090
# define HW_SSP_SDRESP2 0x0A0
# define HW_SSP_SDRESP3 0x0B0
#endif
#ifdef CONFIG_ARCH_IMX28
# define HW_SSP_SDRESP0 0x0A0
# define HW_SSP_SDRESP1 0x0B0
# define HW_SSP_SDRESP2 0x0C0
# define HW_SSP_SDRESP3 0x0D0
#endif

#ifdef CONFIG_ARCH_IMX28
# define HW_SSP_DDR_CTRL 0x0E0
# define HW_SSP_DLL_CTRL 0x0F0
#endif

#ifdef CONFIG_ARCH_IMX23
# define HW_SSP_STATUS 0x0C0
#endif
#ifdef CONFIG_ARCH_IMX28
# define HW_SSP_STATUS 0x100
#endif

/* bit definition for register HW_SSP_STATUS */
# define SSP_STATUS_PRESENT (1 << 31)
# define SSP_STATUS_SD_PRESENT (1 << 29)
# define SSP_STATUS_CARD_DETECT (1 << 28)
# define SSP_STATUS_RESP_CRC_ERR (1 << 16)
# define SSP_STATUS_RESP_ERR (1 << 15)
# define SSP_STATUS_RESP_TIMEOUT (1 << 14)
# define SSP_STATUS_DATA_CRC_ERR (1 << 13)
# define SSP_STATUS_TIMEOUT (1 << 12)
# define SSP_STATUS_FIFO_OVRFLW (1 << 9)
# define SSP_STATUS_FIFO_FULL (1 << 8)
# define SSP_STATUS_FIFO_EMPTY (1 << 5)
# define SSP_STATUS_FIFO_UNDRFLW (1 << 4)
# define SSP_STATUS_CMD_BUSY (1 << 3)
# define SSP_STATUS_DATA_BUSY (1 << 2)
# define SSP_STATUS_BUSY (1 << 0)
# define SSP_STATUS_ERROR (SSP_STATUS_FIFO_OVRFLW | SSP_STATUS_FIFO_UNDRFLW | \
	SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR | \
	SSP_STATUS_RESP_TIMEOUT | SSP_STATUS_DATA_CRC_ERR | SSP_STATUS_TIMEOUT)

#ifdef CONFIG_ARCH_IMX28
# define HW_SSP_DLL_STS 0x110
#endif

#ifdef CONFIG_ARCH_IMX23
# define HW_SSP_DEBUG 0x100
# define HW_SSP_VERSION 0x110
#endif

#ifdef CONFIG_ARCH_IMX28
# define HW_SSP_DEBUG 0x120
# define HW_SSP_VERSION 0x130
#endif

struct mxs_mci_host {
	struct mci_host	host;
	void __iomem	*regs;
	unsigned	clock;	/* current clock speed in Hz ("0" if disabled) */
	unsigned	index;
#ifdef CONFIG_MCI_INFO
	unsigned	f_min;
	unsigned	f_max;
#endif
	int		bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
};

#define to_mxs_mci(mxs) container_of(mxs, struct mxs_mci_host, host)

/**
 * Get the SSP clock rate
 * @param hw_dev Host interface device instance
 * @return Unit's clock in [Hz]
 */
static unsigned mxs_mci_get_unit_clock(struct mxs_mci_host *mxs_mci)
{
	return imx_get_sspclk(mxs_mci->index);
}

/**
 * Get MCI cards response if defined for the type of command
 * @param hw_dev Host interface device instance
 * @param cmd Command description
 * @return Response bytes count, -EINVAL for unsupported response types
 */
static int mxs_mci_get_cards_response(struct mxs_mci_host *mxs_mci, struct mci_cmd *cmd)
{
	switch (cmd->resp_type) {
	case MMC_RSP_NONE:
		return 0;

	case MMC_RSP_R1:
	case MMC_RSP_R1b:
	case MMC_RSP_R3:
		cmd->response[0] = readl(mxs_mci->regs + HW_SSP_SDRESP0);
		return 1;

	case MMC_RSP_R2:
		cmd->response[3] = readl(mxs_mci->regs + HW_SSP_SDRESP0);
		cmd->response[2] = readl(mxs_mci->regs + HW_SSP_SDRESP1);
		cmd->response[1] = readl(mxs_mci->regs + HW_SSP_SDRESP2);
		cmd->response[0] = readl(mxs_mci->regs + HW_SSP_SDRESP3);
		return 4;
	}

	return -EINVAL;
}

/**
 * Finish a request to the MCI card
 * @param hw_dev Host interface device instance
 *
 * Can also stop the clock to save power
 */
static void mxs_mci_finish_request(struct mxs_mci_host *mxs_mci)
{
	/* stop the engines (normaly already done) */
	writel(SSP_CTRL0_RUN, mxs_mci->regs + HW_SSP_CTRL0 + 8);
}

/**
 * Check if the last command failed and if, why it failed
 * @param status HW_SSP_STATUS's content
 * @return 0 if no error, negative values else
 */
static int mxs_mci_get_cmd_error(unsigned status)
{
	if (status & SSP_STATUS_ERROR)
		pr_debug("Status Reg reports %08X\n", status);

	if (status & SSP_STATUS_TIMEOUT) {
		pr_debug("CMD timeout\n");
		return -ETIMEDOUT;
	} else if (status & SSP_STATUS_RESP_TIMEOUT) {
		pr_debug("RESP timeout\n");
		return -ETIMEDOUT;
	} else if (status & SSP_STATUS_RESP_CRC_ERR) {
		pr_debug("CMD crc error\n");
		return -EILSEQ;
	} else if (status & SSP_STATUS_RESP_ERR) {
		pr_debug("RESP error\n");
		return -EIO;
	}

	return 0;
}

/**
 * Define the timout for the next command
 * @param hw_dev Host interface device instance
 * @param to Timeout value in MCI card's bus clocks
 */
static void mxs_mci_setup_timeout(struct mxs_mci_host *mxs_mci, unsigned to)
{
	uint32_t reg;

	reg = readl(mxs_mci->regs + HW_SSP_TIMING) & ~SSP_TIMING_TIMEOUT_MASK;
	reg |= SSP_TIMING_TIMEOUT(to);
	writel(reg, mxs_mci->regs + HW_SSP_TIMING);
}

/**
 * Read data from the MCI card
 * @param hw_dev Host interface device instance
 * @param buffer To write data into
 * @param length Count of bytes to read (must be multiples of 4)
 * @return 0 on success, negative values else
 *
 * @note This routine uses PIO to read in the data bytes from the FIFO. This
 * may fail whith high clock speeds. If you receive -EIO errors you can try
 * again with reduced clock speeds.
 */
static int mxs_mci_read_data(struct mxs_mci_host *mxs_mci, void *buffer, unsigned length)
{
	uint32_t *p = buffer;

	if (length & 0x3) {
		pr_debug("Cannot read data sizes not multiple of 4 (request for %u detected)\n",
				length);
		return -EINVAL;
	}

	while ((length != 0) &&
		((readl(mxs_mci->regs + HW_SSP_STATUS) & SSP_STATUS_ERROR) == 0)) {
		/* TODO sort out FIFO overflows and emit -EOI for this case */
		if ((readl(mxs_mci->regs + HW_SSP_STATUS) & SSP_STATUS_FIFO_EMPTY) == 0) {
			*p = readl(mxs_mci->regs + HW_SSP_DATA);
			p++;
			length -= 4;
		}
	}

	if (length == 0)
		return 0;

	return -EINVAL;
}


/**
 * Write data into the MCI card
 * @param hw_dev Host interface device instance
 * @param buffer To read the data from
 * @param length Count of bytes to write (must be multiples of 4)
 * @return 0 on success, negative values else
 *
 * @note This routine uses PIO to write the data bytes into the FIFO. This
 * may fail with high clock speeds. If you receive -EIO errors you can try
 * again with reduced clock speeds.
 */
static int mxs_mci_write_data(struct mxs_mci_host *mxs_mci, const void *buffer, unsigned length)
{
	const uint32_t *p = buffer;

	if (length & 0x3) {
		pr_debug("Cannot write data sizes not multiple of 4 (request for %u detected)\n",
				length);
		return -EINVAL;
	}

	while ((length != 0) &&
		((readl(mxs_mci->regs + HW_SSP_STATUS) & SSP_STATUS_ERROR) == 0)) {
		/* TODO sort out FIFO overflows and emit -EOI for this case */
		if ((readl(mxs_mci->regs + HW_SSP_STATUS) & SSP_STATUS_FIFO_FULL) == 0) {
			writel(*p, mxs_mci->regs + HW_SSP_DATA);
			p++;
			length -= 4;
		}
	}
	if (length == 0)
		return 0;

	return -EINVAL;
}

/**
 * Start the transaction with or without data
 * @param hw_dev Host interface device instance
 * @param data Data transfer description (might be NULL)
 * @return 0 on success
 */
static int mxs_mci_transfer_data(struct mxs_mci_host *mxs_mci, struct mci_data *data)
{
	/*
	 * Everything is ready for the transaction now:
	 * - transfer configuration
	 * - command and its parameters
	 *
	 * Start the transaction right now
	 */
	writel(SSP_CTRL0_RUN, mxs_mci->regs + HW_SSP_CTRL0 + 4);

	if (data != NULL) {
		unsigned length = data->blocks * data->blocksize;

		if (data->flags & MMC_DATA_READ)
			return mxs_mci_read_data(mxs_mci, data->dest, length);
		else
			return mxs_mci_write_data(mxs_mci, data->src, length);
	}

	return 0;
}

/**
 * Configure the MCI hardware for the next transaction
 * @param cmd_flags Command information
 * @param data_flags Data information (may be 0)
 * @return Corresponding setting for the SSP_CTRL0 register
 */
static uint32_t mxs_mci_prepare_transfer_setup(unsigned cmd_flags, unsigned data_flags)
{
	uint32_t reg = 0;

	if (cmd_flags & MMC_RSP_PRESENT)
		reg |= SSP_CTRL0_GET_RESP;
	if ((cmd_flags & MMC_RSP_CRC) == 0)
		reg |= SSP_CTRL0_IGNORE_CRC;
	if (cmd_flags & MMC_RSP_136)
		reg |= SSP_CTRL0_LONG_RESP;
	if (cmd_flags & MMC_RSP_BUSY)
		reg |= SSP_CTRL0_WAIT_FOR_IRQ;	/* FIXME correct? */
#if 0
	if (cmd_flags & MMC_RSP_OPCODE)
		/* TODO */
#endif
	if (data_flags & MMC_DATA_READ)
		reg |= SSP_CTRL0_READ;

	return reg;
}

/**
 * Handle MCI commands without data
 * @param hw_dev Host interface device instance
 * @param cmd The command to handle
 * @return 0 on success
 *
 * This functions handles the following MCI commands:
 * - "broadcast command (BC)" without a response
 * - "broadcast commands with response (BCR)"
 * - "addressed command (AC)" with response, but without data
 */
static int mxs_mci_std_cmds(struct mxs_mci_host *mxs_mci, struct mci_cmd *cmd)
{
	/* setup command and transfer parameters */
	writel(mxs_mci_prepare_transfer_setup(cmd->resp_type, 0) |
		SSP_CTRL0_ENABLE, mxs_mci->regs + HW_SSP_CTRL0);

	/* prepare the command, when no response is expected add a few trailing clocks */
	writel(SSP_CMD0_CMD(cmd->cmdidx) |
		(cmd->resp_type & MMC_RSP_PRESENT ? 0 : SSP_CMD0_APPEND_8CYC),
		mxs_mci->regs + HW_SSP_CMD0);

	/* prepare command's arguments */
	writel(cmd->cmdarg, mxs_mci->regs + HW_SSP_CMD1);

	mxs_mci_setup_timeout(mxs_mci, 0xffff);

	/* start the transfer */
	writel(SSP_CTRL0_RUN, mxs_mci->regs + HW_SSP_CTRL0 + 4);

	/* wait until finished */
	while (readl(mxs_mci->regs + HW_SSP_CTRL0) & SSP_CTRL0_RUN)
		;

	if (cmd->resp_type & MMC_RSP_PRESENT)
		mxs_mci_get_cards_response(mxs_mci, cmd);

	return mxs_mci_get_cmd_error(readl(mxs_mci->regs + HW_SSP_STATUS));
}

/**
 * Handle an "addressed data transfer command " with or without data
 * @param hw_dev Host interface device instance
 * @param cmd The command to handle
 * @param data The data information (buffer, direction aso.) May be NULL
 * @return 0 on success
 */
static int mxs_mci_adtc(struct mxs_mci_host *mxs_mci, struct mci_cmd *cmd,
			struct mci_data *data)
{
	uint32_t xfer_cnt, log2blocksize, block_cnt;
	int err;

	/* Note: 'data' can be NULL! */
	if (data != NULL) {
		xfer_cnt = data->blocks * data->blocksize;
		block_cnt = data->blocks - 1;	/* can be 0 */
		log2blocksize = find_first_bit((const unsigned long*)&data->blocksize,
						32);
	} else
		xfer_cnt = log2blocksize = block_cnt = 0;

	/* setup command and transfer parameters */
#ifdef CONFIG_ARCH_IMX23
	writel(mxs_mci_prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
		SSP_CTRL0_BUS_WIDTH(mxs_mci->bus_width) |
		(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
		SSP_CTRL0_ENABLE |
		SSP_CTRL0_XFER_COUNT(xfer_cnt), /* byte count to be transfered */
		mxs_mci->regs + HW_SSP_CTRL0);

	/* prepare the command and the transfered data count */
	writel(SSP_CMD0_CMD(cmd->cmdidx) |
		SSP_CMD0_BLOCK_SIZE(log2blocksize) |
		SSP_CMD0_BLOCK_COUNT(block_cnt) |
		(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
		mxs_mci->regs + HW_SSP_CMD0);
#endif
#ifdef CONFIG_ARCH_IMX28
	writel(mxs_mci_prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
		SSP_CTRL0_BUS_WIDTH(mxs_mci->bus_width) |
		(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
		SSP_CTRL0_ENABLE,
		mxs_mci->regs + HW_SSP_CTRL0);
	writel(xfer_cnt, mxs_mci->regs + HW_SSP_XFER_COUNT);

	/* prepare the command and the transfered data count */
	writel(SSP_CMD0_CMD(cmd->cmdidx) |
		(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
		mxs_mci->regs + HW_SSP_CMD0);
	writel(SSP_BLOCK_SIZE(log2blocksize) |
		SSP_BLOCK_COUNT(block_cnt),
		mxs_mci->regs + HW_SSP_BLOCK_SIZE);
#endif

	/* prepare command's arguments */
	writel(cmd->cmdarg, mxs_mci->regs + HW_SSP_CMD1);

	mxs_mci_setup_timeout(mxs_mci, 0xffff);

	err = mxs_mci_transfer_data(mxs_mci, data);
	if (err != 0) {
		pr_debug(" Transfering data failed\n");
		return err;
	}

	/* wait until finished */
	while (readl(mxs_mci->regs + HW_SSP_CTRL0) & SSP_CTRL0_RUN)
		;

	mxs_mci_get_cards_response(mxs_mci, cmd);

	return 0;
}


/**
 * @param hw_dev Host interface device instance
 * @param nc New Clock in [Hz] (may be 0 to disable the clock)
 * @return The real clock frequency
 *
 * The SSP unit clock can base on the external 24 MHz or the internal 480 MHz
 * Its unit clock value is derived from the io clock, from the SSP divider
 * and at least the SSP bus clock itself is derived from the SSP unit's divider
 *
 * @code
 * |------------------- generic -------------|-peripheral specific-|-----all SSPs-----|-per SSP unit-|
 *  24 MHz ----------------------------
 *          \                          \
 *           \                          |----| FRAC |----IO CLK----| SSP unit DIV |---| SSP DIV |--- SSP output clock
 *            \- | PLL |--- 480 MHz ---/
 * @endcode
 *
 * @note Up to "SSP unit DIV" the outer world must care. This routine only
 * handles the "SSP DIV".
 */
static unsigned mxs_mci_setup_clock_speed(struct mxs_mci_host *mxs_mci, unsigned nc)
{
	unsigned ssp, div, rate, reg;

	if (nc == 0U) {
		/* TODO stop the clock */
		return 0;
	}

	ssp = mxs_mci_get_unit_clock(mxs_mci);

	for (div = 2; div < 255; div += 2) {
		rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ssp, nc), div);
		if (rate <= 0x100)
			break;
	}
	if (div >= 255) {
		pr_warning("Cannot set clock to %d Hz\n", nc);
		return 0;
	}

	reg = readl(mxs_mci->regs + HW_SSP_TIMING) & SSP_TIMING_TIMEOUT_MASK;
	reg |= SSP_TIMING_CLOCK_DIVIDE(div) | SSP_TIMING_CLOCK_RATE(rate - 1);
	writel(reg, mxs_mci->regs + HW_SSP_TIMING);

	return ssp / div / rate;
}

/**
 * Reset the MCI engine (the hard way)
 * @param hw_dev Host interface instance
 *
 * This will reset everything in all registers of this unit! (FIXME)
 */
static void mxs_mci_reset(struct mxs_mci_host *mxs_mci)
{
	writel(SSP_CTRL0_SFTRST, mxs_mci->regs + HW_SSP_CTRL0 + 8);
	while (readl(mxs_mci->regs + HW_SSP_CTRL0) & SSP_CTRL0_SFTRST)
		;
}

/* ------------------------- MCI API -------------------------------------- */

/**
 * Keep the attached MMC/SD unit in a well know state
 * @param mci_pdata MCI platform data
 * @param mci_dev MCI device instance
 * @return 0 on success, negative value else
 */
static int mxs_mci_initialize(struct mci_host *host, struct device_d *mci_dev)
{
	struct mxs_mci_host *mxs_mci = to_mxs_mci(host);

	/* enable the clock to this unit to be able to reset it */
	writel(SSP_CTRL0_CLKGATE, mxs_mci->regs + HW_SSP_CTRL0 + 8);

	/* reset the unit */
	mxs_mci_reset(mxs_mci);

	/* restore the last settings */
	mxs_mci_setup_timeout(mxs_mci, 0xffff);
	writel(SSP_CTRL0_IGNORE_CRC |
		SSP_CTRL0_BUS_WIDTH(mxs_mci->bus_width),
		mxs_mci->regs + HW_SSP_CTRL0);
	writel(SSP_CTRL1_POLARITY |
		SSP_CTRL1_SSP_MODE(3) |
		SSP_CTRL1_WORD_LENGTH(7), mxs_mci->regs + HW_SSP_CTRL1);

	return 0;
}

/**
 * Process one command to the MCI card
 * @param mci_pdata MCI platform data
 * @param cmd The command to process
 * @param data The data to handle in the command (can be NULL)
 * @return 0 on success, negative value else
 */
static int mxs_mci_request(struct mci_host *host, struct mci_cmd *cmd,
			struct mci_data *data)
{
	struct mxs_mci_host *mxs_mci = to_mxs_mci(host);
	int rc;

	if ((cmd->resp_type == 0) || (data == NULL))
		rc = mxs_mci_std_cmds(mxs_mci, cmd);
	else
		rc = mxs_mci_adtc(mxs_mci, cmd, data);	/* with response and data */

	mxs_mci_finish_request(mxs_mci);	/* TODO */
	return rc;
}

/**
 * Setup the bus width and IO speed
 * @param mci_pdata MCI platform data
 * @param mci_dev MCI device instance
 * @param bus_width New bus width value (1, 4 or 8)
 * @param clock New clock in Hz (can be '0' to disable the clock)
 *
 * Drivers currently realized values are stored in MCI's platformdata
 */
static void mxs_mci_set_ios(struct mci_host *host, struct device_d *mci_dev,
			unsigned bus_width, unsigned clock)
{
	struct mxs_mci_host *mxs_mci = to_mxs_mci(host);

	switch (bus_width) {
	case 8:
		mxs_mci->bus_width = 2;
		host->bus_width = 8;	/* 8 bit is possible */
		break;
	case 4:
		mxs_mci->bus_width = 1;
		host->bus_width = 4;	/* 4 bit is possible */
		break;
	default:
		mxs_mci->bus_width = 0;
		host->bus_width = 1;	/* 1 bit is possible */
		break;
	}

	mxs_mci->clock = mxs_mci_setup_clock_speed(mxs_mci, clock);
	pr_debug("IO settings: bus width=%d, frequency=%u Hz\n", host->bus_width,
			mxs_mci->clock);
}

/* ----------------------------------------------------------------------- */

#ifdef CONFIG_MCI_INFO
const unsigned char bus_width[3] = { 1, 4, 8 };

static void mxs_mci_info(struct device_d *hw_dev)
{
	struct mxs_mci_host *mxs_mci = GET_HOST_DATA(hw_dev);

	printf(" Interface\n");
	printf("  Min. bus clock: %u Hz\n", mxs_mci->f_min);
	printf("  Max. bus clock: %u Hz\n", mxs_mci->f_max);
	printf("  Current bus clock: %u Hz\n", mxs_mci->clock);
	printf("  Bus width: %u bit\n", bus_width[mxs_mci->bus_width]);
	printf("\n");
}
#endif

static int mxs_mci_probe(struct device_d *hw_dev)
{
	struct mxs_mci_platform_data *pd = hw_dev->platform_data;
	struct mxs_mci_host *mxs_mci;
	struct mci_host *host;

	if (hw_dev->platform_data == NULL) {
		pr_err("Missing platform data\n");
		return -EINVAL;
	}

	mxs_mci = xzalloc(sizeof(*mxs_mci));
	host = &mxs_mci->host;

	hw_dev->priv = mxs_mci;
	host->hw_dev = hw_dev;
	host->send_cmd = mxs_mci_request,
	host->set_ios = mxs_mci_set_ios,
	host->init = mxs_mci_initialize,
	mxs_mci->regs = (void *)hw_dev->map_base;

	/* feed forward the platform specific values */
	host->voltages = pd->voltages;
	host->host_caps = pd->caps;

#ifdef CONFIG_ARCH_IMX23
	mxs_mci->index = 0;	/* there is only one clock for all */
#endif
#ifdef CONFIG_ARCH_IMX28
	/* one dedicated clock per unit */
	switch (hw_dev->map_base) {
	case IMX_SSP0_BASE:
		mxs_mci->index = 0;
		break;
	case IMX_SSP1_BASE:
		mxs_mci->index = 1;
		break;
	case IMX_SSP2_BASE:
		mxs_mci->index = 2;
		break;
	case IMX_SSP3_BASE:
		mxs_mci->index = 3;
		break;
	default:
		pr_debug("Unknown SSP unit at address 0x%08x\n", mxs_mci->regs);
		return 0;
	}
#endif
	if (pd->f_min == 0) {
		host->f_min = mxs_mci_get_unit_clock(mxs_mci) / 254 / 256;
		pr_debug("Min. frequency is %u Hz\n", host->f_min);
	} else {
		host->f_min = pd->f_min;
		pr_debug("Min. frequency is %u Hz, could be %u Hz\n",
			host->f_min, mxs_mci_get_unit_clock(mxs_mci) / 254 / 256);
	}
	if (pd->f_max == 0) {
		host->f_max = mxs_mci_get_unit_clock(mxs_mci) / 2 / 1;
		pr_debug("Max. frequency is %u Hz\n", host->f_max);
	} else {
		host->f_max =  pd->f_max;
		pr_debug("Max. frequency is %u Hz, could be %u Hz\n",
			host->f_max, mxs_mci_get_unit_clock(mxs_mci) / 2 / 1);
	}

#ifdef CONFIG_MCI_INFO
	mxs_mci->f_min = host->f_min;
	mxs_mci->f_max = host->f_max;
#endif

	return mci_register(host);
}

static struct driver_d mxs_mci_driver = {
        .name  = "mxs_mci",
        .probe = mxs_mci_probe,
#ifdef CONFIG_MCI_INFO
	.info = mxs_mci_info,
#endif
};

static int mxs_mci_init_driver(void)
{
        register_driver(&mxs_mci_driver);
        return 0;
}

device_initcall(mxs_mci_init_driver);
