Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: Enable controllers to extend the SPI protocol with MOSI idle configuration

The behavior of an SPI controller data output line (SDO or MOSI or COPI
(Controller Output Peripheral Input) for disambiguation) is usually not
specified when the controller is not clocking out data on SCLK edges.
However, there do exist SPI peripherals that require specific MOSI line
state when data is not being clocked out of the controller.

Conventional SPI controllers may set the MOSI line on SCLK edges then bring
it low when no data is going out or leave the line the state of the last
transfer bit. More elaborated controllers are capable to set the MOSI idle
state according to different configurable levels and thus are more suitable
for interfacing with demanding peripherals.

Add SPI mode bits to allow peripherals to request explicit MOSI idle state
when needed.

When supporting a particular MOSI idle configuration, the data output line
state is expected to remain at the configured level when the controller is
not clocking out data. When a device that needs a specific MOSI idle state
is identified, its driver should request the MOSI idle configuration by
setting the proper SPI mode bit.

Acked-by: Nuno Sa <nuno.sa@analog.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: David Lechner <dlechner@baylibre.com>
Tested-by: David Lechner <dlechner@baylibre.com>
Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
Link: https://patch.msgid.link/9802160b5e5baed7f83ee43ac819cb757a19be55.1720810545.git.marcelo.schmitt@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Marcelo Schmitt and committed by
Mark Brown
f58872f4 8400291e

+92 -2
+83
Documentation/spi/spi-summary.rst
··· 614 614 already running). 615 615 616 616 617 + Extensions to the SPI protocol 618 + ------------------------------ 619 + The fact that SPI doesn't have a formal specification or standard permits chip 620 + manufacturers to implement the SPI protocol in slightly different ways. In most 621 + cases, SPI protocol implementations from different vendors are compatible among 622 + each other. For example, in SPI mode 0 (CPOL=0, CPHA=0) the bus lines may behave 623 + like the following: 624 + 625 + :: 626 + 627 + nCSx ___ ___ 628 + \_________________________________________________________________/ 629 + • • 630 + • • 631 + SCLK ___ ___ ___ ___ ___ ___ ___ ___ 632 + _______/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \_____ 633 + • : ; : ; : ; : ; : ; : ; : ; : ; • 634 + • : ; : ; : ; : ; : ; : ; : ; : ; • 635 + MOSI XXX__________ _______ _______ ________XXX 636 + 0xA5 XXX__/ 1 \_0_____/ 1 \_0_______0_____/ 1 \_0_____/ 1 \_XXX 637 + • ; ; ; ; ; ; ; ; • 638 + • ; ; ; ; ; ; ; ; • 639 + MISO XXX__________ _______________________ _______ XXX 640 + 0xBA XXX__/ 1 \_____0_/ 1 1 1 \_____0__/ 1 \____0__XXX 641 + 642 + Legend:: 643 + 644 + • marks the start/end of transmission; 645 + : marks when data is clocked into the peripheral; 646 + ; marks when data is clocked into the controller; 647 + X marks when line states are not specified. 648 + 649 + In some few cases, chips extend the SPI protocol by specifying line behaviors 650 + that other SPI protocols don't (e.g. data line state for when CS is not 651 + asserted). Those distinct SPI protocols, modes, and configurations are supported 652 + by different SPI mode flags. 653 + 654 + MOSI idle state configuration 655 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 656 + 657 + Common SPI protocol implementations don't specify any state or behavior for the 658 + MOSI line when the controller is not clocking out data. However, there do exist 659 + peripherals that require specific MOSI line state when data is not being clocked 660 + out. For example, if the peripheral expects the MOSI line to be high when the 661 + controller is not clocking out data (``SPI_MOSI_IDLE_HIGH``), then a transfer in 662 + SPI mode 0 would look like the following: 663 + 664 + :: 665 + 666 + nCSx ___ ___ 667 + \_________________________________________________________________/ 668 + • • 669 + • • 670 + SCLK ___ ___ ___ ___ ___ ___ ___ ___ 671 + _______/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \_____ 672 + • : ; : ; : ; : ; : ; : ; : ; : ; • 673 + • : ; : ; : ; : ; : ; : ; : ; : ; • 674 + MOSI _____ _______ _______ _______________ ___ 675 + 0x56 \_0_____/ 1 \_0_____/ 1 \_0_____/ 1 1 \_0_____/ 676 + • ; ; ; ; ; ; ; ; • 677 + • ; ; ; ; ; ; ; ; • 678 + MISO XXX__________ _______________________ _______ XXX 679 + 0xBA XXX__/ 1 \_____0_/ 1 1 1 \_____0__/ 1 \____0__XXX 680 + 681 + Legend:: 682 + 683 + • marks the start/end of transmission; 684 + : marks when data is clocked into the peripheral; 685 + ; marks when data is clocked into the controller; 686 + X marks when line states are not specified. 687 + 688 + In this extension to the usual SPI protocol, the MOSI line state is specified to 689 + be kept high when CS is asserted but the controller is not clocking out data to 690 + the peripheral and also when CS is not asserted. 691 + 692 + Peripherals that require this extension must request it by setting the 693 + ``SPI_MOSI_IDLE_HIGH`` bit into the mode attribute of their ``struct 694 + spi_device`` and call spi_setup(). Controllers that support this extension 695 + should indicate it by setting ``SPI_MOSI_IDLE_HIGH`` in the mode_bits attribute 696 + of their ``struct spi_controller``. The configuration to idle MOSI low is 697 + analogous but uses the ``SPI_MOSI_IDLE_LOW`` mode bit. 698 + 699 + 617 700 THANKS TO 618 701 --------- 619 702 Contributors to Linux-SPI discussions include (in alphabetical order,
+6
drivers/spi/spi.c
··· 3921 3921 (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | 3922 3922 SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL))) 3923 3923 return -EINVAL; 3924 + /* Check against conflicting MOSI idle configuration */ 3925 + if ((spi->mode & SPI_MOSI_IDLE_LOW) && (spi->mode & SPI_MOSI_IDLE_HIGH)) { 3926 + dev_err(&spi->dev, 3927 + "setup: MOSI configured to idle low and high at the same time.\n"); 3928 + return -EINVAL; 3929 + } 3924 3930 /* 3925 3931 * Help drivers fail *cleanly* when they need options 3926 3932 * that aren't supported with their current controller.
+3 -2
include/uapi/linux/spi/spi.h
··· 28 28 #define SPI_RX_OCTAL _BITUL(14) /* receive with 8 wires */ 29 29 #define SPI_3WIRE_HIZ _BITUL(15) /* high impedance turnaround */ 30 30 #define SPI_RX_CPHA_FLIP _BITUL(16) /* flip CPHA on Rx only xfer */ 31 - #define SPI_MOSI_IDLE_LOW _BITUL(17) /* leave mosi line low when idle */ 31 + #define SPI_MOSI_IDLE_LOW _BITUL(17) /* leave MOSI line low when idle */ 32 + #define SPI_MOSI_IDLE_HIGH _BITUL(18) /* leave MOSI line high when idle */ 32 33 33 34 /* 34 35 * All the bits defined above should be covered by SPI_MODE_USER_MASK. ··· 39 38 * These bits must not overlap. A static assert check should make sure of that. 40 39 * If adding extra bits, make sure to increase the bit index below as well. 41 40 */ 42 - #define SPI_MODE_USER_MASK (_BITUL(18) - 1) 41 + #define SPI_MODE_USER_MASK (_BITUL(19) - 1) 43 42 44 43 #endif /* _UAPI_SPI_H */