Skip to contentSkip to conversation

mmc: add generic mmc spi driver

PATCH New Thomas Chou 4 participants 33 messages Apr 23, 2010 – Jul 5, 2010

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mmc: add generic mmc spi driver

This patch supports mmc/sd card with spi interface.
I have tested with sd and mmc cards. But there is still ocr issue with SDHC.

---
 drivers/mmc/Makefile  |    1 +
 drivers/mmc/mmc_spi.c |  252 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 253 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mmc/mmc_spi.c
drivers/mmc/Makefile +1 -0
index 1b8f5bd..d03eb47 100644
@@ -31,6 +31,7 @@ LIB	:= $(obj)libmmc.a
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
+COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
drivers/mmc/mmc_spi.c new file +252 -0

252 lines not on this page · raw message

Signature · 1 line
1.6.6.1
#1 lore raw

PATCH 1/1 mmc: add generic mmc spi driver

Quoted 3 lines · On Thursday 22 April 2010 22:53:34 Thomas Chou wrote:

This patch supports mmc/sd card with spi interface.
I have tested with sd and mmc cards. But there is still ocr issue with SDHC.

now the semi-obvious question ... how does this differ from the old spi_mmc.c driver ? i see this doesnt rely on the legacy mmc framework, but what about device/commandset support parity ?

it's too bad the new framework doesnt allow for dynamic probing like the spi layer. makes it a pain to work with a SPI/MMC card that can have the CS changed on the fly.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100422/4587a788/attachment.pgp

#2 lore raw

PATCH 1/1 mmc: add generic mmc spi driver

Quoted 11 lines · Mike Frysinger
Quoted 4 lines · On Thursday 22 April 2010 22:53:34 Thomas Chou wrote:

This patch supports mmc/sd card with spi interface.
I have tested with sd and mmc cards. But there is still ocr issue with SDHC.

now the semi-obvious question ... how does this differ from the old spi_mmc.c driver ? i see this doesnt rely on the legacy mmc framework, but what about device/commandset support parity ?

Hi Mike,

Right after playing your spi_mmc.c, I started this one based on generic mmc framework last night. I tried hard to recall my memory about mmc/sd, and hoped to catch up the merge window.

Do you mean "parity" as crc? Crc is not supported, but can be added. I make some command set translation when spi doesn't support.

Quoted 5 lines

it's too bad the new framework doesnt allow for dynamic probing like the spi layer. makes it a pain to work with a SPI/MMC card that can have the CS changed on the fly.
-mike

Maybe we can move spi_setup_slave to the mmc->init() and do probing. Or shall we add a subcommand?

Cheers,
Thomas

#3 lore raw

PATCH 1/1 mmc: add generic mmc spi driver

Quoted 8 lines · Thomas Chou

it's too bad the new framework doesnt allow for dynamic probing like the spi

Quoted 5 lines

layer. makes it a pain to work with a SPI/MMC card that can have the CS changed on the fly.
-mike

Second thought.
With generic mmc framework, we can instance multiple mmc devices. Then we can probe one of them when we want.

#ifdef CONFIG_GENERIC_MMC
int board_mmc_init(bd_t *bis)

{
     int rc = 0;
#ifdef CONFIG_MMC_SPI
     extern int mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
     mmc_spi_init(CONFIG_MMC_SPI_BUS,
               CONFIG_MMC_SPI_CS_0,
               CONFIG_MMC_SPI_SPEED,
               CONFIG_MMC_SPI_MODE);
     mmc_spi_init(CONFIG_MMC_SPI_BUS,
               CONFIG_MMC_SPI_CS_1,
               CONFIG_MMC_SPI_SPEED,
               CONFIG_MMC_SPI_MODE);
#endif
     return rc;
}

#endif

Cheers,
Thomas

#4 lore raw

PATCH 1/1 mmc: add generic mmc spi driver

Quoted 8 lines · On Friday 23 April 2010 01:55:11 Thomas Chou wrote:
Quoted 3 lines · Thomas Chou
Quoted 3 lines

it's too bad the new framework doesnt allow for dynamic probing like the spi layer. makes it a pain to work with a SPI/MMC card that can have the CS changed on the fly.

Second thought.
With generic mmc framework, we can instance multiple mmc devices. Then we can probe one of them when we want.

i dont think that's a scalable solution. what if you have multiple spi busses or 10's of GPIO CS's ? only way to scale is to have a new subcommand so people can do it themselves. a simple CONFIG_CMD_MMC_SPI command which forwards along calls to mmc_spi_init() on the fly would work.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100425/c4072e98/attachment.pgp

#5 lore raw

PATCH 1/1 mmc: add generic mmc spi driver

Quoted 12 lines · Mike Frysinger
Quoted 10 lines · On Friday 23 April 2010 01:55:11 Thomas Chou wrote:
Quoted 4 lines · Thomas Chou
Quoted 4 lines

it's too bad the new framework doesnt allow for dynamic probing like the spi layer. makes it a pain to work with a SPI/MMC card that can have the CS changed on the fly.

Second thought.
With generic mmc framework, we can instance multiple mmc devices. Then we can probe one of them when we want.

Quoted 6 lines

i dont think that's a scalable solution. what if you have multiple spi busses or 10's of GPIO CS's ? only way to scale is to have a new subcommand so people can do it themselves. a simple CONFIG_CMD_MMC_SPI command which forwards along calls to mmc_spi_init() on the fly would work. -mike

Hi Mike,

I have resolved the SDHC issue and have tested various MMC/SD cards, including writing. I will submit the patch tomorrow.

I have moved spi slave setup so that we can change the cs on the fly. We could add a subcommand, like,

mmc_spi [bus:]cs

Where should I place this command? in a new file in common dir or inside the mmc_spi driver?

Cheers,
Thomas

#6 lore raw

PATCH 1/1 mmc: add generic mmc spi driver

Quoted 7 lines · On Monday 26 April 2010 10:37:07 Thomas Chou wrote:

I have moved spi slave setup so that we can change the cs on the fly. We could add a subcommand, like,

mmc_spi [bus:]cs

Where should I place this command? in a new file in common dir or inside the mmc_spi driver?

i would keep the current board init hook you have currently so that the boards which do have static settings can leverage that, and have the mmc_spi command simply call that. i'd have the syntax be:

	mmc_spi [bus:]cs [hz [mode]]

i'd have it be a dedicated command in common/ so that people can disable it if they dont want it.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100426/05a65066/attachment.pgp

#7 lore raw

PATCH 1/1 mmc: add generic mmc spi driver

In reply to Thomas Chou
Quoted 2 lines · On Friday 23 April 2010 00:04:51 Thomas Chou wrote:

Do you mean "parity" as crc? Crc is not supported, but can be added. I make some command set translation when spi doesn't support.

i mean functionality wrt card/spec support
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100425/6445f782/attachment.pgp

#8 lore raw

PATCH v2 1/1 mmc: add generic mmc spi driver

In reply to Thomas Chou

This patch supports mmc/sd card with spi interface. It is based on the generic mmc framework. It works with SDHC and supports write.

The crc7 lib func is merged from linux and used to compute mmc command checksum.

There is a subcomamnd "mmc_spi" to setup spi bus and cs at run time.

---
v2 add crc7, use cmd58 to read ocr, add subcommand mmc_spi.

 common/Makefile       |    1 +
 common/cmd_mmc_spi.c  |   92 ++++++++++++++
 drivers/mmc/Makefile  |    1 +
 drivers/mmc/mmc_spi.c |  316 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/crc7.h  |   14 ++
 include/mmc_spi.h     |   19 +++
 lib/Makefile          |    1 +
 lib/crc7.c            |   62 ++++++++++
 8 files changed, 506 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_mmc_spi.c
 create mode 100644 drivers/mmc/mmc_spi.c
 create mode 100644 include/linux/crc7.h
 create mode 100644 include/mmc_spi.h
 create mode 100644 lib/crc7.c
common/Makefile +1 -0
index dbf7a05..ee23e2f 100644
@@ -118,6 +118,7 @@ COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
+COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 COBJS-$(CONFIG_MP) += cmd_mp.o
 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
 COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
common/cmd_mmc_spi.c new file +92 -0

92 lines not on this page · raw message

drivers/mmc/Makefile +1 -0
index 1b8f5bd..d03eb47 100644
@@ -31,6 +31,7 @@ LIB	:= $(obj)libmmc.a
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
+COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
drivers/mmc/mmc_spi.c new file +316 -0

316 lines not on this page · raw message

