AnsweredAssumed Answered

imx6ull ADC read count values error

Question asked by Carlos Barreiro on Apr 3, 2020
Latest reply on Apr 27, 2020 by Carlos Barreiro

Hi, I'm having problems when reading cont values from ADCs on our custom board (I having the same problem when trying the same configuration in imx6ull_14x14_evk).

- VDDA_ADC_3P3(L13), ADC_VREFH(M13) connect to VLDO1(PF3000) 3.3V 

- PADs: ADC1_IN2(L14), ADC1_IN8(N17),ADC1_IN9(M15) (0V in all pads)

- DeviceTree:

 

pinctrl_adc1: adc1grp {
           fsl,pins = <
           MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x000000B0
           MX6UL_PAD_GPIO1_IO08__GPIO1_IO08 0x000000B0
           MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x000000B0
>;
};

 

...

reg_vref_3v3: regulator@2 {
compatible = "regulator-fixed";
reg = <2>;
regulator-name = "vref-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};

...

 

&adc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_adc1>;
vref-supply = <&reg_vref_3v3>;
num-channels = <3>;
status = "okay";
};

drivers/iio/adc/vf610_adc.c with additional debug messages (as in  iMX6UL adc calibration fails)

static void vf610_adc_calibration(struct vf610_adc *info) {     int adc_gc, hc_cfg;      if (!info->adc_feature.calibration)         return;      dev_info(info->dev, "vf610_adc_calibration start: Base address = %x\n",(int) info->regs);     dev_info(info->dev, "VF610_REG_ADC_HC0 = %x\n", readl(info->regs + VF610_REG_ADC_HC0));     dev_info(info->dev, "VF610_REG_ADC_HC1 = %x\n", readl(info->regs + VF610_REG_ADC_HC1));     dev_info(info->dev, "VF610_REG_ADC_HS = %x\n", readl(info->regs + VF610_REG_ADC_HS));     dev_info(info->dev, "VF610_REG_ADC_R0 = %x\n", readl(info->regs + VF610_REG_ADC_R0));     dev_info(info->dev, "VF610_REG_ADC_R1 = %x\n", readl(info->regs + VF610_REG_ADC_R1));     dev_info(info->dev, "VF610_REG_ADC_CFG = %x\n", readl(info->regs + VF610_REG_ADC_CFG));     dev_info(info->dev, "VF610_REG_ADC_GC = %x\n", readl(info->regs + VF610_REG_ADC_GC));     dev_info(info->dev, "VF610_REG_ADC_GS = %x\n", readl(info->regs + VF610_REG_ADC_GS));     dev_info(info->dev, "VF610_REG_ADC_CV = %x\n", readl(info->regs + VF610_REG_ADC_CV));     dev_info(info->dev, "VF610_REG_ADC_OFS = %x\n", readl(info->regs + VF610_REG_ADC_OFS));     dev_info(info->dev, "VF610_REG_ADC_CAL = %x\n", readl(info->regs + VF610_REG_ADC_CAL));     dev_info(info->dev, "VF610_REG_ADC_PCTL = %x\n", readl(info->regs + VF610_REG_ADC_PCTL));      /* enable calibration interrupt */     hc_cfg = VF610_ADC_AIEN | VF610_ADC_CONV_DISABLE;     writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);      adc_gc = readl(info->regs + VF610_REG_ADC_GC);     writel(adc_gc | VF610_ADC_CAL, info->regs + VF610_REG_ADC_GC);      if (!wait_for_completion_timeout(&info->completion, VF610_ADC_TIMEOUT))         dev_err(info->dev, "Timeout for adc calibration\n");      dev_info(info->dev, "vf610_adc_calibration end: Base address = %x\n",(int) info->regs);     dev_info(info->dev, "VF610_REG_ADC_HC0 = %x\n", readl(info->regs + VF610_REG_ADC_HC0));     dev_info(info->dev, "VF610_REG_ADC_HC1 = %x\n", readl(info->regs + VF610_REG_ADC_HC1));     dev_info(info->dev, "VF610_REG_ADC_HS = %x\n", readl(info->regs + VF610_REG_ADC_HS));     dev_info(info->dev, "VF610_REG_ADC_R0 = %x\n", readl(info->regs + VF610_REG_ADC_R0));     dev_info(info->dev, "VF610_REG_ADC_R1 = %x\n", readl(info->regs + VF610_REG_ADC_R1));     dev_info(info->dev, "VF610_REG_ADC_CFG = %x\n", readl(info->regs + VF610_REG_ADC_CFG));     dev_info(info->dev, "VF610_REG_ADC_GC = %x\n", readl(info->regs + VF610_REG_ADC_GC));     dev_info(info->dev, "VF610_REG_ADC_GS = %x\n", readl(info->regs + VF610_REG_ADC_GS));     dev_info(info->dev, "VF610_REG_ADC_CV = %x\n", readl(info->regs + VF610_REG_ADC_CV));     dev_info(info->dev, "VF610_REG_ADC_OFS = %x\n", readl(info->regs + VF610_REG_ADC_OFS));     dev_info(info->dev, "VF610_REG_ADC_CAL = %x\n", readl(info->regs + VF610_REG_ADC_CAL));     dev_info(info->dev, "VF610_REG_ADC_PCTL = %x\n", readl(info->regs + VF610_REG_ADC_PCTL));      adc_gc = readl(info->regs + VF610_REG_ADC_GS);     if (adc_gc & VF610_ADC_CALF)         dev_err(info->dev, "ADC calibration failed\n");      info->adc_feature.calibration = false; }

