diff options
author | Sourav Poddar <sourav.poddar@ti.com> | 2013-08-22 11:50:48 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-08-22 14:05:39 -0400 |
commit | db90a44177ac39fc22b2da5235b231fccdd4c673 (patch) | |
tree | 492a20db7dea81485f18da313a50e1a4136a9575 | |
parent | f477b7fb13df2b843997559ff34e87d054ba6538 (diff) |
spi: conditional checking of mode and transfer bits.
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>
-rw-r--r-- | drivers/spi/spi.c | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 39d38756e984..50f7fc3ed793 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -1473,33 +1473,37 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) | |||
1473 | * 2. keep tx/rx_nbits is contained by mode in spi_device | 1473 | * 2. keep tx/rx_nbits is contained by mode in spi_device |
1474 | * 3. if SPI_3WIRE, tx/rx_nbits should be in single | 1474 | * 3. if SPI_3WIRE, tx/rx_nbits should be in single |
1475 | */ | 1475 | */ |
1476 | if (xfer->tx_nbits != SPI_NBITS_SINGLE && | 1476 | if (xfer->tx_buf) { |
1477 | xfer->tx_nbits != SPI_NBITS_DUAL && | 1477 | if (xfer->tx_nbits != SPI_NBITS_SINGLE && |
1478 | xfer->tx_nbits != SPI_NBITS_QUAD) | 1478 | xfer->tx_nbits != SPI_NBITS_DUAL && |
1479 | return -EINVAL; | 1479 | xfer->tx_nbits != SPI_NBITS_QUAD) |
1480 | if ((xfer->tx_nbits == SPI_NBITS_DUAL) && | 1480 | return -EINVAL; |
1481 | !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD))) | 1481 | if ((xfer->tx_nbits == SPI_NBITS_DUAL) && |
1482 | return -EINVAL; | 1482 | !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD))) |
1483 | if ((xfer->tx_nbits == SPI_NBITS_QUAD) && | 1483 | return -EINVAL; |
1484 | !(spi->mode & SPI_TX_QUAD)) | 1484 | if ((xfer->tx_nbits == SPI_NBITS_QUAD) && |
1485 | return -EINVAL; | 1485 | !(spi->mode & SPI_TX_QUAD)) |
1486 | if ((spi->mode & SPI_3WIRE) && | 1486 | return -EINVAL; |
1487 | (xfer->tx_nbits != SPI_NBITS_SINGLE)) | 1487 | if ((spi->mode & SPI_3WIRE) && |
1488 | return -EINVAL; | 1488 | (xfer->tx_nbits != SPI_NBITS_SINGLE)) |
1489 | return -EINVAL; | ||
1490 | } | ||
1489 | /* check transfer rx_nbits */ | 1491 | /* check transfer rx_nbits */ |
1490 | if (xfer->rx_nbits != SPI_NBITS_SINGLE && | 1492 | if (xfer->rx_buf) { |
1491 | xfer->rx_nbits != SPI_NBITS_DUAL && | 1493 | if (xfer->rx_nbits != SPI_NBITS_SINGLE && |
1492 | xfer->rx_nbits != SPI_NBITS_QUAD) | 1494 | xfer->rx_nbits != SPI_NBITS_DUAL && |
1493 | return -EINVAL; | 1495 | xfer->rx_nbits != SPI_NBITS_QUAD) |
1494 | if ((xfer->rx_nbits == SPI_NBITS_DUAL) && | 1496 | return -EINVAL; |
1495 | !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD))) | 1497 | if ((xfer->rx_nbits == SPI_NBITS_DUAL) && |
1496 | return -EINVAL; | 1498 | !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD))) |
1497 | if ((xfer->rx_nbits == SPI_NBITS_QUAD) && | 1499 | return -EINVAL; |
1498 | !(spi->mode & SPI_RX_QUAD)) | 1500 | if ((xfer->rx_nbits == SPI_NBITS_QUAD) && |
1499 | return -EINVAL; | 1501 | !(spi->mode & SPI_RX_QUAD)) |
1500 | if ((spi->mode & SPI_3WIRE) && | 1502 | return -EINVAL; |
1501 | (xfer->rx_nbits != SPI_NBITS_SINGLE)) | 1503 | if ((spi->mode & SPI_3WIRE) && |
1502 | return -EINVAL; | 1504 | (xfer->rx_nbits != SPI_NBITS_SINGLE)) |
1505 | return -EINVAL; | ||
1506 | } | ||
1503 | } | 1507 | } |
1504 | 1508 | ||
1505 | message->spi = spi; | 1509 | message->spi = spi; |