spi: core,atmel: convert word_delay_usecs -> word_delay for spi_device

This change does a conversion from the `word_delay_usecs` -> `word_delay`
for the `spi_device` struct.

This allows users to specify inter-word delays in other unit types
(nano-seconds or clock cycles), depending on how users want.

The Atmel SPI driver is the only current user of the `word_delay_usecs`
field (from the `spi_device` struct).
So, it needed a slight conversion to use the `word_delay` as an `spi_delay`
struct.

In SPI core, the only required mechanism is to update the `word_delay`
information per `spi_transfer`. This requires a bit more logic than before,
because it needs that both delays be converted to a common unit
(nano-seconds) for comparison.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Link: https://lore.kernel.org/r/20190926105147.7839-8-alexandru.ardelean@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Alexandru Ardelean
2019-09-26 13:51:35 +03:00
committed by Mark Brown
parent ec3fa72fa8
commit 6c613f68aa
3 changed files with 48 additions and 9 deletions

View File

@@ -1149,12 +1149,31 @@ atmel_spi_pdc_interrupt(int irq, void *dev_id)
return ret;
}
static int atmel_word_delay_csr(struct spi_device *spi, struct atmel_spi *as)
{
struct spi_delay *delay = &spi->word_delay;
u32 value = delay->value;
switch (delay->unit) {
case SPI_DELAY_UNIT_NSECS:
value /= 1000;
break;
case SPI_DELAY_UNIT_USECS:
break;
default:
return -EINVAL;
}
return (as->spi_clk / 1000000 * value) >> 5;
}
static int atmel_spi_setup(struct spi_device *spi)
{
struct atmel_spi *as;
struct atmel_spi_device *asd;
u32 csr;
unsigned int bits = spi->bits_per_word;
int word_delay_csr;
as = spi_master_get_devdata(spi->master);
@@ -1178,11 +1197,14 @@ static int atmel_spi_setup(struct spi_device *spi)
*/
csr |= SPI_BF(DLYBS, 0);
word_delay_csr = atmel_word_delay_csr(spi, as);
if (word_delay_csr < 0)
return word_delay_csr;
/* DLYBCT adds delays between words. This is useful for slow devices
* that need a bit of time to setup the next transfer.
*/
csr |= SPI_BF(DLYBCT,
(as->spi_clk / 1000000 * spi->word_delay_usecs) >> 5);
csr |= SPI_BF(DLYBCT, word_delay_csr);
asd = spi->controller_state;
if (!asd) {