Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/sdmmc - mention MMC SPI mode.
details: https://anonhg.NetBSD.org/src/rev/723d14786012
branches: trunk
changeset: 753675:723d14786012
user: nonaka <nonaka%NetBSD.org@localhost>
date: Tue Apr 06 15:10:09 2010 +0000
description:
- mention MMC SPI mode.
- support SD 4bit bus width mode.
diffstat:
sys/dev/sdmmc/sdmmc.c | 184 ++++++++++--
sys/dev/sdmmc/sdmmc_mem.c | 642 ++++++++++++++++++++++++++++++++++++++-------
sys/dev/sdmmc/sdmmcchip.h | 12 +-
sys/dev/sdmmc/sdmmcreg.h | 43 +++-
sys/dev/sdmmc/sdmmcvar.h | 69 +++-
5 files changed, 795 insertions(+), 155 deletions(-)
diffs (truncated from 1525 to 300 lines):
diff -r e80c32cbef4d -r 723d14786012 sys/dev/sdmmc/sdmmc.c
--- a/sys/dev/sdmmc/sdmmc.c Tue Apr 06 14:26:59 2010 +0000
+++ b/sys/dev/sdmmc/sdmmc.c Tue Apr 06 15:10:09 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sdmmc.c,v 1.1 2009/04/21 03:00:30 nonaka Exp $ */
+/* $NetBSD: sdmmc.c,v 1.2 2010/04/06 15:10:09 nonaka Exp $ */
/* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */
/*
@@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.1 2009/04/21 03:00:30 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.2 2010/04/06 15:10:09 nonaka Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -59,6 +59,7 @@
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/systm.h>
+#include <sys/callout.h>
#include <dev/sdmmc/sdmmc_ioreg.h>
#include <dev/sdmmc/sdmmcchip.h>
@@ -85,6 +86,7 @@
static void sdmmc_doattach(device_t);
static void sdmmc_task_thread(void *);
static void sdmmc_discover_task(void *);
+static void sdmmc_polling_card(void *);
static void sdmmc_card_attach(struct sdmmc_softc *);
static void sdmmc_card_detach(struct sdmmc_softc *, int);
static int sdmmc_print(void *, const char *);
@@ -115,6 +117,7 @@
sc->sc_dev = self;
sc->sc_sct = saa->saa_sct;
+ sc->sc_spi_sct = saa->saa_spi_sct;
sc->sc_sch = saa->saa_sch;
sc->sc_dmat = saa->saa_dmat;
sc->sc_clkmin = saa->saa_clkmin;
@@ -133,6 +136,12 @@
}
}
+ if (ISSET(sc->sc_caps, SMC_CAPS_POLL_CARD_DET)) {
+ callout_init(&sc->sc_card_detect_ch, 0);
+ callout_reset(&sc->sc_card_detect_ch, hz,
+ sdmmc_polling_card, sc);
+ }
+
SIMPLEQ_INIT(&sc->sf_head);
TAILQ_INIT(&sc->sc_tskq);
TAILQ_INIT(&sc->sc_intrq);
@@ -291,6 +300,29 @@
}
}
+static void
+sdmmc_polling_card(void *arg)
+{
+ struct sdmmc_softc *sc = (struct sdmmc_softc *)arg;
+ int card_detect;
+ int s;
+
+ s = splsdmmc();
+ card_detect = sdmmc_chip_card_detect(sc->sc_sct, sc->sc_sch);
+ if (card_detect) {
+ if (!ISSET(sc->sc_flags, SMF_CARD_PRESENT)) {
+ sdmmc_needs_discover(sc->sc_dev);
+ }
+ } else {
+ if (ISSET(sc->sc_flags, SMF_CARD_PRESENT)) {
+ sdmmc_needs_discover(sc->sc_dev);
+ }
+ }
+ splx(s);
+
+ callout_schedule(&sc->sc_card_detect_ch, hz);
+}
+
/*
* Called from process context when a card is present.
*/
@@ -325,6 +357,15 @@
}
/*
+ * Initialize the I/O functions and memory cards.
+ */
+ error = sdmmc_init(sc);
+ if (error) {
+ aprint_error_dev(sc->sc_dev, "init failed\n");
+ goto err;
+ }
+
+ /*
* Set SD/MMC bus clock.
*/
#ifdef SDMMC_DEBUG
@@ -338,15 +379,6 @@
#endif
(void)sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, sc->sc_busclk);
- /*
- * Initialize the I/O functions and memory cards.
- */
- error = sdmmc_init(sc);
- if (error) {
- aprint_error_dev(sc->sc_dev, "init failed\n");
- goto err;
- }
-
SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
if (ISSET(sc->sc_flags, SMF_IO_MODE) && sf->number < 1)
continue;
@@ -475,13 +507,16 @@
/* XXX wait for card to power up */
sdmmc_delay(100000);
- /* Initialize SD I/O card function(s). */
- error = sdmmc_io_enable(sc);
- if (error)
- goto out;
+ if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
+ /* Initialize SD I/O card function(s). */
+ error = sdmmc_io_enable(sc);
+ if (error)
+ goto out;
+ }
- /* Initialize SD/MMC memory card(s). */
- if (ISSET(sc->sc_flags, SMF_MEM_MODE))
+ /* Initialize SD/MMC memory card(s). */
+ if (ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE) ||
+ ISSET(sc->sc_flags, SMF_MEM_MODE))
error = sdmmc_mem_enable(sc);
out:
@@ -495,8 +530,10 @@
{
/* XXX complete commands if card is still present. */
- /* Make sure no card is still selected. */
- (void)sdmmc_select_card(sc, NULL);
+ if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
+ /* Make sure no card is still selected. */
+ (void)sdmmc_select_card(sc, NULL);
+ }
/* Turn off bus power and clock. */
(void)sdmmc_chip_bus_width(sc->sc_sct, sc->sc_sch, 1);
@@ -566,9 +603,11 @@
sdmmc_scan(struct sdmmc_softc *sc)
{
- /* Scan for I/O functions. */
- if (ISSET(sc->sc_flags, SMF_IO_MODE))
- sdmmc_io_scan(sc);
+ if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
+ /* Scan for I/O functions. */
+ if (ISSET(sc->sc_flags, SMF_IO_MODE))
+ sdmmc_io_scan(sc);
+ }
/* Scan for memory cards on the bus. */
if (ISSET(sc->sc_flags, SMF_MEM_MODE))
@@ -593,9 +632,12 @@
/* Initialize all identified card functions. */
SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
- if (ISSET(sc->sc_flags, SMF_IO_MODE) &&
- sdmmc_io_init(sc, sf) != 0) {
- aprint_error_dev(sc->sc_dev, "i/o init failed\n");
+ if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
+ if (ISSET(sc->sc_flags, SMF_IO_MODE) &&
+ sdmmc_io_init(sc, sf) != 0) {
+ aprint_error_dev(sc->sc_dev,
+ "i/o init failed\n");
+ }
}
if (ISSET(sc->sc_flags, SMF_MEM_MODE) &&
@@ -622,7 +664,7 @@
}
int
-sdmmc_app_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd)
+sdmmc_app_command(struct sdmmc_softc *sc, struct sdmmc_function *sf, struct sdmmc_command *cmd)
{
struct sdmmc_command acmd;
int error;
@@ -633,12 +675,18 @@
memset(&acmd, 0, sizeof(acmd));
acmd.c_opcode = MMC_APP_CMD;
- acmd.c_arg = 0;
- acmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
+ if (sf != NULL) {
+ acmd.c_arg = sf->rca << 16;
+ acmd.c_flags = SCF_CMD_AC | SCF_RSP_R1 | SCF_RSP_SPI_R1;
+ } else {
+ acmd.c_arg = 0;
+ acmd.c_flags = SCF_CMD_BCR | SCF_RSP_R1 | SCF_RSP_SPI_R1;
+ }
error = sdmmc_mmc_command(sc, &acmd);
if (error == 0) {
- if (!ISSET(MMC_R1(acmd.c_resp), MMC_R1_APP_CMD)) {
+ if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE) &&
+ !ISSET(MMC_R1(acmd.c_resp), MMC_R1_APP_CMD)) {
/* Card does not support application commands. */
error = ENODEV;
} else {
@@ -659,13 +707,13 @@
{
int error;
- DPRINTF(1,("sdmmc_mmc_command: cmd=%#x, arg=%#x, flags=%#x\n",
+ DPRINTF(1,("sdmmc_mmc_command: cmd=%d, arg=%#x, flags=%#x\n",
cmd->c_opcode, cmd->c_arg, cmd->c_flags));
/* Don't lock */
#if defined(DIAGNOSTIC) || defined(SDMMC_DEBUG)
- if (cmd->c_data) {
+ if (cmd->c_data && !ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
if (sc->sc_card == NULL)
panic("%s: deselected card\n", DEVNAME(sc));
}
@@ -698,7 +746,7 @@
memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = MMC_GO_IDLE_STATE;
- cmd.c_flags = SCF_CMD_BC | SCF_RSP_R0;
+ cmd.c_flags = SCF_CMD_BC | SCF_RSP_R0 | SCF_RSP_SPI_R1;
(void)sdmmc_mmc_command(sc, &cmd);
}
@@ -714,6 +762,9 @@
/* Don't lock */
+ if (ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE))
+ return EIO;
+
memset(&cmd, 0, sizeof(cmd));
if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
cmd.c_opcode = SD_SEND_RELATIVE_ADDR;
@@ -741,6 +792,9 @@
/* Don't lock */
+ if (ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE))
+ return EIO;
+
if (sc->sc_card == sf
|| (sf && sc->sc_card && sc->sc_card->rca == sf->rca)) {
sc->sc_card = sf;
@@ -764,11 +818,9 @@
{
int i;
- DPRINTF(1,("%s: cmd %u arg=%#x data=%p dlen=%d flags=%#x "
- "proc=\"%s\" (error %d)\n",
+ DPRINTF(1,("%s: cmd %u arg=%#x data=%p dlen=%d flags=%#x (error %d)\n",
DEVNAME(sc), cmd->c_opcode, cmd->c_arg, cmd->c_data,
- cmd->c_datalen, cmd->c_flags, curproc ? curproc->p_comm : "",
- cmd->c_error));
+ cmd->c_datalen, cmd->c_flags, cmd->c_error));
if (cmd->c_error || sdmmcdebug < 1)
return;
@@ -780,6 +832,66 @@
else if (ISSET(cmd->c_flags, SCF_RSP_PRESENT))
for (i = 0; i < 4; i++)
aprint_normal("%02x ", ((uint8_t *)cmd->c_resp)[i]);
+ else
+ aprint_normal("none");
aprint_normal("\n");
}
+
+void
+sdmmc_dump_data(const char *title, void *ptr, size_t size)
+{
+ char buf[16];
+ uint8_t *p = ptr;
+ int i, j;
+
+ printf("sdmmc_dump_data: %s\n", title ? title : "");
+ printf("--------+--------------------------------------------------+------------------+\n");
+ printf("offset | +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f | data |\n");
+ printf("--------+--------------------------------------------------+------------------+\n");
+ for (i = 0; i < (int)size; i++) {
+ if ((i % 16) == 0) {
+ printf("%08x| ", i);
+ } else if ((i % 16) == 8) {
+ printf(" ");
+ }
Home |
Main Index |
Thread Index |
Old Index