Пример #1
0
void turn_off_led(struct rtsx_chip *chip, u8 gpio)
{
	if (CHECK_PID(chip, 0x5288)) {
		rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0);
	} else {
		rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio));
	}
}
Пример #2
0
void do_reset_sd_card(struct rtsx_chip *chip)
{
	int retval;
	
	RTSX_DEBUGP(("%s: %d, card2lun = 0x%x\n", __FUNCTION__, 
		     chip->sd_reset_counter, chip->card2lun[SD_CARD]));
	
	if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) {
		clear_bit(SD_NR, &(chip->need_reset));
		chip->sd_reset_counter = 0;
		chip->sd_show_cnt = 0;
		return;
	}
	
	chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0;
	
	rtsx_set_stat(chip, RTSX_STAT_RUN);
	rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0);
	
	retval = reset_sd_card(chip);
	if (chip->need_release & SD_CARD) {
		return;
	}
	if (retval == STATUS_SUCCESS) {
		clear_bit(SD_NR, &(chip->need_reset));
		chip->sd_reset_counter = 0;
		chip->sd_show_cnt = 0;
		chip->card_ready |= SD_CARD;
		chip->card_fail &= ~SD_CARD;
		chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw;
	} else {
		if (chip->sd_io || (chip->sd_reset_counter >= MAX_RESET_CNT)) {
			clear_bit(SD_NR, &(chip->need_reset));
			chip->sd_reset_counter = 0;
			chip->sd_show_cnt = 0;
		} else {
			chip->sd_reset_counter ++;
		}
		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;

		rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0);
		if (!chip->ft2_fast_mode) {
			card_power_off(chip, SD_CARD);
		}
		if (chip->sd_io) {
			
			chip->sd_int = 0;
			try_to_switch_sdio_ctrl(chip);
		} else {
			disable_card_clock(chip, SD_CARD);
		}
	}
}
Пример #3
0
static int spi_set_init_para(struct rtsx_chip *chip)
{
	struct spi_info *spi = &(chip->spi);
	int retval;

	retval = rtsx_write_register(chip, SPI_CLK_DIVIDER1, 0xFF,
				     (u8)(spi->clk_div >> 8));
	if (retval) {
		rtsx_trace(chip);
		return retval;
	}
	retval = rtsx_write_register(chip, SPI_CLK_DIVIDER0, 0xFF,
				     (u8)(spi->clk_div));
	if (retval) {
		rtsx_trace(chip);
		return retval;
	}

	retval = switch_clock(chip, spi->spi_clock);
	if (retval != STATUS_SUCCESS) {
		rtsx_trace(chip);
		return STATUS_FAIL;
	}

	retval = select_card(chip, SPI_CARD);
	if (retval != STATUS_SUCCESS) {
		rtsx_trace(chip);
		return STATUS_FAIL;
	}

	retval = rtsx_write_register(chip, CARD_CLK_EN, SPI_CLK_EN,
				     SPI_CLK_EN);
	if (retval) {
		rtsx_trace(chip);
		return retval;
	}
	retval = rtsx_write_register(chip, CARD_OE, SPI_OUTPUT_EN,
				     SPI_OUTPUT_EN);
	if (retval) {
		rtsx_trace(chip);
		return retval;
	}

	wait_timeout(10);

	retval = spi_init(chip);
	if (retval != STATUS_SUCCESS) {
		rtsx_trace(chip);
		return STATUS_FAIL;
	}

	return STATUS_SUCCESS;
}
Пример #4
0
void try_to_switch_sdio_ctrl(struct rtsx_chip *chip)
{
	u8 reg1 = 0, reg2 = 0;

	rtsx_read_register(chip, 0xFF34, &reg1);
	rtsx_read_register(chip, 0xFF38, &reg2);
	RTSX_DEBUGP("reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", reg1, reg2);
	if ((reg1 & 0xC0) && (reg2 & 0xC0)) {
		chip->sd_int = 1;
		rtsx_write_register(chip, SDIO_CTRL, 0xFF, SDIO_BUS_CTRL | SDIO_CD_CTRL);
		rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON);
	}
}
Пример #5
0
static int spi_init(struct rtsx_chip *chip)
{
	int retval;

	retval = rtsx_write_register(chip, SPI_CONTROL, 0xFF,
				     CS_POLARITY_LOW | DTO_MSB_FIRST
				     | SPI_MASTER | SPI_MODE0 | SPI_AUTO);
	if (retval)
		return retval;
	retval = rtsx_write_register(chip, SPI_TCTL, EDO_TIMING_MASK,
				     SAMPLE_DELAY_HALF);
	if (retval)
		return retval;

	return STATUS_SUCCESS;
}
Пример #6
0
void do_reset_ms_card(struct rtsx_chip *chip)
{
	int retval;

	RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__,
		     chip->ms_reset_counter, chip->card2lun[MS_CARD]);

	if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) {
		clear_bit(MS_NR, &(chip->need_reset));
		chip->ms_reset_counter = 0;
		chip->ms_show_cnt = 0;
		return;
	}

	chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0;

	rtsx_set_stat(chip, RTSX_STAT_RUN);
	rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0);

	retval = reset_ms_card(chip);
	if (chip->need_release & MS_CARD)
		return;
	if (retval == STATUS_SUCCESS) {
		clear_bit(MS_NR, &(chip->need_reset));
		chip->ms_reset_counter = 0;
		chip->card_ready |= MS_CARD;
		chip->card_fail &= ~MS_CARD;
		chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw;
	} else {
		if (chip->ms_reset_counter >= MAX_RESET_CNT) {
			clear_bit(MS_NR, &(chip->need_reset));
			chip->ms_reset_counter = 0;
			chip->ms_show_cnt = 0;
		} else {
			chip->ms_reset_counter++;
		}
		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;

		rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0);
		if (!chip->ft2_fast_mode)
			card_power_off(chip, MS_CARD);
		disable_card_clock(chip, MS_CARD);
	}
}
Пример #7
0
void toggle_gpio(struct rtsx_chip *chip, u8 gpio)
{
	u8 temp_reg;

	rtsx_read_register(chip, CARD_GPIO, &temp_reg);
	temp_reg ^= (0x01 << gpio);
	rtsx_write_register(chip, CARD_GPIO, 0xFF, temp_reg);
}
Пример #8
0
static void release_sdio(struct rtsx_chip *chip)
{
	if (chip->sd_io) {
		rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR,
				SD_STOP | SD_CLR_ERR);

		if (chip->chip_insert_with_sdio) {
			chip->chip_insert_with_sdio = 0;

			if (CHECK_PID(chip, 0x5288))
				rtsx_write_register(chip, 0xFE5A, 0x08, 0x00);
			else
				rtsx_write_register(chip, 0xFE70, 0x80, 0x00);
		}

		rtsx_write_register(chip, SDIO_CTRL, SDIO_CD_CTRL, 0);
		chip->sd_io = 0;
	}
}
Пример #9
0
void rtsx_reset_cards(struct rtsx_chip *chip)
{
	if (!chip->need_reset) {
		return;
	}

	rtsx_set_stat(chip, RTSX_STAT_RUN);
	
	rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL);

	rtsx_disable_aspm(chip);

	if ((chip->need_reset & SD_CARD) && chip->chip_insert_with_sdio) {
		clear_bit(SD_NR, &(chip->need_reset));
	}

	if (chip->need_reset & XD_CARD) {
		chip->card_exist |= XD_CARD;
		
		if (chip->xd_show_cnt >= MAX_SHOW_CNT) {
			do_reset_xd_card(chip);
		} else {
			chip->xd_show_cnt ++;
		}
	}
	if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) {
		if (chip->card_exist & XD_CARD) {
			clear_bit(SD_NR, &(chip->need_reset));
			clear_bit(MS_NR, &(chip->need_reset));
		}
	}
	if (chip->need_reset & SD_CARD) {
		chip->card_exist |= SD_CARD;

		if (chip->sd_show_cnt >= MAX_SHOW_CNT) {
			rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);
			do_reset_sd_card(chip);
		} else {
			chip->sd_show_cnt ++;
		}
	}
	if (chip->need_reset & MS_CARD) {
		chip->card_exist |= MS_CARD;
		
		if (chip->ms_show_cnt >= MAX_SHOW_CNT) {
			do_reset_ms_card(chip);
		} else {
			chip->ms_show_cnt ++;
		}
	}
}
Пример #10
0
void dynamic_configure_sdio_aspm(struct rtsx_chip *chip)
{
	u8 buf[12], reg;
	int i;

	for (i = 0; i < 12; i++) {
		rtsx_read_register(chip, 0xFF08 + i, &buf[i]);
	}
	rtsx_read_register(chip, 0xFF25, &reg);
	if ((memcmp(buf, chip->sdio_raw_data, 12) != 0) || (reg & 0x03)) {
		chip->sdio_counter = 0;
		chip->sdio_idle = 0;
	} else {
		if (!chip->sdio_idle) {
			chip->sdio_counter ++;
			if (chip->sdio_counter >= SDIO_IDLE_COUNT) {
				chip->sdio_counter = 0;
				chip->sdio_idle = 1;
			}
		}
	}
	memcpy(chip->sdio_raw_data, buf, 12);

	if (chip->sdio_idle) {
		if (!chip->sdio_aspm) {
			RTSX_DEBUGP(("SDIO enter ASPM!\n"));
			rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 
					0x30 | (chip->aspm_level[1] << 2));
			chip->sdio_aspm = 1;
		}
	} else {
		if (chip->sdio_aspm) {
			RTSX_DEBUGP(("SDIO exit ASPM!\n"));
			rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30);
			chip->sdio_aspm = 0;
		}
	}	
}
Пример #11
0
static int rtsx_resume(struct pci_dev *pci)
{
	struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
	struct rtsx_chip *chip;

	printk(KERN_INFO "Ready to resume\n");

	if (!dev) {
		printk(KERN_ERR "Invalid memory\n");
		return 0;
	}

	chip = dev->chip;
	
	
	mutex_lock(&(dev->dev_mutex));

	pci_set_power_state(pci, PCI_D0);
	pci_restore_state(pci);
	if (pci_enable_device(pci) < 0) {
		printk(KERN_ERR "%s: pci_enable_device failed, "
		       "disabling device\n", CR_DRIVER_NAME);
		
		mutex_unlock(&dev->dev_mutex);
		return -EIO;
	}
	pci_set_master(pci);
	
	if (chip->msi_en) {
		if (pci_enable_msi(pci) < 0) {
			chip->msi_en = 0;
		}
	}
	
	if (rtsx_acquire_irq(dev) < 0) {
		
		mutex_unlock(&dev->dev_mutex);
		return -EIO;
	}

	rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00);
	rtsx_init_chip(chip);

	
	mutex_unlock(&dev->dev_mutex);

	return 0;
}
Пример #12
0
static int rtsx_resume(struct pci_dev *pci)
{
	struct rtsx_dev *dev = pci_get_drvdata(pci);
	struct rtsx_chip *chip;

	if (!dev)
		return 0;

	chip = dev->chip;

	/* lock the device pointers */
	mutex_lock(&(dev->dev_mutex));

	pci_set_power_state(pci, PCI_D0);
	pci_restore_state(pci);
	if (pci_enable_device(pci) < 0) {
		dev_err(&dev->pci->dev,
			"%s: pci_enable_device failed, disabling device\n",
			CR_DRIVER_NAME);
		/* unlock the device pointers */
		mutex_unlock(&dev->dev_mutex);
		return -EIO;
	}
	pci_set_master(pci);

	if (chip->msi_en) {
		if (pci_enable_msi(pci) < 0)
			chip->msi_en = 0;
	}

	if (rtsx_acquire_irq(dev) < 0) {
		/* unlock the device pointers */
		mutex_unlock(&dev->dev_mutex);
		return -EIO;
	}

	rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00);
	rtsx_init_chip(chip);

	/* unlock the device pointers */
	mutex_unlock(&dev->dev_mutex);

	return 0;
}
Пример #13
0
int card_share_mode(struct rtsx_chip *chip, int card)
{
	int retval;
	u8 mask, value;

	if (CHECK_PID(chip, 0x5208)) {
		mask = CARD_SHARE_MASK;
		if (card == SD_CARD)
			value = CARD_SHARE_48_SD;
		else {
			rtsx_trace(chip);
			return STATUS_FAIL;
		}

	} else if (CHECK_PID(chip, 0x5288)) {
		mask = 0x03;
		if (card == SD_CARD)
			value = CARD_SHARE_BAROSSA_SD;
		else {
			rtsx_trace(chip);
			return STATUS_FAIL;
		}

	} else {
		rtsx_trace(chip);
		return STATUS_FAIL;
	}

	retval = rtsx_write_register(chip, CARD_SHARE_MODE, mask, value);
	if (retval) {
		rtsx_trace(chip);
		return retval;
	}

	return STATUS_SUCCESS;
}
Пример #14
0
void rtsx_init_cards(struct rtsx_chip *chip)
{
	if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) {
		RTSX_DEBUGP("Reset chip in polling thread!\n");
		rtsx_reset_chip(chip);
		RTSX_CLR_DELINK(chip);
	}

