/* Driver for Realtek RTS51xx USB card reader
 *
 * 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:
 *   wwang (wei_wang@realsil.com.cn)
 *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
 * Maintainer:
 *   Edwin Rong (edwin_rong@realsil.com.cn)
 *   No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
 */

#include <linux/blkdev.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/workqueue.h>

#include <scsi/scsi.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_device.h>

#include "debug.h"
#include "rts51x.h"
#include "rts51x_chip.h"
#include "rts51x_card.h"
#include "rts51x_transport.h"
#include "xd.h"
#include "sd.h"
#include "ms.h"

void rts51x_do_remaining_work(struct rts51x_chip *chip)
{
	struct sd_info *sd_card = &(chip->sd_card);
	struct xd_info *xd_card = &(chip->xd_card);
	struct ms_info *ms_card = &(chip->ms_card);

	if (chip->card_ready & SD_CARD) {
		if (sd_card->seq_mode) {
			RTS51X_SET_STAT(chip, STAT_RUN);
			sd_card->counter++;
		} else {
			sd_card->counter = 0;
		}
	}

	if (chip->card_ready & XD_CARD) {
		if (xd_card->delay_write.delay_write_flag) {
			RTS51X_SET_STAT(chip, STAT_RUN);
			xd_card->counter++;
		} else {
			xd_card->counter = 0;
		}
	}

	if (chip->card_ready & MS_CARD) {
		if (CHK_MSPRO(ms_card)) {
			if (ms_card->seq_mode) {
				RTS51X_SET_STAT(chip, STAT_RUN);
				ms_card->counter++;
			} else {
				ms_card->counter = 0;
			}
		} else {
			if (ms_card->delay_write.delay_write_flag) {
				RTS51X_SET_STAT(chip, STAT_RUN);
				ms_card->counter++;
			} else {
				ms_card->counter = 0;
			}
		}
	}

	if (sd_card->counter > POLLING_WAIT_CNT)
		rts51x_sd_cleanup_work(chip);

	if (xd_card->counter > POLLING_WAIT_CNT)
		rts51x_xd_cleanup_work(chip);

	if (ms_card->counter > POLLING_WAIT_CNT)
		rts51x_ms_cleanup_work(chip);
}

static void do_rts51x_reset_xd_card(struct rts51x_chip *chip)
{
	int retval;

	if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT)
		return;

	retval = rts51x_reset_xd_card(chip);
	if (retval == STATUS_SUCCESS) {
		chip->card_ready |= XD_CARD;
		chip->card_fail &= ~XD_CARD;
		chip->rw_card[chip->card2lun[XD_CARD]] = rts51x_xd_rw;
	} else {
		chip->card_ready &= ~XD_CARD;
		chip->card_fail |= XD_CARD;
		chip->capacity[chip->card2lun[XD_CARD]] = 0;
		chip->rw_card[chip->card2lun[XD_CARD]] = NULL;

		rts51x_init_cmd(chip);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK,
			       POWER_OFF);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, XD_CLK_EN, 0);
		rts51x_send_cmd(chip, MODE_C, 100);
	}
}

void rts51x_do_rts51x_reset_sd_card(struct rts51x_chip *chip)
{
	int retval;

	if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT)
		return;

	retval = rts51x_reset_sd_card(chip);
	if (retval == STATUS_SUCCESS) {
		chip->card_ready |= SD_CARD;
		chip->card_fail &= ~SD_CARD;
		chip->rw_card[chip->card2lun[SD_CARD]] = rts51x_sd_rw;
	} else {
		chip->card_ready &= ~SD_CARD;
		chip->card_fail |= SD_CARD;
		chip->capacity[chip->card2lun[SD_CARD]] = 0;
		chip->rw_card[chip->card2lun[SD_CARD]] = NULL;

		rts51x_init_cmd(chip);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK,
			       POWER_OFF);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0);
		rts51x_send_cmd(chip, MODE_C, 100);
	}
}

