Unverified Commit 329f0dac authored by Alexandru Ardelean's avatar Alexandru Ardelean Committed by Mark Brown
Browse files

spi: make `cs_change_delay` the first user of the `spi_delay` logic



Since the logic for `spi_delay` struct + `spi_delay_exec()` has been copied
from the `cs_change_delay` logic, it's natural to make this delay, the
first user.

The `cs_change_delay` logic requires that the default remain 10 uS, in case
it is unspecified/unconfigured. So, there is some special handling needed
to do that.

The ADIS library is one of the few users of the new `cs_change_delay`
parameter for an spi_transfer.

The introduction of the `spi_delay` struct, requires that the users of of
`cs_change_delay` get an update. This change also updates the ADIS library.

Signed-off-by: default avatarAlexandru Ardelean <alexandru.ardelean@analog.com>
Link: https://lore.kernel.org/r/20190926105147.7839-4-alexandru.ardelean@analog.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent b2c98153
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -39,24 +39,24 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
			.len = 2,
			.cs_change = 1,
			.delay_usecs = adis->data->write_delay,
			.cs_change_delay = adis->data->cs_change_delay,
			.cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
			.cs_change_delay.value = adis->data->cs_change_delay,
			.cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
		}, {
			.tx_buf = adis->tx + 2,
			.bits_per_word = 8,
			.len = 2,
			.cs_change = 1,
			.delay_usecs = adis->data->write_delay,
			.cs_change_delay = adis->data->cs_change_delay,
			.cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
			.cs_change_delay.value = adis->data->cs_change_delay,
			.cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
		}, {
			.tx_buf = adis->tx + 4,
			.bits_per_word = 8,
			.len = 2,
			.cs_change = 1,
			.delay_usecs = adis->data->write_delay,
			.cs_change_delay = adis->data->cs_change_delay,
			.cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
			.cs_change_delay.value = adis->data->cs_change_delay,
			.cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
		}, {
			.tx_buf = adis->tx + 6,
			.bits_per_word = 8,
@@ -139,16 +139,16 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
			.len = 2,
			.cs_change = 1,
			.delay_usecs = adis->data->write_delay,
			.cs_change_delay = adis->data->cs_change_delay,
			.cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
			.cs_change_delay.value = adis->data->cs_change_delay,
			.cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
		}, {
			.tx_buf = adis->tx + 2,
			.bits_per_word = 8,
			.len = 2,
			.cs_change = 1,
			.delay_usecs = adis->data->read_delay,
			.cs_change_delay = adis->data->cs_change_delay,
			.cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
			.cs_change_delay.value = adis->data->cs_change_delay,
			.cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
		}, {
			.tx_buf = adis->tx + 4,
			.rx_buf = adis->rx,
@@ -156,8 +156,8 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
			.len = 2,
			.cs_change = 1,
			.delay_usecs = adis->data->read_delay,
			.cs_change_delay = adis->data->cs_change_delay,
			.cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
			.cs_change_delay.value = adis->data->cs_change_delay,
			.cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
		}, {
			.rx_buf = adis->rx + 2,
			.bits_per_word = 8,
+7 −21
Original line number Diff line number Diff line
@@ -1160,9 +1160,9 @@ EXPORT_SYMBOL_GPL(spi_delay_exec);
static void _spi_transfer_cs_change_delay(struct spi_message *msg,
					  struct spi_transfer *xfer)
{
	u32 delay = xfer->cs_change_delay;
	u32 unit = xfer->cs_change_delay_unit;
	u32 hz;
	u32 delay = xfer->cs_change_delay.value;
	u32 unit = xfer->cs_change_delay.unit;
	int ret;

	/* return early on "fast" mode - for everything but USECS */
	if (!delay) {
@@ -1171,27 +1171,13 @@ static void _spi_transfer_cs_change_delay(struct spi_message *msg,
		return;
	}

	switch (unit) {
	case SPI_DELAY_UNIT_USECS:
		delay *= 1000;
		break;
	case SPI_DELAY_UNIT_NSECS: /* nothing to do here */
		break;
	case SPI_DELAY_UNIT_SCK:
		/* if there is no effective speed know, then approximate
		 * by underestimating with half the requested hz
		 */
		hz = xfer->effective_speed_hz ?: xfer->speed_hz / 2;
		delay *= DIV_ROUND_UP(1000000000, hz);
		break;
	default:
	ret = spi_delay_exec(&xfer->cs_change_delay, xfer);
	if (ret) {
		dev_err_once(&msg->spi->dev,
			     "Use of unsupported delay unit %i, using default of 10us\n",
			     xfer->cs_change_delay_unit);
		delay = 10000;
			     unit);
		_spi_transfer_delay_ns(10000);
	}
	/* now sleep for the requested amount of time */
	_spi_transfer_delay_ns(delay);
}

/*
+1 −3
Original line number Diff line number Diff line
@@ -778,7 +778,6 @@ extern void spi_res_release(struct spi_controller *ctlr,
 * @cs_change: affects chipselect after this transfer completes
 * @cs_change_delay: delay between cs deassert and assert when
 *      @cs_change is set and @spi_transfer is not the last in @spi_message
 * @cs_change_delay_unit: unit of cs_change_delay
 * @delay_usecs: microseconds to delay after this transfer before
 *	(optionally) changing the chipselect status, then starting
 *	the next transfer or completing this @spi_message.
@@ -900,8 +899,7 @@ struct spi_transfer {
	u8		bits_per_word;
	u8		word_delay_usecs;
	u16		delay_usecs;
	u16		cs_change_delay;
	u8		cs_change_delay_unit;
	struct spi_delay	cs_change_delay;
	u32		speed_hz;
	u16		word_delay;