aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c2
-rw-r--r--drivers/input/touchscreen/ti_am335x_tsc.c78
-rw-r--r--include/linux/mfd/ti_am335x_tscadc.h4
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)
120static void titsc_step_config(struct titsc *ts_dev) 120static 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
201static void titsc_read_coordinates(struct titsc *ts_dev, 202static 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