static int vf610_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
int *val2,
long mask)
{
struct vf610_adc *info = iio_priv(indio_dev);
unsigned int hc_cfg;
long ret;

dev_info(info->dev, "vf610_read_raw \n");
...

Driver registered and device detected:

root@imx6ullcom:/sys/bus/iio/devices/iio:device0# dmesg | grep vf610
calling vf610_pinctrl_init+0x0/0x18 @ 1
bus: 'platform': add driver vf610-pinctrl
initcall vf610_pinctrl_init+0x0/0x18 returned 0 after 0 usecs
calling gpio_vf610_init+0x0/0x18 @ 1
bus: 'platform': add driver gpio-vf610
initcall gpio_vf610_init+0x0/0x18 returned 0 after 530 usecs
calling vf610_adc_driver_init+0x0/0x18 @ 1
bus: 'platform': add driver vf610-adc
bus: 'platform': driver_probe_device: matched device 2198000.adc with driver vf610-adc
bus: 'platform': really_probe: probing driver vf610-adc with device 2198000.adc
vf610-adc 2198000.adc: no sleep pinctrl state
vf610-adc 2198000.adc: no idle pinctrl state
vf610-adc 2198000.adc: vf610_adc_calibration start
vf610-adc 2198000.adc: VF610_REG_ADC_HC0 = 1f
vf610-adc 2198000.adc: VF610_REG_ADC_HC1 = 1f
vf610-adc 2198000.adc: VF610_REG_ADC_HS = 0
vf610-adc 2198000.adc: VF610_REG_ADC_R0 = 0
vf610-adc 2198000.adc: VF610_REG_ADC_R1 = 0
vf610-adc 2198000.adc: VF610_REG_ADC_CFG = 104e8
vf610-adc 2198000.adc: VF610_REG_ADC_GC = 20
vf610-adc 2198000.adc: VF610_REG_ADC_GS = 0
vf610-adc 2198000.adc: VF610_REG_ADC_CV = 0
vf610-adc 2198000.adc: VF610_REG_ADC_OFS = 0
vf610-adc 2198000.adc: VF610_REG_ADC_CAL = 0
vf610-adc 2198000.adc: VF610_REG_ADC_PCTL = 0
vf610-adc 2198000.adc: vf610_adc_calibration end
vf610-adc 2198000.adc: VF610_REG_ADC_HC0 = 9f
vf610-adc 2198000.adc: VF610_REG_ADC_HC1 = 1f
vf610-adc 2198000.adc: VF610_REG_ADC_HS = 0
vf610-adc 2198000.adc: VF610_REG_ADC_R0 = 2
vf610-adc 2198000.adc: VF610_REG_ADC_R1 = 0
vf610-adc 2198000.adc: VF610_REG_ADC_CFG = 104e8
vf610-adc 2198000.adc: VF610_REG_ADC_GC = 20
vf610-adc 2198000.adc: VF610_REG_ADC_GS = 0
vf610-adc 2198000.adc: VF610_REG_ADC_CV = 0
vf610-adc 2198000.adc: VF610_REG_ADC_OFS = 0
vf610-adc 2198000.adc: VF610_REG_ADC_CAL = 8
vf610-adc 2198000.adc: VF610_REG_ADC_PCTL = 0
driver: 'vf610-adc': driver_bound: bound to device '2198000.adc'
bus: 'platform': really_probe: bound device 2198000.adc to driver vf610-adc
initcall vf610_adc_driver_init+0x0/0x18 returned 0 after 126430 usecs
vf610-adc 2198000.adc: vf610_read_raw
vf610-adc 2198000.adc: vf610_read_raw
vf610-adc 2198000.adc: vf610_read_raw
vf610-adc 2198000.adc: vf610_read_raw
vf610-adc 2198000.adc: vf610_read_raw
vf610-adc 2198000.adc: vf610_read_raw
vf610-adc 2198000.adc: vf610_read_raw
vf610-adc 2198000.adc: vf610_read_raw
vf610-adc 2198000.adc: vf610_read_raw
root@imx6ullcom:/sys/bus/iio/devices/iio:device0#

But values got from ADCs are not right:


root@imx6ullcom:/sys/bus/iio/devices/iio:device0# ls -l
-r--r--r-- 1 root root 4096 Jan 21 13:10 dev
-rw-r--r-- 1 root root 4096 Jan 21 13:10 in_voltage0_raw
-rw-r--r-- 1 root root 4096 Jan 21 13:10 in_voltage1_raw
-rw-r--r-- 1 root root 4096 Jan 21 13:10 in_voltage2_raw
-rw-r--r-- 1 root root 4096 Jan 21 13:10 in_voltage_sampling_frequency
-rw-r--r-- 1 root root 4096 Jan 21 13:10 in_voltage_scale
-r--r--r-- 1 root root 4096 Jan 21 13:10 name
lrwxrwxrwx 1 root root 0 Jan 21 13:10 of_node -> ../../../../../../firmware/devicetree/base/soc/aips-bus@02100000/adc@02198000
drwxr-xr-x 2 root root 0 Jan 21 13:10 power
-r--r--r-- 1 root root 4096 Jan 21 13:10 sampling_frequency_available
lrwxrwxrwx 1 root root 0 Jan 21 13:09 subsystem -> ../../../../../../bus/iio
-rw-r--r-- 1 root root 4096 Jan 21 13:09 uevent
root@imx6ullcom:/sys/bus/iio/devices/iio:device0# cat sampling_frequency_available
242647 69915 35869 18171 9146
root@imx6ullcom:/sys/bus/iio/devices/iio:device0# cat in_voltage_scale
vf610-adc 2198000.adc: vf610_read_raw
0.805664062
root@imx6ullcom:/sys/bus/iio/devices/iio:device0# cat in_voltage0_raw
vf610-adc 2198000.adc: vf610_read_raw
4060
root@imx6ullcom:/sys/bus/iio/devices/iio:device0# cat in_voltage1_raw
vf610-adc 2198000.adc: vf610_read_raw
170
root@imx6ullcom:/sys/bus/iio/devices/iio:device0# cat in_voltage2_raw
vf610-adc 2198000.adc: vf610_read_raw
0
root@imx6ullcom:/sys/bus/iio/devices/iio:device0#

Even if I change voltage in inputs to 3.3V I still get the same results.

 

Bets regards

 

Carlos Barreiro

Outcomes