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>
This commit is contained in:
Родитель
f477b7fb13
Коммит
db90a44177
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче