AD4630

AD4630-24/AD4630-16 Dual Channel and AD4030-24 Single Channel Precision SAR ADC Linux Driver.

Note

A mainlined alternative driver is available at AD4030/AD4630/ADAQ4216/ADAQ4224. This page documents the out-of-tree driver (ad4630.c).

Supported Devices

Evaluation Boards

Description

The AD4630-24 is a two-channel, low-noise, 2 MSPS successive approximation register (SAR) analog-to-digital converter (ADC). The AD4030-24 is the single channel version. Both have a guaranteed maximum ±0.9 ppm INL and no missing codes at 24-bits, and achieve unparalleled precision from −40°C to +125°C. The AD4630-16 is a 16-bit, two-channel version.

Operating from 5V and 1.8 V supplies, the AD4630-24, AD4630-16 and AD4030-24 has a ±(65/64 ·VREF) differential input range with VREF ranging from 4.096V to 5V. The input common mode is not restricted – each polarity input may be anywhere from - 1/128 ·VREF to 129/128 ·VREF, simplifying analog signal conditioning requirements and system calibration. A low drift, precision reference buffer makes it easy to share a voltage reference with other circuitry.

The versatile Flexi-SPI serial interface is simple to use. A wide data window, multiple SDO lanes, and optional DDR data can reduce the serial clock to 10 MHz at 2 MSPS. Echo-clock and ADC clock-master modes relax the timing requirements and simplify the use of digital isolators. The parts are compatible with 1.2V to 1.8V logic, using the separate VIO supply.

Source Code

Status

Source

Mainlined?

ADI tree

[No]

Files

Function

File

driver

ad4630.c

devicetree

ad4630-24.dts

===== Devicetree =====

Regulator

ADC voltage reference

vref: regulator-vref {
    compatible = "regulator-fixed";
    regulator-name = "fixed-supply";
    regulator-min-microvolt = <5000000>;
    regulator-max-microvolt = <5000000>;
    regulator-always-on;
};

External clock

Reference clock used for sampling timing

clocks {
    cnv_ext_clk: ext-clk {
        #clock-cells = <0x0>;
        compatible = "fixed-clock";
        clock-frequency = <100000000>;
        clock-output-names = "cnv_ext_clk";
    };
};

Sampling trigger

This PWM generator is used to start the sampling procedure

axi_pwm_gen: axi-pwm-gen@ {
    compatible = "adi,axi-pwmgen";
    reg = <0x44b00000 0x1000>;
    label = "ad463x_cnv";
    #pwm-cells = <2>;
    clocks = <&cnv_ext_clk>;
};

ADC node

The ad4630-24 is a SPI-compatible ADC so it should be under a SPI controller. The following custom attributes are available:

Attribute name

Values

Description

adi,lane-mode

one-lane-shared one-lane-per-ch two-lanes-per-ch four-lanes-per-ch

Use one data lane, interleaved Use two data lanes, one per ch. Use four data lanes, two per ch. Use eight data lanes, four per ch.

adi,clock-mode

spi-compatible echo-clock

Valid BUSY signal for the ADC conversion status Bit clock. BUSY_SCKOUT is a delayed version of SCK input

adi,out-data-mode

16diff-8com 24diff 24diff-8com 30diff-avg 32pat

Output is 16-bit differential data + 8-bit common mode data Output is 24-bit differential data Output is 24-bit differential data + 8-bit common mode data Output is 30-bit averaged differential data + OR-bit + SYNC-bit Output is 32-bit test data pattern

Important

The spi-max-frequency must be a multiple of a 40MHz clock and the dmas handle should use a 64-bit wide data bus.

&spi{
    ad463x: ad463x@0 {
        compatible = "adi,ad4630-24";
        reg = <0>;
        vref-supply = <&vref>;
        spi-max-frequency = <80000000>;
        adi,lane-mode = <2>;
        adi,clock-mode = <1>;
        adi,dual-data-rate;
        adi,out-data-mode = <2>;
        reset-gpios = <&gpio0 86 GPIO_ACTIVE_LOW>;
        clocks = <&cnv_ext_clk>;
        clock-names = "trigger_clock";
        dmas = <&rx_dma 0>;
        dma-names = "rx";
        pwm-names = "spi_trigger", "cnv";
        pwms = <&axi_pwm_gen 0 0>,
               <&axi_pwm_gen 1 0>;
    };
};

adi,lane-mode is 0 for one lane per channel, 1 for two, 2 for four, or 3 for interleaved lanes on SDO0. adi,clock-mode is 0 for SPI-compatible clocking, 1 for echo-clock, or 2 for host clock mode. adi,out-data-mode is 0 for native (16/20/24-bit depending on part) differential data, 1 for 16-bit differential plus 8-bit common mode, 2 for 24-bit differential plus 8-bit common mode, or 3 for 30-bit averaged differential data; which values are valid depends on the specific part.

