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:
committed by
Mark Brown
parent
ec3fa72fa8
commit
6c613f68aa
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user