static void do_rts51x_reset_ms_card(struct rts51x_chip *chip)
{
	int retval;

	if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT)
		return;

	retval = rts51x_reset_ms_card(chip);
	if (retval == STATUS_SUCCESS) {
		chip->card_ready |= MS_CARD;
		chip->card_fail &= ~MS_CARD;
		chip->rw_card[chip->card2lun[MS_CARD]] = rts51x_ms_rw;
	} else {
		chip->card_ready &= ~MS_CARD;
		chip->card_fail |= MS_CARD;
		chip->capacity[chip->card2lun[MS_CARD]] = 0;
		chip->rw_card[chip->card2lun[MS_CARD]] = NULL;

		rts51x_init_cmd(chip);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK,
			       POWER_OFF);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0);
		rts51x_send_cmd(chip, MODE_C, 100);
	}
}

static void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset,
		      u8 *need_release)
{
	int retval;
	u8 release_map = 0, reset_map = 0;
	u8 value;

	retval = rts51x_get_card_status(chip, &(chip->card_status));
#ifdef SUPPORT_OCP
	chip->ocp_stat = (chip->card_status >> 4) & 0x03;
#endif

	if (retval != STATUS_SUCCESS)
		goto Exit_Debounce;

	if (chip->card_exist) {
		retval = rts51x_read_register(chip, CARD_INT_PEND, &value);
		if (retval != STATUS_SUCCESS) {
			rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH,
						  FIFO_FLUSH);
			rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8);
			value = 0;
		}

		if (chip->card_exist & XD_CARD) {
			if (!(chip->card_status & XD_CD))
				release_map |= XD_CARD;
		} else if (chip->card_exist & SD_CARD) {
			/* if (!(chip->card_status & SD_CD)) { */
			if (!(chip->card_status & SD_CD) || (value & SD_INT))
				release_map |= SD_CARD;
		} else if (chip->card_exist & MS_CARD) {
			/* if (!(chip->card_status & MS_CD)) { */
			if (!(chip->card_status & MS_CD) || (value & MS_INT))
				release_map |= MS_CARD;
		}
	} else {
		if (chip->card_status & XD_CD)
			reset_map |= XD_CARD;
		else if (chip->card_status & SD_CD)
			reset_map |= SD_CARD;
		else if (chip->card_status & MS_CD)
			reset_map |= MS_CARD;
	}

	if (CHECK_PKG(chip, QFN24) && reset_map) {
		if (chip->card_exist & XD_CARD) {
			reset_map = 0;
			goto Exit_Debounce;
		}
	}

	if (reset_map) {
		int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0;
		int i;

		for (i = 0; i < (chip->option.debounce_num); i++) {
			retval =
			    rts51x_get_card_status(chip, &(chip->card_status));
			if (retval != STATUS_SUCCESS) {
				reset_map = release_map = 0;
				goto Exit_Debounce;
			}
			if (chip->card_status & XD_CD)
				xd_cnt++;
			else
				xd_cnt = 0;
			if (chip->card_status & SD_CD)
				sd_cnt++;
			else
				sd_cnt = 0;
			if (chip->card_status & MS_CD)
				ms_cnt++;
			else
				ms_cnt = 0;
			wait_timeout(30);
		}

		reset_map = 0;
		if (!(chip->card_exist & XD_CARD)
		    && (xd_cnt > (chip->option.debounce_num - 1))) {
			reset_map |= XD_CARD;
		}
		if (!(chip->card_exist & SD_CARD)
		    && (sd_cnt > (chip->option.debounce_num - 1))) {
			reset_map |= SD_CARD;
		}
		if (!(chip->card_exist & MS_CARD)
		    && (ms_cnt > (chip->option.debounce_num - 1))) {
			reset_map |= MS_CARD;
		}
	}
	rts51x_write_register(chip, CARD_INT_PEND, XD_INT | MS_INT | SD_INT,
			      XD_INT | MS_INT | SD_INT);

Exit_Debounce:
	if (need_reset)
		*need_reset = reset_map;
	if (need_release)
		*need_release = release_map;
}

