mirror of https://github.com/torvalds/linux.git
306 lines
12 KiB
ReStructuredText
306 lines
12 KiB
ReStructuredText
.. 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>;
|
||
};
|
||
};
|