[PATCH] spi: Handle spi-{tx,rx}-bus-width 0 as SPI_NO_TX/SPI_NO_RX

Cole Munz <[email protected]>
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <10e92a74c8a22cc2cd54f5dcccc31594016d4263.1787015208.git.Munzzyy1__8158.44759797386$1787015756$gmane$org@proton.me>
The spi-peripheral-props binding shipped in dts/upstream allows a bus
width of 0, meaning no RX or TX is possible on this device. The
switches in spi_slave_of_to_plat() only handle 1/2/4/8, so a width of
0 falls through to the default case and warns "spi-rx-bus-width 0 not
supported" on every boot, even though the devicetree is valid per the
binding. The fact that the wire is missing is then dropped from
plat->mode.

Map 0 to new SPI_NO_TX/SPI_NO_RX mode bits, as Linux has done since
v5.12 ("spi: Add SPI_NO_TX/RX support", mainline d962608ce218).
Bits 16 and 17 are the first free mode bits.

This comes up on devices with no MISO line at all, such as a
write-only SPI display described with spi-rx-bus-width = <0>.

Signed-off-by: Cole Munz <[email protected]>
---
Raised as a boot-log warning on Flipper One, whose display has no MISO
line at all: that pin is reused as the end-of-frame GPIO. Reported at
flipperdevices/u-boot#33, and sent here rather than to the fork as
suggested on that issue.

Verified on sandbox at 527115ef6783, with spi-rx-bus-width = <0> added
to spi.bin@0 in arch/sandbox/dts/test.dts and CONFIG_LOG disabled, so
warn_non_xpl() reaches the console the way it does on the board.

Before:
 $ ./u-boot -T -c "sf probe"
 spi-rx-bus-width 0 not supported
 spi-rx-bus-width 0 not supported
 SF: Detected m25p16 with page size 256 Bytes, erase size 64 KiB, 2 MiB

After:
 $ ./u-boot -T -c "sf probe"
 SF: Detected m25p16 with page size 256 Bytes, erase size 64 KiB, 2 MiB

It warns twice in sandbox because both the pre- and post-reloc DM scans
run there; the board logs it once.

ut dm spi_flash, spi_xfer, spi_find, spi_claim_bus, spi_set_wordlen and
spi_flash_func all pass with the property in place. Nothing consumes the
new bits yet, matching d962608ce218 in Linux, where the consumers landed
later.

 drivers/spi/spi-uclass.c | 6 ++++++
 include/spi.h            | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 120565df1497..0f0d4b1384f2 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -229,6 +229,9 @@ static int spi_child_post_bind(struct udevice *dev)
 	/* Device DUAL/QUAD mode */
 	value = dev_read_u32_default(dev, "spi-tx-bus-width", 1);
 	switch (value) {
+	case 0:
+		mode |= SPI_NO_TX;
+		break;
 	case 1:
 		break;
 	case 2:
@@ -247,6 +250,9 @@ static int spi_child_post_bind(struct udevice *dev)
 
 	value = dev_read_u32_default(dev, "spi-rx-bus-width", 1);
 	switch (value) {
+	case 0:
+		mode |= SPI_NO_RX;
+		break;
 	case 1:
 		break;
 	case 2:
diff --git a/include/spi.h b/include/spi.h
index 97096a775262..f477763bdc60 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -34,6 +34,8 @@ struct spinand_info;
 #define SPI_RX_QUAD	BIT(13)			/* receive with 4 wires */
 #define SPI_TX_OCTAL	BIT(14)			/* transmit with 8 wires */
 #define SPI_RX_OCTAL	BIT(15)			/* receive with 8 wires */
+#define SPI_NO_TX	BIT(16)			/* no transmit wire */
+#define SPI_NO_RX	BIT(17)			/* no receive wire */
 
 /* Header byte that marks the start of the message */
 #define SPI_PREAMBLE_END_BYTE	0xec
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.