This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SPIDev and SPI_LSB_FIRST

I am using ti-sd-am335x-evm-05.04.01.00 as the starting point for our hardware.

I have enabled SPI in the kernel, and I think I believe I have setup the board-am335xevm.c file correctly.   I am now using spidev in user space and need to communicate with a device that only supports LSB first.  Unfortunately I cannot set the SPI_LSB_FIRST mode.  This problem exists for the spidev_test.c program, found at board-support/linux-3.2-psp04.06.00.07.sdk/Documentation/spidev_test.c.  After cross-compiling this program and attempting to run it (either on my hardware or on the EVM), I get the following output:

./spitest -D /dev/spidev2.0 -L
[17501.325562] spidev spi2.0: setup: unsupported mode bits 8
can't set spi mode: Invalid argument
Aborted

Note that mode bit 8 is defined as SPI_LSB_FIRST.  Other mode bits can be toggled without any problem, and spidev appears to be otherwise working, since if I run it without the -L option I get the expected result.  Also, I did try using the explicit ioctl call,

 ioctl(retVal, SPI_IOC_WR_LSB_FIRST, isLsbFirst)

rather than including this flag in the mode (which is what spidev_test.c does), but I get the identical failure.

Is it true that LSB first is not supported, or if not can anyone offer any advice on what I may have set up incorrectly?

  • Just to be clear in my above post, I meant that I have enabled SPIDEV in the kernel.

  • Update: I also tried setting the value of the .mode member of the spi_board_info struct in board-am335xevm.c, and then rebuilt the kernel.  When I did that, /dev/spidev2.0 no longer was even present.  So of course, with no device present, I could not open it to see if it worked.

  • I have a similar problem but I'm not using a different platform, not the EVM. If I take a look in my source in "build-target/linux-3.2/drivers/spi/spi.c" then there's this code:

    /**
    * spi_setup - setup SPI mode and clock rate
    * @spi: the device whose settings are being modified
    * Context: can sleep, and no requests are queued to the device
    *
    * SPI protocol drivers may need to update the transfer mode if the
    * device doesn't work with its default. They may likewise need
    * to update clock rates or word sizes from initial values. This function
    * changes those settings, and must be called from a context that can sleep.
    * Except for SPI_CS_HIGH, which takes effect immediately, the changes take
    * effect the next time the device is selected and data is transferred to
    * or from it. When this function returns, the spi device is deselected.
    *
    * Note that this call will fail if the protocol driver specifies an option
    * that the underlying controller or its driver does not support. For
    * example, not all hardware supports wire transfers using nine bit words,
    * LSB-first wire encoding, or active-high chipselects.
    */
    int spi_setup(struct spi_device *spi)
    {
    unsigned bad_bits;
    int status;

    /* help drivers fail *cleanly* when they need options
    * that aren't supported with their current master
    */
    bad_bits = spi->mode & ~spi->master->mode_bits;
    if (bad_bits) {
    dev_err(&spi->dev, "setup: unsupported mode bits %x\n",
    bad_bits);
    return -EINVAL;
    }

    if (!spi->bits_per_word)
    spi->bits_per_word = 8;

    status = spi->master->setup(spi);

    dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s"
    "%u bits/w, %u Hz max --> %d\n",
    (int) (spi->mode & (SPI_CPOL | SPI_CPHA)),
    (spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",
    (spi->mode & SPI_LSB_FIRST) ? "lsb, " : "",
    (spi->mode & SPI_3WIRE) ? "3wire, " : "",
    (spi->mode & SPI_LOOP) ? "loopback, " : "",
    spi->bits_per_word, spi->max_speed_hz,
    status);

    return status;
    }
    EXPORT_SYMBOL_GPL(spi_setup);


    Well, it specifically says:

    * Note that this call will fail if the protocol driver specifies an option
    * that the underlying controller or its driver does not support. For
    * example, not all hardware supports wire transfers using nine bit words,
    * LSB-first wire encoding, or active-high chipselects.

    I quickly skimmed the SPI part of "spruh73g.pdf" and I don't think I saw anything that suggests that LSB mode is supported. I guess you need to reverse your bytes yourself.

  • Thanks, that looks to be correct.  Fortunately I already implemented the byte reversal as a workaround to keep the project moving, so that'll now just become permanent!