/* Driver for Realtek USB card reader
 *
 * Copyright(c) 2009-2013 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 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 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:
 *   Roger Tseng <rogerable@realtek.com>
 */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/usb.h>
#include <linux/platform_device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/rtsx_usb.h>

static int polling_pipe = 1;
module_param(polling_pipe, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(polling_pipe, "polling pipe (0: ctl, 1: bulk)");

static const struct mfd_cell rtsx_usb_cells[] = {
	[RTSX_USB_SD_CARD] = {
		.name = "rtsx_usb_sdmmc",
		.pdata_size = 0,
	},
	[RTSX_USB_MS_CARD] = {
		.name = "rtsx_usb_ms",
		.pdata_size = 0,
	},
};

static void rtsx_usb_sg_timed_out(unsigned long data)
{
	struct rtsx_ucr *ucr = (struct rtsx_ucr *)data;

	dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__);
	usb_sg_cancel(&ucr->current_sg);
}

static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr,
		unsigned int pipe, struct scatterlist *sg, int num_sg,
		unsigned int length, unsigned int *act_len, int timeout)
{
	int ret;

	dev_dbg(&ucr->pusb_intf->dev, "%s: xfer %u bytes, %d entries\n",
			__func__, length, num_sg);
	ret = usb_sg_init(&ucr->current_sg, ucr->pusb_dev, pipe, 0,
			sg, num_sg, length, GFP_NOIO);
	if (ret)
		return ret;

	ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout);
	add_timer(&ucr->sg_timer);
	usb_sg_wait(&ucr->current_sg);
	if (!del_timer_sync(&ucr->sg_timer))
		ret = -ETIMEDOUT;
	else
		ret = ucr->current_sg.status;

	if (act_len)
		*act_len = ucr->current_sg.bytes;

	return ret;
}

int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe,
			      void *buf, unsigned int len, int num_sg,
			      unsigned int *act_len, int timeout)
{
	if (timeout < 600)
		timeout = 600;

	if (num_sg)
		return rtsx_usb_bulk_transfer_sglist(ucr, pipe,
				(struct scatterlist *)buf, num_sg, len, act_len,
				timeout);
	else
		return usb_bulk_msg(ucr->pusb_dev, pipe, buf, len, act_len,
				timeout);
}
EXPORT_SYMBOL_GPL(rtsx_usb_transfer_data);

static inline void rtsx_usb_seq_cmd_hdr(struct rtsx_ucr *ucr,
		u16 addr, u16 len, u8 seq_type)
{
	rtsx_usb_cmd_hdr_tag(ucr);

	ucr->cmd_buf[PACKET_TYPE] = seq_type;
	ucr->cmd_buf[5] = (u8)(len >> 8);
	ucr->cmd_buf[6] = (u8)len;
	ucr->cmd_buf[8] = (u8)(addr >> 8);
	ucr->cmd_buf[9] = (u8)addr;

	if (seq_type == SEQ_WRITE)
		ucr->cmd_buf[STAGE_FLAG] = 0;
	else
		ucr->cmd_buf[STAGE_FLAG] = STAGE_R;
}

static int rtsx_usb_seq_write_register(struct rtsx_ucr *ucr,
		u16 addr, u16 len, u8 *data)
{
	u16 cmd_len = ALIGN(SEQ_WRITE_DATA_OFFSET + len, 4);

	if (!data)
		return -EINVAL;

	if (cmd_len > IOBUF_SIZE)
		return -EINVAL;

	rtsx_usb_seq_cmd_hdr(ucr, addr, len, SEQ_WRITE);
	memcpy(ucr->cmd_buf + SEQ_WRITE_DATA_OFFSET, data, len);

	return rtsx_usb_transfer_data(ucr,
			usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT),
			ucr->cmd_buf, cmd_len, 0, NULL, 100);
}

static int rtsx_usb_seq_read_register(struct rtsx_ucr *ucr,
		u16 addr, u16 len, u8 *data)
{
	int i, ret;
	u16 rsp_len = round_down(len, 4);
	u16 res_len = len - rsp_len;

	if (!data)
		return -EINVAL;

	/* 4-byte aligned part */
	if (rsp_len) {
		rtsx_usb_seq_cmd_hdr(ucr, addr, len, SEQ_READ);
		ret = rtsx_usb_transfer_data(ucr,
				usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT),
				ucr->cmd_buf, 12, 0, NULL, 100);
		if (ret)
			return ret;

		ret = rtsx_usb_transfer_data(ucr,
				usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN),
				data, rsp_len, 0, NULL, 100);
		if (ret)
			return ret;
	}

	/* unaligned part */
	for (i = 0; i < res_len; i++) {
		ret = rtsx_usb_read_register(ucr, addr + rsp_len + i,
				data + rsp_len + i);
		if (ret)
			return ret;
	}

	return 0;
}