#ifdef DISABLE_CARD_INT
	card_cd_debounce(chip, &(chip->need_reset), &(chip->need_release));
#endif

	if (chip->need_release) {
		if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) {
			if (chip->int_reg & XD_EXIST) {
				clear_bit(SD_NR, &(chip->need_release));
				clear_bit(MS_NR, &(chip->need_release));
			}
		}

		if (!(chip->card_exist & SD_CARD) && !chip->sd_io)
			clear_bit(SD_NR, &(chip->need_release));
		if (!(chip->card_exist & XD_CARD))
			clear_bit(XD_NR, &(chip->need_release));
		if (!(chip->card_exist & MS_CARD))
			clear_bit(MS_NR, &(chip->need_release));

		RTSX_DEBUGP("chip->need_release = 0x%x\n", (unsigned int)(chip->need_release));

#ifdef SUPPORT_OCP
		if (chip->need_release) {
			if (CHECK_PID(chip, 0x5209)) {
				u8 mask = 0, val = 0;
				if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) {
					if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) {
						mask |= MS_OCP_INT_CLR | MS_OC_CLR;
						val |= MS_OCP_INT_CLR | MS_OC_CLR;
					}
				}
				if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
					mask |= SD_OCP_INT_CLR | SD_OC_CLR;
					val |= SD_OCP_INT_CLR | SD_OC_CLR;
				}
				if (mask)
					rtsx_write_register(chip, OCPCTL, mask, val);
			} else {
				if (chip->ocp_stat & (CARD_OC_NOW | CARD_OC_EVER))
					rtsx_write_register(chip, OCPCLR,
							    CARD_OC_INT_CLR | CARD_OC_CLR,
							    CARD_OC_INT_CLR | CARD_OC_CLR);
			}
			chip->ocp_stat = 0;
		}