include/linux/crc7.h new file +14 -0
new file mode 100644
index 0000000..1786e77
@@ -0,0 +1,14 @@
+#ifndef _LINUX_CRC7_H
+#define _LINUX_CRC7_H
+#include <linux/types.h>
+
+extern const u8 crc7_syndrome_table[256];
+
+static inline u8 crc7_byte(u8 crc, u8 data)
+{
+	return crc7_syndrome_table[(crc << 1) ^ data];
+}
+
+extern u8 crc7(u8 crc, const u8 *buffer, size_t len);
+
+#endif
include/mmc_spi.h new file +19 -0
new file mode 100644
index 0000000..66aa6aa
@@ -0,0 +1,19 @@
+/*
+ * generic mmc spi driver
+ *
+ * Copyright (C) 2010 Thomas Chou <[email protected]>
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _MMC_SPI_H_
+#define _MMC_SPI_H_
+struct mmc_spi_priv {
+	struct spi_slave *slave;
+	uint bus;
+	uint cs;
+	uint speed;
+	uint mode;
+	uint ocr58;
+	uint sd_if_cond:1;
+};
+#endif
lib/Makefile +1 -0
index c45f07c..aef2893 100644
@@ -32,6 +32,7 @@ COBJS-$(CONFIG_BZIP2) += bzlib_decompress.o
 COBJS-$(CONFIG_BZIP2) += bzlib_randtable.o
 COBJS-$(CONFIG_BZIP2) += bzlib_huffman.o
 COBJS-$(CONFIG_USB_TTY) += circbuf.o
+COBJS-y += crc7.o
 COBJS-y += crc16.o
 COBJS-y += crc32.o
 COBJS-y += ctype.o
lib/crc7.c new file +62 -0

62 lines not on this page · raw message

Signature · 1 line
1.6.6.1
#9 lore raw

PATCH v3 1/1 mmc: add generic mmc spi driver

In reply to Thomas Chou

This patch supports mmc/sd card with spi interface. It is based on the generic mmc framework. It works with SDHC and supports write.

The crc7 lib func is merged from linux and used to compute mmc command checksum.

There is a subcomamnd "mmc_spi" to setup spi bus and cs at run time.

---
v3: add mmc_spi_init() proto to mmc_spi.h.
v2: add crc7, use cmd58 to read ocr, add subcommand mmc_spi.

 common/Makefile       |    1 +
 common/cmd_mmc_spi.c  |   92 ++++++++++++++
 drivers/mmc/Makefile  |    1 +
 drivers/mmc/mmc_spi.c |  316 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/crc7.h  |   14 ++
 include/mmc_spi.h     |   26 ++++
 lib/Makefile          |    1 +
 lib/crc7.c            |   62 ++++++++++
 8 files changed, 513 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_mmc_spi.c
 create mode 100644 drivers/mmc/mmc_spi.c
 create mode 100644 include/linux/crc7.h
 create mode 100644 include/mmc_spi.h
 create mode 100644 lib/crc7.c
common/Makefile +1 -0
index dbf7a05..ee23e2f 100644
@@ -118,6 +118,7 @@ COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
+COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 COBJS-$(CONFIG_MP) += cmd_mp.o
 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
 COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
common/cmd_mmc_spi.c new file +92 -0

92 lines not on this page · raw message

drivers/mmc/Makefile +1 -0
index 6fa04b8..02ed329 100644
@@ -28,6 +28,7 @@ LIB	:= $(obj)libmmc.a
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
+COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
drivers/mmc/mmc_spi.c new file +316 -0

316 lines not on this page · raw message

include/linux/crc7.h new file +14 -0
new file mode 100644
index 0000000..1786e77
@@ -0,0 +1,14 @@
+#ifndef _LINUX_CRC7_H
+#define _LINUX_CRC7_H
+#include <linux/types.h>
+
+extern const u8 crc7_syndrome_table[256];
+
+static inline u8 crc7_byte(u8 crc, u8 data)
+{
+	return crc7_syndrome_table[(crc << 1) ^ data];
+}
+
+extern u8 crc7(u8 crc, const u8 *buffer, size_t len);
+
+#endif
include/mmc_spi.h new file +26 -0
new file mode 100644
index 0000000..6c72f65
@@ -0,0 +1,26 @@
+/*
+ * generic mmc spi driver
+ *
+ * Copyright (C) 2010 Thomas Chou <[email protected]>
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _MMC_SPI_H_
+#define _MMC_SPI_H_
+
+#include <spi.h>
+#include <linux/types.h>
+
+struct mmc_spi_priv {
+	struct spi_slave *slave;
+	uint bus;
+	uint cs;
+	uint speed;
+	uint mode;
+	uint ocr58;
+	uint sd_if_cond:1;
+};
+
+int mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
+
+#endif
lib/Makefile +1 -0
index c45f07c..aef2893 100644
@@ -32,6 +32,7 @@ COBJS-$(CONFIG_BZIP2) += bzlib_decompress.o
 COBJS-$(CONFIG_BZIP2) += bzlib_randtable.o
 COBJS-$(CONFIG_BZIP2) += bzlib_huffman.o
 COBJS-$(CONFIG_USB_TTY) += circbuf.o
+COBJS-y += crc7.o
 COBJS-y += crc16.o
 COBJS-y += crc32.o
 COBJS-y += ctype.o
lib/crc7.c new file +62 -0

62 lines not on this page · raw message

Signature · 1 line
1.6.6.1
#10 lore raw

PATCH v3 1/1 mmc: add generic mmc spi driver

common/cmd_mmc_spi.c line 22

Quoted 3 lines · On Monday 26 April 2010 23:27:16 Thomas Chou wrote:
common/cmd_mmc_spi.c new file +1 -0
+	struct mmc *mmc = NULL;

useless assignment since mmc gets set shortly after

common/cmd_mmc_spi.c line 33

Quoted 11 lines
common/cmd_mmc_spi.c new file +11 -0
+	struct mmc_spi_priv *priv;
+
+	if (argc < 2)
+		goto usage;
+
+	dev_num = simple_strtoul(argv[1], &endp, 0);
+	if (*endp != 0)
+			goto usage;
+	mmc = find_mmc_device(dev_num);
+	if (!mmc || strcmp(mmc->name, "MMC_SPI"))
+			goto usage;

too many indents on the goto

also, this looks like it bails if no existing mmc spi device is found ? i thought the point of this command was to create new instances on the fly. this looks like it just reprograms the settings for an existing device.

common/cmd_mmc_spi.c line 75

Quoted 10 lines
common/cmd_mmc_spi.c new file +10 -0
+	if (bus != priv->bus || cs != priv->cs ||
+	    speed != priv->speed || mode != priv->speed) {
+		priv->bus = bus;
+		priv->cs = cs;
+		priv->speed = speed;
+		priv->mode = mode;
+		if (priv->slave) {
+			free(priv->slave);
+			priv->slave = NULL;
+		}

you shouldnt be poking the spi internals like this. use the common spi funcs to free/alloc the slave device.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100427/961b2b68/attachment.pgp

#11 lore raw

PATCH v3 1/1 mmc: add generic mmc spi driver

Hi Mike,

Quoted 8 lines · Mike Frysinger

common/cmd_mmc_spi.c line 22

Quoted 4 lines · On Monday 26 April 2010 23:27:16 Thomas Chou wrote:
common/cmd_mmc_spi.c new file +1 -0
+	struct mmc *mmc = NULL;

useless assignment since mmc gets set shortly after

OK.

Quoted 15 lines

common/cmd_mmc_spi.c line 33

Quoted 13 lines
common/cmd_mmc_spi.c new file +11 -0
+	struct mmc_spi_priv *priv;
+
+	if (argc<  2)
+		goto usage;
+
+	dev_num = simple_strtoul(argv[1],&endp, 0);
+	if (*endp != 0)
+			goto usage;
+	mmc = find_mmc_device(dev_num);
+	if (!mmc || strcmp(mmc->name, "MMC_SPI"))
+			goto usage;

too many indents on the goto

The tabs were interfered by the '+' . It is correct when applied.

Quoted 5 lines

also, this looks like it bails if no existing mmc spi device is found ? i thought the point of this command was to create new instances on the fly. this looks like it just reprograms the settings for an existing device.

OK. Now v4 patch creates a MMC dev on the fly.

Quoted 5 lines
Quoted 5 lines
common/cmd_mmc_spi.c new file +5 -0
+	if (bus != priv->bus || cs != priv->cs ||
+	    speed != priv->speed || mode != priv->speed) {
+		priv->bus = bus;
+		priv->cs = cs;
+		priv->speed = speed;
Quoted 9 lines

common/cmd_mmc_spi.c line 75

Quoted 6 lines
common/cmd_mmc_spi.c new file +5 -0
+		priv->mode = mode;
+		if (priv->slave) {
+			free(priv->slave);
+			priv->slave = NULL;
+		}

you shouldnt be poking the spi internals like this. use the common spi funcs to free/alloc the slave device.

OK.

Best regards,
Thomas

#12 lore raw

PATCH v4 1/1 mmc: add generic mmc spi driver

In reply to Thomas Chou

This patch supports mmc/sd card with spi interface. It is based on the generic mmc framework. It works with SDHC and supports write.

The crc7 lib func is merged from linux and used to compute mmc command checksum.

There is a subcomamnd "mmc_spi" to setup spi bus and cs at run time.

---
v4: change mmc_spi subcommand to search and create new mmc dev.
v3: add mmc_spi_init() proto to mmc_spi.h.
v2: add crc7, use cmd58 to read ocr, add subcommand mmc_spi.

 common/Makefile       |    1 +
 common/cmd_mmc_spi.c  |  117 ++++++++++++++++++
 drivers/mmc/Makefile  |    1 +
 drivers/mmc/mmc_spi.c |  318 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/crc7.h  |   14 ++
 include/mmc_spi.h     |   27 ++++
 lib/Makefile          |    1 +
 lib/crc7.c            |   62 ++++++++++
 8 files changed, 541 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_mmc_spi.c
 create mode 100644 drivers/mmc/mmc_spi.c
 create mode 100644 include/linux/crc7.h
 create mode 100644 include/mmc_spi.h
 create mode 100644 lib/crc7.c
common/Makefile +1 -0
index dbf7a05..ee23e2f 100644
@@ -118,6 +118,7 @@ COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
+COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 COBJS-$(CONFIG_MP) += cmd_mp.o
 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
 COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
common/cmd_mmc_spi.c new file +117 -0

117 lines not on this page · raw message

drivers/mmc/Makefile +1 -0
index 6fa04b8..02ed329 100644
@@ -28,6 +28,7 @@ LIB	:= $(obj)libmmc.a
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
+COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
drivers/mmc/mmc_spi.c new file +318 -0

318 lines not on this page · raw message

include/linux/crc7.h new file +14 -0
new file mode 100644
index 0000000..1786e77
@@ -0,0 +1,14 @@
+#ifndef _LINUX_CRC7_H
+#define _LINUX_CRC7_H
+#include <linux/types.h>
+
+extern const u8 crc7_syndrome_table[256];
+
+static inline u8 crc7_byte(u8 crc, u8 data)
+{
+	return crc7_syndrome_table[(crc << 1) ^ data];
+}
+
+extern u8 crc7(u8 crc, const u8 *buffer, size_t len);
+
+#endif
include/mmc_spi.h new file +27 -0
new file mode 100644
index 0000000..fbfa1ce
@@ -0,0 +1,27 @@
+/*
+ * generic mmc spi driver
+ *
+ * Copyright (C) 2010 Thomas Chou <[email protected]>
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _MMC_SPI_H_
+#define _MMC_SPI_H_
+
+#include <spi.h>
+#include <mmc.h>
+#include <linux/types.h>
+
+struct mmc_spi_priv {
+	struct spi_slave *slave;
+	uint bus;
+	uint cs;
+	uint speed;
+	uint mode;
+	uint ocr58;
+	uint sd_if_cond:1;
+};
+
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
+
+#endif
lib/Makefile +1 -0
index c45f07c..aef2893 100644
@@ -32,6 +32,7 @@ COBJS-$(CONFIG_BZIP2) += bzlib_decompress.o
 COBJS-$(CONFIG_BZIP2) += bzlib_randtable.o
 COBJS-$(CONFIG_BZIP2) += bzlib_huffman.o
 COBJS-$(CONFIG_USB_TTY) += circbuf.o
+COBJS-y += crc7.o
 COBJS-y += crc16.o
 COBJS-y += crc32.o
 COBJS-y += ctype.o
lib/crc7.c new file +62 -0

62 lines not on this page · raw message

Signature · 1 line
1.6.6.1
#13 lore raw

PATCH v5 1/1 mmc: add generic mmc spi driver

In reply to Thomas Chou

This patch supports mmc/sd card with spi interface. It is based on the generic mmc framework. It works with SDHC and supports write.

The crc7 lib func is merged from linux and used to compute mmc command checksum.

There is a subcomamnd "mmc_spi" to setup spi bus and cs at run time.

---
v5: remove dev_num limit to search.
v4: change mmc_spi subcommand to search and create new mmc dev.
v3: add mmc_spi_init() proto to mmc_spi.h.
v2: add crc7, use cmd58 to read ocr, add subcommand mmc_spi.

 common/Makefile       |    1 +
 common/cmd_mmc_spi.c  |  114 ++++++++++++++++++
 drivers/mmc/Makefile  |    1 +
 drivers/mmc/mmc_spi.c |  318 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/crc7.h  |   14 ++
 include/mmc_spi.h     |   27 ++++
 lib/Makefile          |    1 +
 lib/crc7.c            |   62 ++++++++++
 8 files changed, 538 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_mmc_spi.c
 create mode 100644 drivers/mmc/mmc_spi.c
 create mode 100644 include/linux/crc7.h
 create mode 100644 include/mmc_spi.h
 create mode 100644 lib/crc7.c
common/Makefile +1 -0
index dbf7a05..ee23e2f 100644
@@ -118,6 +118,7 @@ COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
+COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 COBJS-$(CONFIG_MP) += cmd_mp.o
 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
 COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
common/cmd_mmc_spi.c new file +114 -0

114 lines not on this page · raw message

drivers/mmc/Makefile +1 -0
index 6fa04b8..02ed329 100644
@@ -28,6 +28,7 @@ LIB	:= $(obj)libmmc.a
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
+COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
drivers/mmc/mmc_spi.c new file +318 -0

318 lines not on this page · raw message

include/linux/crc7.h new file +14 -0
new file mode 100644
index 0000000..1786e77
@@ -0,0 +1,14 @@
+#ifndef _LINUX_CRC7_H
+#define _LINUX_CRC7_H
+#include <linux/types.h>
+
+extern const u8 crc7_syndrome_table[256];
+
+static inline u8 crc7_byte(u8 crc, u8 data)
+{
+	return crc7_syndrome_table[(crc << 1) ^ data];
+}
+
+extern u8 crc7(u8 crc, const u8 *buffer, size_t len);
+
+#endif
include/mmc_spi.h new file +27 -0
new file mode 100644
index 0000000..fbfa1ce
@@ -0,0 +1,27 @@
+/*
+ * generic mmc spi driver
+ *
+ * Copyright (C) 2010 Thomas Chou <[email protected]>
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _MMC_SPI_H_
+#define _MMC_SPI_H_
+
+#include <spi.h>
+#include <mmc.h>
+#include <linux/types.h>
+
+struct mmc_spi_priv {
+	struct spi_slave *slave;
+	uint bus;
+	uint cs;
+	uint speed;
+	uint mode;
+	uint ocr58;
+	uint sd_if_cond:1;
+};
+
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
+
+#endif
lib/Makefile +1 -0
index c45f07c..aef2893 100644
@@ -32,6 +32,7 @@ COBJS-$(CONFIG_BZIP2) += bzlib_decompress.o
 COBJS-$(CONFIG_BZIP2) += bzlib_randtable.o
 COBJS-$(CONFIG_BZIP2) += bzlib_huffman.o
 COBJS-$(CONFIG_USB_TTY) += circbuf.o
+COBJS-y += crc7.o
 COBJS-y += crc16.o
 COBJS-y += crc32.o
 COBJS-y += ctype.o
lib/crc7.c new file +62 -0

62 lines not on this page · raw message

Signature · 1 line
1.6.6.1
#14 lore raw

PATCH v5 1/1 mmc: add generic mmc spi driver

Quoted 5 lines · Thomas Chou

This patch supports mmc/sd card with spi interface. It is based on the generic mmc framework. It works with SDHC and supports write.

The crc7 lib func is merged from linux and used to compute mmc command checksum.

This should probably be a separate patch.

Quoted 22 lines

There is a subcomamnd "mmc_spi" to setup spi bus and cs at run time.

(quoted diff) +17 -0
+
+static int do_mmc_spi(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ ? ? ? int dev_num = -1;
+ ? ? ? uint bus;
+ ? ? ? uint cs;
+ ? ? ? uint speed;
+ ? ? ? uint mode;
+ ? ? ? char *endp;
+ ? ? ? struct mmc *mmc;
+ ? ? ? struct mmc_spi_priv *priv;
+
+ ? ? ? do {
+ ? ? ? ? ? ? ? mmc = find_mmc_device(++dev_num);
+ ? ? ? } while (mmc && strcmp(mmc->name, "MMC_SPI"));
+ ? ? ? if (!mmc) {
+ ? ? ? ? ? ? ? printf("Create MMC Device\n");

Review

Quoted 10 lines
(quoted diff) +10 -0
+ ? ? ? ? ? ? ? mmc = mmc_spi_init(CONFIG_MMC_SPI_BUS,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?CONFIG_MMC_SPI_CS,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?CONFIG_MMC_SPI_SPEED,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?CONFIG_MMC_SPI_MODE);
+ ? ? ? ? ? ? ? if (!mmc) {
+ ? ? ? ? ? ? ? ? ? ? ? printf("Failed to create MMC Device\n");
+ ? ? ? ? ? ? ? ? ? ? ? return 1;
+ ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? dev_num = mmc->block_dev.dev;
+ ? ? ? }

I'm not sure I understand the logic behind this code. The arguments to the command should be used to either find the already-existing bus, or to create a new one. Unless I'm misunderstanding, this searches for the first MMC_SPI bus, and if it finds it, uses that, otherwise it creates a new one with the values specified in the config file. Then it parses the command and overwrites the old parameters for the bus with new ones? Why? My instinct would be to create a separate instance of an MMC_SPI bus for each bus and chip select. My SPI is rusty, so maybe chip-select should be configurable on a use-by-use basis.

Certainly the current code will only use at most one MMC_SPI bus even if more are created, which seems wrong.

Quoted 55 lines
(quoted diff) +46 -0
+
+ ? ? ? priv = mmc->priv;
+ ? ? ? bus = priv->bus;
+ ? ? ? cs = priv->cs;
+ ? ? ? speed = priv->speed;
+ ? ? ? mode = priv->mode;
+
+ ? ? ? if (argc < 2)
+ ? ? ? ? ? ? ? goto info;
+ ? ? ? cs = simple_strtoul(argv[1], &endp, 0);
+ ? ? ? if (*argv[1] == 0 || (*endp != 0 && *endp != ':'))
+ ? ? ? ? ? ? ? goto usage;
+ ? ? ? if (*endp == ':') {
+ ? ? ? ? ? ? ? if (endp[1] == 0)
+ ? ? ? ? ? ? ? ? ? ? ? goto usage;
+ ? ? ? ? ? ? ? bus = cs;
+ ? ? ? ? ? ? ? cs = simple_strtoul(endp + 1, &endp, 0);
+ ? ? ? ? ? ? ? if (*endp != 0)
+ ? ? ? ? ? ? ? ? ? ? ? goto usage;
+ ? ? ? }
+ ? ? ? if (argc >= 3) {
+ ? ? ? ? ? ? ? speed = simple_strtoul(argv[2], &endp, 0);
+ ? ? ? ? ? ? ? if (*argv[2] == 0 || *endp != 0)
+ ? ? ? ? ? ? ? ? ? ? ? goto usage;
+ ? ? ? }
+ ? ? ? if (argc >= 4) {
+ ? ? ? ? ? ? ? mode = simple_strtoul(argv[3], &endp, 16);
+ ? ? ? ? ? ? ? if (*argv[3] == 0 || *endp != 0)
+ ? ? ? ? ? ? ? ? ? ? ? goto usage;
+ ? ? ? }
+ ? ? ? if (!spi_cs_is_valid(bus, cs)) {
+ ? ? ? ? ? ? ? printf("Invalid SPI bus %u cs %u\n", bus, cs);
+ ? ? ? ? ? ? ? return 1;
+ ? ? ? }
+
+ ? ? ? if (bus != priv->bus || cs != priv->cs ||
+ ? ? ? ? ? speed != priv->speed || mode != priv->mode) {
+ ? ? ? ? ? ? ? priv->bus = bus;
+ ? ? ? ? ? ? ? priv->cs = cs;
+ ? ? ? ? ? ? ? priv->speed = speed;
+ ? ? ? ? ? ? ? priv->mode = mode;
+ ? ? ? ? ? ? ? if (priv->slave) {
+ ? ? ? ? ? ? ? ? ? ? ? spi_free_slave(priv->slave);
+ ? ? ? ? ? ? ? ? ? ? ? priv->slave = NULL;
+ ? ? ? ? ? ? ? }
+ ? ? ? }
drivers/mmc/mmc_spi.c new file +2 -0
new file mode 100644
index 0000000..dedcef7
@@ -0,0 +1,318 @@
+/*
+ * generic mmc spi driver

drivers/mmc/mmc_spi.c

Quoted 10 lines
drivers/mmc/mmc_spi.c new file +9 -0
+ *
 
+static uint mmc_spi_sendcmd(struct mmc *mmc, u8 cmdidx, u32 cmdarg)
+{
+ ? ? ? struct mmc_spi_priv *priv = mmc->priv;
+ ? ? ? u8 cmdo[7];
+ ? ? ? u8 r1;
+ ? ? ? int i;
+ ? ? ? cmdo[0] = 0xff;
+ ? ? ? cmdo[1] = 0x40 + cmdidx;

Use a #define'd constant for 0x40. Maybe do this:

/* MMC SPI commands start with a start bit "0" and a transmit bit "1" */ #define MMC_SPI_CMD(x) (0x40 | (x & 0x3f))

