mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-24 12:19:21 +01:00
sdhctrl: use a 4bit bus
This commit is contained in:
parent
9bb8946e59
commit
1e2d42e984
46
sdhc.c
46
sdhc.c
@ -131,8 +131,6 @@ int sdhc_host_maxblklen(sdmmc_chipset_handle_t);
|
||||
int sdhc_card_detect(sdmmc_chipset_handle_t);
|
||||
int sdhc_bus_power(sdmmc_chipset_handle_t, u_int32_t);
|
||||
int sdhc_bus_clock(sdmmc_chipset_handle_t, int);
|
||||
void sdhc_card_intr_mask(sdmmc_chipset_handle_t, int);
|
||||
void sdhc_card_intr_ack(sdmmc_chipset_handle_t);
|
||||
void sdhc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
|
||||
int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *);
|
||||
int sdhc_wait_state(struct sdhc_host *, u_int32_t, u_int32_t);
|
||||
@ -141,6 +139,7 @@ int sdhc_wait_intr(struct sdhc_host *, int, int);
|
||||
void sdhc_transfer_data(struct sdhc_host *, struct sdmmc_command *);
|
||||
void sdhc_read_data(struct sdhc_host *, u_char *, int);
|
||||
void sdhc_write_data(struct sdhc_host *, u_char *, int);
|
||||
void sdhc_set_bus_width(sdmmc_chipset_handle_t, int);
|
||||
|
||||
#ifdef SDHC_DEBUG
|
||||
int sdhcdebug = 2;
|
||||
@ -163,9 +162,7 @@ struct sdmmc_chip_functions sdhc_functions = {
|
||||
sdhc_bus_clock,
|
||||
/* command execution */
|
||||
sdhc_exec_command,
|
||||
/* card interrupt */
|
||||
sdhc_card_intr_mask,
|
||||
sdhc_card_intr_ack
|
||||
sdhc_set_bus_width,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -556,28 +553,6 @@ ret:
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
sdhc_card_intr_mask(sdmmc_chipset_handle_t sch, 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);
|
||||
} else {
|
||||
HCLR2(hp, SDHC_NINTR_SIGNAL_EN, SDHC_CARD_INTERRUPT);
|
||||
HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sdhc_card_intr_ack(sdmmc_chipset_handle_t sch)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
|
||||
HSET2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
|
||||
}
|
||||
|
||||
int
|
||||
sdhc_wait_state(struct sdhc_host *hp, u_int32_t mask, u_int32_t value)
|
||||
{
|
||||
@ -830,6 +805,23 @@ sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
sdhc_set_bus_width(sdmmc_chipset_handle_t sch, int enable)
|
||||
{
|
||||
struct sdhc_host *hp = sch;
|
||||
u_int16_t hctl;
|
||||
|
||||
hctl = HREAD2(hp, SDHC_HOST_CTL);
|
||||
|
||||
if (enable)
|
||||
hctl |= SDHC_4BIT_MODE;
|
||||
else
|
||||
hctl &= ~SDHC_4BIT_MODE;
|
||||
|
||||
HWRITE2(hp, SDHC_HOST_CTL, hctl);
|
||||
|
||||
}
|
||||
|
||||
/* Prepare for another command. */
|
||||
int
|
||||
sdhc_soft_reset(struct sdhc_host *hp, int mask)
|
||||
|
38
sdmmc.c
38
sdmmc.c
@ -82,6 +82,11 @@ static inline void sdmmc_host_exec_command(struct sdmmc_card *card, struct
|
||||
{
|
||||
sdmmc_chip_exec_command(card->functions, card->handle, cmd);
|
||||
}
|
||||
static inline void sdmmc_host_set_bus_width(struct sdmmc_card *card, int
|
||||
enable)
|
||||
{
|
||||
sdmmc_chip_set_bus_width(card->functions, card->handle, enable);
|
||||
}
|
||||
|
||||
struct device *sdmmc_attach(struct sdmmc_chip_functions *functions,
|
||||
sdmmc_chipset_handle_t handle, const char *name, int no)
|
||||
@ -307,6 +312,7 @@ void sdmmc_needs_discover(struct device *dev)
|
||||
}
|
||||
|
||||
sdmmc_select(dev);
|
||||
|
||||
DPRINTF(2, ("sdmmc: MMC_SET_BLOCKLEN\n"));
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.c_opcode = MMC_SET_BLOCKLEN;
|
||||
@ -319,11 +325,43 @@ void sdmmc_needs_discover(struct device *dev)
|
||||
c->inserted = c->selected = 0;
|
||||
goto out_clock;
|
||||
}
|
||||
|
||||
/* we can assume that every card supports a 4bit bus
|
||||
* (see Simplified Physical Layer Spec, 5.6 SCR register (page 90),
|
||||
* SD_BUS_WIDTHS)
|
||||
*/
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.c_opcode = MMC_APP_CMD;
|
||||
cmd.c_arg = ((u32)c->rca)<<16;
|
||||
cmd.c_flags = SCF_RSP_R1;
|
||||
sdmmc_host_exec_command(c, &cmd);
|
||||
|
||||
if (cmd.c_error) {
|
||||
gecko_printf("sdmmc: MMC_APP_CMD failed for "
|
||||
"card %d with %d\n", no, cmd.c_error);
|
||||
goto out_power;
|
||||
}
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.c_opcode = SD_APP_SET_BUS_WIDTH;
|
||||
cmd.c_arg = SD_ARG_BUS_WIDTH_4;
|
||||
cmd.c_flags = SCF_RSP_R1;
|
||||
sdmmc_host_exec_command(c, &cmd);
|
||||
if (cmd.c_error) {
|
||||
gecko_printf("sdmmc: SD_APP_SET_BUS_WIDTH failed for "
|
||||
"card %d with %d\n", no, cmd.c_error);
|
||||
goto out_power;
|
||||
}
|
||||
|
||||
sdmmc_host_set_bus_width(c, 1);
|
||||
|
||||
return;
|
||||
|
||||
out_clock:
|
||||
out_power:
|
||||
c->inserted = c->selected = 0;
|
||||
sdmmc_host_power(c, 0);
|
||||
sdmmc_host_reset(c);
|
||||
out:
|
||||
return;
|
||||
|
||||
|
13
sdmmcchip.h
13
sdmmcchip.h
@ -38,9 +38,8 @@ struct sdmmc_chip_functions {
|
||||
/* command execution */
|
||||
void (*exec_command)(sdmmc_chipset_handle_t,
|
||||
struct sdmmc_command *);
|
||||
/* card interrupt */
|
||||
void (*card_intr_mask)(sdmmc_chipset_handle_t, int);
|
||||
void (*card_intr_ack)(sdmmc_chipset_handle_t);
|
||||
/* bus width */
|
||||
void (*set_bus_width)(sdmmc_chipset_handle_t, int);
|
||||
};
|
||||
|
||||
/* host controller reset */
|
||||
@ -62,11 +61,9 @@ struct sdmmc_chip_functions {
|
||||
/* command execution */
|
||||
#define sdmmc_chip_exec_command(tag, handle, cmdp) \
|
||||
((tag)->exec_command((handle), (cmdp)))
|
||||
/* card interrupt */
|
||||
#define sdmmc_chip_card_intr_mask(tag, handle, enable) \
|
||||
((tag)->card_intr_mask((handle), (enable)))
|
||||
#define sdmmc_chip_card_intr_ack(tag, handle) \
|
||||
((tag)->card_intr_ack((handle)))
|
||||
/* bus widht */
|
||||
#define sdmmc_chip_set_bus_width(tag, handle, enable) \
|
||||
((tag)->set_bus_width((handle), (enable)))
|
||||
|
||||
/* clock frequencies for sdmmc_chip_bus_clock() */
|
||||
#define SDMMC_SDCLK_OFF 0
|
||||
|
Loading…
Reference in New Issue
Block a user