int rtsx_usb_read_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len)
{
	return rtsx_usb_seq_read_register(ucr, PPBUF_BASE2, (u16)buf_len, buf);
}
EXPORT_SYMBOL_GPL(rtsx_usb_read_ppbuf);

int rtsx_usb_write_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len)
{
	return rtsx_usb_seq_write_register(ucr, PPBUF_BASE2, (u16)buf_len, buf);
}
EXPORT_SYMBOL_GPL(rtsx_usb_write_ppbuf);

int rtsx_usb_ep0_write_register(struct rtsx_ucr *ucr, u16 addr,
		u8 mask, u8 data)
{
	u16 value, index;

	addr |= EP0_WRITE_REG_CMD << EP0_OP_SHIFT;
	value = swab16(addr);
	index = mask | data << 8;

	return usb_control_msg(ucr->pusb_dev,
			usb_sndctrlpipe(ucr->pusb_dev, 0), RTSX_USB_REQ_REG_OP,
			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			value, index, NULL, 0, 100);
}
EXPORT_SYMBOL_GPL(rtsx_usb_ep0_write_register);

int rtsx_usb_ep0_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data)
{
	u16 value;

	if (!data)
		return -EINVAL;
	*data = 0;

	addr |= EP0_READ_REG_CMD << EP0_OP_SHIFT;
	value = swab16(addr);

	return usb_control_msg(ucr->pusb_dev,
			usb_rcvctrlpipe(ucr->pusb_dev, 0), RTSX_USB_REQ_REG_OP,
			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			value, 0, data, 1, 100);
}
EXPORT_SYMBOL_GPL(rtsx_usb_ep0_read_register);

void rtsx_usb_add_cmd(struct rtsx_ucr *ucr, u8 cmd_type, u16 reg_addr,
		u8 mask, u8 data)
{
	int i;

	if (ucr->cmd_idx < (IOBUF_SIZE - CMD_OFFSET) / 4) {
		i = CMD_OFFSET + ucr->cmd_idx * 4;

		ucr->cmd_buf[i++] = ((cmd_type & 0x03) << 6) |
			(u8)((reg_addr >> 8) & 0x3F);
		ucr->cmd_buf[i++] = (u8)reg_addr;
		ucr->cmd_buf[i++] = mask;
		ucr->cmd_buf[i++] = data;

		ucr->cmd_idx++;
	}
}
EXPORT_SYMBOL_GPL(rtsx_usb_add_cmd);

int rtsx_usb_send_cmd(struct rtsx_ucr *ucr, u8 flag, int timeout)
{
	int ret;

	ucr->cmd_buf[CNT_H] = (u8)(ucr->cmd_idx >> 8);
	ucr->cmd_buf[CNT_L] = (u8)(ucr->cmd_idx);
	ucr->cmd_buf[STAGE_FLAG] = flag;

	ret = rtsx_usb_transfer_data(ucr,
			usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT),
			ucr->cmd_buf, ucr->cmd_idx * 4 + CMD_OFFSET,
			0, NULL, timeout);
	if (ret) {
		rtsx_usb_clear_fsm_err(ucr);
		return ret;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(rtsx_usb_send_cmd);

int rtsx_usb_get_rsp(struct rtsx_ucr *ucr, int rsp_len, int timeout)
{
	if (rsp_len <= 0)
		return -EINVAL;

	rsp_len = ALIGN(rsp_len, 4);

	return rtsx_usb_transfer_data(ucr,
			usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN),
			ucr->rsp_buf, rsp_len, 0, NULL, timeout);
}
EXPORT_SYMBOL_GPL(rtsx_usb_get_rsp);

static int rtsx_usb_get_status_with_bulk(struct rtsx_ucr *ucr, u16 *status)
{
	int ret;

	rtsx_usb_init_cmd(ucr);
	rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_EXIST, 0x00, 0x00);
	rtsx_usb_add_cmd(ucr, READ_REG_CMD, OCPSTAT, 0x00, 0x00);
	ret = rtsx_usb_send_cmd(ucr, MODE_CR, 100);
	if (ret)
		return ret;

	ret = rtsx_usb_get_rsp(ucr, 2, 100);
	if (ret)
		return ret;

	*status = ((ucr->rsp_buf[0] >> 2) & 0x0f) |
		  ((ucr->rsp_buf[1] & 0x03) << 4);

	return 0;
}

