Пример #1
0
static bool
wb_sdmmc_enable(struct wb_softc *wb)
{
	int i = 5000;

	REPORT(wb, "TRACE: enable(wb)\n");

	/* put the device in a known state */
	wb_idx_write(wb, WB_INDEX_SETUP, WB_SETUP_SOFT_RST);
	while (--i > 0 && wb_idx_read(wb, WB_INDEX_SETUP) & WB_SETUP_SOFT_RST)
		delay(10);
	if (i == 0) {
		aprint_error_dev(wb->wb_dev, "timeout resetting device\n");
		return false;
	}
	wb_idx_write(wb, WB_INDEX_CLK, WB_CLK_375K);
	wb_idx_write(wb, WB_INDEX_FIFOEN, 0);
	wb_idx_write(wb, WB_INDEX_DMA, 0);
	wb_idx_write(wb, WB_INDEX_PBSMSB, 0);
	wb_idx_write(wb, WB_INDEX_PBSLSB, 0);
	/* drain FIFO */
	while ((wb_read(wb, WB_SD_FIFOSTS) & WB_FIFO_EMPTY) == 0)
		wb_read(wb, WB_SD_FIFO);

	wb_write(wb, WB_SD_CSR, 0);

	wb_write(wb, WB_SD_INTCTL, WB_INT_DEFAULT);

	wb_sdmmc_card_detect(wb);

	return true;
}
Пример #2
0
static int
wb_sdmmc_transfer_data(struct wb_softc *wb, struct sdmmc_command *cmd)
{
	uint8_t fifosts;
	int datalen, retry = 5000;

	if (wb->wb_sdmmc_intsts & WB_INT_CARD)
		return EIO;

	fifosts = wb_read(wb, WB_SD_FIFOSTS);
	if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
		if (fifosts & WB_FIFO_EMPTY) {
			while (--retry > 0) {
				fifosts = wb_read(wb, WB_SD_FIFOSTS);
				if ((fifosts & WB_FIFO_EMPTY) == 0)
					break;
				delay(100);
			}
			if (retry == 0)
				return EBUSY;
		}

		if (fifosts & WB_FIFO_FULL)
			datalen = 16;
		else
			datalen = fifosts & WB_FIFO_DEPTH_MASK;
	} else {
		if (fifosts & WB_FIFO_FULL) {
			while (--retry > 0) {
				fifosts = wb_read(wb, WB_SD_FIFOSTS);
				if ((fifosts & WB_FIFO_FULL) == 0)
					break;
				delay(100);
			}
			if (retry == 0)
				return EBUSY;
		}

		if (fifosts & WB_FIFO_EMPTY)
			datalen = 16;
		else
			datalen = 16 - (fifosts & WB_FIFO_DEPTH_MASK);
	}

	datalen = MIN(datalen, cmd->c_resid);
	if (datalen > 0) {
		if (ISSET(cmd->c_flags, SCF_CMD_READ))
			wb_sdmmc_read_data(wb, cmd->c_buf, datalen);
		else
			wb_sdmmc_write_data(wb, cmd->c_buf, datalen);

		cmd->c_buf += datalen;
		cmd->c_resid -= datalen;
	}

	return 0;
}
Пример #3
0
/*
 * intr handler 
 */
int
wb_sdmmc_intr(struct wb_softc *wb)
{
	uint8_t val;

	val = wb_read(wb, WB_SD_INTSTS);
	if (val == 0xff || val == 0x00)
		return 0;

	if (wb->wb_sdmmc_dev == NULL)
		return 1;

	wb->wb_sdmmc_intsts |= val;

	if (wb_sdmmc_debug) {
		char buf[64];
		snprintb(buf, sizeof(buf),
		    "\20\1TC\2BUSYEND\3PROGEND\4TIMEOUT"
		    "\5CRC\6FIFO\7CARD\010PENDING",
		    val);
		REPORT(wb, "WB_SD_INTSTS = %s\n", buf);
	}

	if (val & WB_INT_CARD)
		callout_schedule(&wb->wb_sdmmc_callout, hz / 4);

	return 1;
}
Пример #4
0
void
wb_led(struct wb_softc *wb, bool enable)
{
	uint8_t val;

	val = wb_read(wb, WB_SD_CSR);
	if (enable)
		val |= WB_CSR_MS_LED;
	else
		val &= ~WB_CSR_MS_LED;
	wb_write(wb, WB_SD_CSR, val);
}
Пример #5
0
static bool
wb_sdmmc_disable(struct wb_softc *wb)
{
	uint8_t val;

	REPORT(wb, "TRACE: disable(wb)\n");

	val = wb_read(wb, WB_SD_CSR);
	val |= WB_CSR_POWER_N;
	wb_write(wb, WB_SD_CSR, val);

	return true;
}
Пример #6
0
static int
wb_sdmmc_write_protect(sdmmc_chipset_handle_t sch)
{
	struct wb_softc *wb = sch;
	int rv;

	wb_led(wb, true);
	rv = (wb_read(wb, WB_SD_CSR) & WB_CSR_WRITE_PROTECT) ? 1 : 0;
	wb_led(wb, false);

	REPORT(wb, "TRACE: sdmmc/write_protect(wb) -> %d\n", rv);

	return rv;
}
Пример #7
0
static int
wb_sdmmc_card_detect(sdmmc_chipset_handle_t sch)
{
	struct wb_softc *wb = sch;
	int rv;

	wb_led(wb, true);
	rv = (wb_read(wb, WB_SD_CSR) & WB_CSR_CARD_PRESENT) ? 1 : 0;
	wb_led(wb, false);

	REPORT(wb, "TRACE: sdmmc/card_detect(wb) -> %d\n", rv);

	return rv;
}
Пример #8
0
unsigned char inb (unsigned long port) {
  return wb_read(port);
}