// SPDX-License-Identifier: GPL-2.0-only
/* Realtek USB SD/MMC Card Interface driver
 *
 * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
 *
 * Author:
 *   Roger Tseng <rogerable@realtek.com>
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/usb.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sd.h>
#include <linux/mmc/card.h>
#include <linux/scatterlist.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>

#include <linux/rtsx_usb.h>
#include <asm/unaligned.h>

#if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \
		defined(CONFIG_MMC_REALTEK_USB_MODULE))
#include <linux/leds.h>
#include <linux/workqueue.h>
#define RTSX_USB_USE_LEDS_CLASS
#endif

struct rtsx_usb_sdmmc {
	struct platform_device	*pdev;
	struct rtsx_ucr	*ucr;
	struct mmc_host		*mmc;
	struct mmc_request	*mrq;

	struct mutex		host_mutex;

	u8			ssc_depth;
	unsigned int		clock;
	bool			vpclk;
	bool			double_clk;
	bool			host_removal;
	bool			card_exist;
	bool			initial_mode;
	bool			ddr_mode;

	unsigned char		power_mode;

#ifdef RTSX_USB_USE_LEDS_CLASS
	struct led_classdev	led;
	char			led_name[32];
	struct work_struct	led_work;
#endif
};

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

static inline void sd_clear_error(struct rtsx_usb_sdmmc *host)
{
	struct rtsx_ucr *ucr = host->ucr;
	rtsx_usb_ep0_write_register(ucr, CARD_STOP,
				  SD_STOP | SD_CLR_ERR,
				  SD_STOP | SD_CLR_ERR);

	rtsx_usb_clear_dma_err(ucr);
	rtsx_usb_clear_fsm_err(ucr);
}

#ifdef DEBUG
static void sd_print_debug_regs(struct rtsx_usb_sdmmc *host)
{
	struct rtsx_ucr *ucr = host->ucr;
	u8 val = 0;

	rtsx_usb_ep0_read_register(ucr, SD_STAT1, &val);
	dev_dbg(sdmmc_dev(host), "SD_STAT1: 0x%x\n", val);
	rtsx_usb_ep0_read_register(ucr, SD_STAT2, &val);
	dev_dbg(sdmmc_dev(host), "SD_STAT2: 0x%x\n", val);
	rtsx_usb_ep0_read_register(ucr, SD_BUS_STAT, &val);
	dev_dbg(sdmmc_dev(host), "SD_BUS_STAT: 0x%x\n", val);
}
#else
#define sd_print_debug_regs(host)
#endif /* DEBUG */

static int sd_read_data(struct rtsx_usb_sdmmc *host, struct mmc_command *cmd,
	       u16 byte_cnt, u8 *buf, int buf_len, int timeout)
{
	struct rtsx_ucr *ucr = host->ucr;
	int err;
	u8 trans_mode;

	if (!buf)
		buf_len = 0;

	rtsx_usb_init_cmd(ucr);
	if (cmd != NULL) {
		dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__
				, cmd->opcode);
		if (cmd->opcode == MMC_SEND_TUNING_BLOCK)
			trans_mode = SD_TM_AUTO_TUNING;
		else
			trans_mode = SD_TM_NORMAL_READ;

		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CMD0, 0xFF, (u8)(cmd->opcode) | 0x40);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CMD1, 0xFF, (u8)(cmd->arg >> 24));
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CMD2, 0xFF, (u8)(cmd->arg >> 16));
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CMD3, 0xFF, (u8)(cmd->arg >> 8));
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CMD4, 0xFF, (u8)cmd->arg);
	} else {
		trans_mode = SD_TM_AUTO_READ_3;
	}

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BYTE_CNT_H,
			0xFF, (u8)(byte_cnt >> 8));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CFG2, 0xFF,
			SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
			SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
	if (trans_mode != SD_TM_AUTO_TUNING)
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_TRANSFER,
			0xFF, trans_mode | SD_TRANSFER_START);
	rtsx_usb_add_cmd(ucr, CHECK_REG_CMD, SD_TRANSFER,
			SD_TRANSFER_END, SD_TRANSFER_END);

	if (cmd != NULL) {
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, SD_CMD1, 0, 0);
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, SD_CMD2, 0, 0);
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, SD_CMD3, 0, 0);
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, SD_CMD4, 0, 0);
	}

	err = rtsx_usb_send_cmd(ucr, MODE_CR, timeout);
	if (err) {
		dev_dbg(sdmmc_dev(host),
			"rtsx_usb_send_cmd failed (err = %d)\n", err);
		return err;
	}

	err = rtsx_usb_get_rsp(ucr, !cmd ? 1 : 5, timeout);
	if (err || (ucr->rsp_buf[0] & SD_TRANSFER_ERR)) {
		sd_print_debug_regs(host);

		if (!err) {
			dev_dbg(sdmmc_dev(host),
				"Transfer failed (SD_TRANSFER = %02x)\n",
				ucr->rsp_buf[0]);
			err = -EIO;
		} else {
			dev_dbg(sdmmc_dev(host),
				"rtsx_usb_get_rsp failed (err = %d)\n", err);
		}

		return err;
	}

	if (cmd != NULL) {
		cmd->resp[0] = get_unaligned_be32(ucr->rsp_buf + 1);
		dev_dbg(sdmmc_dev(host), "cmd->resp[0] = 0x%08x\n",
				cmd->resp[0]);
	}

	if (buf && buf_len) {
		/* 2-byte aligned part */
		err = rtsx_usb_read_ppbuf(ucr, buf, byte_cnt - (byte_cnt % 2));
		if (err) {
			dev_dbg(sdmmc_dev(host),
				"rtsx_usb_read_ppbuf failed (err = %d)\n", err);
			return err;
		}

		/* unaligned byte */
		if (byte_cnt % 2)
			return rtsx_usb_read_register(ucr,
					PPBUF_BASE2 + byte_cnt,
					buf + byte_cnt - 1);
	}

	return 0;
}