cmdo[1] = MMC_SPI_CMD(cmdidx);

Quoted 9 lines

+ ? ? ? cmdo[2] = cmdarg >> 24;
+ ? ? ? cmdo[3] = cmdarg >> 16;
+ ? ? ? cmdo[4] = cmdarg >> 8;
+ ? ? ? cmdo[5] = cmdarg;
+ ? ? ? cmdo[6] = (crc7(0, &cmdo[1], 5) << 1) | 0x01;
+ ? ? ? spi_xfer(priv->slave, 7 * 8, cmdo, NULL, SPI_XFER_BEGIN);
+ ? ? ? for (i = 0; i < CTOUT; i++) {
+ ? ? ? ? ? ? ? spi_xfer(priv->slave, 1 * 8, NULL, &r1, 0);
+ ? ? ? ? ? ? ? if ((r1 & 0x80) == 0)

define a constant

Quoted 19 lines

+ ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? }
+ ? ? ? debug("%s:cmd%d resp%d %x\n", __func__, cmdidx, i, r1);
+ ? ? ? return r1;

drivers/mmc/mmc_spi.c new file +15 -0
+}
+
+static uint mmc_spi_readdata(struct mmc *mmc, char *buf,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? u32 bcnt, u32 bsize)
+{
+ ? ? ? struct mmc_spi_priv *priv = mmc->priv;
+ ? ? ? u8 r1;
+ ? ? ? u8 crc[2];
+ ? ? ? int i;
+ ? ? ? while (bcnt--) {
+ ? ? ? ? ? ? ? for (i = 0; i < RTOUT; i++) {
+ ? ? ? ? ? ? ? ? ? ? ? spi_xfer(priv->slave, 1 * 8, NULL, &r1, 0);
+ ? ? ? ? ? ? ? ? ? ? ? if (r1 != 0xff)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? }

drivers/mmc/mmc_spi.c

Quoted 10 lines
drivers/mmc/mmc_spi.c new file +10 -0
+ ? ? ? ? ? ? ? debug("%s:tok%d %x\n", __func__, i, r1);
+ ? ? ? ? ? ? ? if (r1 == 0xfe) {
+ ? ? ? ? ? ? ? ? ? ? ? spi_xfer(priv->slave, bsize * 8, NULL, buf, 0);
+ ? ? ? ? ? ? ? ? ? ? ? buf += bsize;
+ ? ? ? ? ? ? ? ? ? ? ? spi_xfer(priv->slave, 2 * 8, NULL, crc, 0);
+ ? ? ? ? ? ? ? ? ? ? ? r1 = 0;
+ ? ? ? ? ? ? ? } else
+ ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? }
+ ? ? ? return r1;

Why not check the CRC to make sure your data is correct?

Quoted 7 lines
drivers/mmc/mmc_spi.c new file +7 -0
+}
+
+static uint mmc_spi_writedata(struct mmc *mmc, const char *buf,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? u32 bcnt, u32 bsize)
+{
+ ? ? ? struct mmc_spi_priv *priv = mmc->priv;
+ ? ? ? u8 r1;

drivers/mmc/mmc_spi.c

Quoted 10 lines
drivers/mmc/mmc_spi.c new file +10 -0
+ ? ? ? u8 tok[2] = { 0xff, 0xfe };
+ ? ? ? u8 crc[2];
+ ? ? ? int i;
+ ? ? ? while (bcnt--) {
+ ? ? ? ? ? ? ? spi_xfer(priv->slave, 2 * 8, tok, NULL, 0);
+ ? ? ? ? ? ? ? spi_xfer(priv->slave, bsize * 8, buf, NULL, 0);
+ ? ? ? ? ? ? ? buf += bsize;
+ ? ? ? ? ? ? ? spi_xfer(priv->slave, 2 * 8, crc, NULL, 0);
+ ? ? ? ? ? ? ? spi_xfer(priv->slave, 1 * 8, NULL, &r1, 0);
+ ? ? ? ? ? ? ? if (r1 == 0x05) {

Either define a named constant for 0x05, or put a comment describing what's happening. Isn't this technically a data response, rather than r1? Also,

Quoted 10 lines

+ ? ? ? ? ? ? ? ? ? ? ? for (i = 0; i < WTOUT; i++) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? spi_xfer(priv->slave, 1 * 8, NULL, &r1, 0);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (r1 == 0xff) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r1 = 0;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? ? ? ? ? if (i == WTOUT) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? debug("%s:wtout %x\n", __func__, r1);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r1 = 0x04;

A constant for this would be good, too.

Quoted 6 lines

+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? } else
+ ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? }
+ ? ? ? return r1;

drivers/mmc/mmc_spi.c

Quoted 9 lines
drivers/mmc/mmc_spi.c new file +9 -0
+}
+
+static uint mmc_spi_writeblock(struct mmc *mmc, const char *buf,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? u32 bcnt, u32 bsize)
+{
+ ? ? ? struct mmc_spi_priv *priv = mmc->priv;
+ ? ? ? u8 r1;
+ ? ? ? u8 tok[2] = { 0xff, 0xfc };
+ ? ? ? u8 stop[2] = { 0xff, 0xfd };

Constants for 0xfc and 0xfd, please.

Quoted 38 lines

+ ? ? ? u8 crc[2];
+ ? ? ? int i;
+ ? ? ? while (bcnt--) {
+ ? ? ? ? ? ? ? spi_xfer(priv->slave, 2 * 8, tok, NULL, 0);
+ ? ? ? ? ? ? ? spi_xfer(priv->slave, bsize * 8, buf, NULL, 0);
+ ? ? ? ? ? ? ? buf += bsize;
+ ? ? ? ? ? ? ? spi_xfer(priv->slave, 2 * 8, crc, NULL, 0);
+ ? ? ? ? ? ? ? spi_xfer(priv->slave, 1 * 8, NULL, &r1, 0);
+ ? ? ? ? ? ? ? if (r1 == 0x05) {
+ ? ? ? ? ? ? ? ? ? ? ? for (i = 0; i < WTOUT; i++) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? spi_xfer(priv->slave, 1 * 8, NULL, &r1, 0);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (r1 == 0xff) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r1 = 0;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? ? ? ? ? if (i == WTOUT) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? debug("%s:wtout %x\n", __func__, r1);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r1 = 0x04;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? }
+ ? ? ? }
+ ? ? ? if (bcnt == 0 && r1 == 0) {
+ ? ? ? ? ? ? ? spi_xfer(priv->slave, 2 * 8, stop, NULL, 0);
+ ? ? ? ? ? ? ? for (i = 0; i < WTOUT; i++) {
+ ? ? ? ? ? ? ? ? ? ? ? spi_xfer(priv->slave, 1 * 8, NULL, &r1, 0);
+ ? ? ? ? ? ? ? ? ? ? ? if (r1 == 0xff) {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r1 = 0;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? if (i == WTOUT) {
+ ? ? ? ? ? ? ? ? ? ? ? debug("%s:wtout %x\n", __func__, r1);
+ ? ? ? ? ? ? ? ? ? ? ? r1 = 0x04;
+ ? ? ? ? ? ? ? }
+ ? ? ? }
+ ? ? ? return r1;

drivers/mmc/mmc_spi.c line 149

Quoted 3 lines
drivers/mmc/mmc_spi.c new file +3 -0
+}
+
+static inline uint rswab(u8 *d)

Did you mean "swap", here?

Quoted 34 lines
drivers/mmc/mmc_spi.c new file +34 -0
+{
+ ? ? ? return (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3];
+}
+
+static inline void mmc_spi_deactivate(struct mmc *mmc)
+{
+ ? ? ? struct mmc_spi_priv *priv = mmc->priv;
+ ? ? ? spi_xfer(priv->slave, 1 * 8, NULL, NULL, SPI_XFER_END);
+ ? ? ? spi_xfer(priv->slave, 1 * 8, NULL, NULL, 0);
+}
+
+static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd,
+ ? ? ? ? ? ? ? struct mmc_data *data)
+{
+ ? ? ? struct mmc_spi_priv *priv = mmc->priv;
+ ? ? ? u8 r1;
+ ? ? ? ushort cmdidx = cmd->cmdidx;
+ ? ? ? uint cmdarg = cmd->cmdarg;
+ ? ? ? u8 resp[16];
+ ? ? ? int i;
+ ? ? ? int ret = 0;
+ ? ? ? debug("%s:cmd%d %x %x %x\n", __func__,
+ ? ? ? ? ? ? cmd->cmdidx, cmd->resp_type, cmd->cmdarg, cmd->flags);
+ ? ? ? if (cmdidx == MMC_CMD_ALL_SEND_CID)
+ ? ? ? ? ? ? ? cmdidx = MMC_CMD_SEND_CID;
+ ? ? ? r1 = mmc_spi_sendcmd(mmc, cmdidx, cmdarg);
+ ? ? ? if (r1 == 0xff) {
+ ? ? ? ? ? ? ? ret = NO_CARD_ERR;
+ ? ? ? ? ? ? ? goto done;
+ ? ? ? } else if (cmd->resp_type == MMC_RSP_R2) {
+ ? ? ? ? ? ? ? r1 = mmc_spi_readdata(mmc, resp, 1, 16);
+ ? ? ? ? ? ? ? for (i = 0; i < 4; i++)
+ ? ? ? ? ? ? ? ? ? ? ? cmd->response[i] = rswab(resp + i * 4);
+ ? ? ? ? ? ? ? debug("r128 %x %x %x %x\n", cmd->response[0], cmd->response[1],

drivers/mmc/mmc_spi.c

Quoted 10 lines
drivers/mmc/mmc_spi.c new file +10 -0
+ ? ? ? ? ? ? ? ? ? ? cmd->response[2], cmd->response[3]);
+ ? ? ? } else {
+ ? ? ? ? ? ? ? if (!data) {
+ ? ? ? ? ? ? ? ? ? ? ? spi_xfer(priv->slave, 4 * 8, NULL, resp, 0);
+ ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] = rswab(resp);
+ ? ? ? ? ? ? ? ? ? ? ? debug("r32 %x\n", cmd->response[0]);
+ ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? if (cmdidx == MMC_CMD_GO_IDLE_STATE) {
+ ? ? ? ? ? ? ? ? ? ? ? mmc_spi_deactivate(mmc);
+ ? ? ? ? ? ? ? ? ? ? ? r1 = mmc_spi_sendcmd(mmc, 58, 0);

Name "58", please.

Quoted 33 lines

+ ? ? ? ? ? ? ? ? ? ? ? spi_xfer(priv->slave, 4 * 8,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?NULL, resp, 0);
+ ? ? ? ? ? ? ? ? ? ? ? priv->ocr58 = rswab(resp) & ~OCR_BUSY;
+ ? ? ? ? ? ? ? ? ? ? ? debug("ocr58 %x\n", priv->ocr58);
+ ? ? ? ? ? ? ? } else if (cmdidx == SD_CMD_SEND_IF_COND) {
+ ? ? ? ? ? ? ? ? ? ? ? if ((r1 & 0x7e) == 0)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? priv->sd_if_cond = 1;
+ ? ? ? ? ? ? ? } else if (cmdidx == SD_CMD_APP_SEND_OP_COND ||
+ ? ? ? ? ? ? ? ? ? ? ? ? ?cmdidx == MMC_CMD_SEND_OP_COND) {
+ ? ? ? ? ? ? ? ? ? ? ? if (r1 & 0x04)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ret = TIMEOUT;
+ ? ? ? ? ? ? ? ? ? ? ? else {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (r1 & 0x01)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] = priv->ocr58;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? else {
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mmc_spi_deactivate(mmc);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r1 = mmc_spi_sendcmd(mmc, 58, 0);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? spi_xfer(priv->slave, 4 * 8,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?NULL, resp, 0);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? priv->ocr58 = rswab(resp);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? debug("ocr58 %x\n", priv->ocr58);
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] = priv->ocr58;
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? ? ? ? ? }
+ ? ? ? ? ? ? ? } else {
+ ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] = 0;
+ ? ? ? ? ? ? ? ? ? ? ? if (r1 & 0x7e)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] |= (1 << 19);
+ ? ? ? ? ? ? ? ? ? ? ? if (r1 & 0x40)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] |= (1 << 31);
+ ? ? ? ? ? ? ? ? ? ? ? if (r1 & 0x20)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] |= (1 << 30);
+ ? ? ? ? ? ? ? ? ? ? ? if (r1 & 0x10)