Adding Linux driver support

Kernel configuration

This device depends on a PWM based trigger used to start the sampling procedure. The first step is to enable the support for AXI_PWMGEN.

<blockquote>

Symbol: PWM_AXI_PWMGEN [=y]
Type  : tristate
Prompt: Analog Devices AXI PWM generator
   Location:
     -> Device Drivers
       -> Pulse-Width Modulation (PWM) Support (PWM [=y])
   Defined at drivers/pwm/Kconfig:78
   Depends on: PWM [=y] && HAS_IOMEM [=y]
   Selected by [y]:
   - KERNEL_ALL_ADI_DRIVERS [=y]

</blockquote>

Another required component is the SPI controller. The AD4630 has a specific set of SPI timing requirements that are supported by the SPI_ENGINE IP.

<blockquote>

Symbol: SPI_AXI_SPI_ENGINE [=y]
Type  : tristate
Prompt: Analog Devices AXI SPI Engine controller
  Location:
    -> Device Drivers
      -> SPI support (SPI [=y])
  Defined at drivers/spi/Kconfig:112
  Depends on: SPI [=y] && SPI_MASTER [=y] && HAS_IOMEM [=y]
  Selected by [y]:
  - KERNEL_ALL_ADI_DRIVERS [=y]

</blockquote>

And finally, enable support for the AD4630 device family.

<blockquote>

Symbol: AD4630 [=y]
Type  : tristate
Prompt: Analog Device AD4630 ADC Driver
  Location:
    -> Device Drivers
      -> Industrial I/O support (IIO [=y])
        -> Analog to digital converters
  Defined at drivers/iio/adc/Kconfig:26
  Depends on: IIO [=y] && SPI_MASTER [=y]
  Selects: IIO_BUFFER [=y] && IIO_BUFFER_DMA [=y] && IIO_BUFFER_DMAENGINE [=y]

</blockquote>

Driver testing

This device can be found under /sys/bus/iio/devices/

Each channel is a plain indexed voltage channel (not a differential pair in the IIO sense), with its own calibbias and calibscale attributes. in_voltage_scale and sampling_frequency are shared by all channels. In the 30-bit averaged output mode (adi,out-data-mode = <3>), channels also expose in_voltage_oversampling_ratio and in_voltage_oversampling_ratio_available.

Use iio_info to list the channels and attributes of the device.

You can go to the device folder using:

root@analog# cd $(grep -rw /sys/bus/iio/devices//name -e "ad4630-24" -l | xargs dirname)

Power management

The driver uses runtime power management; power transitions are handled by its runtime suspend and resume callbacks.

Sampling frequency

The AD4630 driver supports a variable sampling rate, up to 2 MSPS depending on the part and output data mode. sampling_frequency accepts any positive integer rate up to the device maximum and programs the CNV PWM accordingly; there is no sampling_frequency_available attribute.

See current sampling rate:

root@analog:/sys/bus/iio/devices/iio:device0# cat sampling_frequency
1000000

Change the sampling rate:

root@analog:/sys/bus/iio/devices/iio:device0# echo 2000000 > sampling_frequency
root@analog:/sys/bus/iio/devices/iio:device0# cat sampling_frequency
2000000

Sample average mode

The AD4630 family supports averaging samples in powers of 2, up to 65536, when the output data mode is 30-bit averaged (adi,out-data-mode = <3>). This is controlled through in_voltage_oversampling_ratio and in_voltage_oversampling_ratio_available; after probe the driver sets an averaging count of 2 as its default. Increasing the averaging count lengthens the internal fetch period relative to the conversion trigger, so buffer read timeouts may need to be increased accordingly.

root@analog:/sys/bus/iio/devices/iio:device0# cat in_voltage_oversampling_ratio_available
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536

Display current averaging count:

root@analog:/sys/bus/iio/devices/iio:device0# cat in_voltage_oversampling_ratio
2

Change the averaging count:

root@analog:/sys/bus/iio/devices/iio:device0# echo 2048 > in_voltage_oversampling_ratio
root@analog:/sys/bus/iio/devices/iio:device0# cat in_voltage_oversampling_ratio
2048

Channel hardware gain

Each channel has an independent calibscale attribute for gain correction, accepting values from 0 up to 1.99997 in steps of 1/32768. This gain correction is separate from in_voltage_scale, which converts raw codes to a voltage.

root@analog:/sys/bus/iio/devices/iio:device0# ls | grep calibscale
in_voltage0_calibscale
in_voltage1_calibscale

Read the gain for channel 0:

root@analog:/sys/bus/iio/devices/iio:device0# cat in_voltage0_calibscale
1.000000

Set the gain for channel 1:

root@analog:/sys/bus/iio/devices/iio:device0# echo 0.25 > in_voltage1_calibscale
root@analog:/sys/bus/iio/devices/iio:device0# cat in_voltage1_calibscale
0.250000

