Other Parts Discussed in Thread: ADS7950, DAC104S085
Hello,
I have the following setup:
- CPU: Sitara AM3357,
- Analog: ADS7957
- SPI1 chip select on GPIO0.13
- OS: Yocto Linux based on TI kernel v4.19.94rt (taken from https://git.ti.com/cgit/processor-sdk/processor-sdk-linux?h=processor-sdk-linux-rt-4.19.y, commit a242ccf3f13f03d41d521411ce2cc09775c873a2).
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?