Quoted 8 lines

+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] |= (1 << 28);
+ ? ? ? ? ? ? ? ? ? ? ? if (r1 & 0x08)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] |= (1 << 23);
+ ? ? ? ? ? ? ? ? ? ? ? if (r1 & 0x04)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] |= (1 << 22);
+ ? ? ? ? ? ? ? ? ? ? ? if (r1 & 0x02)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cmd->response[0] |= (1 << 13);
+ ? ? ? ? ? ? ? }

Hmmm.... I'm not entirely sure this is the way to go. If I'm reading this correctly, this function is converting between the standard SD protocol, and the SPI version of the protocol. It might be better to make mmc.c aware of which protocol it is using, so it a) doesn't issue commands that the SPI card doesn't understand, and b) can properly interpret responses.

Quoted 7 lines

+ ? ? ? }
+ ? ? ? if (data) {
+ ? ? ? ? ? ? ? debug("%s:data %x %x %x\n", __func__,
+ ? ? ? ? ? ? ? ? ? ? data->flags, data->blocks, data->blocksize);
+ ? ? ? ? ? ? ? if (data->flags == MMC_DATA_READ) {
+ ? ? ? ? ? ? ? ? ? ? ? r1 = mmc_spi_readdata(mmc, data->dest,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data->blocks, data->blocksize);

Quoted 8 lines

+ ? ? ? ? ? ? ? } else if ?(data->flags == MMC_DATA_WRITE) {
+ ? ? ? ? ? ? ? ? ? ? ? if (cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r1 = mmc_spi_writeblock(mmc, data->src,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data->blocks, data->blocksize);
+ ? ? ? ? ? ? ? ? ? ? ? else
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? r1 = mmc_spi_writedata(mmc, data->src,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data->blocks, data->blocksize);
+ ? ? ? ? ? ? ? }

Why not check r1 to make sure your writes actually succeeded?

Quoted 15 lines
drivers/mmc/mmc_spi.c new file +15 -0
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
+{
+ ? ? ? struct mmc *mmc;
+ ? ? ? struct mmc_spi_priv *priv;
+
+ ? ? ? mmc = malloc(sizeof(*mmc));
+ ? ? ? if (!mmc)
+ ? ? ? ? ? ? ? return NULL;
+ ? ? ? priv = malloc(sizeof(*priv));
+ ? ? ? if (!priv) {
+ ? ? ? ? ? ? ? free(mmc);
+ ? ? ? ? ? ? ? return NULL;
+ ? ? ? }
+ ? ? ? mmc->priv = priv;
+ ? ? ? priv->bus = bus;

drivers/mmc/mmc_spi.c

Quoted 10 lines
drivers/mmc/mmc_spi.c new file +10 -0
+ ? ? ? priv->cs = cs;
+ ? ? ? priv->speed = speed;
+ ? ? ? priv->mode = mode;
+ ? ? ? sprintf(mmc->name, "MMC_SPI");
+ ? ? ? mmc->send_cmd = mmc_spi_request;
+ ? ? ? mmc->set_ios = mmc_spi_set_ios;
+ ? ? ? mmc->init = mmc_spi_init_p;
+ ? ? ? mmc->host_caps = 0;
+
+ ? ? ? mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;

Is this part of the SPI spec? If so, this is fine, otherwise, we need to get the voltage information from the SPI bus, somehow.

Quoted 2 lines

+ ? ? ? mmc->f_max = speed;
+ ? ? ? mmc->f_min = mmc->f_max >> 9;

What's the logic behind f_min being f_max/512?

drivers/mmc/mmc_spi.c

Quoted 6 lines

+ ? ? ? mmc->block_dev.part_type = PART_TYPE_DOS;

drivers/mmc/mmc_spi.c new file +5 -0
+
+ ? ? ? mmc_register(mmc);
+
+ ? ? ? return mmc;
+}

Andy

#15 lore raw

PATCH v5 1/1 mmc: add generic mmc spi driver

Hi Andy,

Thanks for you review.

Quoted 7 lines · Andy Fleming
Quoted 4 lines

The crc7 lib func is merged from linux and used to compute mmc command checksum.

This should probably be a separate patch.

OK.

Quoted 29 lines
Quoted 8 lines
common/cmd_mmc_spi.c new file +6 -0
+
+       do {
+               mmc = find_mmc_device(++dev_num);
+       } while (mmc&&  strcmp(mmc->name, "MMC_SPI"));
+       if (!mmc) {
+               printf("Create MMC Device\n");

common/cmd_mmc_spi.c line 52

Quoted 10 lines
common/cmd_mmc_spi.c new file +10 -0
+               mmc = mmc_spi_init(CONFIG_MMC_SPI_BUS,
+                                  CONFIG_MMC_SPI_CS,
+                                  CONFIG_MMC_SPI_SPEED,
+                                  CONFIG_MMC_SPI_MODE);
+               if (!mmc) {
+                       printf("Failed to create MMC Device\n");
+                       return 1;
+               }
+               dev_num = mmc->block_dev.dev;
+       }

I'm not sure I understand the logic behind this code. The arguments to the command should be used to either find the already-existing bus, or to create a new one. Unless I'm misunderstanding, this searches for the first MMC_SPI bus, and if it finds it, uses that, otherwise it creates a new one with the values specified in the config file. Then it parses the command and overwrites the old parameters for the bus with new ones? Why? My instinct would be to create a separate instance of an MMC_SPI bus for each bus and chip select. My SPI is rusty, so maybe chip-select should be configurable on a use-by-use basis.

Quoted 3 lines

Certainly the current code will only use at most one MMC_SPI bus even if more are created, which seems wrong.

Though more than one MMC_SPI device can be created for specific bus and cs by calling mmc_spi_init() within board_mmc_init() or cpu_mmc_init(). This command is used to change the spi bus and chip select on a use-by-use basis at run time, so one changeable mmc_spi device (the first one if we found) should be enough.

Quoted 10 lines
Quoted 3 lines

+ cmdo[1] = 0x40 + cmdidx;

Use a #define'd constant for 0x40. Maybe do this:

/* MMC SPI commands start with a start bit "0" and a transmit bit "1" */ #define MMC_SPI_CMD(x) (0x40 | (x& 0x3f))

cmdo[1] = MMC_SPI_CMD(cmdidx);

OK. Will define macros for all the cmd, token and response.

Quoted 2 lines

Why not check the CRC to make sure your data is correct?

OK. Will check CRC on data packet.

Quoted 5 lines

Review

Quoted 3 lines
(quoted diff) +2 -0
+
+static inline uint rswab(u8 *d)

Did you mean "swap", here?

It should be swap.

Quoted 8 lines

Hmmm.... I'm not entirely sure this is the way to go. If I'm reading this correctly, this function is converting between the standard SD protocol, and the SPI version of the protocol. It might be better to make mmc.c aware of which protocol it is using, so it a) doesn't issue commands that the SPI card doesn't understand, and b) can properly interpret responses.