static int sd_write_data(struct rtsx_usb_sdmmc *host, struct mmc_command *cmd,
		u16 byte_cnt, u8 *buf, int buf_len, int timeout)
{
	struct rtsx_ucr *ucr = host->ucr;
	int err;
	u8 trans_mode;

	if (!buf)
		buf_len = 0;

	if (buf && buf_len) {
		err = rtsx_usb_write_ppbuf(ucr, buf, buf_len);
		if (err) {
			dev_dbg(sdmmc_dev(host),
				"rtsx_usb_write_ppbuf failed (err = %d)\n",
				err);
			return err;
		}
	}

	trans_mode = (cmd != NULL) ? SD_TM_AUTO_WRITE_2 : SD_TM_AUTO_WRITE_3;
	rtsx_usb_init_cmd(ucr);

	if (cmd != NULL) {
		dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__,
				cmd->opcode);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CMD0, 0xFF, (u8)(cmd->opcode) | 0x40);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CMD1, 0xFF, (u8)(cmd->arg >> 24));
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CMD2, 0xFF, (u8)(cmd->arg >> 16));
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CMD3, 0xFF, (u8)(cmd->arg >> 8));
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CMD4, 0xFF, (u8)cmd->arg);
	}

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BYTE_CNT_H,
			0xFF, (u8)(byte_cnt >> 8));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CFG2, 0xFF,
		SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
		SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
			CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
			trans_mode | SD_TRANSFER_START);
	rtsx_usb_add_cmd(ucr, CHECK_REG_CMD, SD_TRANSFER,
			SD_TRANSFER_END, SD_TRANSFER_END);

	if (cmd != NULL) {
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, SD_CMD1, 0, 0);
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, SD_CMD2, 0, 0);
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, SD_CMD3, 0, 0);
		rtsx_usb_add_cmd(ucr, READ_REG_CMD, SD_CMD4, 0, 0);
	}

	err = rtsx_usb_send_cmd(ucr, MODE_CR, timeout);
	if (err) {
		dev_dbg(sdmmc_dev(host),
			"rtsx_usb_send_cmd failed (err = %d)\n", err);
		return err;
	}

	err = rtsx_usb_get_rsp(ucr, !cmd ? 1 : 5, timeout);
	if (err) {
		sd_print_debug_regs(host);
		dev_dbg(sdmmc_dev(host),
			"rtsx_usb_get_rsp failed (err = %d)\n", err);
		return err;
	}

	if (cmd != NULL) {
		cmd->resp[0] = get_unaligned_be32(ucr->rsp_buf + 1);
		dev_dbg(sdmmc_dev(host), "cmd->resp[0] = 0x%08x\n",
				cmd->resp[0]);
	}

	return 0;
}

static void sd_send_cmd_get_rsp(struct rtsx_usb_sdmmc *host,
		struct mmc_command *cmd)
{
	struct rtsx_ucr *ucr = host->ucr;
	u8 cmd_idx = (u8)cmd->opcode;
	u32 arg = cmd->arg;
	int err = 0;
	int timeout = 100;
	int i;
	u8 *ptr;
	int stat_idx = 0;
	int len = 2;
	u8 rsp_type;

	dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n",
			__func__, cmd_idx, arg);

	/* Response type:
	 * R0
	 * R1, R5, R6, R7
	 * R1b
	 * R2
	 * R3, R4
	 */
	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_NONE:
		rsp_type = SD_RSP_TYPE_R0;
		break;
	case MMC_RSP_R1:
		rsp_type = SD_RSP_TYPE_R1;
		break;
	case MMC_RSP_R1_NO_CRC:
		rsp_type = SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7;
		break;
	case MMC_RSP_R1B:
		rsp_type = SD_RSP_TYPE_R1b;
		break;
	case MMC_RSP_R2:
		rsp_type = SD_RSP_TYPE_R2;
		break;
	case MMC_RSP_R3:
		rsp_type = SD_RSP_TYPE_R3;
		break;
	default:
		dev_dbg(sdmmc_dev(host), "cmd->flag is not valid\n");
		err = -EINVAL;
		goto out;
	}

	if (rsp_type == SD_RSP_TYPE_R1b)
		timeout = cmd->busy_timeout ? cmd->busy_timeout : 3000;

	if (cmd->opcode == SD_SWITCH_VOLTAGE) {
		err = rtsx_usb_write_register(ucr, SD_BUS_STAT,
				SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP,
				SD_CLK_TOGGLE_EN);
		if (err)
			goto out;
	}

	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8)(arg >> 24));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8)(arg >> 16));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8)(arg >> 8));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8)arg);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DATA_SOURCE,
			0x01, PINGPONG_BUFFER);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_TRANSFER,
			0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START);
	rtsx_usb_add_cmd(ucr, CHECK_REG_CMD, SD_TRANSFER,
		     SD_TRANSFER_END | SD_STAT_IDLE,
		     SD_TRANSFER_END | SD_STAT_IDLE);

	if (rsp_type == SD_RSP_TYPE_R2) {
		/* Read data from ping-pong buffer */
		for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++)
			rtsx_usb_add_cmd(ucr, READ_REG_CMD, (u16)i, 0, 0);
		stat_idx = 16;
	} else if (rsp_type != SD_RSP_TYPE_R0) {
		/* Read data from SD_CMDx registers */
		for (i = SD_CMD0; i <= SD_CMD4; i++)
			rtsx_usb_add_cmd(ucr, READ_REG_CMD, (u16)i, 0, 0);
		stat_idx = 5;
	}
	len += stat_idx;

	rtsx_usb_add_cmd(ucr, READ_REG_CMD, SD_STAT1, 0, 0);

	err = rtsx_usb_send_cmd(ucr, MODE_CR, 100);
	if (err) {
		dev_dbg(sdmmc_dev(host),
			"rtsx_usb_send_cmd error (err = %d)\n", err);
		goto out;
	}

	err = rtsx_usb_get_rsp(ucr, len, timeout);
	if (err || (ucr->rsp_buf[0] & SD_TRANSFER_ERR)) {
		sd_print_debug_regs(host);
		sd_clear_error(host);

		if (!err) {
			dev_dbg(sdmmc_dev(host),
				"Transfer failed (SD_TRANSFER = %02x)\n",
					ucr->rsp_buf[0]);
			err = -EIO;
		} else {
			dev_dbg(sdmmc_dev(host),
				"rtsx_usb_get_rsp failed (err = %d)\n", err);
		}

		goto out;
	}

	if (rsp_type == SD_RSP_TYPE_R0) {
		err = 0;
		goto out;
	}

	/* Skip result of CHECK_REG_CMD */
	ptr = ucr->rsp_buf + 1;

	/* Check (Start,Transmission) bit of Response */
	if ((ptr[0] & 0xC0) != 0) {
		err = -EILSEQ;
		dev_dbg(sdmmc_dev(host), "Invalid response bit\n");
		goto out;
	}

	/* Check CRC7 */
	if (!(rsp_type & SD_NO_CHECK_CRC7)) {
		if (ptr[stat_idx] & SD_CRC7_ERR) {
			err = -EILSEQ;
			dev_dbg(sdmmc_dev(host), "CRC7 error\n");
			goto out;
		}
	}

	if (rsp_type == SD_RSP_TYPE_R2) {
		/*
		 * The controller offloads the last byte {CRC-7, end bit 1'b1}
		 * of response type R2. Assign dummy CRC, 0, and end bit to the
		 * byte(ptr[16], goes into the LSB of resp[3] later).
		 */
		ptr[16] = 1;

		for (i = 0; i < 4; i++) {
			cmd->resp[i] = get_unaligned_be32(ptr + 1 + i * 4);
			dev_dbg(sdmmc_dev(host), "cmd->resp[%d] = 0x%08x\n",
					i, cmd->resp[i]);
		}
	} else {
		cmd->resp[0] = get_unaligned_be32(ptr + 1);
		dev_dbg(sdmmc_dev(host), "cmd->resp[0] = 0x%08x\n",
				cmd->resp[0]);
	}

out:
	cmd->error = err;
}

static int sd_rw_multi(struct rtsx_usb_sdmmc *host, struct mmc_request *mrq)
{
	struct rtsx_ucr *ucr = host->ucr;
	struct mmc_data *data = mrq->data;
	int read = (data->flags & MMC_DATA_READ) ? 1 : 0;
	u8 cfg2, trans_mode;
	int err;
	u8 flag;
	size_t data_len = data->blksz * data->blocks;
	unsigned int pipe;

	if (read) {
		dev_dbg(sdmmc_dev(host), "%s: read %zu bytes\n",
				__func__, data_len);
		cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 |
			SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0;
		trans_mode = SD_TM_AUTO_READ_3;
	} else {
		dev_dbg(sdmmc_dev(host), "%s: write %zu bytes\n",
				__func__, data_len);
		cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 |
			SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0;
		trans_mode = SD_TM_AUTO_WRITE_3;
	}

	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BLOCK_CNT_L,
			0xFF, (u8)data->blocks);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BLOCK_CNT_H,
			0xFF, (u8)(data->blocks >> 8));

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DATA_SOURCE,
			0x01, RING_BUFFER);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC3,
			0xFF, (u8)(data_len >> 24));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC2,
			0xFF, (u8)(data_len >> 16));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC1,
			0xFF, (u8)(data_len >> 8));
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC0,
			0xFF, (u8)data_len);
	if (read) {
		flag = MODE_CDIR;
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_CTL,
				0x03 | DMA_PACK_SIZE_MASK,
				DMA_DIR_FROM_CARD | DMA_EN | DMA_512);
	} else {
		flag = MODE_CDOR;
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_CTL,
				0x03 | DMA_PACK_SIZE_MASK,
				DMA_DIR_TO_CARD | DMA_EN | DMA_512);
	}

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_TRANSFER, 0xFF,
			trans_mode | SD_TRANSFER_START);
	rtsx_usb_add_cmd(ucr, CHECK_REG_CMD, SD_TRANSFER,
			SD_TRANSFER_END, SD_TRANSFER_END);

	err = rtsx_usb_send_cmd(ucr, flag, 100);
	if (err)
		return err;

	if (read)
		pipe = usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN);
	else
		pipe = usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT);

	err = rtsx_usb_transfer_data(ucr, pipe, data->sg, data_len,
			data->sg_len,  NULL, 10000);
	if (err) {
		dev_dbg(sdmmc_dev(host), "rtsx_usb_transfer_data error %d\n"
				, err);
		sd_clear_error(host);
		return err;
	}

	return rtsx_usb_get_rsp(ucr, 1, 2000);
}