int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status)
{
	int ret;

	if (!status)
		return -EINVAL;

	if (polling_pipe == 0)
		ret = usb_control_msg(ucr->pusb_dev,
				usb_rcvctrlpipe(ucr->pusb_dev, 0),
				RTSX_USB_REQ_POLL,
				USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
				0, 0, status, 2, 100);
	else
		ret = rtsx_usb_get_status_with_bulk(ucr, status);

	/* usb_control_msg may return positive when success */
	if (ret < 0)
		return ret;

	return 0;
}
EXPORT_SYMBOL_GPL(rtsx_usb_get_card_status);

static int rtsx_usb_write_phy_register(struct rtsx_ucr *ucr, u8 addr, u8 val)
{
	dev_dbg(&ucr->pusb_intf->dev, "Write 0x%x to phy register 0x%x\n",
			val, addr);

	rtsx_usb_init_cmd(ucr);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VSTAIN, 0xFF, val);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VCONTROL, 0xFF, addr & 0x0F);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VCONTROL,
			0xFF, (addr >> 4) & 0x0F);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01);

	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}

int rtsx_usb_write_register(struct rtsx_ucr *ucr, u16 addr, u8 mask, u8 data)
{
	rtsx_usb_init_cmd(ucr);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, addr, mask, data);
	return rtsx_usb_send_cmd(ucr, MODE_C, 100);
}
EXPORT_SYMBOL_GPL(rtsx_usb_write_register);

int rtsx_usb_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data)
{
	int ret;

	if (data != NULL)
		*data = 0;

	rtsx_usb_init_cmd(ucr);
	rtsx_usb_add_cmd(ucr, READ_REG_CMD, addr, 0, 0);
	ret = rtsx_usb_send_cmd(ucr, MODE_CR, 100);
	if (ret)
		return ret;

	ret = rtsx_usb_get_rsp(ucr, 1, 100);
	if (ret)
		return ret;

	if (data != NULL)
		*data = ucr->rsp_buf[0];

	return 0;
}
EXPORT_SYMBOL_GPL(rtsx_usb_read_register);

static inline u8 double_ssc_depth(u8 depth)
{
	return (depth > 1) ? (depth - 1) : depth;
}

static u8 revise_ssc_depth(u8 ssc_depth, u8 div)
{
	if (div > CLK_DIV_1) {
		if (ssc_depth > div - 1)
			ssc_depth -= (div - 1);
		else
			ssc_depth = SSC_DEPTH_2M;
	}

	return ssc_depth;
}

int rtsx_usb_switch_clock(struct rtsx_ucr *ucr, unsigned int card_clock,
		u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk)
{
	int ret;
	u8 n, clk_divider, mcu_cnt, div;

	if (!card_clock) {
		ucr->cur_clk = 0;
		return 0;
	}

	if (initial_mode) {
		/* We use 250k(around) here, in initial stage */
		clk_divider = SD_CLK_DIVIDE_128;
		card_clock = 30000000;
	} else {
		clk_divider = SD_CLK_DIVIDE_0;
	}

	ret = rtsx_usb_write_register(ucr, SD_CFG1,
			SD_CLK_DIVIDE_MASK, clk_divider);
	if (ret < 0)
		return ret;

	card_clock /= 1000000;
	dev_dbg(&ucr->pusb_intf->dev,
			"Switch card clock to %dMHz\n", card_clock);

	if (!initial_mode && double_clk)
		card_clock *= 2;
	dev_dbg(&ucr->pusb_intf->dev,
			"Internal SSC clock: %dMHz (cur_clk = %d)\n",
			card_clock, ucr->cur_clk);

	if (card_clock == ucr->cur_clk)
		return 0;

	/* Converting clock value into internal settings: n and div */
	n = card_clock - 2;
	if ((card_clock <= 2) || (n > MAX_DIV_N))
		return -EINVAL;

	mcu_cnt = 60/card_clock + 3;
	if (mcu_cnt > 15)
		mcu_cnt = 15;

	/* Make sure that the SSC clock div_n is not less than MIN_DIV_N */

	div = CLK_DIV_1;
	while (n < MIN_DIV_N && div < CLK_DIV_4) {
		n = (n + 2) * 2 - 2;
		div++;
	}
	dev_dbg(&ucr->pusb_intf->dev, "n = %d, div = %d\n", n, div);

	if (double_clk)
		ssc_depth = double_ssc_depth(ssc_depth);

	ssc_depth = revise_ssc_depth(ssc_depth, div);
	dev_dbg(&ucr->pusb_intf->dev, "ssc_depth = %d\n", ssc_depth);

	rtsx_usb_init_cmd(ucr);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, CLK_CHANGE);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV,
			0x3F, (div << 4) | mcu_cnt);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL2,
			SSC_DEPTH_MASK, ssc_depth);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
	if (vpclk) {
		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);
	}

	ret = rtsx_usb_send_cmd(ucr, MODE_C, 2000);
	if (ret < 0)
		return ret;

	ret = rtsx_usb_write_register(ucr, SSC_CTL1, 0xff,
			SSC_RSTB | SSC_8X_EN | SSC_SEL_4M);
	if (ret < 0)
		return ret;

	/* Wait SSC clock stable */
	usleep_range(100, 1000);

	ret = rtsx_usb_write_register(ucr, CLK_DIV, CLK_CHANGE, 0);
	if (ret < 0)
		return ret;

	ucr->cur_clk = card_clock;

	return 0;
}
EXPORT_SYMBOL_GPL(rtsx_usb_switch_clock);