I have avoided to touch the core mmc.c, so that I won't break other SD hosts by accident. Only minor translation of initialization commands and status mapping is enough to support SPI protocol.

Quoted 17 lines
Quoted 7 lines
drivers/mmc/mmc_spi.c new file +5 -0
+       }
+       if (data) {
+               debug("%s:data %x %x %x\n", __func__,
+                     data->flags, data->blocks, data->blocksize);
+               if (data->flags == MMC_DATA_READ) {

drivers/mmc/mmc_spi.c line 249

Quoted 10 lines
drivers/mmc/mmc_spi.c new file +10 -0
+                       r1 = mmc_spi_readdata(mmc, data->dest,
+                                       data->blocks, data->blocksize);
+               } else if  (data->flags == MMC_DATA_WRITE) {
+                       if (cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)
+                               r1 = mmc_spi_writeblock(mmc, data->src,
+                                       data->blocks, data->blocksize);
+                       else
+                               r1 = mmc_spi_writedata(mmc, data->src,
+                                       data->blocks, data->blocksize);
+               }
Quoted 3 lines

Why not check r1 to make sure your writes actually succeeded?

OK. Will check data response.

Quoted 8 lines

Review

Quoted 4 lines
(quoted diff) +2 -0
+
+       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;

Is this part of the SPI spec? If so, this is fine, otherwise, we need to get the voltage information from the SPI bus, somehow.

There is no voltage capability from SPI bus. This assumes 3.3V interface. Should I include other voltage?

Quoted 7 lines

Review

Quoted 4 lines
(quoted diff) +2 -0
+       mmc->f_max = speed;
+       mmc->f_min = mmc->f_max>>  9;

What's the logic behind f_min being f_max/512?

It yields f_min lower than 400KHz to meet the requirement for MMC.

Best regards,
Thomas

#16 lore raw

PATCH v5 1/1 mmc: add generic mmc spi driver

In reply to Andy Fleming
Quoted 40 lines · Andy Fleming
Quoted 18 lines
common/cmd_mmc_spi.c new file +16 -0
+static int do_mmc_spi(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       int dev_num = -1;
+       uint bus;
+       uint cs;
+       uint speed;
+       uint mode;
+       char *endp;
+       struct mmc *mmc;
+       struct mmc_spi_priv *priv;
+
+       do {
+               mmc = find_mmc_device(++dev_num);
+       } while (mmc&&  strcmp(mmc->name, "MMC_SPI"));
+       if (!mmc) {
+               printf("Create MMC Device\n");

common/cmd_mmc_spi.c line 52

Quoted 10 lines
common/cmd_mmc_spi.c new file +10 -0
+               mmc = mmc_spi_init(CONFIG_MMC_SPI_BUS,
+                                  CONFIG_MMC_SPI_CS,
+                                  CONFIG_MMC_SPI_SPEED,
+                                  CONFIG_MMC_SPI_MODE);
+               if (!mmc) {
+                       printf("Failed to create MMC Device\n");
+                       return 1;
+               }
+               dev_num = mmc->block_dev.dev;
+       }

I'm not sure I understand the logic behind this code. The arguments to the command should be used to either find the already-existing bus, or to create a new one. Unless I'm misunderstanding, this searches for the first MMC_SPI bus, and if it finds it, uses that, otherwise it creates a new one with the values specified in the config file. Then it parses the command and overwrites the old parameters for the bus with new ones? Why? My instinct would be to create a separate instance of an MMC_SPI bus for each bus and chip select. My SPI is rusty, so maybe chip-select should be configurable on a use-by-use basis.

Quoted 3 lines

Certainly the current code will only use at most one MMC_SPI bus even if more are created, which seems wrong.

Hi Mike,

Could you please give me some suggestion on the mmc_spi subcommand?

1. In v5 patch, I assumed a single changeable mmc_spi device is enough.

2. Andy suggested to create a new mmc_spi device for each bus and cs.

Either way is fine to me. Which one do you prefer?

Best regards,
Thomas

#17 lore raw

PATCH v5 1/1 mmc: add generic mmc spi driver

Quoted 1 line · On Thursday 29 April 2010 10:51:03 Thomas Chou wrote:

2. Andy suggested to create a new mmc_spi device for each bus and cs.

this is what i was suggesting from the start ... sorry if i wasnt clear -mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100429/448e715f/attachment.pgp

#18 lore raw

PATCH v5 1/1 mmc: add generic mmc spi driver

Quoted 7 lines · Mike Frysinger
Quoted 2 lines · On Thursday 29 April 2010 10:51:03 Thomas Chou wrote:

2. Andy suggested to create a new mmc_spi device for each bus and cs.

this is what i was suggesting from the start ... sorry if i wasnt clear -mike

Hi Mike,

Thank you anyway.

Hi Andy,

I will change the command like this,

1. if no args given, show the bus and cs of existing mmc_spi devices.
2. with args given, check for duplicated bus and cs from existing devices, then create a new device.

I will need to move the spurious printing of "MMC Device %d not found\n" out from find_mmc_device() of mmc.c .

Best regards,
Thomas

#19 lore raw

cover mmc: add mmc_spi driver

In reply to Thomas Chou

This patch series adds a mmc_spi driver.

Thomas Chou (3):
lib: add crc7 from Linux
mmc: add find_mmc_device_quiet that doesnt print not found message
mmc: add generic mmc spi driver

 common/Makefile       |    1 +
 common/cmd_mmc_spi.c  |  115 ++++++++++++++
 drivers/mmc/Makefile  |    1 +
 drivers/mmc/mmc.c     |   14 ++-
 drivers/mmc/mmc_spi.c |  393 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/crc7.h  |   14 ++
 include/mmc.h         |    1 +
 include/mmc_spi.h     |   27 ++++
 lib/Makefile          |    1 +
 lib/crc7.c            |   62 ++++++++
 10 files changed, 626 insertions(+), 3 deletions(-)
 create mode 100644 common/cmd_mmc_spi.c
 create mode 100644 drivers/mmc/mmc_spi.c
 create mode 100644 include/linux/crc7.h
 create mode 100644 include/mmc_spi.h
 create mode 100644 lib/crc7.c
#20 lore raw

PATCH 1/3 lib: add crc7 from Linux

In reply to Thomas Chou

Crc7 is used to compute mmc spi comamnd packet checksum.

---
 include/linux/crc7.h |   14 +++++++++++
 lib/Makefile         |    1 +
 lib/crc7.c           |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/crc7.h
 create mode 100644 lib/crc7.c
include/linux/crc7.h new file +14 -0
new file mode 100644
index 0000000..1786e77
@@ -0,0 +1,14 @@
+#ifndef _LINUX_CRC7_H
+#define _LINUX_CRC7_H
+#include <linux/types.h>
+
+extern const u8 crc7_syndrome_table[256];
+
+static inline u8 crc7_byte(u8 crc, u8 data)
+{
+	return crc7_syndrome_table[(crc << 1) ^ data];
+}
+
+extern u8 crc7(u8 crc, const u8 *buffer, size_t len);
+
+#endif
lib/Makefile +1 -0
index c45f07c..aef2893 100644
@@ -32,6 +32,7 @@ COBJS-$(CONFIG_BZIP2) += bzlib_decompress.o
 COBJS-$(CONFIG_BZIP2) += bzlib_randtable.o
 COBJS-$(CONFIG_BZIP2) += bzlib_huffman.o
 COBJS-$(CONFIG_USB_TTY) += circbuf.o
+COBJS-y += crc7.o
 COBJS-y += crc16.o
 COBJS-y += crc32.o
 COBJS-y += ctype.o
lib/crc7.c new file +62 -0

62 lines not on this page · raw message

Signature · 1 line
1.6.6.1
#21 lore raw

PATCH 2/3 mmc: add find_mmc_device_quiet that doesnt print not found message

In reply to Thomas Chou

We need to query mmc devices in mmc_spi subcommand and don't want the "Device not found" message.

---
 drivers/mmc/mmc.c |   14 +++++++++++---
 include/mmc.h     |    1 +
 2 files changed, 12 insertions(+), 3 deletions(-)
drivers/mmc/mmc.c +11 -3
index cf4ea16..55ab13e 100644
@@ -60,7 +60,7 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
 	return mmc_send_cmd(mmc, &cmd, NULL);
 }
 
-struct mmc *find_mmc_device(int dev_num)
+struct mmc *find_mmc_device_quiet(int dev_num)
 {
 	struct mmc *m;
 	struct list_head *entry;
@@ -72,11 +72,19 @@ struct mmc *find_mmc_device(int dev_num)
 			return m;
 	}
 
-	printf("MMC Device %d not found\n", dev_num);
-
 	return NULL;
 }
 