Channel offset

Each channel has an independent calibbias attribute. For a 24-bit part the accepted range is -223 to 223-1; 16-bit and 20-bit parts use the corresponding signed range for their bit width. Calibration writes require the device to be in direct (non-buffered) mode.

root@analog:/sys/bus/iio/devices/iio:device0# ls | grep calibbias
in_voltage0_calibbias
in_voltage1_calibbias

Read the offset for channel 0:

root@analog:/sys/bus/iio/devices/iio:device0# cat in_voltage0_calibbias
0

Set the offset for channel 1:

root@analog:/sys/bus/iio/devices/iio:device0# echo 256 > in_voltage1_calibbias
root@analog:/sys/bus/iio/devices/iio:device0# cat in_voltage1_calibbias
256

Data acquisition

The data acquisition is performed using a buffer system:

root@analog:/sys/bus/iio/devices/iio:device0/# ls buffer
data_available  enable  length  length_align_bytes  watermark
root@analog:/sys/bus/iio/devices/iio:device0# ls scan_elements/
in_voltage0_en      in_voltage0_type  in_voltage1_index
in_voltage0_index   in_voltage1_en    in_voltage1_type

Every buffer implementation features a set of files:

buffer: length Get/set the number of sample sets that may be held by the buffer.

buffer: enable Enables/disables the buffer. This file should be written last, after length and selection of scan elements

scan_elements: in_voltageX_en Enable/disables the channel output so the data won’t be buffered for that specific channel.

Each scan is 32 bits per enabled channel. With both channels enabled, 400 scans require 3200 bytes; the hexdump -n 400 below therefore only reads the first 50 scans.

root@analog:/sys/bus/iio/devices/iio:device0# echo 1 > scan_elements/in_voltage0_en
root@analog:/sys/bus/iio/devices/iio:device0# echo 1 > scan_elements/in_voltage1_en
root@analog:/sys/bus/iio/devices/iio:device0# echo 400 > buffer/length
root@analog:/sys/bus/iio/devices/iio:device0# echo 1 > buffer/enable
root@analog:/sys/bus/iio/devices/iio:device0# hexdump -n 400 /dev/iio\:device0
0000000 e942 000d 0011 0000 afaf 000d 0029 0000
0000010 753b 000d fff5 00ff 39fa 000d 0018 0000
0000020 013e 000d 0017 0000 c776 000c fff4 00ff
0000030 8e84 000c 0017 0000 55d4 000c 0052 0000
0000040 1dab 000c 000b 0000 e5b9 000b 0049 0000
0000050 ab19 000b 0013 0000 6f56 000b 0035 0000
0000060 3470 000b 0020 0000 f9a1 000a 0037 0000
0000070 bcc1 000a 0003 0000 7f89 000a 000d 0000
0000080 4458 000a 0003 0000 0978 000a 000d 0000
0000090 cea9 0009 0041 0000 9551 0009 fff2 00ff
00000a0 5b80 0009 fff1 00ff 210c 0009 0015 0000
00000b0 e486 0008 ffe8 00ff a8d1 0008 ffec 00ff
00000c0 6e13 0008 004e 0000 33a0 0008 001a 0000
00000d0 f7df 0007 fffd 00ff bba2 0007 fffd 00ff
00000e0 7ead 0007 fffe 00ff 43e0 0007 0041 0000
00000f0 08a8 0007 0023 0000 cc9c 0006 ffed 00ff
0000100 9031 0006 001c 0000 5370 0006 fff6 00ff
0000110 1721 0006 0040 0000 dcec 0005 ffe5 00ff
0000120 9ffc 0005 000d 0000 61f3 0005 0016 0000
0000130 247d 0005 0023 0000 e55d 0004 0006 0000
0000140 a725 0004 000e 0000 6d7b 0004 0045 0000
0000150 32e4 0004 ffaa 00ff f77e 0003 ffca 00ff
0000160 bc75 0003 0036 0000 809d 0003 0019 0000
0000170 4582 0003 ffe1 00ff 0921 0003 ffdf 00ff
0000180 c9a5 0002 ffd1 00ff 8a1c 0002 0015 0000
0000190
root@analog:/sys/bus/iio/devices/iio:device0/# echo 0 > buffer/enable

Debug mode

You can write and read the ADC registers using debugfs. Here we will read and write the scratchpad register:

First go to the device debug folder:

root@analog# cd /sys/kernel/debug/iio/iio:device0

Read the 0xA register:

root@analog:/sys/kernel/debug/iio/iio:device0# echo 0xA > direct_reg_access
root@analog:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0x0

Write and verify the value:

root@analog:/sys/kernel/debug/iio/iio:device0# echo 0xA 0x5F> direct_reg_access
root@analog:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0x5F

More Information