| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- ====================================
- SPI devices with multiple data lanes
- ====================================
- Some specialized SPI controllers and peripherals support multiple data lanes
- that allow reading more than one word at a time in parallel. This is different
- from dual/quad/octal SPI where multiple bits of a single word are transferred
- simultaneously.
- For example, controllers that support parallel flash memories have this feature
- as do some simultaneous-sampling ADCs where each channel has its own data lane.
- ---------------------
- Describing the wiring
- ---------------------
- The ``spi-tx-bus-width`` and ``spi-rx-bus-width`` properties in the devicetree
- are used to describe how many data lanes are connected between the controller
- and how wide each lane is. The number of items in the array indicates how many
- lanes there are, and the value of each item indicates how many bits wide that
- lane is.
- For example, a dual-simultaneous-sampling ADC with two 4-bit lanes might be
- wired up like this::
- +--------------+ +----------+
- | SPI | | AD4630 |
- | Controller | | ADC |
- | | | |
- | CS0 |--->| CS |
- | SCK |--->| SCK |
- | SDO |--->| SDI |
- | | | |
- | SDIA0 |<---| SDOA0 |
- | SDIA1 |<---| SDOA1 |
- | SDIA2 |<---| SDOA2 |
- | SDIA3 |<---| SDOA3 |
- | | | |
- | SDIB0 |<---| SDOB0 |
- | SDIB1 |<---| SDOB1 |
- | SDIB2 |<---| SDOB2 |
- | SDIB3 |<---| SDOB3 |
- | | | |
- +--------------+ +----------+
- It is described in a devicetree like this::
- spi {
- compatible = "my,spi-controller";
- ...
- adc@0 {
- compatible = "adi,ad4630";
- reg = <0>;
- ...
- spi-rx-bus-width = <4>, <4>; /* 2 lanes of 4 bits each */
- ...
- };
- };
- In most cases, lanes will be wired up symmetrically (A to A, B to B, etc). If
- this isn't the case, extra ``spi-rx-lane-map`` and ``spi-tx-lane-map``
- properties are needed to provide a mapping between controller lanes and the
- physical lane wires.
- Here is an example where a multi-lane SPI controller has each lane wired to
- separate single-lane peripherals::
- +--------------+ +----------+
- | SPI | | Thing 1 |
- | Controller | | |
- | | | |
- | CS0 |--->| CS |
- | SDO0 |--->| SDI |
- | SDI0 |<---| SDO |
- | SCLK0 |--->| SCLK |
- | | | |
- | | +----------+
- | |
- | | +----------+
- | | | Thing 2 |
- | | | |
- | CS1 |--->| CS |
- | SDO1 |--->| SDI |
- | SDI1 |<---| SDO |
- | SCLK1 |--->| SCLK |
- | | | |
- +--------------+ +----------+
- This is described in a devicetree like this::
- spi {
- compatible = "my,spi-controller";
- ...
- thing1@0 {
- compatible = "my,thing1";
- reg = <0>;
- ...
- };
- thing2@1 {
- compatible = "my,thing2";
- reg = <1>;
- ...
- spi-tx-lane-map = <1>; /* lane 0 is not used, lane 1 is used for tx wire */
- spi-rx-lane-map = <1>; /* lane 0 is not used, lane 1 is used for rx wire */
- ...
- };
- };
- The default values of ``spi-rx-bus-width`` and ``spi-tx-bus-width`` are ``<1>``,
- so these properties can still be omitted even when ``spi-rx-lane-map`` and
- ``spi-tx-lane-map`` are used.
- ----------------------------
- Usage in a peripheral driver
- ----------------------------
- These types of SPI controllers generally do not support arbitrary use of the
- multiple lanes. Instead, they operate in one of a few defined modes. Peripheral
- drivers should set the :c:type:`struct spi_transfer.multi_lane_mode <spi_transfer>`
- field to indicate which mode they want to use for a given transfer.
- The possible values for this field have the following semantics:
- - :c:macro:`SPI_MULTI_BUS_MODE_SINGLE`: Only use the first lane. Other lanes are
- ignored. This means that it is operating just like a conventional SPI
- peripheral. This is the default, so it does not need to be explicitly set.
- Example::
- tx_buf[0] = 0x88;
- struct spi_transfer xfer = {
- .tx_buf = tx_buf,
- .len = 1,
- };
- spi_sync_transfer(spi, &xfer, 1);
- Assuming the controller is sending the MSB first, the sequence of bits
- sent over the tx wire would be (right-most bit is sent first)::
- controller > data bits > peripheral
- ---------- ---------------- ----------
- SDO 0 0-0-0-1-0-0-0-1 SDI 0
- - :c:macro:`SPI_MULTI_BUS_MODE_MIRROR`: Send a single data word over all of the
- lanes at the same time. This only makes sense for writes and not
- for reads.
- Example::
- tx_buf[0] = 0x88;
- struct spi_transfer xfer = {
- .tx_buf = tx_buf,
- .len = 1,
- .multi_lane_mode = SPI_MULTI_BUS_MODE_MIRROR,
- };
- spi_sync_transfer(spi, &xfer, 1);
- The data is mirrored on each tx wire::
- controller > data bits > peripheral
- ---------- ---------------- ----------
- SDO 0 0-0-0-1-0-0-0-1 SDI 0
- SDO 1 0-0-0-1-0-0-0-1 SDI 1
- - :c:macro:`SPI_MULTI_BUS_MODE_STRIPE`: Send or receive two different data words
- at the same time, one on each lane. This means that the buffer needs to be
- sized to hold data for all lanes. Data is interleaved in the buffer, with
- the first word corresponding to lane 0, the second to lane 1, and so on.
- Once the last lane is used, the next word in the buffer corresponds to lane
- 0 again. Accordingly, the buffer size must be a multiple of the number of
- lanes. This mode works for both reads and writes.
- Example::
- struct spi_transfer xfer = {
- .rx_buf = rx_buf,
- .len = 2,
- .multi_lane_mode = SPI_MULTI_BUS_MODE_STRIPE,
- };
- spi_sync_transfer(spi, &xfer, 1);
- Each rx wire has a different data word sent simultaneously::
- controller < data bits < peripheral
- ---------- ---------------- ----------
- SDI 0 0-0-0-1-0-0-0-1 SDO 0
- SDI 1 1-0-0-0-1-0-0-0 SDO 1
- After the transfer, ``rx_buf[0] == 0x11`` (word from SDO 0) and
- ``rx_buf[1] == 0x88`` (word from SDO 1).
- -----------------------------
- SPI controller driver support
- -----------------------------
- To support multiple data lanes, SPI controller drivers need to set
- :c:type:`struct spi_controller.num_data_lanes <spi_controller>` to a value
- greater than 1.
- Then the part of the driver that handles SPI transfers needs to check the
- :c:type:`struct spi_transfer.multi_lane_mode <spi_transfer>` field and implement
- the appropriate behavior for each supported mode and return an error for
- unsupported modes.
- The core SPI code should handle the rest.
|