VoCore: SPI & MicroSD 3

In linux kernel, there are several important files for SPI/MMC part.

spi.c
spi.h
mmc_spi.c
mmc_spi.h
of_mmc_spi.c

From openwrt side, one file related to it.
spi-rt2880.c

But spi-rt2880.c only supports one SPI device, the flash chip.
There is a patch but not work, after I apply that, get the following error log.

[   15.050000] mmc_spi spi32766.1: OF: voltage-ranges unspecified
[   15.060000] mmc_spi spi32766.1: ASSUMING 3.2-3.4 V slot power
[   15.100000] mmc_spi spi32766.1: TX failed, err=-145
[   15.110000] mmc_spi spi32766.1: TX failed, err=-145
[   15.120000] mmc_spi spi32766.1: setup: unsupported mode bits 4
[   15.130000] mmc_spi spi32766.1: can't change chip-select polarity
[   15.140000] mmc_spi spi32766.1: setup: requested speed is too low 400000 Hz
[   15.180000] mmc_spi spi32766.1: SD/MMC host mmc0, no DMA, no WP, no poweroff

In the datasheet, RT5350 SPI is so good. All SPI features are supported, even SPI slave mode.

RT5350 SPI have the following features:
1. MSB first or LSB first
2. SPI clock default state 0 or 1
3. RX/TX data captured on the rising or falling edge of the SPI clock signal.(So RT5350 supports all the four modes of SPI)
4. SPI polarity indicator low active or high active.

Looks like there is no hardware problem to make the microSD over SPI come true. :)

[   15.050000] mmc_spi spi32766.1: OF: voltage-ranges unspecified
[   15.060000] mmc_spi spi32766.1: ASSUMING 3.2-3.4 V slot power
[   15.100000] mmc_spi spi32766.1: TX failed, err=-145
[   15.110000] mmc_spi spi32766.1: TX failed, err=-145

In dts, I did not add the voltage-ranges, after add that line, this fixed.
This voltage-ranges is useless but necessary to compatible with mmc-spi/spi driver, RT5350F do not have hardware support that feature.

[   15.120000] mmc_spi spi32766.1: setup: unsupported mode bits 4

This is caused by SPI_CS_HIGH(0x04) is not proper supported by rt2880-spi driver.

[   15.130000] mmc_spi spi32766.1: can't change chip-select polarity

rt2880-spi driver do not support that too, old driver only support one spi slave, do not need that. The patch has some code about that, but there might be bug.

[   15.140000] mmc_spi spi32766.1: setup: requested speed is too low 400000 Hz

This is not a real problem, the dts error stopped platform struct init, so setup is trying to setup the speed to zero.

Now, code is the only solution. :)
First, I will try to fix the patched rt2880-spi driver.
Then try to write a new one(rt5350-spi.c?) support all 5350 SPI features, so it will have a better compatible with linux SPI driver or other device based on SPI.

20 thoughts on “VoCore: SPI & MicroSD 3

  1. I know nothing of openwrt or linux but I do know arm, pic10f to pic32, xmos and some avr. Im sure more people know more. If you release what you have already then others could try themselves. You can make an official release for us noobs in the future. Is there a way to run this on qemu?

  2. I fix that several years ago … don’t waste your time to do it – let me dig where is the patch …

  3. From 996fe161f2ba7091ff09bb997b1a225f9044006b Mon Sep 17 00:00:00 2001
    From: Atanas Palavrov
    Date: Fri, 22 Feb 2013 07:27:22 +0100
    Subject: [PATCH] Adding RAMIPS SPI Modes support


    target/linux/ramips/files/drivers/spi/spi-ramips.c | 26 ++++++++++++++++++++–
    1 file changed, 24 insertions(+), 2 deletions(-)

    diff –git a/target/linux/ramips/files/drivers/spi/spi-ramips.c b/target/linux/ramips/files/drivers/spi/spi-ramips.c
    index e6a2d8e..3c28e25 100644
    — a/target/linux/ramips/files/drivers/spi/spi-ramips.c
    +++ b/target/linux/ramips/files/drivers/spi/spi-ramips.c
    @@ -110,6 +110,26 @@ static inline void ramips_spi_clrbits(struct ramips_spi *rs, u32 reg, u32 mask)
    iowrite32(val, addr);
    }

    +static void ramips_spi_mode_set(struct spi_device *spi)
    +{
    + struct ramips_spi *rs = ramips_spidev_to_rs(spi);
    + u32 reg;
    +
    + reg = ramips_spi_read(rs, RAMIPS_SPI_CFG);
    +
    + reg &= ~(SPICFG_SPICLKPOL | SPICFG_RXCLKEDGE_FALLING | SPICFG_TXCLKEDGE_FALLING);
    +
    + if(spi->mode & SPI_CPOL)
    + reg |= SPICFG_SPICLKPOL;
    +
    + if(spi->mode & SPI_CPHA)
    + reg |= SPICFG_RXCLKEDGE_FALLING;
    + else
    + reg |= SPICFG_TXCLKEDGE_FALLING;
    +
    + ramips_spi_write(rs, RAMIPS_SPI_CFG, reg);
    +}
    +
    static int ramips_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
    {
    struct ramips_spi *rs = ramips_spidev_to_rs(spi);
    @@ -267,6 +287,8 @@ static void ramips_spi_work(struct work_struct *work)

    spi = m->spi;

    + ramips_spi_mode_set(spi);
    +
    /* Load defaults */
    status = ramips_spi_setup_transfer(spi, NULL);

    @@ -429,8 +451,8 @@ static int __init ramips_spi_probe(struct platform_device *pdev)
    if (pdev->id != -1)
    master->bus_num = pdev->id;

    – /* we support only mode 0, and no options */
    – master->mode_bits = 0;
    + /* we support only mode 0-3, and no options */
    + master->mode_bits = SPI_CPOL | SPI_CPHA;

    master->setup = ramips_spi_setup;
    master->transfer = ramips_spi_transfer;

    2.0.1

  4. This patch is on top of carambola1 openwrt.
    Probably you should figure out yourself how to apply that patch on a more recent kernel – it is easy one … :)

  5. Can you tell me which OpenWRT git sha1 you are working on?
    I am not sure but think that ralink support is now in the official linux kernel, so it is not so obvious how to apply that patch …

    1. not sure about sha1, this is code from git log
      65577cca10cc147df9cd966fbc02cffe6ea9a84b
      new to git :) old time I used it store my own source code.

      1. Looks like you are on top of latest OpenWRT … let me check how ralink spi works here …

          1. It is a big mess … the only way that I see is to patch on top of:
            target/linux/ramips/patches-3.10/0019-SPI-ralink-add-Ralink-SoC-spi-driver.patch

            i.e. in drivers/spi/spi-rt2880.c to reapply the same patch that I provide.

            Unfortunately I really don’t have more time to do that now and don’t have ralink board around to test it … it should be something trivial for the openwrt guys if you have contact with them or they are reading your blog.

    1. :) That is caused by platform data init failed. Now I am fixing that driver, no easy way to test that, have to reflash firmware to the board again and again with tons of log, still need some time.

  6. Hi Vonger,

    I test the patch you mentioned http://patchwork.openwrt.org/patch/5549/ on another hardware mt7620 and I get the same “spi32766.1: TX failed, err=-145”.
    The process is timing out waiting for the transmit status bit to clear.
    So indeed it seems the SPI initialization is not done properly.
    Have you confirm that the above patch makes SPI driver to work OK with two CSs (two devices on SPI bus) ?

    1. The two CSs driver are not working at all. spi-mmc need to support SPI_CS_HIGH and that patch did not support that yet.

Comments are closed.