void rts51x_init_cards(struct rts51x_chip *chip)
{
	u8 need_reset = 0, need_release = 0;

	card_cd_debounce(chip, &need_reset, &need_release);

	if (need_release) {
		RTS51X_DEBUGP("need_release = 0x%x\n", need_release);

		rts51x_prepare_run(chip);
		RTS51X_SET_STAT(chip, STAT_RUN);

#ifdef SUPPORT_OCP
		if (chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) {
			rts51x_write_register(chip, OCPCTL, MS_OCP_CLEAR,
					      MS_OCP_CLEAR);
			chip->ocp_stat = 0;
			RTS51X_DEBUGP("Clear OCP status.\n");
		}
#endif

		if (need_release & XD_CARD) {
			chip->card_exist &= ~XD_CARD;
			chip->card_ejected = 0;
			if (chip->card_ready & XD_CARD) {
				rts51x_release_xd_card(chip);
				chip->rw_card[chip->card2lun[XD_CARD]] = NULL;
				clear_bit(chip->card2lun[XD_CARD],
					  &(chip->lun_mc));
			}
		}

		if (need_release & SD_CARD) {
			chip->card_exist &= ~SD_CARD;
			chip->card_ejected = 0;
			if (chip->card_ready & SD_CARD) {
				rts51x_release_sd_card(chip);
				chip->rw_card[chip->card2lun[SD_CARD]] = NULL;
				clear_bit(chip->card2lun[SD_CARD],
					  &(chip->lun_mc));
			}
		}

		if (need_release & MS_CARD) {
			chip->card_exist &= ~MS_CARD;
			chip->card_ejected = 0;
			if (chip->card_ready & MS_CARD) {
				rts51x_release_ms_card(chip);
				chip->rw_card[chip->card2lun[MS_CARD]] = NULL;
				clear_bit(chip->card2lun[MS_CARD],
					  &(chip->lun_mc));
			}
		}
	}

	if (need_reset && !chip->card_ready) {
		RTS51X_DEBUGP("need_reset = 0x%x\n", need_reset);

		rts51x_prepare_run(chip);
		RTS51X_SET_STAT(chip, STAT_RUN);

		if (need_reset & XD_CARD) {
			chip->card_exist |= XD_CARD;
			do_rts51x_reset_xd_card(chip);
		} else if (need_reset & SD_CARD) {
			chip->card_exist |= SD_CARD;
			rts51x_do_rts51x_reset_sd_card(chip);
		} else if (need_reset & MS_CARD) {
			chip->card_exist |= MS_CARD;
			do_rts51x_reset_ms_card(chip);
		}
	}
}

void rts51x_release_cards(struct rts51x_chip *chip)
{
	if (chip->card_ready & SD_CARD) {
		rts51x_sd_cleanup_work(chip);
		rts51x_release_sd_card(chip);
		chip->card_ready &= ~SD_CARD;
	}

	if (chip->card_ready & XD_CARD) {
		rts51x_xd_cleanup_work(chip);
		rts51x_release_xd_card(chip);
		chip->card_ready &= ~XD_CARD;
	}

	if (chip->card_ready & MS_CARD) {
		rts51x_ms_cleanup_work(chip);
		rts51x_release_ms_card(chip);
		chip->card_ready &= ~MS_CARD;
	}
}

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

