spi: conditional checking of mode and transfer bits.
authorSourav Poddar <sourav.poddar@ti.com>
Thu, 22 Aug 2013 15:50:48 +0000 (21:20 +0530)
committerMark Brown <broonie@linaro.org>
Thu, 22 Aug 2013 18:05:39 +0000 (19:05 +0100)
There is a bug in the following patch:
http://comments.gmane.org/gmane.linux.kernel.spi.devel/14420

spi: DUAL and QUAD support

    fix the previous patch some mistake below:
    1. DT in slave node, use "spi-tx-nbits = <1/2/4>" in place of using
       "spi-tx-dual, spi-tx-quad" directly, same to rx. So correct the
       previous way to get the property in @of_register_spi_devices().
    2. Change the value of transfer bit macro(SPI_NBITS_SINGLE, SPI_NBITS_DUAL
       SPI_NBITS_QUAD) to 0x01, 0x02 and 0x04 to match the actual wires.
    3. Add the following check
       (1)keep the tx_nbits and rx_nbits in spi_transfer is not beyond the
          single, dual and quad.
       (2)keep tx_nbits and rx_nbits are contained by @spi_device->mode
          example: if @spi_device->mode = DUAL, then tx/rx_nbits can not be set
                   to QUAD(SPI_NBITS_QUAD)
       (3)if "@spi_device->mode & SPI_3WIRE", then tx/rx_nbits should be in
          single(SPI_NBITS_SINGLE)

Checking of the tx/rx transfer bits and mode bits should be done conditionally
based on type of buffer filled else EINVAL condition will
always get hit either for rx or tx.

Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
drivers/spi/spi.c

index 39d3875..50f7fc3 100644 (file)
@@ -1473,33 +1473,37 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
                 * 2. keep tx/rx_nbits is contained by mode in spi_device
                 * 3. if SPI_3WIRE, tx/rx_nbits should be in single
                 */
-               if (xfer->tx_nbits != SPI_NBITS_SINGLE &&
-                       xfer->tx_nbits != SPI_NBITS_DUAL &&
-                       xfer->tx_nbits != SPI_NBITS_QUAD)
-                       return -EINVAL;
-               if ((xfer->tx_nbits == SPI_NBITS_DUAL) &&
-                       !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD)))
-                       return -EINVAL;
-               if ((xfer->tx_nbits == SPI_NBITS_QUAD) &&
-                       !(spi->mode & SPI_TX_QUAD))
-                       return -EINVAL;
-               if ((spi->mode & SPI_3WIRE) &&
-                       (xfer->tx_nbits != SPI_NBITS_SINGLE))
-                       return -EINVAL;
+               if (xfer->tx_buf) {
+                       if (xfer->tx_nbits != SPI_NBITS_SINGLE &&
+                               xfer->tx_nbits != SPI_NBITS_DUAL &&
+                               xfer->tx_nbits != SPI_NBITS_QUAD)
+                               return -EINVAL;
+                       if ((xfer->tx_nbits == SPI_NBITS_DUAL) &&
+                               !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD)))
+                               return -EINVAL;
+                       if ((xfer->tx_nbits == SPI_NBITS_QUAD) &&
+                               !(spi->mode & SPI_TX_QUAD))
+                               return -EINVAL;
+                       if ((spi->mode & SPI_3WIRE) &&
+                               (xfer->tx_nbits != SPI_NBITS_SINGLE))
+                               return -EINVAL;
+               }
                /* check transfer rx_nbits */
-               if (xfer->rx_nbits != SPI_NBITS_SINGLE &&
-                       xfer->rx_nbits != SPI_NBITS_DUAL &&
-                       xfer->rx_nbits != SPI_NBITS_QUAD)
-                       return -EINVAL;
-               if ((xfer->rx_nbits == SPI_NBITS_DUAL) &&
-                       !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD)))
-                       return -EINVAL;
-               if ((xfer->rx_nbits == SPI_NBITS_QUAD) &&
-                       !(spi->mode & SPI_RX_QUAD))
-                       return -EINVAL;
-               if ((spi->mode & SPI_3WIRE) &&
-                       (xfer->rx_nbits != SPI_NBITS_SINGLE))
-                       return -EINVAL;
+               if (xfer->rx_buf) {
+                       if (xfer->rx_nbits != SPI_NBITS_SINGLE &&
+                               xfer->rx_nbits != SPI_NBITS_DUAL &&
+                               xfer->rx_nbits != SPI_NBITS_QUAD)
+                               return -EINVAL;
+                       if ((xfer->rx_nbits == SPI_NBITS_DUAL) &&
+                               !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD)))
+                               return -EINVAL;
+                       if ((xfer->rx_nbits == SPI_NBITS_QUAD) &&
+                               !(spi->mode & SPI_RX_QUAD))
+                               return -EINVAL;
+                       if ((spi->mode & SPI_3WIRE) &&
+                               (xfer->rx_nbits != SPI_NBITS_SINGLE))
+                               return -EINVAL;
+               }
        }
 
        message->spi = spi;