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


Reply via email to