int rtsx_usb_card_exclusive_check(struct rtsx_ucr *ucr, int card)
{
	int ret;
	u16 val;
	u16 cd_mask[] = {
		[RTSX_USB_SD_CARD] = (CD_MASK & ~SD_CD),
		[RTSX_USB_MS_CARD] = (CD_MASK & ~MS_CD)
	};

	ret = rtsx_usb_get_card_status(ucr, &val);
	/*
	 * If get status fails, return 0 (ok) for the exclusive check
	 * and let the flow fail at somewhere else.
	 */
	if (ret)
		return 0;

	if (val & cd_mask[card])
		return -EIO;

	return 0;
}
EXPORT_SYMBOL_GPL(rtsx_usb_card_exclusive_check);

static int rtsx_usb_reset_chip(struct rtsx_ucr *ucr)
{
	int ret;
	u8 val;

	rtsx_usb_init_cmd(ucr);

	if (CHECK_PKG(ucr, LQFP48)) {
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
				LDO3318_PWR_MASK, LDO_SUSPEND);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL,
				FORCE_LDO_POWERB, FORCE_LDO_POWERB);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1,
				0x30, 0x10);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5,
				0x03, 0x01);
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6,
				0x0C, 0x04);
	}

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SYS_DUMMY0, NYET_MSAK, NYET_EN);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CD_DEGLITCH_WIDTH, 0xFF, 0x08);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
			CD_DEGLITCH_EN, XD_CD_DEGLITCH_EN, 0x0);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD30_DRIVE_SEL,
			SD30_DRIVE_MASK, DRIVER_TYPE_D);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
			CARD_DRIVE_SEL, SD20_DRIVE_MASK, 0x0);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, LDO_POWER_CFG, 0xE0, 0x0);

	if (ucr->is_rts5179)
		rtsx_usb_add_cmd(ucr, WRITE_REG_CMD,
				CARD_PULL_CTL5, 0x03, 0x01);

	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DMA1_CTL,
		       EXTEND_DMA1_ASYNC_SIGNAL, EXTEND_DMA1_ASYNC_SIGNAL);
	rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_INT_PEND,
			XD_INT | MS_INT | SD_INT,
			XD_INT | MS_INT | SD_INT);

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

	/* config non-crystal mode */
	rtsx_usb_read_register(ucr, CFG_MODE, &val);
	if ((val & XTAL_FREE) || ((val & CLK_MODE_MASK) == CLK_MODE_NON_XTAL)) {
		ret = rtsx_usb_write_phy_register(ucr, 0xC2, 0x7C);
		if (ret)
			return ret;
	}

	return 0;
}

static int rtsx_usb_init_chip(struct rtsx_ucr *ucr)
{
	int ret;
	u8 val;

	rtsx_usb_clear_fsm_err(ucr);

	/* power on SSC */
	ret = rtsx_usb_write_register(ucr,
			FPDCTL, SSC_POWER_MASK, SSC_POWER_ON);
	if (ret)
		return ret;

	usleep_range(100, 1000);
	ret = rtsx_usb_write_register(ucr, CLK_DIV, CLK_CHANGE, 0x00);
	if (ret)
		return ret;

	/* determine IC version */
	ret = rtsx_usb_read_register(ucr, HW_VERSION, &val);
	if (ret)
		return ret;

	ucr->ic_version = val & HW_VER_MASK;

	/* determine package */
	ret = rtsx_usb_read_register(ucr, CARD_SHARE_MODE, &val);
	if (ret)
		return ret;

	if (val & CARD_SHARE_LQFP_SEL) {
		ucr->package = LQFP48;
		dev_dbg(&ucr->pusb_intf->dev, "Package: LQFP48\n");
	} else {
		ucr->package = QFN24;
		dev_dbg(&ucr->pusb_intf->dev, "Package: QFN24\n");
	}

	/* determine IC variations */
	rtsx_usb_read_register(ucr, CFG_MODE_1, &val);
	if (val & RTS5179) {
		ucr->is_rts5179 = true;
		dev_dbg(&ucr->pusb_intf->dev, "Device is rts5179\n");
	} else {
		ucr->is_rts5179 = false;
	}

	return rtsx_usb_reset_chip(ucr);
}

