]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
spi: add support for bits-per-word setting
authorDario Binacchi <dario.binacchi@amarulasolutions.com>
Wed, 25 Feb 2026 16:16:52 +0000 (17:16 +0100)
committerPatrice Chotard <patrice.chotard@foss.st.com>
Thu, 30 Apr 2026 06:01:11 +0000 (08:01 +0200)
Allow dynamic configuration of the SPI word length. This is required
for controllers and slaves that need to operate with non-standard
word lengths, such as 9-bit wide transfers.

Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Reviewed-by: Simon Glass <simon.glass@canonical.com>
drivers/spi/spi-uclass.c
include/spi.h

index 6b7ad47c22d44aa3fcae5c88ea93ca6d3cbf34e7..120565df149742b4412a030ca1ada6e99ca06f2d 100644 (file)
@@ -88,6 +88,20 @@ void dm_spi_release_bus(struct udevice *dev)
                ops->release_bus(dev);
 }
 
+int dm_spi_set_wordlen(struct udevice *dev, unsigned int wordlen)
+{
+       struct udevice *bus = dev->parent;
+       struct dm_spi_ops *ops = spi_get_ops(bus);
+
+       if (bus->uclass->uc_drv->id != UCLASS_SPI)
+               return -EOPNOTSUPP;
+
+       if (!ops->set_wordlen)
+               return -ENOSYS;
+
+       return ops->set_wordlen(dev, wordlen);
+}
+
 int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
                const void *dout, void *din, unsigned long flags)
 {
@@ -141,6 +155,11 @@ int spi_set_speed(struct spi_slave *slave, uint hz)
        return ret;
 }
 
+int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen)
+{
+       return dm_spi_set_wordlen(slave->dev, wordlen);
+}
+
 int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
             const void *dout, void *din, unsigned long flags)
 {
@@ -245,6 +264,7 @@ static int spi_child_post_bind(struct udevice *dev)
        }
 
        plat->mode = mode;
+       plat->wordlen = SPI_DEFAULT_WORDLEN;
 
        return 0;
 }
@@ -277,7 +297,7 @@ static int spi_child_pre_probe(struct udevice *dev)
 
        slave->max_hz = plat->max_hz;
        slave->mode = plat->mode;
-       slave->wordlen = SPI_DEFAULT_WORDLEN;
+       slave->wordlen = plat->wordlen;
 
        return 0;
 }
index 95e7d5b1556500dec840b7c184d4acbcef7f5d68..7eaf0aa69b8b3ec0a9e7bc32ad3028c7f69eb258 100644 (file)
@@ -77,11 +77,13 @@ struct dm_spi_bus {
  * @cs:                Chip select number (0..n-1)
  * @max_hz:    Maximum bus speed that this slave can tolerate
  * @mode:      SPI mode to use for this device (see SPI mode flags)
+ * @wordlen:   Word length in bits to use for this device
  */
 struct dm_spi_slave_plat {
        unsigned int cs[SPI_CS_CNT_MAX];
        uint max_hz;
        uint mode;
+       unsigned int wordlen;
 };
 
 /**
@@ -718,6 +720,18 @@ int dm_spi_claim_bus(struct udevice *dev);
  */
 void dm_spi_release_bus(struct udevice *dev);
 
+/**
+ * Set the word length for SPI transactions
+ *
+ * Set the word length (number of bits per word) for SPI transactions.
+ *
+ * @slave:     The SPI slave
+ * @wordlen:   The number of bits in a word
+ *
+ * Returns: 0 on success, -1 on failure.
+ */
+int dm_spi_set_wordlen(struct udevice *dev, unsigned int wordlen);
+
 /**
  * SPI transfer
  *