mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-24 04:09:18 +01:00
removed more useless SD code
This commit is contained in:
parent
661a30fc21
commit
fa08fede1e
323
sdhc.c
323
sdhc.c
@ -36,12 +36,13 @@
|
||||
#include "ipc.h"
|
||||
#endif
|
||||
|
||||
struct sdhc_host sc_host;
|
||||
|
||||
//#define SDHC_DEBUG
|
||||
|
||||
#define SDHC_COMMAND_TIMEOUT 500
|
||||
#define SDHC_TRANSFER_TIMEOUT 5000
|
||||
|
||||
#define sdmmc_delay(t) udelay(t)
|
||||
#define sdhc_wait_intr(a,b,c) sdhc_wait_intr_debug(__func__, __LINE__, a, b, c)
|
||||
|
||||
static inline u32 bus_space_read_4(bus_space_handle_t ioh, u32 reg)
|
||||
@ -142,11 +143,8 @@ void sdhc_dump_regs(struct sdhc_host *);
|
||||
* host controller standard register set. (1.3)
|
||||
*/
|
||||
int
|
||||
sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot,
|
||||
bus_space_handle_t ioh, int usedma)
|
||||
sdhc_host_found(bus_space_tag_t iot, bus_space_handle_t ioh, int usedma)
|
||||
{
|
||||
struct sdmmcbus_attach_args saa;
|
||||
struct sdhc_host *hp;
|
||||
u_int32_t caps;
|
||||
int error = 1;
|
||||
|
||||
@ -166,46 +164,38 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate one more host structure. */
|
||||
if (sc->sc_nhosts < SDHC_MAX_HOSTS) {
|
||||
sc->sc_nhosts++;
|
||||
hp = &sc->sc_host[sc->sc_nhosts - 1];
|
||||
memset(hp, 0, sizeof(*hp));
|
||||
}
|
||||
else
|
||||
return -EINVAL;
|
||||
memset(&sc_host, 0, sizeof(sc_host));
|
||||
|
||||
/* Fill in the new host structure. */
|
||||
hp->sc = sc;
|
||||
hp->iot = iot;
|
||||
hp->ioh = ioh;
|
||||
hp->data_command = 0;
|
||||
sc_host.iot = iot;
|
||||
sc_host.ioh = ioh;
|
||||
sc_host.data_command = 0;
|
||||
|
||||
/*
|
||||
* Reset the host controller and enable interrupts.
|
||||
*/
|
||||
(void)sdhc_host_reset(hp);
|
||||
(void)sdhc_host_reset(&sc_host);
|
||||
|
||||
/* Determine host capabilities. */
|
||||
caps = HREAD4(hp, SDHC_CAPABILITIES);
|
||||
caps = HREAD4(&sc_host, SDHC_CAPABILITIES);
|
||||
|
||||
/* Use DMA if the host system and the controller support it. */
|
||||
if (usedma && ISSET(caps, SDHC_DMA_SUPPORT))
|
||||
SET(hp->flags, SHF_USE_DMA);
|
||||
SET(sc_host.flags, SHF_USE_DMA);
|
||||
|
||||
/*
|
||||
* Determine the base clock frequency. (2.2.24)
|
||||
*/
|
||||
if (SDHC_BASE_FREQ_KHZ(caps) != 0)
|
||||
hp->clkbase = SDHC_BASE_FREQ_KHZ(caps);
|
||||
if (hp->clkbase == 0) {
|
||||
sc_host.clkbase = SDHC_BASE_FREQ_KHZ(caps);
|
||||
if (sc_host.clkbase == 0) {
|
||||
/* The attachment driver must tell us. */
|
||||
gecko_printf("sdhc: base clock frequency unknown\n");
|
||||
goto err;
|
||||
} else if (hp->clkbase < 10000 || hp->clkbase > 63000) {
|
||||
} else if (sc_host.clkbase < 10000 || sc_host.clkbase > 63000) {
|
||||
/* SDHC 1.0 supports only 10-63 MHz. */
|
||||
gecko_printf("sdhc: base clock frequency out of range: %u MHz\n",
|
||||
hp->clkbase / 1000);
|
||||
sc_host.clkbase / 1000);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -214,41 +204,17 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot,
|
||||
* capabilities. (2.2.15)
|
||||
*/
|
||||
|
||||
SET(hp->ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V);
|
||||
|
||||
/*
|
||||
* Determine the maximum block length supported by the host
|
||||
* controller. (2.2.24)
|
||||
*/
|
||||
switch((caps >> SDHC_MAX_BLK_LEN_SHIFT) & SDHC_MAX_BLK_LEN_MASK) {
|
||||
case SDHC_MAX_BLK_LEN_512:
|
||||
hp->maxblklen = 512;
|
||||
break;
|
||||
case SDHC_MAX_BLK_LEN_1024:
|
||||
hp->maxblklen = 1024;
|
||||
break;
|
||||
case SDHC_MAX_BLK_LEN_2048:
|
||||
hp->maxblklen = 2048;
|
||||
break;
|
||||
default:
|
||||
hp->maxblklen = 1;
|
||||
break;
|
||||
}
|
||||
SET(sc_host.ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V);
|
||||
|
||||
/*
|
||||
* Attach the generic SD/MMC bus driver. (The bus driver must
|
||||
* not invoke any chipset functions before it is attached.)
|
||||
*/
|
||||
bzero(&saa, sizeof(saa));
|
||||
saa.saa_busname = "sdmmc";
|
||||
saa.sch = hp;
|
||||
|
||||
sdmmc_attach(hp, "sdhc", ioh);
|
||||
sdmmc_attach(&sc_host);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
sc->sc_nhosts--;
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -257,17 +223,10 @@ err:
|
||||
* Shutdown hook established by or called from attachment driver.
|
||||
*/
|
||||
void
|
||||
sdhc_shutdown(void *arg)
|
||||
sdhc_shutdown(void)
|
||||
{
|
||||
struct sdhc_softc *sc = arg;
|
||||
struct sdhc_host *hp;
|
||||
int i;
|
||||
|
||||
/* XXX chip locks up if we don't disable it before reboot. */
|
||||
for (i = 0; i < sc->sc_nhosts; i++) {
|
||||
hp = &sc->sc_host[i];
|
||||
(void)sdhc_host_reset(hp);
|
||||
}
|
||||
(void)sdhc_host_reset(&sc_host);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -276,9 +235,8 @@ sdhc_shutdown(void *arg)
|
||||
* cards are removed, upon resume, and during error recovery.
|
||||
*/
|
||||
int
|
||||
sdhc_host_reset(sdmmc_chipset_handle_t sch)
|
||||
sdhc_host_reset(struct sdhc_host *hp)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
u_int16_t imask;
|
||||
int error;
|
||||
|
||||
@ -313,27 +271,12 @@ sdhc_host_reset(sdmmc_chipset_handle_t sch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
sdhc_host_ocr(sdmmc_chipset_handle_t sch)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
return hp->ocr;
|
||||
}
|
||||
|
||||
int
|
||||
sdhc_host_maxblklen(sdmmc_chipset_handle_t sch)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
return hp->maxblklen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return non-zero if the card is currently inserted.
|
||||
*/
|
||||
int
|
||||
sdhc_card_detect(sdmmc_chipset_handle_t sch)
|
||||
sdhc_card_detect(struct sdhc_host *hp)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
return ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CARD_INSERTED) ?
|
||||
1 : 0;
|
||||
}
|
||||
@ -343,10 +286,8 @@ sdhc_card_detect(sdmmc_chipset_handle_t sch)
|
||||
* Return zero on success.
|
||||
*/
|
||||
int
|
||||
sdhc_bus_power(sdmmc_chipset_handle_t sch, u_int32_t ocr)
|
||||
sdhc_bus_power(struct sdhc_host *hp, u_int32_t ocr)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
|
||||
gecko_printf("sdhc_bus_power(%u)\n", ocr);
|
||||
/* Disable bus power before voltage change. */
|
||||
HWRITE1(hp, SDHC_POWER_CTL, 0);
|
||||
@ -363,7 +304,7 @@ sdhc_bus_power(sdmmc_chipset_handle_t sch, u_int32_t ocr)
|
||||
*/
|
||||
HWRITE1(hp, SDHC_POWER_CTL, (SDHC_VOLTAGE_3_3V << SDHC_VOLTAGE_SHIFT) |
|
||||
SDHC_BUS_POWER);
|
||||
sdmmc_delay(10000);
|
||||
udelay(10000);
|
||||
|
||||
/*
|
||||
* The host system may not power the bus due to battery low,
|
||||
@ -399,12 +340,10 @@ sdhc_clock_divisor(struct sdhc_host *hp, u_int freq)
|
||||
* Return zero on success.
|
||||
*/
|
||||
int
|
||||
sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
|
||||
sdhc_bus_clock(struct sdhc_host *hp, int freq)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
int div;
|
||||
int timo;
|
||||
int error = 0;
|
||||
|
||||
gecko_printf("%s(%d)\n", __FUNCTION__, freq);
|
||||
#ifdef DIAGNOSTIC
|
||||
@ -414,52 +353,39 @@ sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
|
||||
gecko_printf("sdhc_sdclk_frequency_select: command in progress\n");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Stop SD clock before changing the frequency.
|
||||
*/
|
||||
/* Stop SD clock before changing the frequency. */
|
||||
HWRITE2(hp, SDHC_CLOCK_CTL, 0);
|
||||
if (freq == SDMMC_SDCLK_OFF)
|
||||
goto ret;
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Set the minimum base clock frequency divisor.
|
||||
*/
|
||||
/* Set the minimum base clock frequency divisor. */
|
||||
if ((div = sdhc_clock_divisor(hp, freq)) < 0) {
|
||||
/* Invalid base clock frequency or `freq' value. */
|
||||
error = EINVAL;
|
||||
goto ret;
|
||||
return EINVAL;
|
||||
}
|
||||
HWRITE2(hp, SDHC_CLOCK_CTL, div << SDHC_SDCLK_DIV_SHIFT);
|
||||
|
||||
/*
|
||||
* Start internal clock. Wait 10ms for stabilization.
|
||||
*/
|
||||
/* Start internal clock. Wait 10ms for stabilization. */
|
||||
HSET2(hp, SDHC_CLOCK_CTL, SDHC_INTCLK_ENABLE);
|
||||
for (timo = 1000; timo > 0; timo--) {
|
||||
if (ISSET(HREAD2(hp, SDHC_CLOCK_CTL), SDHC_INTCLK_STABLE))
|
||||
break;
|
||||
sdmmc_delay(10);
|
||||
udelay(10);
|
||||
}
|
||||
if (timo == 0) {
|
||||
gecko_printf("sdhc: internal clock never stabilized\n");
|
||||
error = ETIMEDOUT;
|
||||
goto ret;
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable SD clock.
|
||||
*/
|
||||
/* Enable SD clock. */
|
||||
HSET2(hp, SDHC_CLOCK_CTL, SDHC_SDCLK_ENABLE);
|
||||
|
||||
ret:
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sdhc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable)
|
||||
sdhc_card_intr_mask(struct sdhc_host *hp, int enable)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
|
||||
if (enable) {
|
||||
HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
|
||||
HSET2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
|
||||
@ -470,10 +396,8 @@ sdhc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable)
|
||||
}
|
||||
|
||||
void
|
||||
sdhc_card_intr_ack(sdmmc_chipset_handle_t sch)
|
||||
sdhc_card_intr_ack(struct sdhc_host *hp)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
|
||||
HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
|
||||
}
|
||||
|
||||
@ -487,16 +411,15 @@ sdhc_wait_state(struct sdhc_host *hp, u_int32_t mask, u_int32_t value)
|
||||
if (((state = HREAD4(hp, SDHC_PRESENT_STATE)) & mask)
|
||||
== value)
|
||||
return 0;
|
||||
sdmmc_delay(10000);
|
||||
udelay(10000);
|
||||
}
|
||||
DPRINTF(0,("sdhc: timeout waiting for %x (state=%d)\n", value, state));
|
||||
return ETIMEDOUT;
|
||||
}
|
||||
|
||||
void
|
||||
sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
|
||||
sdhc_exec_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
int error;
|
||||
|
||||
if (cmd->c_datalen > 0)
|
||||
@ -509,8 +432,7 @@ sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
|
||||
cmd->c_timeout = SDHC_COMMAND_TIMEOUT;
|
||||
}
|
||||
|
||||
|
||||
sdhc_reset_intr_status(hp);
|
||||
hp->intr_status = 0;
|
||||
|
||||
/*
|
||||
* Start the MMC command, or mark `cmd' as failed and return.
|
||||
@ -563,9 +485,6 @@ sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
|
||||
if (cmd->c_error == 0 && cmd->c_datalen > 0)
|
||||
sdhc_transfer_data(hp, cmd);
|
||||
|
||||
/* Turn off the LED. */
|
||||
HCLR1(hp, SDHC_HOST_CTL, SDHC_LED_ON);
|
||||
|
||||
DPRINTF(1,("sdhc: cmd %u done (flags=%#x error=%d prev state=%d)\n",
|
||||
cmd->c_opcode, cmd->c_flags, cmd->c_error, (cmd->c_resp[0] >> 9) & 15));
|
||||
SET(cmd->c_flags, SCF_ITSDONE);
|
||||
@ -647,9 +566,6 @@ sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
|
||||
if ((error = sdhc_wait_state(hp, SDHC_CMD_INHIBIT_MASK, 0)) != 0)
|
||||
return error;
|
||||
|
||||
/* Alert the user not to remove the card. */
|
||||
HSET1(hp, SDHC_HOST_CTL, SDHC_LED_ON);
|
||||
|
||||
if (ISSET(hp->flags, SHF_USE_DMA) && cmd->c_datalen > 0) {
|
||||
cmd->c_resid = blkcount;
|
||||
cmd->c_buf = cmd->c_data;
|
||||
@ -751,7 +667,7 @@ sdhc_soft_reset(struct sdhc_host *hp, int mask)
|
||||
for (timo = 10; timo > 0; timo--) {
|
||||
if (!ISSET(HREAD1(hp, SDHC_SOFTWARE_RESET), mask))
|
||||
break;
|
||||
sdmmc_delay(10000);
|
||||
udelay(10000);
|
||||
HWRITE1(hp, SDHC_SOFTWARE_RESET, 0);
|
||||
}
|
||||
if (timo == 0) {
|
||||
@ -762,12 +678,6 @@ sdhc_soft_reset(struct sdhc_host *hp, int mask)
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void sdhc_reset_intr_status(struct sdhc_host *hp)
|
||||
{
|
||||
hp->intr_status = 0;
|
||||
}
|
||||
|
||||
int
|
||||
sdhc_wait_intr_debug(const char *funcname, int line, struct sdhc_host *hp, int mask, int timo)
|
||||
{
|
||||
@ -778,7 +688,6 @@ sdhc_wait_intr_debug(const char *funcname, int line, struct sdhc_host *hp, int m
|
||||
|
||||
status = hp->intr_status & mask;
|
||||
|
||||
|
||||
for (; timo > 0; timo--) {
|
||||
#ifndef CAN_HAZ_IRQ
|
||||
sdhc_irq(); // seems backwards but ok
|
||||
@ -825,98 +734,77 @@ sdhc_wait_intr_debug(const char *funcname, int line, struct sdhc_host *hp, int m
|
||||
* Established by attachment driver at interrupt priority IPL_SDMMC.
|
||||
*/
|
||||
int
|
||||
sdhc_intr(void *arg)
|
||||
sdhc_intr(void)
|
||||
{
|
||||
struct sdhc_softc *sc = arg;
|
||||
int host;
|
||||
int done = 0;
|
||||
u_int16_t status;
|
||||
|
||||
/* We got an interrupt, but we don't know from which slot. */
|
||||
for (host = 0; host < sc->sc_nhosts; host++) {
|
||||
struct sdhc_host *hp = &sc->sc_host[host];
|
||||
u_int16_t status;
|
||||
DPRINTF(1,("shdc_intr():\n"));
|
||||
sdhc_dump_regs(&sc_host);
|
||||
|
||||
if (hp == NULL)
|
||||
continue;
|
||||
/* Find out which interrupts are pending. */
|
||||
status = HREAD2(&sc_host, SDHC_NINTR_STATUS);
|
||||
if (!ISSET(status, SDHC_NINTR_STATUS_MASK)) {
|
||||
DPRINTF(1, ("unknown interrupt\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DPRINTF(1,("shdc_intr(%d):\n", host));
|
||||
sdhc_dump_regs(hp);
|
||||
/* Acknowledge the interrupts we are about to handle. */
|
||||
HWRITE2(&sc_host, SDHC_NINTR_STATUS, status);
|
||||
DPRINTF(2,("sdhc: interrupt status=%d\n", status));
|
||||
|
||||
/* Find out which interrupts are pending. */
|
||||
status = HREAD2(hp, SDHC_NINTR_STATUS);
|
||||
if (!ISSET(status, SDHC_NINTR_STATUS_MASK))
|
||||
continue; /* no interrupt for us */
|
||||
/* Service error interrupts. */
|
||||
if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
|
||||
u_int16_t error;
|
||||
u_int16_t signal;
|
||||
|
||||
/* Acknowledge the interrupts we are about to handle. */
|
||||
HWRITE2(hp, SDHC_NINTR_STATUS, status);
|
||||
DPRINTF(2,("sdhc: interrupt status=%d\n", status));
|
||||
/* Acknowledge error interrupts. */
|
||||
error = HREAD2(&sc_host, SDHC_EINTR_STATUS);
|
||||
signal = HREAD2(&sc_host, SDHC_EINTR_SIGNAL_EN);
|
||||
HWRITE2(&sc_host, SDHC_EINTR_SIGNAL_EN, 0);
|
||||
(void)sdhc_soft_reset(&sc_host, SDHC_RESET_DAT|SDHC_RESET_CMD);
|
||||
if (sc_host.data_command == 1) {
|
||||
sc_host.data_command = 0;
|
||||
|
||||
|
||||
/* Claim this interrupt. */
|
||||
done = 1;
|
||||
|
||||
/*
|
||||
* Service error interrupts.
|
||||
*/
|
||||
if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
|
||||
u_int16_t error;
|
||||
u_int16_t signal;
|
||||
|
||||
/* Acknowledge error interrupts. */
|
||||
error = HREAD2(hp, SDHC_EINTR_STATUS);
|
||||
signal = HREAD2(hp, SDHC_EINTR_SIGNAL_EN);
|
||||
HWRITE2(hp, SDHC_EINTR_SIGNAL_EN, 0);
|
||||
(void)sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD);
|
||||
if (hp->data_command == 1) {
|
||||
hp->data_command = 0;
|
||||
|
||||
// TODO: add a way to send commands from irq
|
||||
// context and uncomment this
|
||||
// sdmmc_abort();
|
||||
}
|
||||
HWRITE2(hp, SDHC_EINTR_STATUS, error);
|
||||
HWRITE2(hp, SDHC_EINTR_SIGNAL_EN, signal);
|
||||
|
||||
DPRINTF(2,("sdhc: error interrupt, status=%d\n", error));
|
||||
|
||||
if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR|
|
||||
SDHC_DATA_TIMEOUT_ERROR)) {
|
||||
hp->intr_error_status |= error;
|
||||
hp->intr_status |= status;
|
||||
}
|
||||
// TODO: add a way to send commands from irq
|
||||
// context and uncomment this
|
||||
// sdmmc_abort();
|
||||
}
|
||||
HWRITE2(&sc_host, SDHC_EINTR_STATUS, error);
|
||||
HWRITE2(&sc_host, SDHC_EINTR_SIGNAL_EN, signal);
|
||||
|
||||
#ifdef CAN_HAZ_IPC
|
||||
/*
|
||||
* Wake up the sdmmc event thread to scan for cards.
|
||||
*/
|
||||
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) {
|
||||
// this pushes a request to the slow queue so that we
|
||||
// don't block other IRQs.
|
||||
ipc_enqueue_slow(IPC_DEV_SDHC, IPC_SDHC_DISCOVER, 0);
|
||||
}
|
||||
#endif
|
||||
DPRINTF(2,("sdhc: error interrupt, status=%d\n", error));
|
||||
|
||||
/*
|
||||
* Wake up the blocking process to service command
|
||||
* related interrupt(s).
|
||||
*/
|
||||
if (ISSET(status, SDHC_BUFFER_READ_READY|
|
||||
SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE|
|
||||
SDHC_TRANSFER_COMPLETE|SDHC_DMA_INTERRUPT)) {
|
||||
hp->intr_status |= status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Service SD card interrupts.
|
||||
*/
|
||||
if (ISSET(status, SDHC_CARD_INTERRUPT)) {
|
||||
// DPRINTF(0,("%s: card interrupt\n", HDEVNAME(hp)));
|
||||
HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
|
||||
// sdmmc_card_intr(hp->sdmmc);
|
||||
if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR|
|
||||
SDHC_DATA_TIMEOUT_ERROR)) {
|
||||
sc_host.intr_error_status |= error;
|
||||
sc_host.intr_status |= status;
|
||||
}
|
||||
}
|
||||
return done;
|
||||
|
||||
#ifdef CAN_HAZ_IPC
|
||||
/* Wake up the sdmmc event thread to scan for cards. */
|
||||
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) {
|
||||
// this pushes a request to the slow queue so that we
|
||||
// don't block other IRQs.
|
||||
ipc_enqueue_slow(IPC_DEV_SDHC, IPC_SDHC_DISCOVER, 0);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Wake up the blocking process to service command
|
||||
* related interrupt(s).
|
||||
*/
|
||||
if (ISSET(status, SDHC_BUFFER_READ_READY|
|
||||
SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE|
|
||||
SDHC_TRANSFER_COMPLETE|SDHC_DMA_INTERRUPT)) {
|
||||
sc_host.intr_status |= status;
|
||||
}
|
||||
|
||||
/* Service SD card interrupts. */
|
||||
if (ISSET(status, SDHC_CARD_INTERRUPT)) {
|
||||
DPRINTF(0,("sdhc: card interrupt\n"));
|
||||
HCLR2(&sc_host, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef SDHC_DEBUG
|
||||
@ -947,15 +835,10 @@ sdhc_dump_regs(struct sdhc_host *hp)
|
||||
#endif
|
||||
|
||||
#include "hollywood.h"
|
||||
#ifdef LOADER
|
||||
static struct sdhc_softc __softc;
|
||||
#else
|
||||
static struct sdhc_softc __softc MEM2_BSS;
|
||||
#endif
|
||||
|
||||
void sdhc_irq(void)
|
||||
{
|
||||
sdhc_intr(&__softc);
|
||||
sdhc_intr();
|
||||
}
|
||||
|
||||
void sdhc_init(void)
|
||||
@ -963,18 +846,15 @@ void sdhc_init(void)
|
||||
#ifdef CAN_HAZ_IRQ
|
||||
irq_enable(IRQ_SDHC);
|
||||
#endif
|
||||
memset(&__softc, 0, sizeof(__softc));
|
||||
sdhc_host_found(&__softc, 0, SDHC_REG_BASE, 1);
|
||||
// sdhc_host_found(&__softc, 0, SDHC_REG_BASE + 0x100, 1);
|
||||
// sdhc_host_found(&__softc, 0, 0x0d080000, 1);
|
||||
sdhc_host_found(0, SDHC_REG_BASE, 1);
|
||||
}
|
||||
|
||||
void sdhc_exit(void)
|
||||
{
|
||||
#ifdef CAN_HAZ_IRQ
|
||||
irq_disable(IRQ_SDHC);
|
||||
irq_disable(IRQ_SDHC);
|
||||
#endif
|
||||
sdhc_shutdown();
|
||||
sdhc_shutdown();
|
||||
}
|
||||
|
||||
#ifdef CAN_HAZ_IPC
|
||||
@ -987,6 +867,7 @@ void sdhc_ipc(volatile ipc_request *req)
|
||||
case IPC_SDHC_EXIT:
|
||||
sdhc_exit();
|
||||
ipc_post(req->code, req->tag, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
14
sdhc.h
14
sdhc.h
@ -25,16 +25,10 @@
|
||||
#include "ipc.h"
|
||||
#endif
|
||||
#include "sdmmc.h"
|
||||
|
||||
#define SDHC_MAX_HOSTS 4
|
||||
|
||||
struct sdhc_host {
|
||||
struct sdhc_softc *sc; /* host controller device */
|
||||
struct device *sdmmc; /* generic SD/MMC device */
|
||||
bus_space_tag_t iot; /* host register set tag */
|
||||
bus_space_handle_t ioh; /* host register set handle */
|
||||
u_int clkbase; /* base clock frequency in KHz */
|
||||
int maxblklen; /* maximum block length */
|
||||
int flags; /* flags for this host */
|
||||
u_int32_t ocr; /* OCR value from capabilities */
|
||||
u_int8_t regs[14]; /* host controller state */
|
||||
@ -174,11 +168,6 @@ void sdhc_ipc(volatile ipc_request *req);
|
||||
#define SDHC_VOLTAGE_SUPP_3_3V (1<<24)
|
||||
#define SDHC_DMA_SUPPORT (1<<22)
|
||||
#define SDHC_HIGH_SPEED_SUPP (1<<21)
|
||||
#define SDHC_MAX_BLK_LEN_512 0
|
||||
#define SDHC_MAX_BLK_LEN_1024 1
|
||||
#define SDHC_MAX_BLK_LEN_2048 2
|
||||
#define SDHC_MAX_BLK_LEN_SHIFT 16
|
||||
#define SDHC_MAX_BLK_LEN_MASK 0x3
|
||||
#define SDHC_BASE_FREQ_SHIFT 8
|
||||
#define SDHC_BASE_FREQ_MASK 0x3f
|
||||
#define SDHC_TIMEOUT_FREQ_UNIT (1<<7) /* 0=KHz, 1=MHz */
|
||||
@ -208,12 +197,9 @@ void sdhc_ipc(volatile ipc_request *req);
|
||||
#define SDHC_VENDOR_VERSION(hcv) \
|
||||
(((hcv) >> SDHC_VENDOR_VERS_SHIFT) & SDHC_VENDOR_VERS_MASK)
|
||||
|
||||
//typedef void *sdmmc_chipset_handle_t;
|
||||
struct sdmmc_command;
|
||||
|
||||
int sdhc_host_reset(struct sdhc_host *hp);
|
||||
u_int32_t sdhc_host_ocr(struct sdhc_host *hp);
|
||||
int sdhc_host_maxblklen(struct sdhc_host *hp);
|
||||
int sdhc_card_detect(struct sdhc_host *hp);
|
||||
int sdhc_bus_power(struct sdhc_host *hp, u_int32_t);
|
||||
int sdhc_bus_clock(struct sdhc_host *hp, int);
|
||||
|
150
sdmmc.c
150
sdmmc.c
@ -25,10 +25,7 @@ static int sdmmcdebug = 0;
|
||||
#endif
|
||||
|
||||
struct sdmmc_card {
|
||||
struct sdmmc_chip_functions *functions;
|
||||
sdmmc_chipset_handle_t handle;
|
||||
char name[30];
|
||||
int no;
|
||||
int inserted;
|
||||
int sdhc_blockmode;
|
||||
int selected;
|
||||
@ -41,35 +38,22 @@ struct sdmmc_card {
|
||||
};
|
||||
|
||||
#ifdef LOADER
|
||||
static struct sdmmc_card cards[SDHC_MAX_HOSTS];
|
||||
static struct sdmmc_card card;
|
||||
#else
|
||||
static struct sdmmc_card cards[SDHC_MAX_HOSTS] MEM2_BSS;
|
||||
static struct sdmmc_card card MEM2_BSS;
|
||||
#endif
|
||||
|
||||
static int n_cards = 0;
|
||||
|
||||
void sdmmc_attach(sdmmc_chipset_handle_t handle, const char *name, int no)
|
||||
void sdmmc_attach(sdmmc_chipset_handle_t handle)
|
||||
{
|
||||
struct sdmmc_card *c;
|
||||
memset(&card, 0, sizeof(card));
|
||||
|
||||
if (n_cards >= SDHC_MAX_HOSTS) {
|
||||
gecko_printf("n_cards(%d) >= %d!\n", n_cards, SDHC_MAX_HOSTS);
|
||||
gecko_printf("starlet is soo going to crash very soon...\n");
|
||||
}
|
||||
card.handle = handle;
|
||||
|
||||
c = &cards[n_cards++];
|
||||
memset(c, 0, sizeof(*c));
|
||||
DPRINTF(0, ("sdmmc: attached new SD/MMC card\n"));
|
||||
|
||||
c->handle = handle;
|
||||
c->no = no;
|
||||
strlcpy(c->name, name, sizeof(c->name));
|
||||
sdhc_host_reset(card.handle);
|
||||
|
||||
DPRINTF(0, ("sdmmc: attached new SD/MMC card %d for host [%s:%d]\n",
|
||||
n_cards-1, c->name, c->no));
|
||||
|
||||
sdhc_host_reset(c->handle);
|
||||
|
||||
if (sdhc_card_detect(c->handle)) {
|
||||
if (sdhc_card_detect(card.handle)) {
|
||||
DPRINTF(1, ("card is inserted. starting init sequence.\n"));
|
||||
sdmmc_needs_discover();
|
||||
}
|
||||
@ -83,33 +67,32 @@ void sdmmc_abort(void) {
|
||||
cmd.c_opcode = MMC_STOP_TRANSMISSION;
|
||||
cmd.c_arg = 0;
|
||||
cmd.c_flags = SCF_RSP_R1B;
|
||||
sdhc_exec_command(&cards[0].handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
}
|
||||
|
||||
void sdmmc_needs_discover(void)
|
||||
{
|
||||
struct sdmmc_card *c = &cards[0];
|
||||
struct sdmmc_command cmd;
|
||||
u32 ocr;
|
||||
|
||||
DPRINTF(0, ("sdmmc: card needs discovery.\n"));
|
||||
sdhc_host_reset(c->handle);
|
||||
c->new_card = 1;
|
||||
sdhc_host_reset(card.handle);
|
||||
card.new_card = 1;
|
||||
|
||||
if (!sdhc_card_detect(c->handle)) {
|
||||
if (!sdhc_card_detect(card.handle)) {
|
||||
DPRINTF(1, ("sdmmc: card (no longer?) inserted.\n"));
|
||||
c->inserted = 0;
|
||||
card.inserted = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINTF(1, ("sdmmc: enabling power\n"));
|
||||
if (sdhc_bus_power(c->handle, 1) != 0) {
|
||||
if (sdhc_bus_power(card.handle, 1) != 0) {
|
||||
gecko_printf("sdmmc: powerup failed for card\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
DPRINTF(1, ("sdmmc: enabling clock\n"));
|
||||
if (sdhc_bus_clock(c->handle, SDMMC_DEFAULT_CLOCK) != 0) {
|
||||
if (sdhc_bus_clock(card.handle, SDMMC_DEFAULT_CLOCK) != 0) {
|
||||
gecko_printf("sdmmc: could not enable clock for card\n");
|
||||
goto out_power;
|
||||
}
|
||||
@ -119,7 +102,7 @@ void sdmmc_needs_discover(void)
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.c_opcode = MMC_GO_IDLE_STATE;
|
||||
cmd.c_flags = SCF_RSP_R0;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
|
||||
if (cmd.c_error) {
|
||||
gecko_printf("sdmmc: GO_IDLE_STATE failed with %d\n", cmd.c_error);
|
||||
@ -134,9 +117,9 @@ void sdmmc_needs_discover(void)
|
||||
cmd.c_arg = 0x1aa;
|
||||
cmd.c_flags = SCF_RSP_R7;
|
||||
cmd.c_timeout = 100;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
|
||||
ocr = sdhc_host_ocr(c->handle);
|
||||
ocr = card.handle->ocr;
|
||||
if (cmd.c_error || (cmd.c_resp[0] & 0xff) != 0xaa)
|
||||
ocr &= ~SD_OCR_SDHC_CAP;
|
||||
else
|
||||
@ -151,7 +134,7 @@ void sdmmc_needs_discover(void)
|
||||
cmd.c_opcode = MMC_APP_CMD;
|
||||
cmd.c_arg = 0;
|
||||
cmd.c_flags = SCF_RSP_R1;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
|
||||
if (cmd.c_error)
|
||||
continue;
|
||||
@ -160,7 +143,7 @@ void sdmmc_needs_discover(void)
|
||||
cmd.c_opcode = SD_APP_OP_COND;
|
||||
cmd.c_arg = ocr;
|
||||
cmd.c_flags = SCF_RSP_R3;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
if (cmd.c_error)
|
||||
continue;
|
||||
|
||||
@ -175,10 +158,10 @@ void sdmmc_needs_discover(void)
|
||||
}
|
||||
|
||||
if (ISSET(MMC_R1(cmd.c_resp), SD_OCR_SDHC_CAP))
|
||||
c->sdhc_blockmode = 1;
|
||||
card.sdhc_blockmode = 1;
|
||||
else
|
||||
c->sdhc_blockmode = 0;
|
||||
DPRINTF(2, ("sdmmc: SDHC: %d\n", c->sdhc_blockmode));
|
||||
card.sdhc_blockmode = 0;
|
||||
DPRINTF(2, ("sdmmc: SDHC: %d\n", card.sdhc_blockmode));
|
||||
|
||||
u8 *resp;
|
||||
DPRINTF(2, ("sdmmc: MMC_ALL_SEND_CID\n"));
|
||||
@ -186,13 +169,13 @@ void sdmmc_needs_discover(void)
|
||||
cmd.c_opcode = MMC_ALL_SEND_CID;
|
||||
cmd.c_arg = 0;
|
||||
cmd.c_flags = SCF_RSP_R2;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
if (cmd.c_error) {
|
||||
gecko_printf("sdmmc: MMC_ALL_SEND_CID failed with %d\n", cmd.c_error);
|
||||
goto out_clock;
|
||||
}
|
||||
|
||||
c->cid = MMC_R1(cmd.c_resp);
|
||||
card.cid = MMC_R1(cmd.c_resp);
|
||||
resp = (u8 *)cmd.c_resp;
|
||||
gecko_printf("CID: mid=%02x name='%c%c%c%c%c%c%c' prv=%d.%d psn=%02x%02x%02x%02x mdt=%d/%d\n", resp[14],
|
||||
resp[13],resp[12],resp[11],resp[10],resp[9],resp[8],resp[7], resp[6], resp[5] >> 4, resp[5] & 0xf,
|
||||
@ -203,23 +186,23 @@ void sdmmc_needs_discover(void)
|
||||
cmd.c_opcode = SD_SEND_RELATIVE_ADDR;
|
||||
cmd.c_arg = 0;
|
||||
cmd.c_flags = SCF_RSP_R6;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
if (cmd.c_error) {
|
||||
gecko_printf("sdmmc: SD_SEND_RCA failed with %d\n", cmd.c_error);
|
||||
goto out_clock;
|
||||
}
|
||||
|
||||
c->rca = MMC_R1(cmd.c_resp)>>16;
|
||||
DPRINTF(2, ("sdmmc: rca: %08x\n", c->rca));
|
||||
card.rca = MMC_R1(cmd.c_resp)>>16;
|
||||
DPRINTF(2, ("sdmmc: rca: %08x\n", card.rca));
|
||||
|
||||
c->selected = 0;
|
||||
c->inserted = 1;
|
||||
card.selected = 0;
|
||||
card.inserted = 1;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.c_opcode = MMC_SEND_CSD;
|
||||
cmd.c_arg = ((u32)c->rca)<<16;
|
||||
cmd.c_arg = ((u32)card.rca)<<16;
|
||||
cmd.c_flags = SCF_RSP_R2;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
if (cmd.c_error) {
|
||||
gecko_printf("sdmmc: MMC_SEND_CSD failed with %d\n", cmd.c_error);
|
||||
goto out_power;
|
||||
@ -235,8 +218,8 @@ void sdmmc_needs_discover(void)
|
||||
if (resp[13] == 0xe) { // sdhc
|
||||
unsigned int c_size = resp[7] << 16 | resp[6] << 8 | resp[5];
|
||||
gecko_printf("sdmmc: sdhc mode, c_size=%u, card size = %uk\n", c_size, (c_size + 1)* 512);
|
||||
c->timeout = 250 * 1000000; // spec says read timeout is 100ms and write/erase timeout is 250ms
|
||||
c->num_sectors = (c_size + 1) * 1024; // number of 512-byte sectors
|
||||
card.timeout = 250 * 1000000; // spec says read timeout is 100ms and write/erase timeout is 250ms
|
||||
card.num_sectors = (c_size + 1) * 1024; // number of 512-byte sectors
|
||||
}
|
||||
else {
|
||||
unsigned int taac, nsac, read_bl_len, c_size, c_size_mult;
|
||||
@ -253,9 +236,9 @@ void sdmmc_needs_discover(void)
|
||||
taac, nsac, read_bl_len, c_size, c_size_mult, (c_size + 1) * (4 << c_size_mult) * (1 << read_bl_len));
|
||||
static const unsigned int time_unit[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};
|
||||
static const unsigned int time_value[] = {1, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80}; // must div by 10
|
||||
c->timeout = time_unit[taac & 7] * time_value[(taac >> 3) & 0xf] / 10;
|
||||
gecko_printf("calculated timeout = %uns\n", c->timeout);
|
||||
c->num_sectors = (c_size + 1) * (4 << c_size_mult) * (1 << read_bl_len) / 512;
|
||||
card.timeout = time_unit[taac & 7] * time_value[(taac >> 3) & 0xf] / 10;
|
||||
gecko_printf("calculated timeout = %uns\n", card.timeout);
|
||||
card.num_sectors = (c_size + 1) * (4 << c_size_mult) * (1 << read_bl_len) / 512;
|
||||
}
|
||||
|
||||
sdmmc_select();
|
||||
@ -264,19 +247,19 @@ void sdmmc_needs_discover(void)
|
||||
cmd.c_opcode = MMC_SET_BLOCKLEN;
|
||||
cmd.c_arg = SDMMC_DEFAULT_BLOCKLEN;
|
||||
cmd.c_flags = SCF_RSP_R1;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
if (cmd.c_error) {
|
||||
gecko_printf("sdmmc: MMC_SET_BLOCKLEN failed with %d\n", cmd.c_error);
|
||||
c->inserted = c->selected = 0;
|
||||
card.inserted = card.selected = 0;
|
||||
goto out_clock;
|
||||
}
|
||||
return;
|
||||
|
||||
out_clock:
|
||||
sdhc_bus_clock(c->handle, SDMMC_SDCLK_OFF);
|
||||
sdhc_bus_clock(card.handle, SDMMC_SDCLK_OFF);
|
||||
|
||||
out_power:
|
||||
sdhc_bus_power(c->handle, 0);
|
||||
sdhc_bus_power(card.handle, 0);
|
||||
out:
|
||||
return;
|
||||
}
|
||||
@ -284,17 +267,16 @@ out:
|
||||
|
||||
int sdmmc_select(void)
|
||||
{
|
||||
struct sdmmc_card *c = &cards[0];
|
||||
struct sdmmc_command cmd;
|
||||
|
||||
DPRINTF(2, ("sdmmc: MMC_SELECT_CARD\n"));
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.c_opcode = MMC_SELECT_CARD;
|
||||
cmd.c_arg = ((u32)c->rca)<<16;
|
||||
cmd.c_arg = ((u32)card.rca)<<16;
|
||||
cmd.c_flags = SCF_RSP_R1B;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
gecko_printf("%s: resp=%x\n", __FUNCTION__, MMC_R1(cmd.c_resp));
|
||||
sdhc_dump_regs(c->handle);
|
||||
sdhc_dump_regs(card.handle);
|
||||
|
||||
// gecko_printf("present state = %x\n", HREAD4(hp, SDHC_PRESENT_STATE));
|
||||
if (cmd.c_error) {
|
||||
@ -302,18 +284,16 @@ int sdmmc_select(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
c->selected = 1;
|
||||
card.selected = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdmmc_check_card(void)
|
||||
{
|
||||
struct sdmmc_card *c = &cards[0];
|
||||
|
||||
if (c->inserted == 0)
|
||||
if (card.inserted == 0)
|
||||
return SDMMC_NO_CARD;
|
||||
|
||||
if (c->new_card == 1)
|
||||
if (card.new_card == 1)
|
||||
return SDMMC_NEW_CARD;
|
||||
|
||||
return SDMMC_INSERTED;
|
||||
@ -321,10 +301,8 @@ int sdmmc_check_card(void)
|
||||
|
||||
int sdmmc_ack_card(void)
|
||||
{
|
||||
struct sdmmc_card *c = &cards[0];
|
||||
|
||||
if (c->new_card == 1) {
|
||||
c->new_card = 0;
|
||||
if (card.new_card == 1) {
|
||||
card.new_card = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -333,23 +311,22 @@ int sdmmc_ack_card(void)
|
||||
|
||||
int sdmmc_read(u32 blk_start, u32 blk_count, void *data)
|
||||
{
|
||||
struct sdmmc_card *c = &cards[0];
|
||||
struct sdmmc_command cmd;
|
||||
|
||||
gecko_printf("%s(%u, %u, %p)\n", __FUNCTION__, blk_start, blk_count, data);
|
||||
if (c->inserted == 0) {
|
||||
if (card.inserted == 0) {
|
||||
gecko_printf("sdmmc: READ: no card inserted.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c->selected == 0) {
|
||||
if (card.selected == 0) {
|
||||
if (sdmmc_select() < 0) {
|
||||
gecko_printf("sdmmc: READ: cannot select card.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (c->new_card == 1) {
|
||||
if (card.new_card == 1) {
|
||||
gecko_printf("sdmmc: new card inserted but not acknowledged yet.\n");
|
||||
return -1;
|
||||
}
|
||||
@ -357,7 +334,7 @@ int sdmmc_read(u32 blk_start, u32 blk_count, void *data)
|
||||
DPRINTF(2, ("sdmmc: MMC_READ_BLOCK_MULTIPLE\n"));
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.c_opcode = MMC_READ_BLOCK_MULTIPLE;
|
||||
if (c->sdhc_blockmode)
|
||||
if (card.sdhc_blockmode)
|
||||
cmd.c_arg = blk_start;
|
||||
else
|
||||
cmd.c_arg = blk_start * SDMMC_DEFAULT_BLOCKLEN;
|
||||
@ -365,7 +342,7 @@ int sdmmc_read(u32 blk_start, u32 blk_count, void *data)
|
||||
cmd.c_datalen = blk_count * SDMMC_DEFAULT_BLOCKLEN;
|
||||
cmd.c_blklen = SDMMC_DEFAULT_BLOCKLEN;
|
||||
cmd.c_flags = SCF_RSP_R1 | SCF_CMD_READ;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
|
||||
if (cmd.c_error) {
|
||||
gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed with %d\n", cmd.c_error);
|
||||
@ -379,22 +356,21 @@ int sdmmc_read(u32 blk_start, u32 blk_count, void *data)
|
||||
#ifndef LOADER
|
||||
int sdmmc_write(u32 blk_start, u32 blk_count, void *data)
|
||||
{
|
||||
struct sdmmc_card *c = &cards[0];
|
||||
struct sdmmc_command cmd;
|
||||
|
||||
if (c->inserted == 0) {
|
||||
if (card.inserted == 0) {
|
||||
gecko_printf("sdmmc: READ: no card inserted.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c->selected == 0) {
|
||||
if (card.selected == 0) {
|
||||
if (sdmmc_select() < 0) {
|
||||
gecko_printf("sdmmc: READ: cannot select card.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (c->new_card == 1) {
|
||||
if (card.new_card == 1) {
|
||||
gecko_printf("sdmmc: new card inserted but not acknowledged yet.\n");
|
||||
return -1;
|
||||
}
|
||||
@ -402,7 +378,7 @@ int sdmmc_write(u32 blk_start, u32 blk_count, void *data)
|
||||
DPRINTF(2, ("sdmmc: MMC_WRITE_BLOCK_MULTIPLE\n"));
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.c_opcode = MMC_WRITE_BLOCK_MULTIPLE;
|
||||
if (c->sdhc_blockmode)
|
||||
if (card.sdhc_blockmode)
|
||||
cmd.c_arg = blk_start;
|
||||
else
|
||||
cmd.c_arg = blk_start * SDMMC_DEFAULT_BLOCKLEN;
|
||||
@ -410,7 +386,7 @@ int sdmmc_write(u32 blk_start, u32 blk_count, void *data)
|
||||
cmd.c_datalen = blk_count * SDMMC_DEFAULT_BLOCKLEN;
|
||||
cmd.c_blklen = SDMMC_DEFAULT_BLOCKLEN;
|
||||
cmd.c_flags = SCF_RSP_R1;
|
||||
sdhc_exec_command(c->handle, &cmd);
|
||||
sdhc_exec_command(card.handle, &cmd);
|
||||
|
||||
if (cmd.c_error) {
|
||||
gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed with %d\n", cmd.c_error);
|
||||
@ -423,21 +399,19 @@ int sdmmc_write(u32 blk_start, u32 blk_count, void *data)
|
||||
|
||||
int sdmmc_get_sectors(void)
|
||||
{
|
||||
struct sdmmc_card *c = &cards[0];
|
||||
|
||||
if (c->inserted == 0) {
|
||||
if (card.inserted == 0) {
|
||||
gecko_printf("sdmmc: READ: no card inserted.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c->new_card == 1) {
|
||||
if (card.new_card == 1) {
|
||||
gecko_printf("sdmmc: new card inserted but not acknowledged yet.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// sdhc_error(sdhci->reg_base, "num sectors = %u", sdhci->num_sectors);
|
||||
|
||||
return c->num_sectors;
|
||||
return card.num_sectors;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
5
sdmmc.h
5
sdmmc.h
@ -15,8 +15,7 @@ Copyright (C) 2008, 2009 Sven Peter <svenpeter@gmail.com>
|
||||
|
||||
struct sdmmc_command;
|
||||
|
||||
typedef struct sdmmc_chip_functions *sdmmc_chipset_tag_t;
|
||||
typedef void *sdmmc_chipset_handle_t;
|
||||
typedef struct sdhc_host * sdmmc_chipset_handle_t;
|
||||
|
||||
/* clock frequencies for sdmmc_chip_bus_clock() */
|
||||
#define SDMMC_SDCLK_OFF 0
|
||||
@ -157,7 +156,7 @@ struct sdmmc_function {
|
||||
#define SDMMC_NEW_CARD 2
|
||||
#define SDMMC_INSERTED 3
|
||||
|
||||
void sdmmc_attach(sdmmc_chipset_handle_t handle, const char *name, int no);
|
||||
void sdmmc_attach(sdmmc_chipset_handle_t handle);
|
||||
void sdmmc_needs_discover(void);
|
||||
int sdmmc_select(void);
|
||||
int sdmmc_check_card(void);
|
||||
|
Loading…
Reference in New Issue
Block a user