diff options
Diffstat (limited to 'drivers/staging/rts5139/rts51x_card.c')
-rw-r--r-- | drivers/staging/rts5139/rts51x_card.c | 940 |
1 files changed, 0 insertions, 940 deletions
diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c deleted file mode 100644 index 03456d9873e5..000000000000 --- a/drivers/staging/rts5139/rts51x_card.c +++ /dev/null @@ -1,940 +0,0 @@ -/* 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; -} |