static inline void sd_enable_initial_mode(struct rtsx_usb_sdmmc *host)
{
	rtsx_usb_write_register(host->ucr, SD_CFG1,
			SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128);
}

static inline void sd_disable_initial_mode(struct rtsx_usb_sdmmc *host)
{
	rtsx_usb_write_register(host->ucr, SD_CFG1,
			SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0);
}

static void sd_normal_rw(struct rtsx_usb_sdmmc *host,
		struct mmc_request *mrq)
{
	struct mmc_command *cmd = mrq->cmd;
	struct mmc_data *data = mrq->data;
	u8 *buf;

	buf = kzalloc(data->blksz, GFP_NOIO);
	if (!buf) {
		cmd->error = -ENOMEM;
		return;
	}

	if (data->flags & MMC_DATA_READ) {
		if (host->initial_mode)
			sd_disable_initial_mode(host);

		cmd->error = sd_read_data(host, cmd, (u16)data->blksz, buf,
				data->blksz, 200);

		if (host->initial_mode)
			sd_enable_initial_mode(host);

		sg_copy_from_buffer(data->sg, data->sg_len, buf, data->blksz);
	} else {
		sg_copy_to_buffer(data->sg, data->sg_len, buf, data->blksz);

		cmd->error = sd_write_data(host, cmd, (u16)data->blksz, buf,
				data->blksz, 200);
	}

	kfree(buf);
}

static int sd_change_phase(struct rtsx_usb_sdmmc *host, u8 sample_point, int tx)
{
	struct rtsx_ucr *ucr = host->ucr;

	dev_dbg(sdmmc_dev(host), "%s: %s sample_point = %d\n",
			__func__, tx ? "TX" : "RX", sample_point);

	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, CLK_CHANGE);

	if (tx)
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_VPCLK0_CTL,
				0x0F, sample_point);
	else
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_VPCLK1_CTL,
				0x0F, sample_point);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_VPCLK0_CTL,
			PHASE_NOT_RESET, PHASE_NOT_RESET);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, 0);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CFG1, SD_ASYNC_FIFO_RST, 0);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static inline u32 get_phase_point(u32 phase_map, unsigned int idx)
{
	idx &= MAX_PHASE;
	return phase_map & (1 << idx);
}

static int get_phase_len(u32 phase_map, unsigned int idx)
{
	int i;

	for (i = 0; i < MAX_PHASE + 1; i++) {
		if (get_phase_point(phase_map, idx + i) == 0)
			return i;
	}
	return MAX_PHASE + 1;
}

static u8 sd_search_final_phase(struct rtsx_usb_sdmmc *host, u32 phase_map)
{
	int start = 0, len = 0;
	int start_final = 0, len_final = 0;
	u8 final_phase = 0xFF;

	if (phase_map == 0) {
		dev_dbg(sdmmc_dev(host), "Phase: [map:%x]\n", phase_map);
		return final_phase;
	}

	while (start < MAX_PHASE + 1) {
		len = get_phase_len(phase_map, start);
		if (len_final < len) {
			start_final = start;
			len_final = len;
		}
		start += len ? len : 1;
	}

	final_phase = (start_final + len_final / 2) & MAX_PHASE;
	dev_dbg(sdmmc_dev(host), "Phase: [map:%x] [maxlen:%d] [final:%d]\n",
		phase_map, len_final, final_phase);

	return final_phase;
}

static void sd_wait_data_idle(struct rtsx_usb_sdmmc *host)
{
	int i;
	u8 val = 0;

	for (i = 0; i < 100; i++) {
		rtsx_usb_ep0_read_register(host->ucr, SD_DATA_STATE, &val);
		if (val & SD_DATA_IDLE)
			return;

		usleep_range(100, 1000);
	}
}

static int sd_tuning_rx_cmd(struct rtsx_usb_sdmmc *host,
		u8 opcode, u8 sample_point)
{
	int err;
	struct mmc_command cmd = {};

	err = sd_change_phase(host, sample_point, 0);
	if (err)
		return err;

	cmd.opcode = MMC_SEND_TUNING_BLOCK;
	err = sd_read_data(host, &cmd, 0x40, NULL, 0, 100);
	if (err) {
		/* Wait till SD DATA IDLE */
		sd_wait_data_idle(host);
		sd_clear_error(host);
		return err;
	}

	return 0;
}

static void sd_tuning_phase(struct rtsx_usb_sdmmc *host,
		u8 opcode, u16 *phase_map)
{
	int err, i;
	u16 raw_phase_map = 0;

	for (i = MAX_PHASE; i >= 0; i--) {
		err = sd_tuning_rx_cmd(host, opcode, (u8)i);
		if (!err)
			raw_phase_map |= 1 << i;
	}

	if (phase_map)
		*phase_map = raw_phase_map;
}