int rts51x_switch_ssc_clock(struct rts51x_chip *chip, int clk)
{
	struct sd_info *sd_card = &(chip->sd_card);
	struct ms_info *ms_card = &(chip->ms_card);
	int retval;
	u8 N = (u8) (clk - 2), min_N, max_N;
	u8 mcu_cnt, div, max_div, ssc_depth;
	int sd_vpclk_phase_reset = 0;

	if (chip->cur_clk == clk)
		return STATUS_SUCCESS;

	min_N = 60;
	max_N = 120;
	max_div = CLK_DIV_4;

	RTS51X_DEBUGP("Switch SSC clock to %dMHz\n", clk);

	if ((clk <= 2) || (N > max_N))
		TRACE_RET(chip, STATUS_FAIL);

	mcu_cnt = (u8) (60 / clk + 3);
	if (mcu_cnt > 15)
		mcu_cnt = 15;
	/* To make sure that the SSC clock div_n is
	 * equal or greater than min_N */
	div = CLK_DIV_1;
	while ((N < min_N) && (div < max_div)) {
		N = (N + 2) * 2 - 2;
		div++;
	}
	RTS51X_DEBUGP("N = %d, div = %d\n", N, div);

	if (chip->option.ssc_en) {
		if (chip->cur_card == SD_CARD) {
			if (CHK_SD_SDR104(sd_card)) {
				ssc_depth = chip->option.ssc_depth_sd_sdr104;
			} else if (CHK_SD_SDR50(sd_card)) {
				ssc_depth = chip->option.ssc_depth_sd_sdr50;
			} else if (CHK_SD_DDR50(sd_card)) {
				ssc_depth =
				    double_depth(chip->option.
						 ssc_depth_sd_ddr50);
			} else if (CHK_SD_HS(sd_card)) {
				ssc_depth =
				    double_depth(chip->option.ssc_depth_sd_hs);
			} else if (CHK_MMC_52M(sd_card)
				   || CHK_MMC_DDR52(sd_card)) {
				ssc_depth =
				    double_depth(chip->option.
						 ssc_depth_mmc_52m);
			} else {
				ssc_depth =
				    double_depth(chip->option.
						 ssc_depth_low_speed);
			}
		} else if (chip->cur_card == MS_CARD) {
			if (CHK_MSPRO(ms_card)) {
				if (CHK_HG8BIT(ms_card)) {
					ssc_depth =
					    double_depth(chip->option.
							 ssc_depth_ms_hg);
				} else {
					ssc_depth =
					    double_depth(chip->option.
							 ssc_depth_ms_4bit);
				}
			} else {
				if (CHK_MS4BIT(ms_card)) {
					ssc_depth =
					    double_depth(chip->option.
							 ssc_depth_ms_4bit);
				} else {
					ssc_depth =
					    double_depth(chip->option.
							 ssc_depth_low_speed);
				}
			}
		} else {
			ssc_depth =
			    double_depth(chip->option.ssc_depth_low_speed);
		}

		if (ssc_depth) {
			if (div == CLK_DIV_2) {
				/* If clock divided by 2, ssc depth must
				 * be multiplied by 2 */
				if (ssc_depth > 1)
					ssc_depth -= 1;
				else
					ssc_depth = SSC_DEPTH_2M;
			} else if (div == CLK_DIV_4) {
				/* If clock divided by 4, ssc depth must
				 * be multiplied by 4 */
				if (ssc_depth > 2)
					ssc_depth -= 2;
				else
					ssc_depth = SSC_DEPTH_2M;
			}
		}
	} else {
		/* Disable SSC */
		ssc_depth = 0;
	}

	RTS51X_DEBUGP("ssc_depth = %d\n", ssc_depth);

	rts51x_init_cmd(chip);
	rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, CLK_CHANGE);
	rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0x3F,
		       (div << 4) | mcu_cnt);
	rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
	rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, SSC_DEPTH_MASK,
		       ssc_depth);
	rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N);
	if (sd_vpclk_phase_reset) {
		rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL,
			       PHASE_NOT_RESET, 0);
		rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL,
			       PHASE_NOT_RESET, PHASE_NOT_RESET);
	}

	retval = rts51x_send_cmd(chip, MODE_C, 2000);
	if (retval != STATUS_SUCCESS)
		TRACE_RET(chip, retval);
	if (chip->option.ssc_en && ssc_depth)
		rts51x_write_register(chip, SSC_CTL1, 0xff, 0xD0);
	else
		rts51x_write_register(chip, SSC_CTL1, 0xff, 0x50);
	udelay(100);
	RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, 0);

	chip->cur_clk = clk;

	return STATUS_SUCCESS;
}

