summaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorPratyush Yadav <p.yadav@ti.com>2021-06-25 22:17:14 +0300
committerJagan Teki <jagan@amarulasolutions.com>2021-06-28 09:29:35 +0300
commit71025f013ccb2da5a39e60cec319f1fdef031d3d (patch)
treedbbb26b9ebb0a7f1184344b6cd6ddefd827b9929 /drivers/spi
parent8702188ce5479729c81863680fb8ac7fffbd6b6a (diff)
downloadu-boot-71025f013ccb2da5a39e60cec319f1fdef031d3d.tar.xz
mtd: spi-nor-core: Rework hwcaps selection
The spi-mem layer provides a spi_mem_supports_op() function to check whether a specific operation is supported by the controller or not. This is much more accurate than the hwcaps selection logic based on SPI_{RX,TX}_ flags. Rework the hwcaps selection logic to use spi_mem_supports_op(). To make sure the build doesn't break for boards not using CONFIG_DM_SPI, add a simple SPI_{RX,TX}_ based hwcaps selection logic in spi-mem-nodm similar to spi_mem_default_supports_op(). This change is only compile-tested. To avoid SPL size problems on the x530 board, the old hwcaps selection is still kept around. Leaving the code in-place was getting difficult to read and understand, so the code is restructured to have it all in one isolated function. As a result of this, the parameter hwcaps to spi_nor_setup() is no longer needed. Remove it. Based on the Linux commit c76f5089796a (mtd: spi-nor: Rework hwcaps selection for the spi-mem case, 2019-08-06) Signed-off-by: Pratyush Yadav <p.yadav@ti.com> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-mem-nodm.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/spi/spi-mem-nodm.c b/drivers/spi/spi-mem-nodm.c
index db54101383..a228c808c7 100644
--- a/drivers/spi/spi-mem-nodm.c
+++ b/drivers/spi/spi-mem-nodm.c
@@ -105,3 +105,65 @@ int spi_mem_adjust_op_size(struct spi_slave *slave,
return 0;
}
+
+static int spi_check_buswidth_req(struct spi_slave *slave, u8 buswidth, bool tx)
+{
+ u32 mode = slave->mode;
+
+ switch (buswidth) {
+ case 1:
+ return 0;
+
+ case 2:
+ if ((tx && (mode & (SPI_TX_DUAL | SPI_TX_QUAD))) ||
+ (!tx && (mode & (SPI_RX_DUAL | SPI_RX_QUAD))))
+ return 0;
+
+ break;
+
+ case 4:
+ if ((tx && (mode & SPI_TX_QUAD)) ||
+ (!tx && (mode & SPI_RX_QUAD)))
+ return 0;
+
+ break;
+ case 8:
+ if ((tx && (mode & SPI_TX_OCTAL)) ||
+ (!tx && (mode & SPI_RX_OCTAL)))
+ return 0;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return -ENOTSUPP;
+}
+
+bool spi_mem_supports_op(struct spi_slave *slave, const struct spi_mem_op *op)
+{
+ if (spi_check_buswidth_req(slave, op->cmd.buswidth, true))
+ return false;
+
+ if (op->addr.nbytes &&
+ spi_check_buswidth_req(slave, op->addr.buswidth, true))
+ return false;
+
+ if (op->dummy.nbytes &&
+ spi_check_buswidth_req(slave, op->dummy.buswidth, true))
+ return false;
+
+ if (op->data.nbytes &&
+ spi_check_buswidth_req(slave, op->data.buswidth,
+ op->data.dir == SPI_MEM_DATA_OUT))
+ return false;
+
+ if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr)
+ return false;
+
+ if (op->cmd.nbytes != 1)
+ return false;
+
+ return true;
+}