diff --git a/doc/device-tree-bindings/spi/soft-spi.txt b/doc/device-tree-bindings/spi/soft-spi.txt index bdf7e86befb..77b01b2fd9a 100644 --- a/doc/device-tree-bindings/spi/soft-spi.txt +++ b/doc/device-tree-bindings/spi/soft-spi.txt @@ -8,14 +8,15 @@ The soft SPI node requires the following properties: Mandatory properties: compatible: "spi-gpio" -cs-gpios: GPIOs to use for SPI chip select (output) +cs-gpios: GPIOs to use for SPI chip select (output), not required if num-chipselects = <0> sck-gpios: GPIO to use for SPI clock (output) And at least one of: mosi-gpios: GPIO to use for SPI MOSI line (output) miso-gpios: GPIO to use for SPI MISO line (input) -Optional propertie: +Optional properties: spi-delay-us: Number of microseconds of delay between each CS transition +num-chipselects: Number of chipselect lines The GPIOs should be specified as required by the GPIO controller referenced. The first cell holds the phandle of the controller and the second cell diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c index 04691d3a3ba..a8ec2f4f7b4 100644 --- a/drivers/spi/soft_spi.c +++ b/drivers/spi/soft_spi.c @@ -237,6 +237,18 @@ static int soft_spi_of_to_plat(struct udevice *dev) return 0; } +static int retrieve_num_chipselects(struct udevice *dev) +{ + int chipselects; + int ret; + + ret = ofnode_read_u32(dev_ofnode(dev), "num-chipselects", &chipselects); + if (ret) + return ret; + + return chipselects; +} + static int soft_spi_probe(struct udevice *dev) { struct spi_slave *slave = dev_get_parent_priv(dev); @@ -249,7 +261,15 @@ static int soft_spi_probe(struct udevice *dev) ret = gpio_request_by_name(dev, "cs-gpios", 0, &plat->cs, GPIOD_IS_OUT | cs_flags); - if (ret) + /* + * If num-chipselects is zero we're ignoring absence of cs-gpios. This + * code relies on the fact that `gpio_request_by_name` call above + * initiailizes plat->cs to correct value with invalid GPIO even when + * there is no cs-gpios node in dts. All other functions which work + * with plat->cs verify it via `dm_gpio_is_valid` before using it, so + * such value doesn't cause any problems. + */ + if (ret && retrieve_num_chipselects(dev) != 0) return -EINVAL; ret = gpio_request_by_name(dev, "gpio-sck", 0, &plat->sclk,