#endif
		if (chip->need_release) {
			rtsx_set_stat(chip, RTSX_STAT_RUN);
			rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL);
		}

		if (chip->need_release & SD_CARD) {
			clear_bit(SD_NR, &(chip->need_release));
			chip->card_exist &= ~SD_CARD;
			chip->card_ejected &= ~SD_CARD;
			chip->card_fail &= ~SD_CARD;
			CLR_BIT(chip->lun_mc, chip->card2lun[SD_CARD]);
			chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0;
			rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH);

			release_sdio(chip);
			release_sd_card(chip);
		}

		if (chip->need_release & XD_CARD) {
			clear_bit(XD_NR, &(chip->need_release));
			chip->card_exist &= ~XD_CARD;
			chip->card_ejected &= ~XD_CARD;
			chip->card_fail &= ~XD_CARD;
			CLR_BIT(chip->lun_mc, chip->card2lun[XD_CARD]);
			chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0;

			release_xd_card(chip);

			if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN))
				rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0xC0);
		}

		if (chip->need_release & MS_CARD) {
			clear_bit(MS_NR, &(chip->need_release));
			chip->card_exist &= ~MS_CARD;
			chip->card_ejected &= ~MS_CARD;
			chip->card_fail &= ~MS_CARD;
			CLR_BIT(chip->lun_mc, chip->card2lun[MS_CARD]);
			chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0;

			release_ms_card(chip);
		}

		RTSX_DEBUGP("chip->card_exist = 0x%x\n", chip->card_exist);

		if (!chip->card_exist)
			turn_off_led(chip, LED_GPIO);
	}

	if (chip->need_reset) {
		RTSX_DEBUGP("chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset));

		rtsx_reset_cards(chip);
	}

	if (chip->need_reinit) {
		RTSX_DEBUGP("chip->need_reinit = 0x%x\n", (unsigned int)(chip->need_reinit));

		rtsx_reinit_cards(chip, 0);
	}
}
Пример #15
0
void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, unsigned long *need_release)
{
	u8 release_map = 0, reset_map = 0;

	chip->int_reg = rtsx_readl(chip, RTSX_BIPR);

	if (chip->card_exist) {
		if (chip->card_exist & XD_CARD) {
			if (!(chip->int_reg & XD_EXIST))
				release_map |= XD_CARD;
		} else if (chip->card_exist & SD_CARD) {
			if (!(chip->int_reg & SD_EXIST))
				release_map |= SD_CARD;
		} else if (chip->card_exist & MS_CARD) {
			if (!(chip->int_reg & MS_EXIST))
				release_map |= MS_CARD;
		}
	} else {
		if (chip->int_reg & XD_EXIST) {
			reset_map |= XD_CARD;
		} else if (chip->int_reg & SD_EXIST) {
			reset_map |= SD_CARD;
		} else if (chip->int_reg & MS_EXIST) {
			reset_map |= MS_CARD;
		}
	}

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

		for (i = 0; i < (DEBOUNCE_CNT); i++) {
			chip->int_reg = rtsx_readl(chip, RTSX_BIPR);

			if (chip->int_reg & XD_EXIST) {
				xd_cnt++;
			} else {
				xd_cnt = 0;
			}
			if (chip->int_reg & SD_EXIST) {
				sd_cnt++;
			} else {
				sd_cnt = 0;
			}
			if (chip->int_reg & MS_EXIST) {
				ms_cnt++;
			} else {
				ms_cnt = 0;
			}
			wait_timeout(30);
		}

		reset_map = 0;
		if (!(chip->card_exist & XD_CARD) && (xd_cnt > (DEBOUNCE_CNT-1)))
			reset_map |= XD_CARD;
		if (!(chip->card_exist & SD_CARD) && (sd_cnt > (DEBOUNCE_CNT-1)))
			reset_map |= SD_CARD;
		if (!(chip->card_exist & MS_CARD) && (ms_cnt > (DEBOUNCE_CNT-1)))
			reset_map |= MS_CARD;
	}

	if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN))
		rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0x00);

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