AD4030/AD4630/ADAQ4216/ADAQ4224
AD4030/AD4630/ADAQ4216/ADAQ4224 ADC Linux Driver.
Note
This is the mainlined driver (ad4030.c). An alternative out-of-tree driver is documented at AD4630.
Supported Devices
Evaluation Boards
Description
The ad4030-24, ad4630-24, and similar ADCs are low noise, low power, high speed, 2 MSPS or 500 kSPS SAR ADCs. The digital features include offset correction, gain adjustment, and averaging, which offload the host processor. The user can configure the device for one of several output code formats.
Source Code
Status
Files
Function |
File |
|
|---|---|---|
driver file |
||
devicetree bindings |
||
documentation |
Adding Linux driver support
Kernel configuration
Configure kernel with make menuconfig (alternatively use make xconfig or
make qconfig)
Note
The AD4030 driver depends on CONFIG_SPI, CONFIG_GPIOLIB and CONFIG_PWM, and selects CONFIG_REGMAP, CONFIG_IIO_BUFFER, CONFIG_IIO_BUFFER_DMA, CONFIG_IIO_BUFFER_DMAENGINE, CONFIG_IIO_TRIGGERED_BUFFER and CONFIG_SPI_OFFLOAD.
Linux Kernel Configuration
Device Drivers --->
...
<*> Industrial I/O support --->
--- Industrial I/O support
...
Analog to digital converters --->
...
<*> Analog Devices AD4030 ADC driver
...
...
...
Devicetree configuration
// SPDX-License-Identifier: GPL-2.0
/*
* Analog Devices ADAQ4216 without isolated power supply
*
* hdl_project: <ad4630_fmc/zed>
* board_revision: <3>
*
* Copyright (C) 2024 Analog Devices Inc.
*/
/dts-v1/;
#include "zynq-zed.dtsi"
#include "zynq-zed-adv7511.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pwm/pwm.h>
/ {
vref: regulator-vref {
compatible = "regulator-fixed";
regulator-name = "fixed-supply";
regulator-min-microvolt = <4096000>;
regulator-max-microvolt = <4096000>;
regulator-always-on;
};
vdd_1_8: regulator-vdd-1-8 {
compatible = "regulator-fixed";
regulator-name = "fixed-supply";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
vio: regulator-vio {
compatible = "regulator-fixed";
regulator-name = "fixed-supply";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
trigger_pwm: adc-pwm-trigger {
compatible = "pwm-trigger";
#trigger-source-cells = <0>;
pwms = <&adc_trigger 0 1000000 0>;
};
clocks {
cnv_ext_clk: ext-clk {
#clock-cells = <0x0>;
compatible = "fixed-clock";
clock-frequency = <100000000>;
clock-output-names = "cnv_ext_clk";
};
};
};
&fpga_axi {
i2c@41620000 {
compatible = "xlnx,axi-iic-1.01.b", "xlnx,xps-iic-2.00.a";
reg = <0x41620000 0x10000>;
interrupt-parent = <&intc>;
interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clkc 15>;
clock-names = "pclk";
#size-cells = <0>;
#address-cells = <1>;
eeprom1: eeprom@50 {
compatible = "at24,24c02";
reg = <0x50>;
};
};
adc_trigger: pwm@44b00000 {
compatible = "adi,axi-pwmgen-2.00.a";
reg = <0x44b00000 0x1000>;
label = "ad463x_cnv";
#pwm-cells = <3>;
clocks = <&clkc 15>, <&cnv_ext_clk>;
clock-names = "axi", "ext";
};
rx_dma: dma-controller@44a30000 {
compatible = "adi,axi-dmac-1.00.a";
reg = <0x44a30000 0x1000>;
#dma-cells = <1>;
interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clkc 15>;
};
spi_clk: clock-controller@44a70000 {
compatible = "adi,axi-clkgen-2.00.a";
reg = <0x44a70000 0x10000>;
#clock-cells = <0>;
clocks = <&clkc 15>, <&clkc 15>;
clock-names = "clkin1", "s_axi_aclk";
clock-output-names = "spi_clk";
};
axi_spi_engine: spi@44a00000 {
compatible = "adi,axi-spi-engine-1.00.a";
reg = <0x44a00000 0x1FF>;
interrupt-parent = <&intc>;
interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clkc 15>, <&spi_clk>;
clock-names = "s_axi_aclk", "spi_clk";
dmas = <&rx_dma 0>;
dma-names = "offload0-rx";
trigger-sources = <&trigger_pwm>;
#address-cells = <0x1>;
#size-cells = <0x0>;
adaq4216: adaq4216@0 {
compatible = "adi,adaq4216";
reg = <0>;
spi-max-frequency = <80000000>;
vdd-5v-supply = <&vref>;
vdd-1v8-supply = <&vdd_1_8>;
vio-supply = <&vio>;
ref-supply = <&vref>;
pwm-names = "cnv";
pwms = <&adc_trigger 1 1000000 0>;
reset-gpios = <&gpio0 86 GPIO_ACTIVE_LOW>;
cnv-gpios = <&gpio0 85 GPIO_ACTIVE_HIGH>;
pga-gpios = <&gpio0 87 GPIO_ACTIVE_HIGH>,
<&gpio0 88 GPIO_ACTIVE_HIGH>;
};
};
};
Driver testing
Each and every IIO device, typically a hardware chip, has a device folder under
/sys/bus/iio/devices/iio:deviceX. Where X is the IIO index of the device. Under
every of these directory folders reside a set of files, depending on the
characteristics and features of the hardware device in question. These files
are consistently generalized and documented in the IIO ABI documentation. In
order to determine which IIO deviceX corresponds to which hardware device, the
user can read the name file /sys/bus/iio/devices/iio:deviceX/name. In case
the sequence in which the iio device drivers are loaded/registered is constant,
the numbering is constant and may be known in advance.
Tip
An example program whiroot@analog:/sys/bus/iio/devices# ls -lch uses the interface can be found here:
Identify the device
root@analog:~# cat /sys/bus/iio/devices/iio:device0/name
adaq4216
Basic operation
Show channel scale
Description: Scale to be applied to in_voltageX_raw in order to obtain the measured voltage in millivolts
root@analog:~# cat /sys/bus/iio/devices/iio:device0/in_voltage0-voltage1_scale
0.018750000
Example test single-shot readings through IIO device sysfs interface.
root@analog:~# ls -l /sys/bus/iio/devices/iio:device0/
total 0
drwxr-xr-x 2 root root 0 Feb 4 19:03 buffer
drwxr-xr-x 2 root root 0 Feb 4 19:03 buffer0
-r--r--r-- 1 root root 4096 Feb 4 19:03 dev
-rw-r--r-- 1 root root 4096 Feb 4 19:03 in_voltage0-voltage1_calibbias
-r--r--r-- 1 root root 4096 Feb 4 19:03 in_voltage0-voltage1_calibbias_available
-rw-r--r-- 1 root root 4096 Feb 4 19:03 in_voltage0-voltage1_calibscale
-r--r--r-- 1 root root 4096 Feb 4 19:03 in_voltage0-voltage1_calibscale_available
-r--r--r-- 1 root root 4096 Feb 4 19:03 in_voltage0-voltage1_label
-rw-r--r-- 1 root root 4096 Feb 4 19:03 in_voltage0-voltage1_raw
-rw-r--r-- 1 root root 4096 Feb 4 19:03 in_voltage0-voltage1_scale
-r--r--r-- 1 root root 4096 Feb 4 19:03 name
lrwxrwxrwx 1 root root 0 Feb 4 19:03 of_node -> ../../../../../../../../firmware/devicetree/base/fpga-axi@0/spi@44a00000/adaq4216@0
-rw-r--r-- 1 root root 4096 Feb 4 19:03 oversampling_ratio
-r--r--r-- 1 root root 4096 Feb 4 19:03 oversampling_ratio_available
drwxr-xr-x 2 root root 0 Feb 4 19:03 power
drwxr-xr-x 2 root root 0 Feb 4 19:03 scan_elements
lrwxrwxrwx 1 root root 0 Feb 4 19:03 subsystem -> ../../../../../../../../bus/iio
-rw-r--r-- 1 root root 4096 Feb 4 19:03 uevent
-r--r--r-- 1 root root 4096 Feb 4 19:03 waiting_for_supplier
The driver has no sampling_frequency attribute; capture pacing comes from
the selected IIO trigger. The scale is read-only and has no scale_available
attribute. Calibration bias/scale and oversampling ratio are supported;
reading raw and reading or writing calibration and oversampling attributes
fail while the buffer is enabled.
Application Software
A supported ADC bound to ad4030 can be managed with IIO Oscilloscope which has interfaces for configuring and retrieving data from IIO devices. After installing IIO Oscilloscope in the host computer, open the application and connect to the IIO context provided by the Kuiper Linux installation running on the ZedBoard.
The example below shows ADAQ4216 running a 125 kSPS data capture of a test sine wave. 1000 samples were kept for the plot.
The example below shows the same sine wave but captured at 500 kSPS.
Finally, at 2 MSPS, we keep a larger number of samples to be able to visualize the sine wave captured with ADAQ4216.