Exemplo n.º 1
0
int card_power_on(struct rtsx_chip *chip, u8 card)
{
	int retval;
	u8 mask, val1, val2;

	if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) {
		mask = MS_POWER_MASK;
		val1 = MS_PARTIAL_POWER_ON;
		val2 = MS_POWER_ON;
	} else {
		mask = SD_POWER_MASK;
		val1 = SD_PARTIAL_POWER_ON;
		val2 = SD_POWER_ON;
	}

	rtsx_init_cmd(chip);
	rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1);

	retval = rtsx_send_cmd(chip, 0, 100);
	if (retval != STATUS_SUCCESS)
		TRACE_RET(chip, STATUS_FAIL);

	udelay(chip->pmos_pwr_on_interval);

	rtsx_init_cmd(chip);
	rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2);

	retval = rtsx_send_cmd(chip, 0, 100);
	if (retval != STATUS_SUCCESS)
		TRACE_RET(chip, STATUS_FAIL);

	return STATUS_SUCCESS;
}
Exemplo n.º 2
0
Arquivo: spi.c Projeto: acton393/linux
static int sf_disable_write(struct rtsx_chip *chip, u8 ins)
{
	struct spi_info *spi = &(chip->spi);
	int retval;

	if (!spi->write_en)
		return STATUS_SUCCESS;

	rtsx_init_cmd(chip);

	rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
		SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
		SPI_TRANSFER0_START | SPI_C_MODE0);
	rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
		SPI_TRANSFER0_END);

	retval = rtsx_send_cmd(chip, 0, 100);
	if (retval < 0) {
		rtsx_clear_spi_error(chip);
		spi_set_err_code(chip, SPI_HW_ERR);
		rtsx_trace(chip);
		return STATUS_FAIL;
	}

	return STATUS_SUCCESS;
}
Exemplo n.º 3
0
static int sf_polling_status(struct rtsx_chip *chip, int msec)
{
	int retval;

	rtsx_init_cmd(chip);

	rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, SPI_RDSR);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_POLLING_MODE0);
	rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);

	retval = rtsx_send_cmd(chip, 0, msec);
	if (retval < 0) {
		rtsx_clear_spi_error(chip);
		spi_set_err_code(chip, SPI_BUSY_ERR);
		TRACE_RET(chip, STATUS_FAIL);
	}

	return STATUS_SUCCESS;
}
Exemplo n.º 4
0
int switch_ssc_clock(struct rtsx_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, ssc_depth_mask;
	int sd_vpclk_phase_reset = 0;

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

	if (CHECK_PID(chip, 0x5209)) {
		min_N = 80;
		max_N = 208;
		max_div = CLK_DIV_8;
	} else {
		min_N = 60;
		max_N = 120;
		max_div = CLK_DIV_4;
	}

	if (CHECK_PID(chip, 0x5209) && (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;
	}

	RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n", clk, chip->cur_clk);

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

	mcu_cnt = (u8)(125/clk + 3);
	if (CHECK_PID(chip, 0x5209)) {
		if (mcu_cnt > 15)
			mcu_cnt = 15;
	} else {
		if (mcu_cnt > 7)
			mcu_cnt = 7;
	}

	div = CLK_DIV_1;
	while ((N < min_N) && (div < max_div)) {
		N = (N + 2) * 2 - 2;
		div++;
	}
	RTSX_DEBUGP("N = %d, div = %d\n", N, div);

	if (chip->ssc_en) {
		if (CHECK_PID(chip, 0x5209)) {
			if (chip->cur_card == SD_CARD) {
				if (CHK_SD_SDR104(sd_card)) {
					ssc_depth = chip->ssc_depth_sd_sdr104;
				} else if (CHK_SD_SDR50(sd_card)) {
					ssc_depth = chip->ssc_depth_sd_sdr50;
				} else if (CHK_SD_DDR50(sd_card)) {
					ssc_depth = double_depth(chip->ssc_depth_sd_ddr50);
				} else if (CHK_SD_HS(sd_card)) {
					ssc_depth = double_depth(chip->ssc_depth_sd_hs);
				} else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) {
					ssc_depth = double_depth(chip->ssc_depth_mmc_52m);
				} else {
					ssc_depth = double_depth(chip->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->ssc_depth_ms_hg);
					} else {
						ssc_depth = double_depth(chip->ssc_depth_ms_4bit);
					}
				} else {
					if (CHK_MS4BIT(ms_card)) {
						ssc_depth = double_depth(chip->ssc_depth_ms_4bit);
					} else {
						ssc_depth = double_depth(chip->ssc_depth_low_speed);
					}
				}
			} else {
				ssc_depth = double_depth(chip->ssc_depth_low_speed);
			}

			if (ssc_depth) {
				if (div == CLK_DIV_2) {
					if (ssc_depth > 1) {
						ssc_depth -= 1;
					} else {
						ssc_depth = SSC_DEPTH_4M;
					}
				} else if (div == CLK_DIV_4) {
					if (ssc_depth > 2) {
						ssc_depth -= 2;
					} else {
						ssc_depth = SSC_DEPTH_4M;
					}
				} else if (div == CLK_DIV_8) {
					if (ssc_depth > 3) {
						ssc_depth -= 3;
					} else {
						ssc_depth = SSC_DEPTH_4M;
					}
				}
			}
		} else {
			ssc_depth = 0x01;
			N -= 2;
		}
	} else {
		ssc_depth = 0;
	}

	if (CHECK_PID(chip, 0x5209)) {
		ssc_depth_mask = SSC_DEPTH_MASK;
	} else {
		ssc_depth_mask = 0x03;
	}

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

	rtsx_init_cmd(chip);
	rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
	rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
	if (sd_vpclk_phase_reset) {
		rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0);
		rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET);
	}

	retval = rtsx_send_cmd(chip, 0, WAIT_TIME);
	if (retval < 0) {
		TRACE_RET(chip, STATUS_ERROR);
	}

	udelay(10);
	RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0);

	chip->cur_clk = clk;

	return STATUS_SUCCESS;
}
Exemplo n.º 5
0
int switch_ssc_clock(struct rtsx_chip *chip, int clk)
{
	int retval;
	u8 N = (u8)(clk - 2), min_N, max_N;
	u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask;
	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;

	RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n",
			clk, chip->cur_clk);

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

	mcu_cnt = (u8)(125/clk + 3);
	if (mcu_cnt > 7)
		mcu_cnt = 7;

	div = CLK_DIV_1;
	while ((N < min_N) && (div < max_div)) {
		N = (N + 2) * 2 - 2;
		div++;
	}
	RTSX_DEBUGP("N = %d, div = %d\n", N, div);

	if (chip->ssc_en) {
		ssc_depth = 0x01;
		N -= 2;
	} else {
		ssc_depth = 0;
	}

	ssc_depth_mask = 0x03;

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

	rtsx_init_cmd(chip);
	rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
	rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N);
	rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
	if (sd_vpclk_phase_reset) {
		rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL,
			PHASE_NOT_RESET, 0);
		rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL,
			PHASE_NOT_RESET, PHASE_NOT_RESET);
	}

	retval = rtsx_send_cmd(chip, 0, WAIT_TIME);
	if (retval < 0)
		TRACE_RET(chip, STATUS_ERROR);

	udelay(10);
	RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0);

	chip->cur_clk = clk;

	return STATUS_SUCCESS;
}