diff options
Diffstat (limited to 'drivers/spi/spi-uclass.c')
-rw-r--r-- | drivers/spi/spi-uclass.c | 71 |
1 files changed, 43 insertions, 28 deletions
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 0ca108ee3d..4a02d95a34 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -224,7 +224,32 @@ int spi_chip_select(struct udevice *dev) int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp) { + struct dm_spi_ops *ops; + struct spi_cs_info info; struct udevice *dev; + int ret; + + /* + * Ask the driver. For the moment we don't have CS info. + * When we do we could provide the driver with a helper function + * to figure out what chip selects are valid, or just handle the + * request. + */ + ops = spi_get_ops(bus); + if (ops->cs_info) { + ret = ops->cs_info(bus, cs, &info); + } else { + /* + * We could assume there is at least one valid chip select. + * The driver didn't care enough to tell us. + */ + ret = 0; + } + + if (ret) { + printf("Invalid cs %d (err=%d)\n", cs, ret); + return ret; + } for (device_find_first_child(bus, &dev); dev; device_find_next_child(&dev)) { @@ -259,7 +284,6 @@ int spi_cs_is_valid(unsigned int busnum, unsigned int cs) int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info) { struct spi_cs_info local_info; - struct dm_spi_ops *ops; int ret; if (!info) @@ -268,24 +292,7 @@ int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info) /* If there is a device attached, return it */ info->dev = NULL; ret = spi_find_chip_select(bus, cs, &info->dev); - if (!ret) - return 0; - - /* - * Otherwise ask the driver. For the moment we don't have CS info. - * When we do we could provide the driver with a helper function - * to figure out what chip selects are valid, or just handle the - * request. - */ - ops = spi_get_ops(bus); - if (ops->cs_info) - return ops->cs_info(bus, cs, info); - - /* - * We could assume there is at least one valid chip select. - * The driver didn't care enough to tell us. - */ - return 0; + return ret == -ENODEV ? 0 : ret; } int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp, @@ -316,6 +323,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, { struct udevice *bus, *dev; struct dm_spi_slave_platdata *plat; + struct spi_slave *slave; bool created = false; int ret; @@ -371,19 +379,20 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, slave->dev = dev; } - plat = dev_get_parent_platdata(dev); + slave = dev_get_parent_priv(dev); - /* get speed and mode from platdata when available */ - if (plat->max_hz) { - speed = plat->max_hz; - mode = plat->mode; + /* + * In case the operation speed is not yet established by + * dm_spi_claim_bus() ensure the bus is configured properly. + */ + if (!slave->speed) { + ret = spi_claim_bus(slave); + if (ret) + goto err; } - ret = spi_set_speed_mode(bus, speed, mode); - if (ret) - goto err; *busp = bus; - *devp = dev_get_parent_priv(dev); + *devp = slave; debug("%s: bus=%p, slave=%p\n", __func__, bus, *devp); return 0; @@ -452,6 +461,9 @@ int spi_slave_ofdata_to_platdata(struct udevice *dev, case 4: mode |= SPI_TX_QUAD; break; + case 8: + mode |= SPI_TX_OCTAL; + break; default: warn_non_spl("spi-tx-bus-width %d not supported\n", value); break; @@ -467,6 +479,9 @@ int spi_slave_ofdata_to_platdata(struct udevice *dev, case 4: mode |= SPI_RX_QUAD; break; + case 8: + mode |= SPI_RX_OCTAL; + break; default: warn_non_spl("spi-rx-bus-width %d not supported\n", value); break; |