+struct mmc *find_mmc_device(int dev_num)
+{
+	struct mmc *m = find_mmc_device_quiet(dev_num);
+
+	if (!m)
+		printf("MMC Device %d not found\n", dev_num);
+
+	return m;
+}
+
 static ulong
 mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
 {
include/mmc.h +1 -0
index 8973bc7..b24b596 100644
@@ -270,6 +270,7 @@ int mmc_register(struct mmc *mmc);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
+struct mmc *find_mmc_device_quiet(int dev_num);
 struct mmc *find_mmc_device(int dev_num);
 void print_mmc_devices(char separator);
 int board_mmc_getcd(u8 *cd, struct mmc *mmc);
Signature · 1 line
1.6.6.1
#22 lore raw

PATCH 2/3 mmc: add find_mmc_device_quiet that doesnt print not found message

Dear Thomas Chou,

Quoted 2 lines · In message <[email protected]> you wrote:

We need to query mmc devices in mmc_spi subcommand and don't want the "Device not found" message.

Your subject line is way too long.

Quoted 28 lines
---
 drivers/mmc/mmc.c |   14 +++++++++++---
 include/mmc.h     |    1 +
 2 files changed, 12 insertions(+), 3 deletions(-)
drivers/mmc/mmc.c +1 -3
index cf4ea16..55ab13e 100644
@@ -60,7 +60,7 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
 	return mmc_send_cmd(mmc, &cmd, NULL);
 }
 
-struct mmc *find_mmc_device(int dev_num)
+struct mmc *find_mmc_device_quiet(int dev_num)
 {
 	struct mmc *m;
 	struct list_head *entry;
@@ -72,11 +72,19 @@ struct mmc *find_mmc_device(int dev_num)
 			return m;
 	}
 
-	printf("MMC Device %d not found\n", dev_num);
-
 	return NULL;
 }
 

drivers/mmc/mmc.c struct mmc *find_mmc_device(int dev_num) · line 87

Quoted 10 lines
drivers/mmc/mmc.c +10 -0
+struct mmc *find_mmc_device(int dev_num)
+{
+	struct mmc *m = find_mmc_device_quiet(dev_num);
+
+	if (!m)
+		printf("MMC Device %d not found\n", dev_num);
+
+	return m;
+}
+

Instead of creating a new function please consider using an argument instead?

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
While money can't buy happiness, it certainly lets  you  choose  your
own form of misery.
#23 lore raw

PATCH 2/3 mmc: add find_mmc_device_quiet that doesnt print not found message

Dear Wolfgang,

Quoted 9 lines · Wolfgang Denk

Dear Thomas Chou,

Quoted 3 lines · In message<[email protected]> you wrote:

We need to query mmc devices in mmc_spi subcommand and don't want the "Device not found" message.

Your subject line is way too long.

I will resubmit with a shorter subject.

Quoted 5 lines

Instead of creating a new function please consider using an argument instead?

I will add an argument, int verbose.

Thanks.

Best regards,
Thomas

#24 lore raw

PATCH v2 2/3 mmc: control message print in find_mmc_device

In reply to Wolfgang Denk

An argument, verbose, is added to enable/disable the "Device not found" message. Because we need to query mmc devices in mmc_spi subcommand and don't want the message.

---
v2: add an argument instead of add a new func, per Wolfgang.

 common/cmd_mmc.c  |    8 ++++----
 drivers/mmc/mmc.c |   11 ++++++-----
 include/mmc.h     |    2 +-
 3 files changed, 11 insertions(+), 10 deletions(-)
common/cmd_mmc.c +4 -4
index c67c9cf..9736e5a 100644
@@ -124,7 +124,7 @@ int do_mmcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	else
 		dev_num = simple_strtoul(argv[1], NULL, 0);
 
-	mmc = find_mmc_device(dev_num);
+	mmc = find_mmc_device(dev_num, 1);
 
 	if (mmc) {
 		mmc_init(mmc);
@@ -148,7 +148,7 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	case 3:
 		if (strcmp(argv[1], "rescan") == 0) {
 			int dev = simple_strtoul(argv[2], NULL, 10);
-			struct mmc *mmc = find_mmc_device(dev);
+			struct mmc *mmc = find_mmc_device(dev, 1);
 
 			if (!mmc)
 				return 1;
@@ -177,7 +177,7 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 			u32 cnt = simple_strtoul(argv[5], NULL, 16);
 			u32 n;
 			u32 blk = simple_strtoul(argv[4], NULL, 16);
-			struct mmc *mmc = find_mmc_device(dev);
+			struct mmc *mmc = find_mmc_device(dev, 1);
 
 			if (!mmc)
 				return 1;
@@ -200,7 +200,7 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 			void *addr = (void *)simple_strtoul(argv[3], NULL, 16);
 			u32 cnt = simple_strtoul(argv[5], NULL, 16);
 			u32 n;
-			struct mmc *mmc = find_mmc_device(dev);
+			struct mmc *mmc = find_mmc_device(dev, 1);
 
 			int blk = simple_strtoul(argv[4], NULL, 16);
 
drivers/mmc/mmc.c +6 -5
index cf4ea16..42e7937 100644
@@ -60,7 +60,7 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
 	return mmc_send_cmd(mmc, &cmd, NULL);
 }
 
-struct mmc *find_mmc_device(int dev_num)
+struct mmc *find_mmc_device(int dev_num, int verbose)
 {
 	struct mmc *m;
 	struct list_head *entry;
@@ -72,7 +72,8 @@ struct mmc *find_mmc_device(int dev_num)
 			return m;
 	}
 
-	printf("MMC Device %d not found\n", dev_num);
+	if (verbose)
+		printf("MMC Device %d not found\n", dev_num);
 
 	return NULL;
 }
