Commit 663aa2e74f36a5a8000224b37a74c11ee729550d

Authored by Patil, Rachna
1 parent 2ce225a521

IIO: ADC: ti_adc: Fix wrong samples received on 1st read

Previously we tried to read data form ADC even before ADC sequencer
finished sampling. This led to wrong samples.

We now wait on ADC status register idle bit to be set.

Signed-off-by: Patil, Rachna <rachna@ti.com>

Showing 2 changed files with 34 additions and 6 deletions Side-by-side Diff

drivers/staging/iio/adc/ti_adc.c
... ... @@ -69,7 +69,6 @@
69 69 TSCADC_STEPCONFIG_OPENDLY);
70 70 channels++;
71 71 }
72   - adc_writel(adc_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB);
73 72 }
74 73  
75 74 static int tiadc_channel_init(struct iio_dev *idev, struct adc_device *adc_dev)
76 75  
77 76  
78 77  
... ... @@ -111,18 +110,31 @@
111 110 int *val, int *val2, long mask)
112 111 {
113 112 struct adc_device *adc_dev = iio_priv(idev);
114   - int i;
115   - unsigned int fifo1count, readx1;
  113 + int i, map_val;
  114 + unsigned int fifo1count, readx1, stepid;
  115 + unsigned long timeout = jiffies + usecs_to_jiffies
  116 + (IDLE_TIMEOUT * adc_dev->channels);
116 117  
  118 + adc_writel(adc_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB);
  119 +
  120 + /* Wait for ADC sequencer to complete sampling */
  121 + while (adc_readl(adc_dev, TSCADC_REG_ADCFSM) & TSCADC_SEQ_STATUS) {
  122 + if (time_after(jiffies, timeout))
  123 + return -EAGAIN;
  124 + }
  125 +
  126 + map_val = chan->channel + TOTAL_CHANNELS;
117 127 fifo1count = adc_readl(adc_dev, TSCADC_REG_FIFO1CNT);
118 128 for (i = 0; i < fifo1count; i++) {
119 129 readx1 = adc_readl(adc_dev, TSCADC_REG_FIFO1);
120   - if (i == chan->channel) {
121   - readx1 = readx1 & 0xfff;
  130 + stepid = readx1 & TSCADC_FIFOREAD_CHNLID_MASK;
  131 + stepid = stepid >> 0x10;
  132 +
  133 + if (stepid == map_val) {
  134 + readx1 = readx1 & TSCADC_FIFOREAD_DATA_MASK;
122 135 *val = readx1;
123 136 }
124 137 }
125   - adc_writel(adc_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB);
126 138 return IIO_VAL_INT;
127 139 }
128 140  
include/linux/mfd/ti_tscadc.h
... ... @@ -115,10 +115,26 @@
115 115 #define TSCADC_CNTRLREG_8WIRE TSCADC_CNTRLREG_AFE_CTRL(3)
116 116 #define TSCADC_CNTRLREG_TSCENB BIT(7)
117 117  
  118 +/* FIFO READ Register */
  119 +#define TSCADC_FIFOREAD_DATA_MASK (0xfff << 0)
  120 +#define TSCADC_FIFOREAD_CHNLID_MASK (0xf << 16)
  121 +
  122 +/* Sequencer Status */
  123 +#define TSCADC_SEQ_STATUS BIT(5)
  124 +
118 125 #define ADC_CLK 3000000
119 126 #define MAX_CLK_DIV 7
120 127 #define TOTAL_STEPS 16
121 128 #define TOTAL_CHANNELS 8
  129 +
  130 +/*
  131 + * ADC runs at 3MHz, and it takes
  132 + * 15 cycles to latch one data output.
  133 + * Hence the idle time for ADC to
  134 + * process one sample data would be
  135 + * around 5 micro seconds.
  136 + */
  137 +#define IDLE_TIMEOUT 5 /* microsec */
122 138  
123 139 #define TSCADC_CELLS 2
124 140