diff options
author | Mark Brown <broonie@kernel.org> | 2023-01-13 15:56:45 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2023-01-13 17:37:52 +0000 |
commit | c5d808691c2cf61c7b85003027ee35267dd74d7b (patch) | |
tree | 6173acd7ec3c599b79a308e1786ff1339d332376 /drivers/spi | |
parent | f66804bf7665f9d2db04791496ba2c7f4173941c (diff) | |
parent | 5827b31d858e399e0ba9fbd33da7a39b31769e11 (diff) |
spi: SPI core CS delay fixes and additions
Merge series from Hector Martin <marcan@marcan.st>:
Commits f6c911f3308c ("spi: dt-bindings: Introduce
spi-cs-setup-ns property") and 33a2fde5f77b ("spi: Introduce
spi-cs-setup-ns property") introduced a new property to represent the
CS setup delay in the device tree, but they have some issues:
- The property is only parsed as a 16-bit integer number of nanoseconds,
which limits the maximum value to ~65us. This is not a reasonable
upper limit, as some devices might need a lot more.
- The property name is inconsistent with other delay properties, which
use a "*-delay-ns" naming scheme.
- Only the setup delay is introduced, but not the related hold and
inactive delay times.
This series fixes the issues and adds support for the two missing
properties. Please pull in the first 3 patches as fixes for 6.2, to
avoid introducing a problematic DT API in this release. The last two
patches can wait until 6.3, though are probably harmless to throw in
as fixes too, since they're trivial.
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 15f174f4e056..fc4f6308efd8 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2220,11 +2220,26 @@ void spi_flush_queue(struct spi_controller *ctlr) /*-------------------------------------------------------------------------*/ #if defined(CONFIG_OF) +static void of_spi_parse_dt_cs_delay(struct device_node *nc, + struct spi_delay *delay, const char *prop) +{ + u32 value; + + if (!of_property_read_u32(nc, prop, &value)) { + if (value > U16_MAX) { + delay->value = DIV_ROUND_UP(value, 1000); + delay->unit = SPI_DELAY_UNIT_USECS; + } else { + delay->value = value; + delay->unit = SPI_DELAY_UNIT_NSECS; + } + } +} + static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, struct device_node *nc) { u32 value; - u16 cs_setup; int rc; /* Mode (clock phase/polarity/etc.) */ @@ -2310,10 +2325,10 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, if (!of_property_read_u32(nc, "spi-max-frequency", &value)) spi->max_speed_hz = value; - if (!of_property_read_u16(nc, "spi-cs-setup-delay-ns", &cs_setup)) { - spi->cs_setup.value = cs_setup; - spi->cs_setup.unit = SPI_DELAY_UNIT_NSECS; - } + /* Device CS delays */ + of_spi_parse_dt_cs_delay(nc, &spi->cs_setup, "spi-cs-setup-delay-ns"); + of_spi_parse_dt_cs_delay(nc, &spi->cs_hold, "spi-cs-hold-delay-ns"); + of_spi_parse_dt_cs_delay(nc, &spi->cs_inactive, "spi-cs-inactive-delay-ns"); return 0; } |