Skip to content

Commit

Permalink
Merge tag 'spi-mosi-config' into togreg
Browse files Browse the repository at this point in the history
spi: Support MOSI idle configuration

Add support for configuring the idle state of the MOSI signal in
controllers.
  • Loading branch information
Jonathan Cameron authored and Jonathan Cameron committed Aug 3, 2024
2 parents 6140a92 + 96472f1 commit b71fdd6
Show file tree
Hide file tree
Showing 9 changed files with 344 additions and 6 deletions.
197 changes: 197 additions & 0 deletions Documentation/devicetree/bindings/iio/adc/adi,ad4000.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adi,ad4000.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Analog Devices AD4000 and similar Analog to Digital Converters

maintainers:
- Marcelo Schmitt <marcelo.schmitt@analog.com>

description: |
Analog Devices AD4000 family of Analog to Digital Converters with SPI support.
Specifications can be found at:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4000-4004-4008.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4001-4005.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4002-4006-4010.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4003-4007-4011.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4020-4021-4022.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4001.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4003.pdf
$ref: /schemas/spi/spi-peripheral-props.yaml#

properties:
compatible:
oneOf:
- const: adi,ad4000
- items:
- enum:
- adi,ad4004
- adi,ad4008
- const: adi,ad4000

- const: adi,ad4001
- items:
- enum:
- adi,ad4005
- const: adi,ad4001

- const: adi,ad4002
- items:
- enum:
- adi,ad4006
- adi,ad4010
- const: adi,ad4002

- const: adi,ad4003
- items:
- enum:
- adi,ad4007
- adi,ad4011
- const: adi,ad4003

- const: adi,ad4020
- items:
- enum:
- adi,ad4021
- adi,ad4022
- const: adi,ad4020

- const: adi,adaq4001

- const: adi,adaq4003

reg:
maxItems: 1

spi-max-frequency:
maximum: 102040816 # for VIO > 2.7 V, 81300813 for VIO > 1.7 V

adi,sdi-pin:
$ref: /schemas/types.yaml#/definitions/string
enum: [ high, low, cs, sdi ]
default: sdi
description:
Describes how the ADC SDI pin is wired. A value of "sdi" indicates that
the ADC SDI is connected to host SDO. "high" indicates that the ADC SDI
pin is hard-wired to logic high (VIO). "low" indicates that it is
hard-wired low (GND). "cs" indicates that the ADC SDI pin is connected to
the host CS line.

'#daisy-chained-devices': true

vdd-supply:
description: A 1.8V supply that powers the chip (VDD).

vio-supply:
description:
A 1.8V to 5.5V supply for the digital inputs and outputs (VIO).

ref-supply:
description:
A 2.5 to 5V supply for the external reference voltage (REF).

cnv-gpios:
description:
When provided, this property indicates the GPIO that is connected to the
CNV pin.
maxItems: 1

adi,high-z-input:
type: boolean
description:
High-Z mode allows the amplifier and RC filter in front of the ADC to be
chosen based on the signal bandwidth of interest, rather than the settling
requirements of the switched capacitor SAR ADC inputs.

adi,gain-milli:
description: |
The hardware gain applied to the ADC input (in milli units).
The gain provided by the ADC input scaler is defined by the hardware
connections between chip pins OUT+, R1K-, R1K1-, R1K+, R1K1+, and OUT-.
If not present, default to 1000 (no actual gain applied).
$ref: /schemas/types.yaml#/definitions/uint16
enum: [454, 909, 1000, 1900]
default: 1000

interrupts:
description:
The SDO pin can also function as a busy indicator. This node should be
connected to an interrupt that is triggered when the SDO line goes low
while the SDI line is high and the CNV line is low ("3-wire" mode) or the
SDI line is low and the CNV line is high ("4-wire" mode); or when the SDO
line goes high while the SDI and CNV lines are high (chain mode),
maxItems: 1

required:
- compatible
- reg
- vdd-supply
- vio-supply
- ref-supply

allOf:
# The configuration register can only be accessed if SDI is connected to MOSI
- if:
required:
- adi,sdi-pin
then:
properties:
adi,high-z-input: false
# chain mode has lower SCLK max rate
- if:
required:
- '#daisy-chained-devices'
then:
properties:
spi-max-frequency:
maximum: 50000000 # for VIO > 2.7 V, 40000000 for VIO > 1.7 V
# Gain property only applies to ADAQ devices
- if:
properties:
compatible:
not:
contains:
enum:
- adi,adaq4001
- adi,adaq4003
then:
properties:
adi,gain-milli: false

unevaluatedProperties: false

examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad4020";
reg = <0>;
spi-max-frequency = <71000000>;
vdd-supply = <&supply_1_8V>;
vio-supply = <&supply_1_8V>;
ref-supply = <&supply_5V>;
adi,sdi-pin = "cs";
cnv-gpios = <&gpio0 88 GPIO_ACTIVE_HIGH>;
};
};
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,adaq4003";
reg = <0>;
spi-max-frequency = <80000000>;
vdd-supply = <&supply_1_8V>;
vio-supply = <&supply_1_8V>;
ref-supply = <&supply_5V>;
adi,high-z-input;
adi,gain-milli = /bits/ 16 <454>;
};
};
83 changes: 83 additions & 0 deletions Documentation/spi/spi-summary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,89 @@ queue, and then start some asynchronous transfer engine (unless it's
already running).


Extensions to the SPI protocol
------------------------------
The fact that SPI doesn't have a formal specification or standard permits chip
manufacturers to implement the SPI protocol in slightly different ways. In most
cases, SPI protocol implementations from different vendors are compatible among
each other. For example, in SPI mode 0 (CPOL=0, CPHA=0) the bus lines may behave
like the following:

