Post Go back to editing

AD7904 returns "Input/Output Error" for all connected voltage lines (Using AD7923 Driver)

I've been spending a few days trying to get this kernel module hooked up properly, and I'm running out of options on the software front.

Here is the output from the command line. I get "Invalid argument" for scale, and "Input/Output Error" for all the adc lines except voltage0 returns 0 but that line isn't hooked up to anything.

:~# cat /sys/bus/iio/devices/iio\:device0/name
ad7904
:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage_scale
cat: '/sys/bus/iio/devices/iio:device0/in_voltage_scale': Invalid argument
:~# cat /sys/bus/iio/devices/iio\:device0/
buffer/                  dev                      in_voltage1_raw          in_voltage3_raw          name                     power/                   subsystem/               uevent
current_timestamp_clock  in_voltage0_raw          in_voltage2_raw          in_voltage_scale         of_node/                 scan_elements/           trigger/
:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw
0
:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage1_raw
cat: '/sys/bus/iio/devices/iio:device0/in_voltage1_raw': Input/output error
:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage2_raw
cat: '/sys/bus/iio/devices/iio:device0/in_voltage2_raw': Input/output error
:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage3_raw
cat: '/sys/bus/iio/devices/iio:device0/in_voltage3_raw': Input/output error

This is my device tree:

&quad_spi {
	#address-cells = <2>;
	#size-cells = <0>;

	gpiom2: gpio@0 {
			compatible = "microchip,mcp23s17";
			gpio-controller;
			#gpio-cells = <2>;
			microchip,spi-present-mask = <0x02>;
			reg = <0>;
			spi-max-frequency = <1000000>;
		};

	adc_supply: fixedregulator {
		compatible = "regulator-fixed";
		regulator-name = "fixed-supply";
		regulator-min-microvolt = <3300000>;
		regulator-max-microvolt = <3300000>;
	};

	adc_vref: fixedregulator {
		compatible = "regulator-fixed";
		regulator-name = "fixed-supply";
		regulator-min-microvolt = <2500000>;
		regulator-max-microvolt = <2500000>;
	};

	ad7904: ad7904@1 {
			compatible = "adi,ad7904";
			reg = <1>;
			spi-max-frequency = <1000000>;
			spi-cpha;
			spi-cpol;
			vcc-supply = <&adc_supply>;
			vref-supply = <&adc_vref>;
		};
};

This is my first time dealing with device tree. The gpioe works already and this ADC is on the same spi bus.

The AD7904 uses the AD7923 driver, but there is no documentation for this one, only a git source. I've been looking at other drivers similar and trying to make the device tree properly.