static int sd_tuning_rx(struct rtsx_usb_sdmmc *host, u8 opcode)
{
	int err, i;
	u16 raw_phase_map[RX_TUNING_CNT] = {0}, phase_map;
	u8 final_phase;

	/* setting fixed default TX phase */
	err = sd_change_phase(host, 0x01, 1);
	if (err) {
		dev_dbg(sdmmc_dev(host), "TX phase setting failed\n");
		return err;
	}

	/* tuning RX phase */
	for (i = 0; i < RX_TUNING_CNT; i++) {
		sd_tuning_phase(host, opcode, &(raw_phase_map[i]));

		if (raw_phase_map[i] == 0)
			break;
	}

	phase_map = 0xFFFF;
	for (i = 0; i < RX_TUNING_CNT; i++) {
		dev_dbg(sdmmc_dev(host), "RX raw_phase_map[%d] = 0x%04x\n",
				i, raw_phase_map[i]);
		phase_map &= raw_phase_map[i];
	}
	dev_dbg(sdmmc_dev(host), "RX phase_map = 0x%04x\n", phase_map);

	if (phase_map) {
		final_phase = sd_search_final_phase(host, phase_map);
		if (final_phase == 0xFF)
			return -EINVAL;

		err = sd_change_phase(host, final_phase, 0);
		if (err)
			return err;
	} else {
		return -EINVAL;
	}

	return 0;
}

static int sdmmc_get_ro(struct mmc_host *mmc)
{
	struct rtsx_usb_sdmmc *host = mmc_priv(mmc);
	struct rtsx_ucr *ucr = host->ucr;
	int err;
	u16 val;

	if (host->host_removal)
		return -ENOMEDIUM;

	mutex_lock(&ucr->dev_mutex);

	/* Check SD card detect */
	err = rtsx_usb_get_card_status(ucr, &val);

	mutex_unlock(&ucr->dev_mutex);


	/* Treat failed detection as non-ro */
	if (err)
		return 0;

	if (val & SD_WP)
		return 1;

	return 0;
}

static int sdmmc_get_cd(struct mmc_host *mmc)
{
	struct rtsx_usb_sdmmc *host = mmc_priv(mmc);
	struct rtsx_ucr *ucr = host->ucr;
	int err;
	u16 val;

	if (host->host_removal)
		return -ENOMEDIUM;

	mutex_lock(&ucr->dev_mutex);

	/* Check SD card detect */
	err = rtsx_usb_get_card_status(ucr, &val);

	mutex_unlock(&ucr->dev_mutex);

	/* Treat failed detection as non-exist */
	if (err)
		goto no_card;

	if (val & SD_CD) {
		host->card_exist = true;
		return 1;
	}

no_card:
	host->card_exist = false;
	return 0;
}

static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct rtsx_usb_sdmmc *host = mmc_priv(mmc);
	struct rtsx_ucr *ucr = host->ucr;
	struct mmc_command *cmd = mrq->cmd;
	struct mmc_data *data = mrq->data;
	unsigned int data_size = 0;

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

	if (host->host_removal) {
		cmd->error = -ENOMEDIUM;
		goto finish;
	}

	if ((!host->card_exist)) {
		cmd->error = -ENOMEDIUM;
		goto finish_detect_card;
	}

	mutex_lock(&ucr->dev_mutex);

	mutex_lock(&host->host_mutex);
	host->mrq = mrq;
	mutex_unlock(&host->host_mutex);

	if (mrq->data)
		data_size = data->blocks * data->blksz;

	if (!data_size) {
		sd_send_cmd_get_rsp(host, cmd);
	} else if ((!(data_size % 512) && cmd->opcode != MMC_SEND_EXT_CSD) ||
		   mmc_op_multi(cmd->opcode)) {
		sd_send_cmd_get_rsp(host, cmd);

		if (!cmd->error) {
			sd_rw_multi(host, mrq);

			if (mmc_op_multi(cmd->opcode) && mrq->stop) {
				sd_send_cmd_get_rsp(host, mrq->stop);
				rtsx_usb_write_register(ucr, MC_FIFO_CTL,
						FIFO_FLUSH, FIFO_FLUSH);
			}
		}
	} else {
		sd_normal_rw(host, mrq);
	}

	if (mrq->data) {
		if (cmd->error || data->error)
			data->bytes_xfered = 0;
		else
			data->bytes_xfered = data->blocks * data->blksz;
	}

	mutex_unlock(&ucr->dev_mutex);

finish_detect_card:
	if (cmd->error) {
		/*
		 * detect card when fail to update card existence state and
		 * speed up card removal when retry
		 */
		sdmmc_get_cd(mmc);
		dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error);
	}

finish:
	mutex_lock(&host->host_mutex);
	host->mrq = NULL;
	mutex_unlock(&host->host_mutex);

	mmc_request_done(mmc, mrq);
}

static int sd_set_bus_width(struct rtsx_usb_sdmmc *host,
		unsigned char bus_width)
{
	int err = 0;
	static const u8 width[] = {
		[MMC_BUS_WIDTH_1] = SD_BUS_WIDTH_1BIT,
		[MMC_BUS_WIDTH_4] = SD_BUS_WIDTH_4BIT,
		[MMC_BUS_WIDTH_8] = SD_BUS_WIDTH_8BIT,
	};

	if (bus_width <= MMC_BUS_WIDTH_8)
		err = rtsx_usb_write_register(host->ucr, SD_CFG1,
				0x03, width[bus_width]);

	return err;
}

