/* 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;
}
