aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorDavid Lechner <dlechner@baylibre.com>2023-11-17 14:13:04 -0600
committerMark Brown <broonie@kernel.org>2023-11-20 13:29:14 +0000
commit145bb2aedb9f78f290c2b5503b553894a6ec53fe (patch)
tree47b6807cb4aab6f03326dd5851b723306fc4bfcc /drivers/spi
parent4e991445478c6404a6846928093837249c52694a (diff)
downloadlinux-145bb2aedb9f78f290c2b5503b553894a6ec53fe.tar.gz
spi: axi-spi-engine: add support for cs_off
This adds support for the spi_transfer::cs_off flag to the AXI SPI Engine driver. The logic is copied from the generic spi_transfer_one_message() in spi.c. Signed-off-by: David Lechner <dlechner@baylibre.com> Link: https://lore.kernel.org/r/20231117-axi-spi-engine-series-1-v1-13-cc59db999b87@baylibre.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-axi-spi-engine.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c
index c39f478f34a71..1c60e6486ee24 100644
--- a/drivers/spi/spi-axi-spi-engine.c
+++ b/drivers/spi/spi-axi-spi-engine.c
@@ -216,7 +216,7 @@ static int spi_engine_compile_message(struct spi_engine *spi_engine,
struct spi_device *spi = msg->spi;
struct spi_transfer *xfer;
int clk_div, new_clk_div;
- bool cs_change = true;
+ bool keep_cs = false;
clk_div = -1;
@@ -224,6 +224,9 @@ static int spi_engine_compile_message(struct spi_engine *spi_engine,
SPI_ENGINE_CMD_WRITE(SPI_ENGINE_CMD_REG_CONFIG,
spi_engine_get_config(spi)));
+ xfer = list_first_entry(&msg->transfers, struct spi_transfer, transfer_list);
+ spi_engine_gen_cs(p, dry, spi, !xfer->cs_off);
+
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
new_clk_div = spi_engine_get_clk_div(spi_engine, spi, xfer);
if (new_clk_div != clk_div) {
@@ -233,20 +236,28 @@ static int spi_engine_compile_message(struct spi_engine *spi_engine,
clk_div));
}
- if (cs_change)
- spi_engine_gen_cs(p, dry, spi, true);
-
spi_engine_gen_xfer(p, dry, xfer);
spi_engine_gen_sleep(p, dry, spi_engine, clk_div, xfer);
- cs_change = xfer->cs_change;
- if (list_is_last(&xfer->transfer_list, &msg->transfers))
- cs_change = !cs_change;
-
- if (cs_change)
- spi_engine_gen_cs(p, dry, spi, false);
+ if (xfer->cs_change) {
+ if (list_is_last(&xfer->transfer_list, &msg->transfers)) {
+ keep_cs = true;
+ } else {
+ if (!xfer->cs_off)
+ spi_engine_gen_cs(p, dry, spi, false);
+
+ if (!list_next_entry(xfer, transfer_list)->cs_off)
+ spi_engine_gen_cs(p, dry, spi, true);
+ }
+ } else if (!list_is_last(&xfer->transfer_list, &msg->transfers) &&
+ xfer->cs_off != list_next_entry(xfer, transfer_list)->cs_off) {
+ spi_engine_gen_cs(p, dry, spi, xfer->cs_off);
+ }
}
+ if (!keep_cs)
+ spi_engine_gen_cs(p, dry, spi, false);
+
return 0;
}