diff options
author | Pratyush Yadav <p.yadav@ti.com> | 2020-12-22 21:44:23 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-01-06 16:08:45 +0300 |
commit | a273596b9b50c76a9cc1f65d3eb7f8ab5c3eb3e3 (patch) | |
tree | bbd7669fd16b3073f5ef0bc8b081d53ad7f49eef /drivers/spi/spi-cadence-quadspi.c | |
parent | 7512eaf54190e4cc9247f18439c008d44b15022c (diff) | |
download | linux-a273596b9b50c76a9cc1f65d3eb7f8ab5c3eb3e3.tar.xz |
spi: cadence-quadspi: Implement a simple supports_op hook
The default SPI MEM supports_op hook rejects DTR ops by default. Add a
simple supports_op hook that very closely imitates the SPI MEM one. It
will be extended in later commits to allow DTR ops.
Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20201222184425.7028-6-p.yadav@ti.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-cadence-quadspi.c')
-rw-r--r-- | drivers/spi/spi-cadence-quadspi.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 376abef43530..1781d4e94ebd 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1031,6 +1031,66 @@ static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) return ret; } +static int cqspi_check_buswidth_req(struct spi_mem *mem, u8 buswidth, bool tx) +{ + u32 mode = mem->spi->mode; + + switch (buswidth) { + case 1: + return 0; + + case 2: + if ((tx && + (mode & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL))) || + (!tx && + (mode & (SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL)))) + return 0; + + break; + + case 4: + if ((tx && (mode & (SPI_TX_QUAD | SPI_TX_OCTAL))) || + (!tx && (mode & (SPI_RX_QUAD | SPI_RX_OCTAL)))) + return 0; + + break; + + case 8: + if ((tx && (mode & SPI_TX_OCTAL)) || + (!tx && (mode & SPI_RX_OCTAL))) + return 0; + + break; + + default: + break; + } + + return -EOPNOTSUPP; +} + +static bool cqspi_supports_mem_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + if (cqspi_check_buswidth_req(mem, op->cmd.buswidth, true)) + return false; + + if (op->addr.nbytes && + cqspi_check_buswidth_req(mem, op->addr.buswidth, true)) + return false; + + if (op->dummy.nbytes && + cqspi_check_buswidth_req(mem, op->dummy.buswidth, true)) + return false; + + if (op->data.nbytes && + cqspi_check_buswidth_req(mem, op->data.buswidth, + op->data.dir == SPI_MEM_DATA_OUT)) + return false; + + return true; +} + static int cqspi_of_get_flash_pdata(struct platform_device *pdev, struct cqspi_flash_pdata *f_pdata, struct device_node *np) @@ -1159,6 +1219,7 @@ static const char *cqspi_get_name(struct spi_mem *mem) static const struct spi_controller_mem_ops cqspi_mem_ops = { .exec_op = cqspi_exec_mem_op, .get_name = cqspi_get_name, + .supports_op = cqspi_supports_mem_op, }; static int cqspi_setup_flash(struct cqspi_st *cqspi) |