| .. SPDX-License-Identifier: GPL-2.0-only | |
| ========================= | |
| IIO Abstractions for ADCs | |
| ========================= | |
| 1. Overview | |
| =========== | |
| The IIO subsystem supports many Analog to Digital Converters (ADCs). Some ADCs | |
| have features and characteristics that are supported in specific ways by IIO | |
| device drivers. This documentation describes common ADC features and explains | |
| how they are supported by the IIO subsystem. | |
| 1. ADC Channel Types | |
| ==================== | |
| ADCs can have distinct types of inputs, each of them measuring analog voltages | |
| in a slightly different way. An ADC digitizes the analog input voltage over a | |
| span that is often given by the provided voltage reference, the input type, and | |
| the input polarity. The input range allowed to an ADC channel is needed to | |
| determine the scale factor and offset needed to obtain the measured value in | |
| real-world units (millivolts for voltage measurement, milliamps for current | |
| measurement, etc.). | |
| Elaborate designs may have nonlinear characteristics or integrated components | |
| (such as amplifiers and reference buffers) that might also have to be considered | |
| to derive the allowed input range for an ADC. For clarity, the sections below | |
| assume the input range only depends on the provided voltage references, input | |
| type, and input polarity. | |
| There are three general types of ADC inputs (single-ended, differential, | |
| pseudo-differential) and two possible polarities (unipolar, bipolar). The input | |
| type (single-ended, differential, pseudo-differential) is one channel | |
| characteristic, and is completely independent of the polarity (unipolar, | |
| bipolar) aspect. A comprehensive article about ADC input types (on which this | |
| doc is heavily based on) can be found at | |
| https://www.analog.com/en/resources/technical-articles/sar-adc-input-types.html. | |
| 1.1 Single-ended channels | |
| ------------------------- | |
| Single-ended channels digitize the analog input voltage relative to ground and | |
| can be either unipolar or bipolar. | |
| 1.1.1 Single-ended Unipolar Channels | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| :: | |
| ---------- VREF ------------- | |
| ´ ` ´ ` _____________ | |
| / \ / \ / | | |
| / \ / \ --- < IN ADC | | |
| \ / \ / \ | | |
| `-´ `-´ \ VREF | | |
| -------- GND (0V) ----------- +-----------+ | |
| ^ | |
| | | |
| External VREF | |
| The input voltage to a **single-ended unipolar** channel is allowed to swing | |
| from GND to VREF (where VREF is a voltage reference with electrical potential | |
| higher than system ground). The maximum input voltage is also called VFS | |
| (Voltage input Full-Scale), with VFS being determined by VREF. The voltage | |
| reference may be provided from an external supply or derived from the chip power | |
| source. | |
| A single-ended unipolar channel could be described in device tree like the | |
| following example:: | |
| adc@0 { | |
| ... | |
| #address-cells = <1>; | |
| #size-cells = <0>; | |
| channel@0 { | |
| reg = <0>; | |
| }; | |
| }; | |
| One is always allowed to include ADC channel nodes in the device tree. Though, | |
| if the device has a uniform set of inputs (e.g. all inputs are single-ended), | |
| then declaring the channel nodes is optional. | |
| One caveat for devices that support mixed single-ended and differential channels | |
| is that single-ended channel nodes also need to provide a ``single-channel`` | |
| property when ``reg`` is an arbitrary number that doesn't match the input pin | |
| number. | |
| See ``Documentation/devicetree/bindings/iio/adc/adc.yaml`` for the complete | |
| documentation of ADC specific device tree properties. | |
| 1.1.2 Single-ended Bipolar Channels | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| :: | |
| ---------- +VREF ------------ | |
| ´ ` ´ ` _____________________ | |
| / \ / \ / | | |
| / \ / \ --- < IN ADC | | |
| \ / \ / \ | | |
| `-´ `-´ \ +VREF -VREF | | |
| ---------- -VREF ------------ +-------------------+ | |
| ^ ^ | |
| | | | |
| External +VREF ------+ External -VREF | |
| For a **single-ended bipolar** channel, the analog voltage input can go from | |
| -VREF to +VREF (where -VREF is the voltage reference that has the lower | |
| electrical potential while +VREF is the reference with the higher one). Some ADC | |
| chips derive the lower reference from +VREF, others get it from a separate | |
| input. Often, +VREF and -VREF are symmetric but they don't need to be so. When | |
| -VREF is lower than system ground, these inputs are also called single-ended | |
| true bipolar. Also, while there is a relevant difference between bipolar and | |
| true bipolar from the electrical perspective, IIO makes no explicit distinction | |
| between them. | |
| Here's an example device tree description of a single-ended bipolar channel:: | |
| adc@0 { | |
| ... | |
| #address-cells = <1>; | |
| #size-cells = <0>; | |
| channel@0 { | |
| reg = <0>; | |
| bipolar; | |
| }; | |
| }; | |
| 1.2 Differential channels | |
| ------------------------- | |
| A differential voltage measurement digitizes the voltage level at the positive | |
| input (IN+) relative to the negative input (IN-) over the -VREF to +VREF span. | |
| In other words, a differential channel measures the potential difference between | |
| IN+ and IN-, which is often denoted by the IN+ - IN- formula. | |
| 1.2.1 Differential Bipolar Channels | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| :: | |
| -------- +VREF ------ +-------------------+ | |
| ´ ` ´ ` / | | |
| / \ / \ / --- < IN+ | | |
| `-´ `-´ | | | |
| -------- -VREF ------ | | | |
| | ADC | | |
| -------- +VREF ------ | | | |
| ´ ` ´ ` | | | |
| \ / \ / \ --- < IN- | | |
| `-´ `-´ \ +VREF -VREF | | |
| -------- -VREF ------ +-------------------+ | |
| ^ ^ | |
| | +---- External -VREF | |
| External +VREF | |
| The analog signals to **differential bipolar** inputs are also allowed to swing | |
| from -VREF to +VREF. The bipolar part of the name means that the resulting value | |
| of the difference (IN+ - IN-) can be positive or negative. If -VREF is below | |
| system GND, these are also called differential true bipolar inputs. | |
| Device tree example of a differential bipolar channel:: | |
| adc@0 { | |
| ... | |
| #address-cells = <1>; | |
| #size-cells = <0>; | |
| channel@0 { | |
| reg = <0>; | |
| bipolar; | |
| diff-channels = <0 1>; | |
| }; | |
| }; | |
| In the ADC driver, ``differential = 1`` is set into ``struct iio_chan_spec`` for | |
| the channel. Even though, there are three general input types, ``differential`` | |
| is only used to distinguish between differential and non-differential (either | |
| single-ended or pseudo-differential) input types. See | |
| ``include/linux/iio/iio.h`` for more information. | |
| 1.2.2 Differential Unipolar Channels | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| For **differential unipolar** channels, the analog voltage at the positive input | |
| must also be higher than the voltage at the negative input. Thus, the actual | |
| input range allowed to a differential unipolar channel is IN- to +VREF. Because | |
| IN+ is allowed to swing with the measured analog signal and the input setup must | |
| guarantee IN+ will not go below IN- (nor IN- will raise above IN+), most | |
| differential unipolar channel setups have IN- fixed to a known voltage that does | |
| not fall within the voltage range expected for the measured signal. That leads | |
| to a setup that is equivalent to a pseudo-differential channel. Thus, | |
| differential unipolar setups can often be supported as pseudo-differential | |
| unipolar channels. | |
| 1.3 Pseudo-differential Channels | |
| -------------------------------- | |
| There is a third ADC input type which is called pseudo-differential or | |
| single-ended to differential configuration. A pseudo-differential channel is | |
| similar to a differential channel in that it also measures IN+ relative to IN-. | |
| However, unlike bipolar differential channels, the negative input is limited to | |
| a narrow voltage range (taken as a constant voltage) while only IN+ is allowed | |
| to swing. A pseudo-differential channel can be made out from a differential pair | |
| of inputs by restricting the negative input to a known voltage while allowing | |
| only the positive input to swing. Sometimes, the input provided to IN- is called | |
| common-mode voltage. Besides, some parts have a COM pin that allows single-ended | |
| inputs to be referenced to a common-mode voltage, making them | |
| pseudo-differential channels. Often, the common mode input voltage can be | |
| described in the device tree as a voltage regulator (e.g. ``com-supply``) since | |
| it is basically a constant voltage source. | |
| 1.3.1 Pseudo-differential Unipolar Channels | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| :: | |
| -------- +VREF ------ +-------------------+ | |
| ´ ` ´ ` / | | |
| / \ / \ / --- < IN+ | | |
| `-´ `-´ | | | |
| --------- IN- ------- | ADC | | |
| | | | |
| Common-mode voltage --> --- < IN- | | |
| \ +VREF -VREF | | |
| +-------------------+ | |
| ^ ^ | |
| | +---- External -VREF | |
| External +VREF | |
| A **pseudo-differential unipolar** input has the limitations a differential | |
| unipolar channel would have, meaning the analog voltage to the positive input | |
| IN+ must stay within IN- to +VREF. The fixed voltage to IN- is often called | |
| common-mode voltage and it must be within -VREF to +VREF as would be expected | |
| from the signal to any differential channel negative input. | |
| The voltage measured from IN+ is relative to IN- but, unlike differential | |
| channels, pseudo-differential setups are intended to gauge single-ended input | |
| signals. To enable applications to calculate IN+ voltage with respect to system | |
| ground, the IIO channel may provide an ``_offset`` sysfs attribute to be added | |
| to ADC output when converting raw data to voltage units. In many setups, the | |
| common-mode voltage input is at GND level and the ``_offset`` attribute is | |
| omitted due to being always zero. | |
| Device tree example for pseudo-differential unipolar channel:: | |
| adc@0 { | |
| ... | |
| #address-cells = <1>; | |
| #size-cells = <0>; | |
| channel@0 { | |
| reg = <0>; | |
| single-channel = <0>; | |
| common-mode-channel = <1>; | |
| }; | |
| }; | |
| Do not set ``differential`` in the channel ``iio_chan_spec`` struct of | |
| pseudo-differential channels. | |
| 1.3.2 Pseudo-differential Bipolar Channels | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| :: | |
| -------- +VREF ------ +-------------------+ | |
| ´ ` ´ ` / | | |
| / \ / \ / --- < IN+ | | |
| `-´ `-´ | | | |
| -------- -VREF ------ | ADC | | |
| | | | |
| Common-mode voltage --> --- < IN- | | |
| \ +VREF -VREF | | |
| +-------------------+ | |
| ^ ^ | |
| | +---- External -VREF | |
| External +VREF | |
| A **pseudo-differential bipolar** input is not limited by the level at IN- but | |
| it will be limited to -VREF or to GND on the lower end of the input range | |
| depending on the particular ADC. Similar to their unipolar counter parts, | |
| pseudo-differential bipolar channels ought to declare an ``_offset`` attribute | |
| to enable the conversion of raw ADC data to voltage units. For the setup with | |
| IN- connected to GND, ``_offset`` is often omitted. | |
| Device tree example for pseudo-differential bipolar channel:: | |
| adc@0 { | |
| ... | |
| #address-cells = <1>; | |
| #size-cells = <0>; | |
| channel@0 { | |
| reg = <0>; | |
| bipolar; | |
| single-channel = <0>; | |
| common-mode-channel = <1>; | |
| }; | |
| }; |