[PATCH 5/7] spi: spi-uclass: Read chipselect and restrict capabilities
Ashok Reddy Soma
ashok.reddy.soma at amd.com
Fri Aug 18 06:21:17 CEST 2023
Read chipselect properties from DT which are populated using 'reg'
property and save it in plat->cs[] array for later use.
Also read multi chipselect capability which is used for
parallel-memories and return errors if they are passed on using DT but
driver is not capable of handling it.
Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma at amd.com>
Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu at amd.com>
---
drivers/spi/spi-uclass.c | 21 ++++++++++++++++-----
drivers/spi/xilinx_spi.c | 4 ++--
drivers/spi/zynq_qspi.c | 6 +++---
drivers/spi/zynq_spi.c | 6 +++---
include/spi.h | 2 +-
5 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index c929e7c1d0..cdcf16d346 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -257,7 +257,7 @@ int spi_chip_select(struct udevice *dev)
{
struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);
- return plat ? plat->cs : -ENOENT;
+ return plat ? plat->cs[0] : -ENOENT;
}
int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp)
@@ -294,8 +294,8 @@ int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp)
struct dm_spi_slave_plat *plat;
plat = dev_get_parent_plat(dev);
- dev_dbg(bus, "%s: plat=%p, cs=%d\n", __func__, plat, plat->cs);
- if (plat->cs == cs) {
+ dev_dbg(bus, "%s: plat=%p, cs=%d\n", __func__, plat, plat->cs[0]);
+ if (plat->cs[0] == cs) {
*devp = dev;
return 0;
}
@@ -448,7 +448,7 @@ int _spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
return ret;
}
plat = dev_get_parent_plat(dev);
- plat->cs = cs;
+ plat->cs[0] = cs;
if (speed) {
plat->max_hz = speed;
} else {
@@ -479,6 +479,11 @@ int _spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
slave = dev_get_parent_priv(dev);
bus_data = dev_get_uclass_priv(bus);
+ if ((dev_read_bool(dev, "parallel-memories")) && !slave->multi_cs_cap) {
+ dev_err(dev, "controller doesn't support multi CS\n");
+ return -EINVAL;
+ }
+
/*
* In case the operation speed is not yet established by
* dm_spi_claim_bus() ensure the bus is configured properly.
@@ -541,8 +546,14 @@ int spi_slave_of_to_plat(struct udevice *dev, struct dm_spi_slave_plat *plat)
{
int mode = 0;
int value;
+ int ret;
+
+ ret = dev_read_u32_array(dev, "reg", plat->cs, SPI_CS_CNT_MAX);
+ if (ret && ret != -EOVERFLOW) {
+ dev_err(dev, "has no valid 'reg' property (%d)\n", ret);
+ return ret;
+ }
- plat->cs = dev_read_u32_default(dev, "reg", -1);
plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency",
SPI_DEFAULT_SPEED_HZ);
if (dev_read_bool(dev, "spi-cpol"))
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
index b58a3f632a..7c4a9b79bb 100644
--- a/drivers/spi/xilinx_spi.c
+++ b/drivers/spi/xilinx_spi.c
@@ -270,7 +270,7 @@ static void xilinx_spi_startup_block(struct spi_slave *spi)
* Perform a dummy read as a work around for
* the startup block issue.
*/
- spi_cs_activate(spi->dev, slave_plat->cs);
+ spi_cs_activate(spi->dev, slave_plat->cs[0]);
txp = 0x9f;
start_transfer(spi, (void *)&txp, NULL, 1);
@@ -298,7 +298,7 @@ static int xilinx_spi_mem_exec_op(struct spi_slave *spi,
startup++;
}
- spi_cs_activate(spi->dev, slave_plat->cs);
+ spi_cs_activate(spi->dev, slave_plat->cs[0]);
if (op->cmd.opcode) {
ret = start_transfer(spi, (void *)&op->cmd.opcode, NULL, 1);
diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c
index cb52c0f307..069d2a77de 100644
--- a/drivers/spi/zynq_qspi.c
+++ b/drivers/spi/zynq_qspi.c
@@ -586,13 +586,13 @@ static int zynq_qspi_xfer(struct udevice *dev, unsigned int bitlen,
struct zynq_qspi_priv *priv = dev_get_priv(bus);
struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
- priv->cs = slave_plat->cs;
+ priv->cs = slave_plat->cs[0];
priv->tx_buf = dout;
priv->rx_buf = din;
priv->len = bitlen / 8;
- debug("zynq_qspi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n",
- dev_seq(bus), slave_plat->cs, bitlen, priv->len, flags);
+ debug("zynq_qspi_xfer: bus:%i cs[0]:%i bitlen:%i len:%i flags:%lx\n",
+ dev_seq(bus), slave_plat->cs[0], bitlen, priv->len, flags);
/*
* Festering sore.
diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c
index b3e0858eb9..17bb1015fa 100644
--- a/drivers/spi/zynq_spi.c
+++ b/drivers/spi/zynq_spi.c
@@ -242,15 +242,15 @@ static int zynq_spi_xfer(struct udevice *dev, unsigned int bitlen,
u8 *rx_buf = din, buf;
u32 ts, status;
- debug("spi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n",
- dev_seq(bus), slave_plat->cs, bitlen, len, flags);
+ debug("spi_xfer: bus:%i cs[0]:%i bitlen:%i len:%i flags:%lx\n",
+ dev_seq(bus), slave_plat->cs[0], bitlen, len, flags);
if (bitlen % 8) {
debug("spi_xfer: Non byte aligned SPI transfer\n");
return -1;
}
- priv->cs = slave_plat->cs;
+ priv->cs = slave_plat->cs[0];
if (flags & SPI_XFER_BEGIN)
spi_cs_activate(dev);
diff --git a/include/spi.h b/include/spi.h
index 2a3ccaa754..f050227168 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -82,7 +82,7 @@ struct dm_spi_bus {
* @mode: SPI mode to use for this device (see SPI mode flags)
*/
struct dm_spi_slave_plat {
- unsigned int cs;
+ unsigned int cs[SPI_CS_CNT_MAX];
uint max_hz;
uint mode;
};
--
2.17.1
More information about the U-Boot
mailing list