static int sd_pull_ctl_disable_lqfp48(struct rtsx_ucr *ucr)
{
	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static int sd_pull_ctl_disable_qfn24(struct rtsx_ucr *ucr)
{
	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x56);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static int sd_pull_ctl_enable_lqfp48(struct rtsx_ucr *ucr)
{
	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0xAA);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xA9);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static int sd_pull_ctl_enable_qfn24(struct rtsx_ucr *ucr)
{
	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xA5);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x9A);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xA5);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x9A);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x65);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x5A);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static int sd_power_on(struct rtsx_usb_sdmmc *host)
{
	struct rtsx_ucr *ucr = host->ucr;
	int err;

	dev_dbg(sdmmc_dev(host), "%s\n", __func__);
	rtsx_usb_init_cmd(ucr);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_SELECT, 0x07, SD_MOD_SEL);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_SHARE_MODE,
			CARD_SHARE_MASK, CARD_SHARE_SD);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_EN,
			SD_CLK_EN, SD_CLK_EN);
	err = rtsx_usb_send_cmd(ucr, MODE_C, 100);
	if (err)
		return err;

	if (CHECK_PKG(ucr, LQFP48))
		err = sd_pull_ctl_enable_lqfp48(ucr);
	else
		err = sd_pull_ctl_enable_qfn24(ucr);
	if (err)
		return err;

	err = rtsx_usb_write_register(ucr, CARD_PWR_CTL,
			POWER_MASK, PARTIAL_POWER_ON);
	if (err)
		return err;

	usleep_range(800, 1000);

	rtsx_usb_init_cmd(ucr);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
			POWER_MASK|LDO3318_PWR_MASK, POWER_ON|LDO_ON);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_OE,
			SD_OUTPUT_EN, SD_OUTPUT_EN);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static int sd_power_off(struct rtsx_usb_sdmmc *host)
{
	struct rtsx_ucr *ucr = host->ucr;
	int err;

	dev_dbg(sdmmc_dev(host), "%s\n", __func__);
	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
			POWER_MASK, POWER_OFF);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
			POWER_MASK|LDO3318_PWR_MASK, POWER_OFF|LDO_SUSPEND);

	err = rtsx_usb_send_cmd(ucr, MODE_C, 100);
	if (err)
		return err;

	if (CHECK_PKG(ucr, LQFP48))
			return sd_pull_ctl_disable_lqfp48(ucr);
	return sd_pull_ctl_disable_qfn24(ucr);
}

static int sd_set_power_mode(struct rtsx_usb_sdmmc *host,
		unsigned char power_mode)
{
	int err;

	if (power_mode != MMC_POWER_OFF)
		power_mode = MMC_POWER_ON;

	if (power_mode == host->power_mode)
		return 0;

	if (power_mode == MMC_POWER_OFF) {
		err = sd_power_off(host);
		pm_runtime_put_noidle(sdmmc_dev(host));
	} else {
		pm_runtime_get_noresume(sdmmc_dev(host));
		err = sd_power_on(host);
	}

	if (!err)
		host->power_mode = power_mode;

	return err;
}

static int sd_set_timing(struct rtsx_usb_sdmmc *host,
		unsigned char timing, bool *ddr_mode)
{
	struct rtsx_ucr *ucr = host->ucr;

	*ddr_mode = false;

	rtsx_usb_init_cmd(ucr);

	switch (timing) {
	case MMC_TIMING_UHS_SDR104:
	case MMC_TIMING_UHS_SDR50:
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CFG1,
				0x0C | SD_ASYNC_FIFO_RST,
				SD_30_MODE | SD_ASYNC_FIFO_RST);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
				CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
		break;

	case MMC_TIMING_UHS_DDR50:
		*ddr_mode = true;

		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CFG1,
				0x0C | SD_ASYNC_FIFO_RST,
				SD_DDR_MODE | SD_ASYNC_FIFO_RST);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
				CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_PUSH_POINT_CTL,
				DDR_VAR_TX_CMD_DAT, DDR_VAR_TX_CMD_DAT);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL,
				DDR_VAR_RX_DAT | DDR_VAR_RX_CMD,
				DDR_VAR_RX_DAT | DDR_VAR_RX_CMD);
		break;

	case MMC_TIMING_MMC_HS:
	case MMC_TIMING_SD_HS:
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_CFG1,
				0x0C, SD_20_MODE);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
				CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_PUSH_POINT_CTL,
				SD20_TX_SEL_MASK, SD20_TX_14_AHEAD);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL,
				SD20_RX_SEL_MASK, SD20_RX_14_DELAY);
		break;

	default:
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_CFG1, 0x0C, SD_20_MODE);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF,
				CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				SD_PUSH_POINT_CTL, 0xFF, 0);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL,
				SD20_RX_SEL_MASK, SD20_RX_POS_EDGE);
		break;
	}

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