int rts51x_switch_normal_clock(struct rts51x_chip *chip, int clk)
{
	int retval;
	u8 sel, div, mcu_cnt;
	int sd_vpclk_phase_reset = 0;

	if (chip->cur_clk == clk)
		return STATUS_SUCCESS;

	if (chip->cur_card == SD_CARD) {
		struct sd_info *sd_card = &(chip->sd_card);
		if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card))
			sd_vpclk_phase_reset = 1;
	}

	switch (clk) {
	case CLK_20:
		RTS51X_DEBUGP("Switch clock to 20MHz\n");
		sel = SSC_80;
		div = CLK_DIV_4;
		mcu_cnt = 5;
		break;

	case CLK_30:
		RTS51X_DEBUGP("Switch clock to 30MHz\n");
		sel = SSC_60;
		div = CLK_DIV_2;
		mcu_cnt = 4;
		break;

	case CLK_40:
		RTS51X_DEBUGP("Switch clock to 40MHz\n");
		sel = SSC_80;
		div = CLK_DIV_2;
		mcu_cnt = 3;
		break;

	case CLK_50:
		RTS51X_DEBUGP("Switch clock to 50MHz\n");
		sel = SSC_100;
		div = CLK_DIV_2;
		mcu_cnt = 3;
		break;

	case CLK_60:
		RTS51X_DEBUGP("Switch clock to 60MHz\n");
		sel = SSC_60;
		div = CLK_DIV_1;
		mcu_cnt = 3;
		break;

	case CLK_80:
		RTS51X_DEBUGP("Switch clock to 80MHz\n");
		sel = SSC_80;
		div = CLK_DIV_1;
		mcu_cnt = 2;
		break;

	case CLK_100:
		RTS51X_DEBUGP("Switch clock to 100MHz\n");
		sel = SSC_100;
		div = CLK_DIV_1;
		mcu_cnt = 2;
		break;

	/* case CLK_120:
		RTS51X_DEBUGP("Switch clock to 120MHz\n");
		sel = SSC_120;
		div = CLK_DIV_1;
		mcu_cnt = 2;
		break;

	case CLK_150:
		RTS51X_DEBUGP("Switch clock to 150MHz\n");
		sel = SSC_150;
		div = CLK_DIV_1;
		mcu_cnt = 2;
		break; */

	default:
		RTS51X_DEBUGP("Try to switch to an illegal clock (%d)\n",
			       clk);
		TRACE_RET(chip, STATUS_FAIL);
	}

	if (!sd_vpclk_phase_reset) {
		rts51x_init_cmd(chip);

		rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE,
			       CLK_CHANGE);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0x3F,
			       (div << 4) | mcu_cnt);
		rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CLK_FPGA_SEL, 0xFF,
			       sel);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, 0);

		retval = rts51x_send_cmd(chip, MODE_C, 100);
		if (retval != STATUS_SUCCESS)
			TRACE_RET(chip, retval);
	} else {
		rts51x_init_cmd(chip);

		rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE,
			       CLK_CHANGE);
		rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL,
			       PHASE_NOT_RESET, 0);
		rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK1_CTL,
			       PHASE_NOT_RESET, 0);
		rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0x3F,
			       (div << 4) | mcu_cnt);
		rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CLK_FPGA_SEL, 0xFF,
			       sel);

		retval = rts51x_send_cmd(chip, MODE_C, 100);
		if (retval != STATUS_SUCCESS)
			TRACE_RET(chip, retval);

		udelay(200);

		rts51x_init_cmd(chip);

		rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL,
			       PHASE_NOT_RESET, PHASE_NOT_RESET);
		rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK1_CTL,
			       PHASE_NOT_RESET, PHASE_NOT_RESET);

		retval = rts51x_send_cmd(chip, MODE_C, 100);
		if (retval != STATUS_SUCCESS)
			TRACE_RET(chip, retval);

		udelay(200);

		RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, 0);
	}

	chip->cur_clk = clk;

	return STATUS_SUCCESS;
}

int rts51x_card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip,
		u32 sec_addr, u16 sec_cnt)
{
	int retval;
	unsigned int lun = SCSI_LUN(srb);
	int i;

	if (chip->rw_card[lun] == NULL)
		return STATUS_FAIL;

	RTS51X_DEBUGP("%s card, sector addr: 0x%x, sector cnt: %d\n",
		       (srb->sc_data_direction ==
			DMA_TO_DEVICE) ? "Write" : "Read", sec_addr, sec_cnt);

	chip->rw_need_retry = 0;
	for (i = 0; i < 3; i++) {
		retval = chip->rw_card[lun] (srb, chip, sec_addr, sec_cnt);
		if (retval != STATUS_SUCCESS) {
			CATCH_TRIGGER(chip);
			if (chip->option.reset_or_rw_fail_set_pad_drive) {
				rts51x_write_register(chip, CARD_DRIVE_SEL,
						      SD20_DRIVE_MASK,
						      DRIVE_8mA);
			}
		}

		if (!chip->rw_need_retry)
			break;

		RTS51X_DEBUGP("Retry RW, (i = %d\n)", i);
	}

	return retval;
}

