mmc: add generic mmc spi driver
Subsystems (3)
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
@@ -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
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
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.cdriver ? 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
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
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
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_SPIcommand which forwards along calls tommc_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
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:]csWhere should I place this command? in a new file in common dir or inside the
mmc_spidriver?
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
PATCH 1/1 mmc: add generic mmc spi driver
In reply to Thomas ChouQuoted 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
PATCH v2 1/1 mmc: add generic mmc spi driver
In reply to Thomas ChouThis 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v3 1/1 mmc: add generic mmc spi driver
In reply to Thomas ChouThis 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
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
PATCH v4 1/1 mmc: add generic mmc spi driver
In reply to Thomas ChouThis 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH v5 1/1 mmc: add generic mmc spi driver
In reply to Thomas ChouThis 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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.Signed-off-by Thomas Chou <[email protected]>(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@@ -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
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_SPIbus, 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 anMMC_SPIbus 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_SPIbus 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.caware 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_minbeing f_max/512?
It yields f_min lower than 400KHz to meet the requirement for MMC.
Best regards,
Thomas
PATCH v5 1/1 mmc: add generic mmc spi driver
In reply to Andy FlemingQuoted 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_SPIbus, 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 anMMC_SPIbus 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_SPIbus 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
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_spidevice 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
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_spidevice 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
cover mmc: add mmc_spi driver
In reply to Thomas ChouThis 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
PATCH 1/3 lib: add crc7 from Linux
In reply to Thomas ChouCrc7 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
@@ -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
@@ -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
PATCH 2/3 mmc: add find_mmc_device_quiet that doesnt print not found message
In reply to Thomas ChouWe 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
@@ -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
@@ -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
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_spisubcommand and don't want the "Device not found" message.
Your subject line is way too long.
Quoted 28 lines
Signed-off-by Thomas Chou <[email protected]>--- drivers/mmc/mmc.c | 14 +++++++++++--- include/mmc.h | 1 + 2 files changed, 12 insertions(+), 3 deletions(-)drivers/mmc/mmc.c +1
-3@@ -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.
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_spisubcommand 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
PATCH v2 2/3 mmc: control message print in find_mmc_device
In reply to Wolfgang DenkAn 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
@@ -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
@@ -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
@@ -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
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_spisubcommand 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
PATCH v7 3/3 mmc: add generic mmc spi driver
In reply to Wolfgang DenkThis 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
@@ -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
@@ -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
@@ -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
PATCH v6 3/3 mmc: add generic mmc spi driver
In reply to Thomas ChouThis 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
@@ -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
@@ -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
@@ -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
PATCH v8 3/3 mmc: add generic mmc spi driver
In reply to Thomas ChouThis 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
@@ -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
@@ -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
@@ -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
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
PATCH v8 3/3 mmc: add generic mmc spi driver
In reply to Thomas Choucommon/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 3MMC_SPI: 0 at 0:4 30000000 3
bfin> mmc listMMC_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> mmcinfommc_spi_init_p: clock 0mmc_spi_set_ios: clock 0mmc_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
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_maxanywhere ininclude/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_spidriver 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
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_maxanywhere ininclude/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_spidriver 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_HCSinmmc_send_op_cond()ofmmc.ctemporarily.cmd.cmdarg = OCR_HCS | mmc->voltages;---------------------^^^^^^^^^
that does fix the timeout/warning, but the card doesnt probe yet:
bfin> mmcinfommc_spi_init_p: clock 0mmc_spi_set_ios: clock 0mmc_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> mmcinfommc_spi_init_p: clock 0mmc_spi_set_ios: clock 0mmc_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 1659810mmc_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