This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS7957: Unable to read channels via Linux IIO

Part Number: ADS7957
Other Parts Discussed in Thread: AM3357,

Hello,

I have the following setup:

In the device tree I have the following configuration (only relevant parts):

&am33xx_pinmux {
	pinctrl-names = "default";
	spi1_pins: pinmux_spi1_pins {
		
		pinctrl-single,pins = <
			AM33XX_IOPAD(0x90c, PIN_INPUT | MUX_MODE2) /* (H17) gmii1_crs.spi1_d0 */
			AM33XX_IOPAD(0x910, PIN_INPUT | MUX_MODE2) /* (J15) gmii1_rxer.spi1_d1 */
			AM33XX_IOPAD(0x964, PIN_INPUT | MUX_MODE4) /* (C18) eCAP0_in_PWM0_out.spi1_sclk */

			AM33XX_IOPAD(0x978, PIN_INPUT | MUX_MODE7) /* (D18) uart1_ctsn.gpio0[12] */
			AM33XX_IOPAD(0x97c, PIN_INPUT | MUX_MODE7) /* (D19) uart1_rtsn.gpio0[13] */
		>;
	};
};

&spi1 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&spi1_pins>;
	cs-gpios =  <&gpio0 12 GPIO_ACTIVE_LOW>, <&gpio0 13 GPIO_ACTIVE_LOW>;
        spi-max-frequency = <60000000>;

	ads7957: adc@1 {
		compatible = "ti,ads7957";
		reg = <1>;
		#io-channel-cells = <1>;
		spi-max-frequency = <10000000>;
	};
};

TI's Linux driver is properly loaded and IIO subsystem detects ADS7957 chip:

root@am335x-cmpc30:~# dmesg | grep ads
[    5.806242] ads7950 spi1.1: spi1.1 supply vref not found, using dummy regulator
[    5.878974] ads7950 spi1.1: Linked as a consumer to regulator.0

However I'm unable to read any channel except first and last (and values are wrong). Here is output from the iio_info Linux tool:

root@am335x-cmpc30:~# iio_info
Library version: 0.15 (git tag: v0.15)
Compiled with backends: local xml ip usb
IIO context created with local backend.
Backend version: 0.15 (git tag: v0.15)
Backend description string: Linux am335x-cmpc30 4.19.94-rt39cmpc30_v8-ga242ccf3f1 #1 PREEMPT RT Fri Oct 23 10:26:45 UTC 2020 armv7l
IIO context has 1 attributes:
        local,kernel: 4.19.94-rt39cmpc30_v8-ga242ccf3f1
IIO context has 1 devices:
        iio:device0: ads7957 (buffer capable)
                17 channels found:
                        voltage0:  (input, index: 0, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw value: 1
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage1:  (input, index: 1, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage2:  (input, index: 2, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage3:  (input, index: 3, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage4:  (input, index: 4, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage5:  (input, index: 5, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage6:  (input, index: 6, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage7:  (input, index: 7, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage8:  (input, index: 8, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage9:  (input, index: 9, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage10:  (input, index: 10, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage11:  (input, index: 11, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage12:  (input, index: 12, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage13:  (input, index: 13, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage14:  (input, index: 14, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw ERROR: Input/output error (-5)
                                attr  1: scale ERROR: Invalid argument (-22)
                        voltage15:  (input, index: 15, format: be:u10/16>>2)
                        2 channel-specific attributes found:
                                attr  0: raw value: 523
                                attr  1: scale ERROR: Invalid argument (-22)
                        timestamp:  (input, index: 16, format: le:S64/64>>0)
                1 device-specific attributes found:
                                attr  0: current_timestamp_clock value: realtime

                2 buffer-specific attributes found:
                                attr  0: watermark value: 1
                                attr  1: data_available value: 0

Scale returns error, because I didn't specify regulator in device tree. This is on purpose, because ADS7957 has hardwired 3.3V voltage on my PCB. But channels should work correctly.

While debugging, I added kernel logs in the TI's ADS7957 driver and the following errors showed up:

[  598.869235] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (1 != 0)
[  598.880442] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (2 != 1)
[  598.891315] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (3 != 1)
[  598.902920] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (4 != 2)
[  598.912788] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (5 != 2)
[  598.923756] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (6 != 3)
[  598.934229] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (7 != 3)
[  598.945349] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (8 != 12)
[  598.956098] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (9 != 12)
[  598.966881] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (10 != 13)
[  598.977712] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (11 != 13)
[  598.988269] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (12 != 14)
[  598.999733] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (13 != 14)
[  599.010557] chan->address != TI_ADS7950_EXTRACT(ret, 12, 4) -> (14 != 15)

So it seems, that for every read value driver detects, that it is coming from different channel that it expected.

I checked the SPI transmission with logic analyzer and decoded bytes looks valid (transmission ends with a correct value read from correct channel).

The same PCB works fine with self-coded baremetal driver on SYS/BIOS, so chip is working.

What am I doing wrong?