static void sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct rtsx_usb_sdmmc *host = mmc_priv(mmc);
	struct rtsx_ucr *ucr = host->ucr;

	dev_dbg(sdmmc_dev(host), "%s\n", __func__);
	mutex_lock(&ucr->dev_mutex);

	sd_set_power_mode(host, ios->power_mode);
	sd_set_bus_width(host, ios->bus_width);
	sd_set_timing(host, ios->timing, &host->ddr_mode);

	host->vpclk = false;
	host->double_clk = true;

	switch (ios->timing) {
	case MMC_TIMING_UHS_SDR104:
	case MMC_TIMING_UHS_SDR50:
		host->ssc_depth = SSC_DEPTH_2M;
		host->vpclk = true;
		host->double_clk = false;
		break;
	case MMC_TIMING_UHS_DDR50:
	case MMC_TIMING_UHS_SDR25:
		host->ssc_depth = SSC_DEPTH_1M;
		break;
	default:
		host->ssc_depth = SSC_DEPTH_512K;
		break;
	}

	host->initial_mode = (ios->clock <= 1000000) ? true : false;
	host->clock = ios->clock;

	rtsx_usb_switch_clock(host->ucr, host->clock, host->ssc_depth,
			host->initial_mode, host->double_clk, host->vpclk);

	mutex_unlock(&ucr->dev_mutex);
	dev_dbg(sdmmc_dev(host), "%s end\n", __func__);
}

static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct rtsx_usb_sdmmc *host = mmc_priv(mmc);
	struct rtsx_ucr *ucr = host->ucr;
	int err = 0;

	dev_dbg(sdmmc_dev(host), "%s: signal_voltage = %d\n",
			__func__, ios->signal_voltage);

	if (host->host_removal)
		return -ENOMEDIUM;

	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_120)
		return -EPERM;

	mutex_lock(&ucr->dev_mutex);

	err = rtsx_usb_card_exclusive_check(ucr, RTSX_USB_SD_CARD);
	if (err) {
		mutex_unlock(&ucr->dev_mutex);
		return err;
	}

	/* Let mmc core do the busy checking, simply stop the forced-toggle
	 * clock(while issuing CMD11) and switch voltage.
	 */
	rtsx_usb_init_cmd(ucr);

	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_PAD_CTL,
				SD_IO_USING_1V8, SD_IO_USING_3V3);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, LDO_POWER_CFG,
				TUNE_SD18_MASK, TUNE_SD18_3V3);
	} else {
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_BUS_STAT,
				SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP,
				SD_CLK_FORCE_STOP);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_PAD_CTL,
				SD_IO_USING_1V8, SD_IO_USING_1V8);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, LDO_POWER_CFG,
				TUNE_SD18_MASK, TUNE_SD18_1V8);
	}

	err = rtsx_usb_send_cmd(ucr, MODE_C, 100);
	mutex_unlock(&ucr->dev_mutex);

	return err;
}

static int sdmmc_card_busy(struct mmc_host *mmc)
{
	struct rtsx_usb_sdmmc *host = mmc_priv(mmc);
	struct rtsx_ucr *ucr = host->ucr;
	int err;
	u8 stat;
	u8 mask = SD_DAT3_STATUS | SD_DAT2_STATUS | SD_DAT1_STATUS
		| SD_DAT0_STATUS;

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

	mutex_lock(&ucr->dev_mutex);

	err = rtsx_usb_write_register(ucr, SD_BUS_STAT,
			SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP,
			SD_CLK_TOGGLE_EN);
	if (err)
		goto out;

	mdelay(1);

	err = rtsx_usb_read_register(ucr, SD_BUS_STAT, &stat);
	if (err)
		goto out;

	err = rtsx_usb_write_register(ucr, SD_BUS_STAT,
			SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
out:
	mutex_unlock(&ucr->dev_mutex);

	if (err)
		return err;

	/* check if any pin between dat[0:3] is low */
	if ((stat & mask) != mask)
		return 1;
	else
		return 0;
}

static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
	struct rtsx_usb_sdmmc *host = mmc_priv(mmc);
	struct rtsx_ucr *ucr = host->ucr;
	int err = 0;

	if (host->host_removal)
		return -ENOMEDIUM;

	mutex_lock(&ucr->dev_mutex);

	if (!host->ddr_mode)
		err = sd_tuning_rx(host, MMC_SEND_TUNING_BLOCK);

	mutex_unlock(&ucr->dev_mutex);

	return err;
}

static const struct mmc_host_ops rtsx_usb_sdmmc_ops = {
	.request = sdmmc_request,
	.set_ios = sdmmc_set_ios,
	.get_ro = sdmmc_get_ro,
	.get_cd = sdmmc_get_cd,
	.start_signal_voltage_switch = sdmmc_switch_voltage,
	.card_busy = sdmmc_card_busy,
	.execute_tuning = sdmmc_execute_tuning,
};

#ifdef RTSX_USB_USE_LEDS_CLASS
static void rtsx_usb_led_control(struct led_classdev *led,
	enum led_brightness brightness)
{
	struct rtsx_usb_sdmmc *host = container_of(led,
			struct rtsx_usb_sdmmc, led);

	if (host->host_removal)
		return;

	host->led.brightness = brightness;
	schedule_work(&host->led_work);
}

static void rtsx_usb_update_led(struct work_struct *work)
{
	struct rtsx_usb_sdmmc *host =
		container_of(work, struct rtsx_usb_sdmmc, led_work);
	struct rtsx_ucr *ucr = host->ucr;

	pm_runtime_get_noresume(sdmmc_dev(host));
	mutex_lock(&ucr->dev_mutex);

	if (host->power_mode == MMC_POWER_OFF)
		goto out;

	if (host->led.brightness == LED_OFF)
		rtsx_usb_turn_off_led(ucr);
	else
		rtsx_usb_turn_on_led(ucr);

out:
	mutex_unlock(&ucr->dev_mutex);
	pm_runtime_put_sync_suspend(sdmmc_dev(host));
}
#endif