u8 rts51x_get_lun_card(struct rts51x_chip *chip, unsigned int lun)
{
	if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD)
		return (u8) XD_CARD;
	else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD)
		return (u8) SD_CARD;
	else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD)
		return (u8) MS_CARD;

	return 0;
}

static int card_share_mode(struct rts51x_chip *chip, int card)
{
	u8 value;

	if (card == SD_CARD)
		value = CARD_SHARE_SD;
	else if (card == MS_CARD)
		value = CARD_SHARE_MS;
	else if (card == XD_CARD)
		value = CARD_SHARE_XD;
	else
		TRACE_RET(chip, STATUS_FAIL);

	RTS51X_WRITE_REG(chip, CARD_SHARE_MODE, CARD_SHARE_MASK, value);

	return STATUS_SUCCESS;
}

int rts51x_select_card(struct rts51x_chip *chip, int card)
{
	int retval;

	if (chip->cur_card != card) {
		u8 mod;

		if (card == SD_CARD)
			mod = SD_MOD_SEL;
		else if (card == MS_CARD)
			mod = MS_MOD_SEL;
		else if (card == XD_CARD)
			mod = XD_MOD_SEL;
		else
			TRACE_RET(chip, STATUS_FAIL);
		RTS51X_WRITE_REG(chip, CARD_SELECT, 0x07, mod);
		chip->cur_card = card;

		retval = card_share_mode(chip, card);
		if (retval != STATUS_SUCCESS)
			TRACE_RET(chip, retval);
	}

	return STATUS_SUCCESS;
}

void rts51x_eject_card(struct rts51x_chip *chip, unsigned int lun)
{
	RTS51X_DEBUGP("eject card\n");
	RTS51X_SET_STAT(chip, STAT_RUN);
	rts51x_do_remaining_work(chip);

	if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) {
		rts51x_release_sd_card(chip);
		chip->card_ejected |= SD_CARD;
		chip->card_ready &= ~SD_CARD;
		chip->capacity[lun] = 0;
	} else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) {
		rts51x_release_xd_card(chip);
		chip->card_ejected |= XD_CARD;
		chip->card_ready &= ~XD_CARD;
		chip->capacity[lun] = 0;
	} else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) {
		rts51x_release_ms_card(chip);
		chip->card_ejected |= MS_CARD;
		chip->card_ready &= ~MS_CARD;
		chip->capacity[lun] = 0;
	}
	rts51x_write_register(chip, CARD_INT_PEND, XD_INT | MS_INT | SD_INT,
			      XD_INT | MS_INT | SD_INT);
}

void rts51x_trans_dma_enable(enum dma_data_direction dir,
		struct rts51x_chip *chip, u32 byte_cnt, u8 pack_size)
{
	if (pack_size > DMA_1024)
		pack_size = DMA_512;

	rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01,
		       RING_BUFFER);

	rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC3, 0xFF,
		       (u8) (byte_cnt >> 24));
	rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC2, 0xFF,
		       (u8) (byte_cnt >> 16));
	rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC1, 0xFF,
		       (u8) (byte_cnt >> 8));
	rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC0, 0xFF, (u8) byte_cnt);

	if (dir == DMA_FROM_DEVICE) {
		rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_CTL,
			       0x03 | DMA_PACK_SIZE_MASK,
			       DMA_DIR_FROM_CARD | DMA_EN | pack_size);
	} else {
		rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_CTL,
			       0x03 | DMA_PACK_SIZE_MASK,
			       DMA_DIR_TO_CARD | DMA_EN | pack_size);
	}
}

int rts51x_enable_card_clock(struct rts51x_chip *chip, u8 card)
{
	u8 clk_en = 0;

	if (card & XD_CARD)
		clk_en |= XD_CLK_EN;
	if (card & SD_CARD)
		clk_en |= SD_CLK_EN;
	if (card & MS_CARD)
		clk_en |= MS_CLK_EN;

	RTS51X_WRITE_REG(chip, CARD_CLK_EN, clk_en, clk_en);

	return STATUS_SUCCESS;
}