@@ -84,7 +85,7 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
 	struct mmc_data data;
 	int err;
 	int stoperr = 0;
-	struct mmc *mmc = find_mmc_device(dev_num);
+	struct mmc *mmc = find_mmc_device(dev_num, 1);
 	int blklen;
 
 	if (!mmc)
@@ -214,7 +215,7 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
 {
 	int err;
 	int i;
-	struct mmc *mmc = find_mmc_device(dev_num);
+	struct mmc *mmc = find_mmc_device(dev_num, 1);
 
 	if (!mmc)
 		return 0;
@@ -860,7 +861,7 @@ int mmc_register(struct mmc *mmc)
 
 block_dev_desc_t *mmc_get_dev(int dev)
 {
-	struct mmc *mmc = find_mmc_device(dev);
+	struct mmc *mmc = find_mmc_device(dev, 1);
 
 	return mmc ? &mmc->block_dev : NULL;
 }
include/mmc.h +1 -1
index 8973bc7..0903491 100644
@@ -270,7 +270,7 @@ int mmc_register(struct mmc *mmc);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
-struct mmc *find_mmc_device(int dev_num);
+struct mmc *find_mmc_device(int dev_num, int verbose);
 void print_mmc_devices(char separator);
 int board_mmc_getcd(u8 *cd, struct mmc *mmc);
 
Signature · 1 line
1.6.6.1
#25 lore raw

PATCH v2 2/3 mmc: control message print in find_mmc_device

Quoted 4 lines · Thomas Chou

An argument, verbose, is added to enable/disable the "Device not found" message. Because we need to query mmc devices in mmc_spi subcommand and don't want the message.

Please drop this one. Because I reduced the cmd_mmc_spi.c, so that the query is not needed.

- Thomas

#26 lore raw

PATCH v7 3/3 mmc: add generic mmc spi driver

In reply to Wolfgang Denk

This patch supports mmc/sd card with spi interface. It is based on the generic mmc framework. It works with SDHC and supports write.

The crc checksum on data packet is enabled with the def, #define CONFIG_MMC_SPI_CRC_ON

There is a subcomamnd "mmc_spi" to setup spi bus and cs at run time.

---
v7: use find_mmc_device(dev, verbose), per Wolfgang.
v6: add constant macros, crc check on data, per Andy.
v5: remove dev_num limit to search.
v4: change mmc_spi subcommand to search and create new mmc dev.
v3: add mmc_spi_init() proto to mmc_spi.h.
v2: add crc7, use cmd58 to read ocr, add subcommand mmc_spi.

 common/Makefile       |    1 +
 common/cmd_mmc_spi.c  |  115 ++++++++++++++
 drivers/mmc/Makefile  |    1 +
 drivers/mmc/mmc_spi.c |  393 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc_spi.h     |   27 ++++
 5 files changed, 537 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_mmc_spi.c
 create mode 100644 drivers/mmc/mmc_spi.c
 create mode 100644 include/mmc_spi.h
common/Makefile +1 -0
index dbf7a05..ee23e2f 100644
@@ -118,6 +118,7 @@ COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
+COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 COBJS-$(CONFIG_MP) += cmd_mp.o
 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
 COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
common/cmd_mmc_spi.c new file +115 -0

115 lines not on this page · raw message

drivers/mmc/Makefile +1 -0
index 6fa04b8..02ed329 100644
@@ -28,6 +28,7 @@ LIB	:= $(obj)libmmc.a
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
+COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
drivers/mmc/mmc_spi.c new file +393 -0

393 lines not on this page · raw message

include/mmc_spi.h new file +27 -0
new file mode 100644
index 0000000..fbfa1ce
@@ -0,0 +1,27 @@
+/*
+ * generic mmc spi driver
+ *
+ * Copyright (C) 2010 Thomas Chou <[email protected]>
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _MMC_SPI_H_
+#define _MMC_SPI_H_
+
+#include <spi.h>
+#include <mmc.h>
+#include <linux/types.h>
+
+struct mmc_spi_priv {
+	struct spi_slave *slave;
+	uint bus;
+	uint cs;
+	uint speed;
+	uint mode;
+	uint ocr58;
+	uint sd_if_cond:1;
+};
+
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
+
+#endif
Signature · 1 line
1.6.6.1
#27 lore raw

PATCH v6 3/3 mmc: add generic mmc spi driver

In reply to Thomas Chou

This patch supports mmc/sd card with spi interface. It is based on the generic mmc framework. It works with SDHC and supports write.

The crc checksum on data packet is enabled with the def, #define CONFIG_MMC_SPI_CRC_ON

There is a subcomamnd "mmc_spi" to setup spi bus and cs at run time.

---
v6: add constant macros, crc check on data, per Andy.
v5: remove dev_num limit to search.
v4: change mmc_spi subcommand to search and create new mmc dev.
v3: add mmc_spi_init() proto to mmc_spi.h.
v2: add crc7, use cmd58 to read ocr, add subcommand mmc_spi.

 common/Makefile       |    1 +
 common/cmd_mmc_spi.c  |  115 ++++++++++++++
 drivers/mmc/Makefile  |    1 +
 drivers/mmc/mmc_spi.c |  393 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc_spi.h     |   27 ++++
 5 files changed, 537 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_mmc_spi.c
 create mode 100644 drivers/mmc/mmc_spi.c
 create mode 100644 include/mmc_spi.h
common/Makefile +1 -0
index dbf7a05..ee23e2f 100644
@@ -118,6 +118,7 @@ COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
+COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 COBJS-$(CONFIG_MP) += cmd_mp.o
 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
 COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
common/cmd_mmc_spi.c new file +115 -0

115 lines not on this page · raw message

drivers/mmc/Makefile +1 -0
index 6fa04b8..02ed329 100644
@@ -28,6 +28,7 @@ LIB	:= $(obj)libmmc.a
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
+COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
drivers/mmc/mmc_spi.c new file +393 -0

393 lines not on this page · raw message

include/mmc_spi.h new file +27 -0
new file mode 100644
index 0000000..fbfa1ce
@@ -0,0 +1,27 @@
+/*
+ * generic mmc spi driver
+ *
+ * Copyright (C) 2010 Thomas Chou <[email protected]>
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _MMC_SPI_H_
+#define _MMC_SPI_H_
+
+#include <spi.h>
+#include <mmc.h>
+#include <linux/types.h>
+
+struct mmc_spi_priv {
+	struct spi_slave *slave;
+	uint bus;
+	uint cs;
+	uint speed;
+	uint mode;
+	uint ocr58;
+	uint sd_if_cond:1;
+};
+
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
+
+#endif
Signature · 1 line
1.6.6.1
#28 lore raw

PATCH v8 3/3 mmc: add generic mmc spi driver

In reply to Thomas Chou

This patch supports mmc/sd card with spi interface. It is based on the generic mmc framework. It works with SDHC and supports multi blocks read/write.

The crc checksum on data packet is enabled with the def, #define CONFIG_MMC_SPI_CRC_ON

There is a subcomamnd "mmc_spi" to setup spi bus and cs at run time.

---
v8: make mmc.c core aware of spi protocol, per Andy.
work with multi blocks read/write.
reduce cmd_mmc_spi.c, doesnt query to mmc dev list.
v7: use find_mmc_device(dev, verbose), per Wolfgang.
v6: add constant macros, crc check on data, per Andy.
v5: remove dev_num limit to search.
v4: change mmc_spi subcommand to search and create new mmc dev.
v3: add mmc_spi_init() proto to mmc_spi.h.
v2: add crc7, use cmd58 to read ocr, add subcommand mmc_spi.

 common/Makefile       |    1 +
 common/cmd_mmc_spi.c  |   82 ++++++++++++++
 drivers/mmc/Makefile  |    1 +
 drivers/mmc/mmc.c     |   81 +++++++++++---
 drivers/mmc/mmc_spi.c |  296 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc.h         |    8 ++
 6 files changed, 451 insertions(+), 18 deletions(-)
 create mode 100644 common/cmd_mmc_spi.c
 create mode 100644 drivers/mmc/mmc_spi.c
common/Makefile +1 -0
index 2c37073..55beac5 100644
@@ -119,6 +119,7 @@ COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
+COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 COBJS-$(CONFIG_MP) += cmd_mp.o
 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
 COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
common/cmd_mmc_spi.c new file +82 -0

82 lines not on this page · raw message

drivers/mmc/Makefile +1 -0
index 6fa04b8..02ed329 100644
@@ -28,6 +28,7 @@ LIB	:= $(obj)libmmc.a
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
+COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
drivers/mmc/mmc.c +63 -18

122 lines not on this page · raw message

drivers/mmc/mmc_spi.c new file +296 -0

296 lines not on this page · raw message

include/mmc.h +8 -0
index 04c7eaf..0422e22 100644
@@ -44,6 +44,9 @@
 #define MMC_MODE_HS_52MHz	0x010
 #define MMC_MODE_4BIT		0x100
 #define MMC_MODE_8BIT		0x200
+#define MMC_MODE_SPI		0x400
+
+#define mmc_host_is_spi(mmc)	((mmc)->host_caps & MMC_MODE_SPI)
 
 #define SD_DATA_4BIT	0x00040000
 
@@ -75,6 +78,8 @@
 #define MMC_CMD_WRITE_SINGLE_BLOCK	24
 #define MMC_CMD_WRITE_MULTIPLE_BLOCK	25
 #define MMC_CMD_APP_CMD			55
+#define MMC_CMD_SPI_READ_OCR		58
+#define MMC_CMD_SPI_CRC_ON_OFF		59
 
 #define SD_CMD_SEND_RELATIVE_ADDR	3
 #define SD_CMD_SWITCH_FUNC		6
@@ -277,6 +282,9 @@ struct mmc *find_mmc_device(int dev_num);
 void print_mmc_devices(char separator);
 int board_mmc_getcd(u8 *cd, struct mmc *mmc);
 
+/* Driver initialization prototypes */
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
+
 #ifndef CONFIG_GENERIC_MMC
 int mmc_legacy_init(int verbose);
 #endif
Signature · 1 line
1.7.1.86.g0e460
#29 lore raw

PATCH v8 3/3 mmc: add generic mmc spi driver

Hi Andy,

Would you please review these patches?

05/03 [PATCH 1/3] lib: add crc7 from Linux 05/19 [PATCH 3/3 v8] mmc: add generic mmc spi driver

Best regards,
Thomas

#30 lore raw

PATCH v8 3/3 mmc: add generic mmc spi driver

In reply to Thomas Chou

common/cmd_mmc_spi.c line 69

Quoted 4 lines · On Wednesday, May 19, 2010 00:37:47 Thomas Chou wrote:
common/cmd_mmc_spi.c new file +2 -0
+	printf("%s: %d at %u:%u %u %u\n", mmc->name, mmc->block_dev.dev,
+	       bus, cs, speed, mode);

this is a bit terse. how about prefixing the hz output with like "hz:" and the mode with like "mode:" ?

common/cmd_mmc_spi.c line 82

Quoted 6 lines
common/cmd_mmc_spi.c new file +6 -0
+U_BOOT_CMD(
+	mmc_spi,	4,	0,	do_mmc_spi,
+	"mmc_spi setup",
+	"[bus:]cs [hz] [mode]	- setup mmc_spi device on given\n"
+	"				   SPI bus and chip select\n"
+);

there should be no newline at the end of the help string

drivers/mmc/mmc_spi.c line 291

Quoted 6 lines
drivers/mmc/mmc_spi.c new file +4 -0
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
+{
+	struct mmc *mmc;
+	mmc->b_max = MMC_SPI_MAX_BLOCKS;

do you have some local modification ? i dont see b_max anywhere in include/mmc.h ...

unfortunately though, i tried this on my system and it doesnt seem to work. using a simple SPI<->MMC card, the old mmc_spi driver works on my board, but booting the new u-boot and running the same things shows:

bfin> mmc_spi 4 30000000 3
MMC_SPI: 0 at 0:4 30000000 3

bfin> mmc list
MMC_SPI: 0

bfin> mmcinfo
Card did not respond to voltage select!
Device: MMC_SPI
Manufacturer ID: 0
OEM: 0
Name: Tran Speed: 0
Rd Block Len: 0
MMC version 0.0
High Capacity: No
Capacity: 0
Bus Width: 1-bit

enabling debugging in the driver shows this:
bfin> mmcinfo
mmc_spi_init_p: clock 0
mmc_spi_set_ios: clock 0
mmc_spi_set_ios: clock 400000
mmc_spi_request:cmd0 0 0 0
mmc_spi_sendcmd:cmd0 resp6 1
mmc_spi_request:cmd8 15 1aa 0
mmc_spi_sendcmd:cmd8 resp8 ff
mmc_spi_request:cmd55 15 0 0
mmc_spi_sendcmd:cmd55 resp6 5
mmc_spi_request:cmd0 0 0 0
mmc_spi_sendcmd:cmd0 resp6 1
mmc_spi_request:cmd1 1 40300000 0
mmc_spi_sendcmd:cmd1 resp6 1
mmc_spi_request:cmd1 1 40300000 0
mmc_spi_sendcmd:cmd1 resp6 1
mmc_spi_request:cmd1 1 40300000 0
mmc_spi_sendcmd:cmd1 resp4 1
mmc_spi_request:cmd1 1 40300000 0
mmc_spi_sendcmd:cmd1 resp4 1
<these last 2 lines repeat for a while>
Card did not respond to voltage select!
...
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100705/d2acad0b/attachment.pgp

#31 lore raw

PATCH v8 3/3 mmc: add generic mmc spi driver

Hi Mike,

Thank you very much for the review and testing.

Quoted 8 lines · Mike Frysinger

common/cmd_mmc_spi.c line 69

Quoted 4 lines · On Wednesday, May 19, 2010 00:37:47 Thomas Chou wrote:
common/cmd_mmc_spi.c new file +2 -0
+	printf("%s: %d at %u:%u %u %u\n", mmc->name, mmc->block_dev.dev,
+	       bus, cs, speed, mode);

this is a bit terse. how about prefixing the hz output with like "hz:" and the mode with like "mode:" ?

Yes, I will add them.

Quoted 9 lines

common/cmd_mmc_spi.c line 82

Quoted 7 lines
common/cmd_mmc_spi.c new file +6 -0
+U_BOOT_CMD(
+	mmc_spi,	4,	0,	do_mmc_spi,
+	"mmc_spi setup",
+	"[bus:]cs [hz] [mode]	- setup mmc_spi device on given\n"
+	"				   SPI bus and chip select\n"
+);

there should be no newline at the end of the help string

OK. I will remove the last newline.

Quoted 10 lines

drivers/mmc/mmc_spi.c line 291

Quoted 7 lines
drivers/mmc/mmc_spi.c new file +4 -0
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
+{
+	struct mmc *mmc;
+	mmc->b_max = MMC_SPI_MAX_BLOCKS;

do you have some local modification ? i dont see b_max anywhere in include/mmc.h ...

Please apply the multi-blocks patches (1,2,3/4) from Alagu on 05/12, as Andy said he had applied them.

Quoted 10 lines

unfortunately though, i tried this on my system and it doesnt seem to work. using a simple SPI<->MMC card, the old mmc_spi driver works on my board, but booting the new u-boot and running the same things shows:

mmc_spi_request:cmd1 1 40300000 0
mmc_spi_sendcmd:cmd1 resp4 1
<these last 2 lines repeat for a while>
Card did not respond to voltage select!

It seems the mmc card was not initialized and timed out. Please try remove the OCR_HCS in mmc_send_op_cond() of mmc.c temporarily.

	cmd.cmdarg = OCR_HCS | mmc->voltages;

---------------------^^^^^^^^^

Best regards,
Thomas

#32 lore raw

PATCH v8 3/3 mmc: add generic mmc spi driver

Quoted 12 lines · On Monday, July 05, 2010 10:22:45 Thomas Chou wrote:
Quoted 10 lines · Mike Frysinger

drivers/mmc/mmc_spi.c line 291

Quoted 6 lines · On Wednesday, May 19, 2010 00:37:47 Thomas Chou wrote:
drivers/mmc/mmc_spi.c new file +4 -0
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
+{
+	struct mmc *mmc;
+	mmc->b_max = MMC_SPI_MAX_BLOCKS;

do you have some local modification ? i dont see b_max anywhere in include/mmc.h ...

Quoted 2 lines

Please apply the multi-blocks patches (1,2,3/4) from Alagu on 05/12, as Andy said he had applied them.

those arent required for basic probing functionality, right ?

Quoted 10 lines
Quoted 9 lines

unfortunately though, i tried this on my system and it doesnt seem to work. using a simple SPI<->MMC card, the old mmc_spi driver works on my board, but booting the new u-boot and running the same things shows:

mmc_spi_request:cmd1 1 40300000 0
mmc_spi_sendcmd:cmd1 resp4 1
<these last 2 lines repeat for a while>
Card did not respond to voltage select!

Quoted 5 lines

It seems the mmc card was not initialized and timed out. Please try remove the OCR_HCS in mmc_send_op_cond() of mmc.c temporarily.

	cmd.cmdarg = OCR_HCS | mmc->voltages;

---------------------^^^^^^^^^

that does fix the timeout/warning, but the card doesnt probe yet:
bfin> mmcinfo
mmc_spi_init_p: clock 0
mmc_spi_set_ios: clock 0
mmc_spi_set_ios: clock 400000
mmc_spi_request:cmd0 0 0 0
mmc_spi_sendcmd:cmd0 resp8 ff
Device: MMC_SPI
Manufacturer ID: 0
OEM: 0
Name: Tran Speed: 0
Rd Block Len: 0
MMC version 0.0
High Capacity: No
Capacity: 0
Bus Width: 1-bit

if i boot up the old u-boot and probe the card there, then load up the new u- boot and try again, things get further:
bfin> mmcinfo
mmc_spi_init_p: clock 0
mmc_spi_set_ios: clock 0
mmc_spi_set_ios: clock 400000
mmc_spi_request:cmd0 0 0 0
mmc_spi_sendcmd:cmd0 resp6 1
mmc_spi_request:cmd8 15 1aa 0
mmc_spi_sendcmd:cmd8 resp8 ff
mmc_spi_request:cmd55 15 0 0
mmc_spi_sendcmd:cmd55 resp6 5
mmc_spi_request:cmd0 0 0 0
mmc_spi_sendcmd:cmd0 resp6 1
mmc_spi_request:cmd1 1 300000 0
mmc_spi_sendcmd:cmd1 resp6 1
mmc_spi_request:cmd1 1 300000 0
mmc_spi_sendcmd:cmd1 resp6 1
mmc_spi_request:cmd1 1 300000 0
mmc_spi_sendcmd:cmd1 resp6 1
mmc_spi_request:cmd1 1 300000 0
mmc_spi_sendcmd:cmd1 resp6 1
mmc_spi_request:cmd1 1 300000 0
mmc_spi_sendcmd:cmd1 resp6 1
mmc_spi_request:cmd1 1 300000 0
mmc_spi_sendcmd:cmd1 resp6 1
mmc_spi_request:cmd1 1 300000 0
mmc_spi_sendcmd:cmd1 resp6 0
mmc_spi_request:cmd58 1 0 0
mmc_spi_sendcmd:cmd58 resp6 0
r32 ffffffff
mmc_spi_request:cmd10 7 0 0
mmc_spi_sendcmd:cmd10 resp6 0
mmc_spi_readdata:tok0 80
r128 0 ff7a0000 fdff 3831f903
mmc_spi_request:cmd9 7 0 0
mmc_spi_sendcmd:cmd9 resp6 0
mmc_spi_readdata:tok1 fe
r128 ff4900 263 61726420 1659810
mmc_spi_set_ios: clock 20000000
mmc_spi_request:cmd16 15 1 0
mmc_spi_sendcmd:cmd16 resp6 0
mmc_spi_request:cmd17 15 0 0
mmc_spi_sendcmd:cmd17 resp8 ff
block read failed: -16
Device: MMC_SPI
Manufacturer ID: 0
OEM: 0
Name: Tran Speed: 0
Rd Block Len: 1
MMC version 1.2
High Capacity: Yes
Capacity: 2374355968
Bus Width: 1-bit

however, in poking the code, i see your mmc_spi_init_p() function calls spi_claim_bus(), but nowhere do i see spi_release_bus().
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100705/5bf8f0e8/attachment.pgp