diff options
-rw-r--r-- | drivers/iio/adc/ti_am335x_adc.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/ti_am335x_tsc.c | 78 | ||||
-rw-r--r-- | include/linux/mfd/ti_am335x_tscadc.h | 4 |
3 files changed, 44 insertions, 40 deletions
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 4bec91e40bf7..307a7c07be47 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c | |||
@@ -75,7 +75,7 @@ static void tiadc_step_config(struct tiadc_device *adc_dev) | |||
75 | 75 | ||
76 | stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1; | 76 | stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1; |
77 | 77 | ||
78 | for (i = (steps + 1); i <= TOTAL_STEPS; i++) { | 78 | for (i = steps; i < TOTAL_STEPS; i++) { |
79 | tiadc_writel(adc_dev, REG_STEPCONFIG(i), | 79 | tiadc_writel(adc_dev, REG_STEPCONFIG(i), |
80 | stepconfig | STEPCONFIG_INP(channels)); | 80 | stepconfig | STEPCONFIG_INP(channels)); |
81 | tiadc_writel(adc_dev, REG_STEPDELAY(i), | 81 | tiadc_writel(adc_dev, REG_STEPDELAY(i), |
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index ff3215ddf9f5..1bceb2591fc7 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c | |||
@@ -120,11 +120,9 @@ static int titsc_config_wires(struct titsc *ts_dev) | |||
120 | static void titsc_step_config(struct titsc *ts_dev) | 120 | static void titsc_step_config(struct titsc *ts_dev) |
121 | { | 121 | { |
122 | unsigned int config; | 122 | unsigned int config; |
123 | unsigned int stepenable = 0; | 123 | int i; |
124 | int i, total_steps; | 124 | int end_step; |
125 | 125 | u32 stepenable; | |
126 | /* Configure the Step registers */ | ||
127 | total_steps = 2 * ts_dev->coordinate_readouts; | ||
128 | 126 | ||
129 | config = STEPCONFIG_MODE_HWSYNC | | 127 | config = STEPCONFIG_MODE_HWSYNC | |
130 | STEPCONFIG_AVG_16 | ts_dev->bit_xp; | 128 | STEPCONFIG_AVG_16 | ts_dev->bit_xp; |
@@ -142,7 +140,9 @@ static void titsc_step_config(struct titsc *ts_dev) | |||
142 | break; | 140 | break; |
143 | } | 141 | } |
144 | 142 | ||
145 | for (i = 1; i <= ts_dev->coordinate_readouts; i++) { | 143 | /* 1 … coordinate_readouts is for X */ |
144 | end_step = ts_dev->coordinate_readouts; | ||
145 | for (i = 0; i < end_step; i++) { | ||
146 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); | 146 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); |
147 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); | 147 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); |
148 | } | 148 | } |
@@ -150,7 +150,7 @@ static void titsc_step_config(struct titsc *ts_dev) | |||
150 | config = 0; | 150 | config = 0; |
151 | config = STEPCONFIG_MODE_HWSYNC | | 151 | config = STEPCONFIG_MODE_HWSYNC | |
152 | STEPCONFIG_AVG_16 | ts_dev->bit_yn | | 152 | STEPCONFIG_AVG_16 | ts_dev->bit_yn | |
153 | STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1; | 153 | STEPCONFIG_INM_ADCREFM; |
154 | switch (ts_dev->wires) { | 154 | switch (ts_dev->wires) { |
155 | case 4: | 155 | case 4: |
156 | config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); | 156 | config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); |
@@ -164,12 +164,13 @@ static void titsc_step_config(struct titsc *ts_dev) | |||
164 | break; | 164 | break; |
165 | } | 165 | } |
166 | 166 | ||
167 | for (i = (ts_dev->coordinate_readouts + 1); i <= total_steps; i++) { | 167 | /* coordinate_readouts … coordinate_readouts * 2 is for Y */ |
168 | end_step = ts_dev->coordinate_readouts * 2; | ||
169 | for (i = ts_dev->coordinate_readouts; i < end_step; i++) { | ||
168 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); | 170 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); |
169 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); | 171 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); |
170 | } | 172 | } |
171 | 173 | ||
172 | config = 0; | ||
173 | /* Charge step configuration */ | 174 | /* Charge step configuration */ |
174 | config = ts_dev->bit_xp | ts_dev->bit_yn | | 175 | config = ts_dev->bit_xp | ts_dev->bit_yn | |
175 | STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | | 176 | STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | |
@@ -178,35 +179,39 @@ static void titsc_step_config(struct titsc *ts_dev) | |||
178 | titsc_writel(ts_dev, REG_CHARGECONFIG, config); | 179 | titsc_writel(ts_dev, REG_CHARGECONFIG, config); |
179 | titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); | 180 | titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); |
180 | 181 | ||
181 | config = 0; | 182 | /* coordinate_readouts * 2 … coordinate_readouts * 2 + 2 is for Z */ |
182 | /* Configure to calculate pressure */ | ||
183 | config = STEPCONFIG_MODE_HWSYNC | | 183 | config = STEPCONFIG_MODE_HWSYNC | |
184 | STEPCONFIG_AVG_16 | ts_dev->bit_yp | | 184 | STEPCONFIG_AVG_16 | ts_dev->bit_yp | |
185 | ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | | 185 | ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | |
186 | STEPCONFIG_INP(ts_dev->inp_xp); | 186 | STEPCONFIG_INP(ts_dev->inp_xp); |
187 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config); | 187 | titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config); |
188 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1), | 188 | titsc_writel(ts_dev, REG_STEPDELAY(end_step), |
189 | STEPCONFIG_OPENDLY); | 189 | STEPCONFIG_OPENDLY); |
190 | 190 | ||
191 | config |= STEPCONFIG_INP(ts_dev->inp_yn) | STEPCONFIG_FIFO1; | 191 | end_step++; |
192 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config); | 192 | config |= STEPCONFIG_INP(ts_dev->inp_yn); |
193 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2), | 193 | titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config); |
194 | titsc_writel(ts_dev, REG_STEPDELAY(end_step), | ||
194 | STEPCONFIG_OPENDLY); | 195 | STEPCONFIG_OPENDLY); |
195 | 196 | ||
196 | /* The steps1 … end and bit 0 for TS_Charge */ | 197 | /* The steps1 … end and bit 0 for TS_Charge */ |
197 | stepenable = (1 << (total_steps + 2)) - 1; | 198 | stepenable = (1 << (end_step + 2)) - 1; |
198 | am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable); | 199 | am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable); |
199 | } | 200 | } |
200 | 201 | ||
201 | static void titsc_read_coordinates(struct titsc *ts_dev, | 202 | static void titsc_read_coordinates(struct titsc *ts_dev, |
202 | unsigned int *x, unsigned int *y) | 203 | u32 *x, u32 *y, u32 *z1, u32 *z2) |
203 | { | 204 | { |
204 | unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT); | 205 | unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT); |
205 | unsigned int prev_val_x = ~0, prev_val_y = ~0; | 206 | unsigned int prev_val_x = ~0, prev_val_y = ~0; |
206 | unsigned int prev_diff_x = ~0, prev_diff_y = ~0; | 207 | unsigned int prev_diff_x = ~0, prev_diff_y = ~0; |
207 | unsigned int read, diff; | 208 | unsigned int read, diff; |
208 | unsigned int i, channel; | 209 | unsigned int i, channel; |
210 | unsigned int creads = ts_dev->coordinate_readouts; | ||
209 | 211 | ||
212 | *z1 = *z2 = 0; | ||
213 | if (fifocount % (creads * 2 + 2)) | ||
214 | fifocount -= fifocount % (creads * 2 + 2); | ||
210 | /* | 215 | /* |
211 | * Delta filter is used to remove large variations in sampled | 216 | * Delta filter is used to remove large variations in sampled |
212 | * values from ADC. The filter tries to predict where the next | 217 | * values from ADC. The filter tries to predict where the next |
@@ -215,32 +220,32 @@ static void titsc_read_coordinates(struct titsc *ts_dev, | |||
215 | * algorithm compares the difference with that of a present value, | 220 | * algorithm compares the difference with that of a present value, |
216 | * if true the value is reported to the sub system. | 221 | * if true the value is reported to the sub system. |
217 | */ | 222 | */ |
218 | for (i = 0; i < fifocount - 1; i++) { | 223 | for (i = 0; i < fifocount; i++) { |
219 | read = titsc_readl(ts_dev, REG_FIFO0); | 224 | read = titsc_readl(ts_dev, REG_FIFO0); |
220 | channel = read & 0xf0000; | 225 | |
221 | channel = channel >> 0x10; | 226 | channel = (read & 0xf0000) >> 16; |
222 | if ((channel >= 0) && (channel < ts_dev->coordinate_readouts)) { | 227 | read &= 0xfff; |
223 | read &= 0xfff; | 228 | if (channel < creads) { |
224 | diff = abs(read - prev_val_x); | 229 | diff = abs(read - prev_val_x); |
225 | if (diff < prev_diff_x) { | 230 | if (diff < prev_diff_x) { |
226 | prev_diff_x = diff; | 231 | prev_diff_x = diff; |
227 | *x = read; | 232 | *x = read; |
228 | } | 233 | } |
229 | prev_val_x = read; | 234 | prev_val_x = read; |
230 | } | ||
231 | 235 | ||
232 | read = titsc_readl(ts_dev, REG_FIFO1); | 236 | } else if (channel < creads * 2) { |
233 | channel = read & 0xf0000; | ||
234 | channel = channel >> 0x10; | ||
235 | if ((channel >= ts_dev->coordinate_readouts) && | ||
236 | (channel < (2 * ts_dev->coordinate_readouts - 1))) { | ||
237 | read &= 0xfff; | ||
238 | diff = abs(read - prev_val_y); | 237 | diff = abs(read - prev_val_y); |
239 | if (diff < prev_diff_y) { | 238 | if (diff < prev_diff_y) { |
240 | prev_diff_y = diff; | 239 | prev_diff_y = diff; |
241 | *y = read; | 240 | *y = read; |
242 | } | 241 | } |
243 | prev_val_y = read; | 242 | prev_val_y = read; |
243 | |||
244 | } else if (channel < creads * 2 + 1) { | ||
245 | *z1 = read; | ||
246 | |||
247 | } else if (channel < creads * 2 + 2) { | ||
248 | *z2 = read; | ||
244 | } | 249 | } |
245 | } | 250 | } |
246 | } | 251 | } |
@@ -256,10 +261,8 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
256 | 261 | ||
257 | status = titsc_readl(ts_dev, REG_IRQSTATUS); | 262 | status = titsc_readl(ts_dev, REG_IRQSTATUS); |
258 | if (status & IRQENB_FIFO0THRES) { | 263 | if (status & IRQENB_FIFO0THRES) { |
259 | titsc_read_coordinates(ts_dev, &x, &y); | ||
260 | 264 | ||
261 | z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff; | 265 | titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2); |
262 | z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff; | ||
263 | 266 | ||
264 | if (ts_dev->pen_down && z1 != 0 && z2 != 0) { | 267 | if (ts_dev->pen_down && z1 != 0 && z2 != 0) { |
265 | /* | 268 | /* |
@@ -267,10 +270,10 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
267 | * Resistance(touch) = x plate resistance * | 270 | * Resistance(touch) = x plate resistance * |
268 | * x postion/4096 * ((z2 / z1) - 1) | 271 | * x postion/4096 * ((z2 / z1) - 1) |
269 | */ | 272 | */ |
270 | z = z2 - z1; | 273 | z = z1 - z2; |
271 | z *= x; | 274 | z *= x; |
272 | z *= ts_dev->x_plate_resistance; | 275 | z *= ts_dev->x_plate_resistance; |
273 | z /= z1; | 276 | z /= z2; |
274 | z = (z + 2047) >> 12; | 277 | z = (z + 2047) >> 12; |
275 | 278 | ||
276 | if (z <= MAX_12BIT) { | 279 | if (z <= MAX_12BIT) { |
@@ -391,7 +394,8 @@ static int titsc_probe(struct platform_device *pdev) | |||
391 | goto err_free_irq; | 394 | goto err_free_irq; |
392 | } | 395 | } |
393 | titsc_step_config(ts_dev); | 396 | titsc_step_config(ts_dev); |
394 | titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->coordinate_readouts); | 397 | titsc_writel(ts_dev, REG_FIFO0THR, |
398 | ts_dev->coordinate_readouts * 2 + 2 - 1); | ||
395 | 399 | ||
396 | input_dev->name = "ti-tsc"; | 400 | input_dev->name = "ti-tsc"; |
397 | input_dev->dev.parent = &pdev->dev; | 401 | input_dev->dev.parent = &pdev->dev; |
@@ -468,7 +472,7 @@ static int titsc_resume(struct device *dev) | |||
468 | } | 472 | } |
469 | titsc_step_config(ts_dev); | 473 | titsc_step_config(ts_dev); |
470 | titsc_writel(ts_dev, REG_FIFO0THR, | 474 | titsc_writel(ts_dev, REG_FIFO0THR, |
471 | ts_dev->coordinate_readouts); | 475 | ts_dev->coordinate_readouts * 2 + 2 - 1); |
472 | return 0; | 476 | return 0; |
473 | } | 477 | } |
474 | 478 | ||
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h index 533f200e6d0e..8d73fe29796a 100644 --- a/include/linux/mfd/ti_am335x_tscadc.h +++ b/include/linux/mfd/ti_am335x_tscadc.h | |||
@@ -30,8 +30,8 @@ | |||
30 | #define REG_IDLECONFIG 0x058 | 30 | #define REG_IDLECONFIG 0x058 |
31 | #define REG_CHARGECONFIG 0x05C | 31 | #define REG_CHARGECONFIG 0x05C |
32 | #define REG_CHARGEDELAY 0x060 | 32 | #define REG_CHARGEDELAY 0x060 |
33 | #define REG_STEPCONFIG(n) (0x64 + ((n - 1) * 8)) | 33 | #define REG_STEPCONFIG(n) (0x64 + ((n) * 8)) |
34 | #define REG_STEPDELAY(n) (0x68 + ((n - 1) * 8)) | 34 | #define REG_STEPDELAY(n) (0x68 + ((n) * 8)) |
35 | #define REG_FIFO0CNT 0xE4 | 35 | #define REG_FIFO0CNT 0xE4 |
36 | #define REG_FIFO0THR 0xE8 | 36 | #define REG_FIFO0THR 0xE8 |
37 | #define REG_FIFO1CNT 0xF0 | 37 | #define REG_FIFO1CNT 0xF0 |