spi: soft_spi: Parse cs-gpios only if num-chipselects is not <0>

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.polyntsov@iopsys.eu>
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
This commit is contained in:
Michael Polyntsov 2024-07-31 08:11:29 +04:00 committed by Tom Rini
parent 1d662a64a7
commit 3d7f194597
2 changed files with 24 additions and 3 deletions

View file

@ -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

View file

@ -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,