int rts51x_card_power_on(struct rts51x_chip *chip, u8 card)
{
	u8 mask, val1, val2;

	mask = POWER_MASK;
	val1 = PARTIAL_POWER_ON;
	val2 = POWER_ON;

#ifdef SD_XD_IO_FOLLOW_PWR
	if ((card == SD_CARD) || (card == XD_CARD)) {
		RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask | LDO3318_PWR_MASK,
				 val1 | LDO_SUSPEND);
	} else {
#endif
		RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val1);
#ifdef SD_XD_IO_FOLLOW_PWR
	}
#endif
	udelay(chip->option.pwr_delay);
	RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val2);
#ifdef SD_XD_IO_FOLLOW_PWR
	if (card == SD_CARD) {
		rts51x_write_register(chip, CARD_PWR_CTL, LDO3318_PWR_MASK,
				      LDO_ON);
	}
#endif

	return STATUS_SUCCESS;
}

int monitor_card_cd(struct rts51x_chip *chip, u8 card)
{
	int retval;
	u8 card_cd[32] = { 0 };

	card_cd[SD_CARD] = SD_CD;
	card_cd[XD_CARD] = XD_CD;
	card_cd[MS_CARD] = MS_CD;

	retval = rts51x_get_card_status(chip, &(chip->card_status));
	if (retval != STATUS_SUCCESS)
		return CD_NOT_EXIST;

	if (chip->card_status & card_cd[card])
		return CD_EXIST;

	return CD_NOT_EXIST;
}

int rts51x_toggle_gpio(struct rts51x_chip *chip, u8 gpio)
{
	int retval;
	u8 temp_reg;
	u8 gpio_output[4] = {
		0x01,
	};
	u8 gpio_oe[4] = {
		0x02,
	};
	if (chip->rts5179) {
		retval = rts51x_ep0_read_register(chip, CARD_GPIO, &temp_reg);
		if (retval != STATUS_SUCCESS)
			TRACE_RET(chip, STATUS_FAIL);
		temp_reg ^= gpio_oe[gpio];
		temp_reg &= 0xfe; /* bit 0 always set 0 */
		retval =
		    rts51x_ep0_write_register(chip, CARD_GPIO, 0x03, temp_reg);
		if (retval != STATUS_SUCCESS)
			TRACE_RET(chip, STATUS_FAIL);
	} else {
		retval = rts51x_ep0_read_register(chip, CARD_GPIO, &temp_reg);
		if (retval != STATUS_SUCCESS)
			TRACE_RET(chip, STATUS_FAIL);
		temp_reg ^= gpio_output[gpio];
		retval =
		    rts51x_ep0_write_register(chip, CARD_GPIO, 0xFF,
					      temp_reg | gpio_oe[gpio]);
		if (retval != STATUS_SUCCESS)
			TRACE_RET(chip, STATUS_FAIL);
	}

	return STATUS_SUCCESS;
}

int rts51x_turn_on_led(struct rts51x_chip *chip, u8 gpio)
{
	int retval;
	u8 gpio_oe[4] = {
		0x02,
	};
	u8 gpio_mask[4] = {
		0x03,
	};

	retval =
	    rts51x_ep0_write_register(chip, CARD_GPIO, gpio_mask[gpio],
				      gpio_oe[gpio]);
	if (retval != STATUS_SUCCESS)
		TRACE_RET(chip, STATUS_FAIL);

	return STATUS_SUCCESS;
}

int rts51x_turn_off_led(struct rts51x_chip *chip, u8 gpio)
{
	int retval;
	u8 gpio_output[4] = {
		0x01,
	};
	u8 gpio_oe[4] = {
		0x02,
	};
	u8 gpio_mask[4] = {
		0x03,
	};

	retval =
	    rts51x_ep0_write_register(chip, CARD_GPIO, gpio_mask[gpio],
				      gpio_oe[gpio] | gpio_output[gpio]);
	if (retval != STATUS_SUCCESS)
		TRACE_RET(chip, STATUS_FAIL);

	return STATUS_SUCCESS;
}