static int rtsx_usb_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
{
	struct usb_device *usb_dev = interface_to_usbdev(intf);
	struct rtsx_ucr *ucr;
	int ret;

	dev_dbg(&intf->dev,
		": Realtek USB Card Reader found at bus %03d address %03d\n",
		 usb_dev->bus->busnum, usb_dev->devnum);

	ucr = devm_kzalloc(&intf->dev, sizeof(*ucr), GFP_KERNEL);
	if (!ucr)
		return -ENOMEM;

	ucr->pusb_dev = usb_dev;

	ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE,
			GFP_KERNEL, &ucr->iobuf_dma);
	if (!ucr->iobuf)
		return -ENOMEM;

	usb_set_intfdata(intf, ucr);

	ucr->vendor_id = id->idVendor;
	ucr->product_id = id->idProduct;
	ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf;

	mutex_init(&ucr->dev_mutex);

	ucr->pusb_intf = intf;

	/* initialize */
	ret = rtsx_usb_init_chip(ucr);
	if (ret)
		goto out_init_fail;

	/* initialize USB SG transfer timer */
	setup_timer(&ucr->sg_timer, rtsx_usb_sg_timed_out, (unsigned long) ucr);

	ret = mfd_add_devices(&intf->dev, usb_dev->devnum, rtsx_usb_cells,
			ARRAY_SIZE(rtsx_usb_cells), NULL, 0, NULL);
	if (ret)
		goto out_init_fail;

#ifdef CONFIG_PM
	intf->needs_remote_wakeup = 1;
	usb_enable_autosuspend(usb_dev);
#endif

	return 0;

out_init_fail:
	usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
			ucr->iobuf_dma);
	return ret;
}

static void rtsx_usb_disconnect(struct usb_interface *intf)
{
	struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf);

	dev_dbg(&intf->dev, "%s called\n", __func__);

	mfd_remove_devices(&intf->dev);

	usb_set_intfdata(ucr->pusb_intf, NULL);
	usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
			ucr->iobuf_dma);
}

#ifdef CONFIG_PM
static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
{
	dev_dbg(&intf->dev, "%s called with pm message 0x%04x\n",
			__func__, message.event);

	return 0;
}

static int rtsx_usb_resume(struct usb_interface *intf)
{
	return 0;
}

static int rtsx_usb_reset_resume(struct usb_interface *intf)
{
	struct rtsx_ucr *ucr =
		(struct rtsx_ucr *)usb_get_intfdata(intf);

	rtsx_usb_reset_chip(ucr);
	return 0;
}

#else /* CONFIG_PM */

#define rtsx_usb_suspend NULL
#define rtsx_usb_resume NULL
#define rtsx_usb_reset_resume NULL

#endif /* CONFIG_PM */


static int rtsx_usb_pre_reset(struct usb_interface *intf)
{
	struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf);

	mutex_lock(&ucr->dev_mutex);
	return 0;
}

static int rtsx_usb_post_reset(struct usb_interface *intf)
{
	struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf);

	mutex_unlock(&ucr->dev_mutex);
	return 0;
}

static struct usb_device_id rtsx_usb_usb_ids[] = {
	{ USB_DEVICE(0x0BDA, 0x0129) },
	{ USB_DEVICE(0x0BDA, 0x0139) },
	{ USB_DEVICE(0x0BDA, 0x0140) },
	{ }
};
MODULE_DEVICE_TABLE(usb, rtsx_usb_usb_ids);

static struct usb_driver rtsx_usb_driver = {
	.name			= "rtsx_usb",
	.probe			= rtsx_usb_probe,
	.disconnect		= rtsx_usb_disconnect,
	.suspend		= rtsx_usb_suspend,
	.resume			= rtsx_usb_resume,
	.reset_resume		= rtsx_usb_reset_resume,
	.pre_reset		= rtsx_usb_pre_reset,
	.post_reset		= rtsx_usb_post_reset,
	.id_table		= rtsx_usb_usb_ids,
	.supports_autosuspend	= 1,
	.soft_unbind		= 1,
};

module_usb_driver(rtsx_usb_driver);

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