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>;
|
|||
|
|
};
|
|||
|
|
};
|