::

nCSx ___ ___
\_________________________________________________________________/
• •
• •
SCLK ___ ___ ___ ___ ___ ___ ___ ___
_______/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \_____
• : ; : ; : ; : ; : ; : ; : ; : ; •
• : ; : ; : ; : ; : ; : ; : ; : ; •
MOSI XXX__________ _______ _______ ________XXX
0xA5 XXX__/ 1 \_0_____/ 1 \_0_______0_____/ 1 \_0_____/ 1 \_XXX
• ; ; ; ; ; ; ; ; •
• ; ; ; ; ; ; ; ; •
MISO XXX__________ _______________________ _______ XXX
0xBA XXX__/ 1 \_____0_/ 1 1 1 \_____0__/ 1 \____0__XXX

Legend::

• marks the start/end of transmission;
: marks when data is clocked into the peripheral;
; marks when data is clocked into the controller;
X marks when line states are not specified.

In some few cases, chips extend the SPI protocol by specifying line behaviors
that other SPI protocols don't (e.g. data line state for when CS is not
asserted). Those distinct SPI protocols, modes, and configurations are supported
by different SPI mode flags.

MOSI idle state configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Common SPI protocol implementations don't specify any state or behavior for the
MOSI line when the controller is not clocking out data. However, there do exist
peripherals that require specific MOSI line state when data is not being clocked
out. For example, if the peripheral expects the MOSI line to be high when the
controller is not clocking out data (``SPI_MOSI_IDLE_HIGH``), then a transfer in
SPI mode 0 would look like the following:

::

nCSx ___ ___
\_________________________________________________________________/
• •
• •
SCLK ___ ___ ___ ___ ___ ___ ___ ___
_______/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \_____
• : ; : ; : ; : ; : ; : ; : ; : ; •
• : ; : ; : ; : ; : ; : ; : ; : ; •
MOSI _____ _______ _______ _______________ ___
0x56 \_0_____/ 1 \_0_____/ 1 \_0_____/ 1 1 \_0_____/
• ; ; ; ; ; ; ; ; •
• ; ; ; ; ; ; ; ; •
MISO XXX__________ _______________________ _______ XXX
0xBA XXX__/ 1 \_____0_/ 1 1 1 \_____0__/ 1 \____0__XXX

Legend::

• marks the start/end of transmission;
: marks when data is clocked into the peripheral;
; marks when data is clocked into the controller;
X marks when line states are not specified.

In this extension to the usual SPI protocol, the MOSI line state is specified to
be kept high when CS is asserted but the controller is not clocking out data to
the peripheral and also when CS is not asserted.

Peripherals that require this extension must request it by setting the
``SPI_MOSI_IDLE_HIGH`` bit into the mode attribute of their ``struct
spi_device`` and call spi_setup(). Controllers that support this extension
should indicate it by setting ``SPI_MOSI_IDLE_HIGH`` in the mode_bits attribute
of their ``struct spi_controller``. The configuration to idle MOSI low is
analogous but uses the ``SPI_MOSI_IDLE_LOW`` mode bit.


THANKS TO
---------
Contributors to Linux-SPI discussions include (in alphabetical order,
Expand Down
7 changes: 7 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,13 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
F: drivers/iio/dac/ad3552r.c

ANALOG DEVICES INC AD4000 DRIVER
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad4000.yaml

ANALOG DEVICES INC AD4130 DRIVER
M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-iio@vger.kernel.org
Expand Down
15 changes: 12 additions & 3 deletions drivers/spi/spi-axi-spi-engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#define SPI_ENGINE_CONFIG_CPHA BIT(0)
#define SPI_ENGINE_CONFIG_CPOL BIT(1)
#define SPI_ENGINE_CONFIG_3WIRE BIT(2)
#define SPI_ENGINE_CONFIG_SDO_IDLE_HIGH BIT(3)

#define SPI_ENGINE_INST_TRANSFER 0x0
#define SPI_ENGINE_INST_ASSERT 0x1
Expand Down Expand Up @@ -137,6 +138,10 @@ static unsigned int spi_engine_get_config(struct spi_device *spi)
config |= SPI_ENGINE_CONFIG_CPHA;
if (spi->mode & SPI_3WIRE)
config |= SPI_ENGINE_CONFIG_3WIRE;
if (spi->mode & SPI_MOSI_IDLE_HIGH)
config |= SPI_ENGINE_CONFIG_SDO_IDLE_HIGH;
if (spi->mode & SPI_MOSI_IDLE_LOW)
config &= ~SPI_ENGINE_CONFIG_SDO_IDLE_HIGH;

return config;
}
Expand Down Expand Up @@ -692,9 +697,13 @@ static int spi_engine_probe(struct platform_device *pdev)
host->num_chipselect = 8;

/* Some features depend of the IP core version. */
if (ADI_AXI_PCORE_VER_MINOR(version) >= 2) {
host->mode_bits |= SPI_CS_HIGH;
host->setup = spi_engine_setup;
if (ADI_AXI_PCORE_VER_MAJOR(version) >= 1) {
if (ADI_AXI_PCORE_VER_MINOR(version) >= 2) {
host->mode_bits |= SPI_CS_HIGH;
host->setup = spi_engine_setup;
}
if (ADI_AXI_PCORE_VER_MINOR(version) >= 3)
host->mode_bits |= SPI_MOSI_IDLE_LOW | SPI_MOSI_IDLE_HIGH;
}

if (host->max_speed_hz == 0)
Expand Down
Loading

0 comments on commit b71fdd6

Please sign in to comment.