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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'spi-mosi-config' into togreg

spi: Support MOSI idle configuration

Add support for configuring the idle state of the MOSI signal in
controllers.

+344 -6
+197
Documentation/devicetree/bindings/iio/adc/adi,ad4000.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/adc/adi,ad4000.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Analog Devices AD4000 and similar Analog to Digital Converters 8 + 9 + maintainers: 10 + - Marcelo Schmitt <marcelo.schmitt@analog.com> 11 + 12 + description: | 13 + Analog Devices AD4000 family of Analog to Digital Converters with SPI support. 14 + Specifications can be found at: 15 + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4000-4004-4008.pdf 16 + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4001-4005.pdf 17 + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4002-4006-4010.pdf 18 + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4003-4007-4011.pdf 19 + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4020-4021-4022.pdf 20 + https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4001.pdf 21 + https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4003.pdf 22 + 23 + $ref: /schemas/spi/spi-peripheral-props.yaml# 24 + 25 + properties: 26 + compatible: 27 + oneOf: 28 + - const: adi,ad4000 29 + - items: 30 + - enum: 31 + - adi,ad4004 32 + - adi,ad4008 33 + - const: adi,ad4000 34 + 35 + - const: adi,ad4001 36 + - items: 37 + - enum: 38 + - adi,ad4005 39 + - const: adi,ad4001 40 + 41 + - const: adi,ad4002 42 + - items: 43 + - enum: 44 + - adi,ad4006 45 + - adi,ad4010 46 + - const: adi,ad4002 47 + 48 + - const: adi,ad4003 49 + - items: 50 + - enum: 51 + - adi,ad4007 52 + - adi,ad4011 53 + - const: adi,ad4003 54 + 55 + - const: adi,ad4020 56 + - items: 57 + - enum: 58 + - adi,ad4021 59 + - adi,ad4022 60 + - const: adi,ad4020 61 + 62 + - const: adi,adaq4001 63 + 64 + - const: adi,adaq4003 65 + 66 + reg: 67 + maxItems: 1 68 + 69 + spi-max-frequency: 70 + maximum: 102040816 # for VIO > 2.7 V, 81300813 for VIO > 1.7 V 71 + 72 + adi,sdi-pin: 73 + $ref: /schemas/types.yaml#/definitions/string 74 + enum: [ high, low, cs, sdi ] 75 + default: sdi 76 + description: 77 + Describes how the ADC SDI pin is wired. A value of "sdi" indicates that 78 + the ADC SDI is connected to host SDO. "high" indicates that the ADC SDI 79 + pin is hard-wired to logic high (VIO). "low" indicates that it is 80 + hard-wired low (GND). "cs" indicates that the ADC SDI pin is connected to 81 + the host CS line. 82 + 83 + '#daisy-chained-devices': true 84 + 85 + vdd-supply: 86 + description: A 1.8V supply that powers the chip (VDD). 87 + 88 + vio-supply: 89 + description: 90 + A 1.8V to 5.5V supply for the digital inputs and outputs (VIO). 91 + 92 + ref-supply: 93 + description: 94 + A 2.5 to 5V supply for the external reference voltage (REF). 95 + 96 + cnv-gpios: 97 + description: 98 + When provided, this property indicates the GPIO that is connected to the 99 + CNV pin. 100 + maxItems: 1 101 + 102 + adi,high-z-input: 103 + type: boolean 104 + description: 105 + High-Z mode allows the amplifier and RC filter in front of the ADC to be 106 + chosen based on the signal bandwidth of interest, rather than the settling 107 + requirements of the switched capacitor SAR ADC inputs. 108 + 109 + adi,gain-milli: 110 + description: | 111 + The hardware gain applied to the ADC input (in milli units). 112 + The gain provided by the ADC input scaler is defined by the hardware 113 + connections between chip pins OUT+, R1K-, R1K1-, R1K+, R1K1+, and OUT-. 114 + If not present, default to 1000 (no actual gain applied). 115 + $ref: /schemas/types.yaml#/definitions/uint16 116 + enum: [454, 909, 1000, 1900] 117 + default: 1000 118 + 119 + interrupts: 120 + description: 121 + The SDO pin can also function as a busy indicator. This node should be 122 + connected to an interrupt that is triggered when the SDO line goes low 123 + while the SDI line is high and the CNV line is low ("3-wire" mode) or the 124 + SDI line is low and the CNV line is high ("4-wire" mode); or when the SDO 125 + line goes high while the SDI and CNV lines are high (chain mode), 126 + maxItems: 1 127 + 128 + required: 129 + - compatible 130 + - reg 131 + - vdd-supply 132 + - vio-supply 133 + - ref-supply 134 + 135 + allOf: 136 + # The configuration register can only be accessed if SDI is connected to MOSI 137 + - if: 138 + required: 139 + - adi,sdi-pin 140 + then: 141 + properties: 142 + adi,high-z-input: false 143 + # chain mode has lower SCLK max rate 144 + - if: 145 + required: 146 + - '#daisy-chained-devices' 147 + then: 148 + properties: 149 + spi-max-frequency: 150 + maximum: 50000000 # for VIO > 2.7 V, 40000000 for VIO > 1.7 V 151 + # Gain property only applies to ADAQ devices 152 + - if: 153 + properties: 154 + compatible: 155 + not: 156 + contains: 157 + enum: 158 + - adi,adaq4001 159 + - adi,adaq4003 160 + then: 161 + properties: 162 + adi,gain-milli: false 163 + 164 + unevaluatedProperties: false 165 + 166 + examples: 167 + - | 168 + #include <dt-bindings/gpio/gpio.h> 169 + spi { 170 + #address-cells = <1>; 171 + #size-cells = <0>; 172 + adc@0 { 173 + compatible = "adi,ad4020"; 174 + reg = <0>; 175 + spi-max-frequency = <71000000>; 176 + vdd-supply = <&supply_1_8V>; 177 + vio-supply = <&supply_1_8V>; 178 + ref-supply = <&supply_5V>; 179 + adi,sdi-pin = "cs"; 180 + cnv-gpios = <&gpio0 88 GPIO_ACTIVE_HIGH>; 181 + }; 182 + }; 183 + - | 184 + spi { 185 + #address-cells = <1>; 186 + #size-cells = <0>; 187 + adc@0 { 188 + compatible = "adi,adaq4003"; 189 + reg = <0>; 190 + spi-max-frequency = <80000000>; 191 + vdd-supply = <&supply_1_8V>; 192 + vio-supply = <&supply_1_8V>; 193 + ref-supply = <&supply_5V>; 194 + adi,high-z-input; 195 + adi,gain-milli = /bits/ 16 <454>; 196 + }; 197 + };
+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,
+7
MAINTAINERS
··· 1214 1214 F: Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml 1215 1215 F: drivers/iio/dac/ad3552r.c 1216 1216 1217 + ANALOG DEVICES INC AD4000 DRIVER 1218 + M: Marcelo Schmitt <marcelo.schmitt@analog.com> 1219 + L: linux-iio@vger.kernel.org 1220 + S: Supported 1221 + W: https://ez.analog.com/linux-software-drivers 1222 + F: Documentation/devicetree/bindings/iio/adc/adi,ad4000.yaml 1223 + 1217 1224 ANALOG DEVICES INC AD4130 DRIVER 1218 1225 M: Cosmin Tanislav <cosmin.tanislav@analog.com> 1219 1226 L: linux-iio@vger.kernel.org
+12 -3
drivers/spi/spi-axi-spi-engine.c
··· 41 41 #define SPI_ENGINE_CONFIG_CPHA BIT(0) 42 42 #define SPI_ENGINE_CONFIG_CPOL BIT(1) 43 43 #define SPI_ENGINE_CONFIG_3WIRE BIT(2) 44 + #define SPI_ENGINE_CONFIG_SDO_IDLE_HIGH BIT(3) 44 45 45 46 #define SPI_ENGINE_INST_TRANSFER 0x0 46 47 #define SPI_ENGINE_INST_ASSERT 0x1 ··· 138 137 config |= SPI_ENGINE_CONFIG_CPHA; 139 138 if (spi->mode & SPI_3WIRE) 140 139 config |= SPI_ENGINE_CONFIG_3WIRE; 140 + if (spi->mode & SPI_MOSI_IDLE_HIGH) 141 + config |= SPI_ENGINE_CONFIG_SDO_IDLE_HIGH; 142 + if (spi->mode & SPI_MOSI_IDLE_LOW) 143 + config &= ~SPI_ENGINE_CONFIG_SDO_IDLE_HIGH; 141 144 142 145 return config; 143 146 } ··· 697 692 host->num_chipselect = 8; 698 693 699 694 /* Some features depend of the IP core version. */ 700 - if (ADI_AXI_PCORE_VER_MINOR(version) >= 2) { 701 - host->mode_bits |= SPI_CS_HIGH; 702 - host->setup = spi_engine_setup; 695 + if (ADI_AXI_PCORE_VER_MAJOR(version) >= 1) { 696 + if (ADI_AXI_PCORE_VER_MINOR(version) >= 2) { 697 + host->mode_bits |= SPI_CS_HIGH; 698 + host->setup = spi_engine_setup; 699 + } 700 + if (ADI_AXI_PCORE_VER_MINOR(version) >= 3) 701 + host->mode_bits |= SPI_MOSI_IDLE_LOW | SPI_MOSI_IDLE_HIGH; 703 702 } 704 703 705 704 if (host->max_speed_hz == 0)
+24
drivers/spi/spi-bitbang.c
··· 54 54 struct spi_transfer *t, 55 55 unsigned int flags) 56 56 { 57 + struct spi_bitbang *bitbang; 57 58 unsigned int bits = t->bits_per_word; 58 59 unsigned int count = t->len; 59 60 const u8 *tx = t->tx_buf; 60 61 u8 *rx = t->rx_buf; 61 62 63 + bitbang = spi_controller_get_devdata(spi->controller); 62 64 while (likely(count > 0)) { 63 65 u8 word = 0; 64 66 65 67 if (tx) 66 68 word = *tx++; 69 + else 70 + word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFF : 0; 67 71 word = txrx_word(spi, ns, word, bits, flags); 68 72 if (rx) 69 73 *rx++ = word; 70 74 count -= 1; 71 75 } 76 + if (bitbang->set_mosi_idle) 77 + bitbang->set_mosi_idle(spi); 78 + 72 79 return t->len - count; 73 80 } 74 81 ··· 85 78 struct spi_transfer *t, 86 79 unsigned int flags) 87 80 { 81 + struct spi_bitbang *bitbang; 88 82 unsigned int bits = t->bits_per_word; 89 83 unsigned int count = t->len; 90 84 const u16 *tx = t->tx_buf; 91 85 u16 *rx = t->rx_buf; 92 86 87 + bitbang = spi_controller_get_devdata(spi->controller); 93 88 while (likely(count > 1)) { 94 89 u16 word = 0; 95 90 96 91 if (tx) 97 92 word = *tx++; 93 + else 94 + word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFFFF : 0; 98 95 word = txrx_word(spi, ns, word, bits, flags); 99 96 if (rx) 100 97 *rx++ = word; 101 98 count -= 2; 102 99 } 100 + if (bitbang->set_mosi_idle) 101 + bitbang->set_mosi_idle(spi); 102 + 103 103 return t->len - count; 104 104 } 105 105 ··· 116 102 struct spi_transfer *t, 117 103 unsigned int flags) 118 104 { 105 + struct spi_bitbang *bitbang; 119 106 unsigned int bits = t->bits_per_word; 120 107 unsigned int count = t->len; 121 108 const u32 *tx = t->tx_buf; 122 109 u32 *rx = t->rx_buf; 123 110 111 + bitbang = spi_controller_get_devdata(spi->controller); 124 112 while (likely(count > 3)) { 125 113 u32 word = 0; 126 114 127 115 if (tx) 128 116 word = *tx++; 117 + else 118 + word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFFFFFFFF : 0; 129 119 word = txrx_word(spi, ns, word, bits, flags); 130 120 if (rx) 131 121 *rx++ = word; 132 122 count -= 4; 133 123 } 124 + if (bitbang->set_mosi_idle) 125 + bitbang->set_mosi_idle(spi); 126 + 134 127 return t->len - count; 135 128 } 136 129 ··· 212 191 if (retval < 0) 213 192 goto err_free; 214 193 } 194 + 195 + if (bitbang->set_mosi_idle) 196 + bitbang->set_mosi_idle(spi); 215 197 216 198 dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); 217 199
+11 -1
drivers/spi/spi-gpio.c
··· 236 236 } 237 237 } 238 238 239 + static void spi_gpio_set_mosi_idle(struct spi_device *spi) 240 + { 241 + struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); 242 + 243 + gpiod_set_value_cansleep(spi_gpio->mosi, 244 + !!(spi->mode & SPI_MOSI_IDLE_HIGH)); 245 + } 246 + 239 247 static int spi_gpio_setup(struct spi_device *spi) 240 248 { 241 249 struct gpio_desc *cs; ··· 397 389 398 390 host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); 399 391 host->mode_bits = SPI_3WIRE | SPI_3WIRE_HIZ | SPI_CPHA | SPI_CPOL | 400 - SPI_CS_HIGH | SPI_LSB_FIRST; 392 + SPI_CS_HIGH | SPI_LSB_FIRST | SPI_MOSI_IDLE_LOW | 393 + SPI_MOSI_IDLE_HIGH; 401 394 if (!spi_gpio->mosi) { 402 395 /* HW configuration without MOSI pin 403 396 * ··· 423 414 host->flags |= SPI_CONTROLLER_GPIO_SS; 424 415 bb->chipselect = spi_gpio_chipselect; 425 416 bb->set_line_direction = spi_gpio_set_direction; 417 + bb->set_mosi_idle = spi_gpio_set_mosi_idle; 426 418 427 419 if (host->flags & SPI_CONTROLLER_NO_TX) { 428 420 bb->txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0;
+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.
+1
include/linux/spi/spi_bitbang.h
··· 24 24 #define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */ 25 25 #define BITBANG_CS_INACTIVE 0 26 26 27 + void (*set_mosi_idle)(struct spi_device *spi); 27 28 /* txrx_bufs() may handle dma mapping for transfers that don't 28 29 * already have one (transfer.{tx,rx}_dma is zero), or use PIO 29 30 */
+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 */