static void rtsx_usb_init_host(struct rtsx_usb_sdmmc *host)
{
	struct mmc_host *mmc = host->mmc;

	mmc->f_min = 250000;
	mmc->f_max = 208000000;
	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED |
		MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST |
		MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 |
		MMC_CAP_SYNC_RUNTIME_PM;
	mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE |
		MMC_CAP2_NO_SDIO;

	mmc->max_current_330 = 400;
	mmc->max_current_180 = 800;
	mmc->ops = &rtsx_usb_sdmmc_ops;
	mmc->max_segs = 256;
	mmc->max_seg_size = 65536;
	mmc->max_blk_size = 512;
	mmc->max_blk_count = 65535;
	mmc->max_req_size = 524288;

	host->power_mode = MMC_POWER_OFF;
}

static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
{
	struct mmc_host *mmc;
	struct rtsx_usb_sdmmc *host;
	struct rtsx_ucr *ucr;
#ifdef RTSX_USB_USE_LEDS_CLASS
	int err;
#endif
	int ret;

	ucr = usb_get_intfdata(to_usb_interface(pdev->dev.parent));
	if (!ucr)
		return -ENXIO;

	dev_dbg(&(pdev->dev), ": Realtek USB SD/MMC controller found\n");

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

	host = mmc_priv(mmc);
	host->ucr = ucr;
	host->mmc = mmc;
	host->pdev = pdev;
	platform_set_drvdata(pdev, host);

	mutex_init(&host->host_mutex);
	rtsx_usb_init_host(host);
	pm_runtime_enable(&pdev->dev);

#ifdef RTSX_USB_USE_LEDS_CLASS
	snprintf(host->led_name, sizeof(host->led_name),
		"%s::", mmc_hostname(mmc));
	host->led.name = host->led_name;
	host->led.brightness = LED_OFF;
	host->led.default_trigger = mmc_hostname(mmc);
	host->led.brightness_set = rtsx_usb_led_control;

	err = led_classdev_register(mmc_dev(mmc), &host->led);
	if (err)
		dev_err(&(pdev->dev),
				"Failed to register LED device: %d\n", err);
	INIT_WORK(&host->led_work, rtsx_usb_update_led);

#endif
	ret = mmc_add_host(mmc);
	if (ret) {
#ifdef RTSX_USB_USE_LEDS_CLASS
		led_classdev_unregister(&host->led);
#endif
		mmc_free_host(mmc);
		pm_runtime_disable(&pdev->dev);
		return ret;
	}

	return 0;
}

static void rtsx_usb_sdmmc_drv_remove(struct platform_device *pdev)
{
	struct rtsx_usb_sdmmc *host = platform_get_drvdata(pdev);
	struct mmc_host *mmc;

	if (!host)
		return;

	mmc = host->mmc;
	host->host_removal = true;

	mutex_lock(&host->host_mutex);
	if (host->mrq) {
		dev_dbg(&(pdev->dev),
			"%s: Controller removed during transfer\n",
			mmc_hostname(mmc));
		host->mrq->cmd->error = -ENOMEDIUM;
		if (host->mrq->stop)
			host->mrq->stop->error = -ENOMEDIUM;
		mmc_request_done(mmc, host->mrq);
	}
	mutex_unlock(&host->host_mutex);

	mmc_remove_host(mmc);

#ifdef RTSX_USB_USE_LEDS_CLASS
	cancel_work_sync(&host->led_work);
	led_classdev_unregister(&host->led);
#endif

	mmc_free_host(mmc);
	pm_runtime_disable(&pdev->dev);
	platform_set_drvdata(pdev, NULL);

	dev_dbg(&(pdev->dev),
		": Realtek USB SD/MMC module has been removed\n");
}

#ifdef CONFIG_PM
static int rtsx_usb_sdmmc_runtime_suspend(struct device *dev)
{
	struct rtsx_usb_sdmmc *host = dev_get_drvdata(dev);

	host->mmc->caps &= ~MMC_CAP_NEEDS_POLL;
	return 0;
}

static int rtsx_usb_sdmmc_runtime_resume(struct device *dev)
{
	struct rtsx_usb_sdmmc *host = dev_get_drvdata(dev);

	host->mmc->caps |= MMC_CAP_NEEDS_POLL;
	if (sdmmc_get_cd(host->mmc) == 1)
		mmc_detect_change(host->mmc, 0);
	return 0;
}
#endif

static const struct dev_pm_ops rtsx_usb_sdmmc_dev_pm_ops = {
	SET_RUNTIME_PM_OPS(rtsx_usb_sdmmc_runtime_suspend,
			   rtsx_usb_sdmmc_runtime_resume, NULL)
};

static const struct platform_device_id rtsx_usb_sdmmc_ids[] = {
	{
		.name = "rtsx_usb_sdmmc",
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(platform, rtsx_usb_sdmmc_ids);

static struct platform_driver rtsx_usb_sdmmc_driver = {
	.probe		= rtsx_usb_sdmmc_drv_probe,
	.remove_new	= rtsx_usb_sdmmc_drv_remove,
	.id_table       = rtsx_usb_sdmmc_ids,
	.driver		= {
		.name	= "rtsx_usb_sdmmc",
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
		.pm	= &rtsx_usb_sdmmc_dev_pm_ops,
	},
};
module_platform_driver(rtsx_usb_sdmmc_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Roger Tseng <rogerable@realtek.com>");
MODULE_DESCRIPTION("Realtek USB SD/MMC Card Host Driver");
