From: Michael Polyntsov <michael.polynt...@iopsys.eu>

Some boards don't have chipselect lines for leds so cs-gpios is not
specified in the dts leading to probing error. Fix it by making
behavior similar to the one in Linux, parse num-chipselects and
if it is zero, ignore cs-gpios.

Signed-off-by: Michael Polyntsov <michael.polynt...@iopsys.eu>
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevets...@iopsys.eu>
---
 doc/device-tree-bindings/spi/soft-spi.txt |  5 +++--
 drivers/spi/soft_spi.c                    | 22 +++++++++++++++++++++-
 2 files changed, 24 insertions(+), 3 deletions(-)

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 3fe62818a44..2e80b7bb08e 100644
--- a/drivers/spi/soft_spi.c
+++ b/drivers/spi/soft_spi.c
@@ -238,6 +238,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);
@@ -250,7 +262,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,
-- 
2.43.0

Reply via email to