Any and all advice would be appreciated. I'm asking our EE if there is a line I can probe easily for chip-select and will update on whether its toggling.

  • I also get this message during the boot process:

    [ 14.454752] ad7923 spi5.1: supply refin not found, using dummy regulator

    Even though I explicitly define the reference voltage in the DT.

  •  Your author of the driver. Has this been tested for all 4 models?

    I'm running out of ideas besides the driver just crapping out. I probed all the lines and they work! I see data coming to and from the part and the cs going low. However, the driver will always EIO, which only seems to appear if the address pins are wrong but how can that be?

  • Reading scale returns error since the regulator issn't connected.

    Can you check if you kernel is CONFIG_REGULATOR_FIXED_VOLTAGE enabled?

    Regarding -EIO on raw reads, this can only be related to read the data via SPI.

    Can you add this debug print and read all channels:

    pr_err("%s:%d: ret = 0x%X", __func__, __LINE__, ret;)
    
    if (chan->address == EXTRACT(ret, 12, 4))
        *val = EXTRACT(ret, 0, 12);
    else
        return -EIO;
     

    -Michael

  • HI Michael! First off thank you for responding.

    I went into the config and added 

    CONFIG_REGULATOR_FIXED_VOLTAGE=y
    However, now it screams
    [ 14.099833] spi_master spi5: /amba_pl@0/axi_quad_spi@80100000/fixedregulator has no valid 'reg' property (-22)
    [ 14.104209] spi_master spi5: Failed to create SPI device for /amba_pl@0/axi_quad_spi@80100000/fixedregulator
    in_voltage_scale still throws the same error. The regulator inclusion is just based on the example device trees I've seen in the wiki but not sure if actually needed? Vref is connected 2.5v line but not a configurable regulator of any sort.
    As for the prints on debugging, currently working on that. Problem is I work on a propriety skew of linux so finding where the "actual kernel" files are have been difficult.
  • Ah, probably because I declared inside the spi {} instead of outside of it..

  • So vcc-supply is listed as a requirement, however we currently use a AD dac (ad5676) that doesn't include a vcc-supply parameter and it operates fine. So are these parameters actually necessary?

  •   I finally got my printk's working and the return is always 0. That explains why in_voltage0_raw always works fine but none of the others.

    Probing the spi lines like I said all look good. Suggestions? Would not having a regulator referenced affect it?

    Here is the diff from the git patch.

    @@ -274,8 +274,12 @@ static int ad7923_read_raw(struct iio_dev *indio_dev,
                    if (chan->address == EXTRACT(ret, 12, 4))
                            *val = EXTRACT(ret, 0, 12);
                    else
    +               {
    +                       printk(KERN_ALERT "chan->address= %ld\n", chan->address);
    +                       printk(KERN_ALERT "read ret=%d\n",EXTRACT(ret, 12, 4));
    +                       printk(KERN_ALERT "address pins don't match read value.\n");
                            return -EIO;
    -
    +               }
                    return IIO_VAL_INT;
            case IIO_CHAN_INFO_SCALE:
                    ret = ad7923_get_range(st);
    @@ -334,12 +338,16 @@ static int ad7923_probe(struct spi_device *spi)
     
            st->reg = devm_regulator_get(&spi->dev, "refin");
            if (IS_ERR(st->reg))
    +       {
    +               printk(KERN_ALERT "refin ptr_err!");
                    return PTR_ERR(st->reg);
    -
    +       }
            ret = regulator_enable(st->reg);
            if (ret)
    +       {
    +               printk(KERN_ALERT "regulator enable error");
                    return ret;
    -
    +       }
            ret = iio_triggered_buffer_setup(indio_dev, NULL,
                                             &ad7923_trigger_handler, NULL);
            if (ret)
    -- 
    2.28.0

  • Here you're printing the raw samples returned from spi_sync(), so the regulator should matter here.

    When looking at the SPI signals you're seeing none zero samples on MISO?

    With the channel ID, and likely some LSB flickering?

    Can you try changing the SPI modes using spi-cpha, spi-cpol?

    Please see here:

    elixir.bootlin.com/.../spi-bus.txt

    -Michael

  • This is an image of the MISO line when calling a cat in_voltage2_raw. First one looks right, but not sure why I'm getting two blocks of 16clock cycles. Shouldn't it just be 1?

    I got the regulator hooked up correctly I believe. Vref is 2.5v. voltage_scale now populates, however raws still throw error.

    root@pif:~# cat /sys/bus/iio/devices/iio\:device2/in_voltage0_raw
    0
    root@pif:~# cat /sys/bus/iio/devices/iio\:device2/in_voltage_scale
    9.765625000
    root@pif:~# cat /sys/bus/iio/devices/iio\:device2/in_voltage_scale
    9.765625000
    root@pif:~# cat /sys/bus/iio/devices/iio\:device2/in_voltage1_raw
    cat: '/sys/bus/iio/devices/iio:device2/in_voltage1_raw': Input/output error
    

    I'll go ahead and try changing those spi modes and report back.

  • First one looks right, but not sure why I'm getting two blocks of 16clock cycles. Shouldn't it just be 1?

    Looks like the device supports different modes of operation.

    This code here:

    https://github.com/analogdevicesinc/linux/blob/master/drivers/iio/adc/ad7923.c#L323

    Creates these two messages.

    -Michael