aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorBrad Griffis <bgriffis@ti.com>2015-02-03 14:41:58 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-03 14:50:37 -0500
commit3a59684ccc5d529e7e9ce8b068889dbaa4c34e9b (patch)
treea7cdee1b66db17d7b071e3517128d00e1bc4d0b6 /drivers/input
parent448c7f3830ca283e485aa943279acea6bde8b270 (diff)
Input: ti_am335x_tsc - interchange touchscreen and ADC steps
This patch makes the initial changes required to workaround TSC-false pen-up interrupts. It is required to implement these changes in order to remove udelay in the TSC interrupt handler and false pen-up events. The charge step is to be executed immediately after sampling X+. Hence TSC is made to use higher numbered steps (steps 5 to 16 for 5 co-ordinate readouts, 4 wire TSC configuration) and ADC to use lower ones. Further X co-ordinate readouts must be the last to be sampled, thus co-ordinates are sampled in the order Y-Z-X. Signed-off-by: Brad Griffis <bgriffis@ti.com> [vigneshr@ti.com: Ported the patch from v3.12 to v3.19rc1] Signed-off-by: Vignesh R <vigneshr@ti.com> Acked-by: Jonathan Cameron <jic23@kernel.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/ti_am335x_tsc.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index 004f1346a957..dfbb9fe6a270 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -121,7 +121,7 @@ static void titsc_step_config(struct titsc *ts_dev)
121{ 121{
122 unsigned int config; 122 unsigned int config;
123 int i; 123 int i;
124 int end_step; 124 int end_step, first_step, tsc_steps;
125 u32 stepenable; 125 u32 stepenable;
126 126
127 config = STEPCONFIG_MODE_HWSYNC | 127 config = STEPCONFIG_MODE_HWSYNC |
@@ -140,9 +140,11 @@ static void titsc_step_config(struct titsc *ts_dev)
140 break; 140 break;
141 } 141 }
142 142
143 /* 1 … coordinate_readouts is for X */ 143 tsc_steps = ts_dev->coordinate_readouts * 2 + 2;
144 end_step = ts_dev->coordinate_readouts; 144 first_step = TOTAL_STEPS - tsc_steps;
145 for (i = 0; i < end_step; i++) { 145 /* Steps 16 to 16-coordinate_readouts is for X */
146 end_step = first_step + tsc_steps;
147 for (i = end_step - ts_dev->coordinate_readouts; i < end_step; i++) {
146 titsc_writel(ts_dev, REG_STEPCONFIG(i), config); 148 titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
147 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); 149 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
148 } 150 }
@@ -164,9 +166,9 @@ static void titsc_step_config(struct titsc *ts_dev)
164 break; 166 break;
165 } 167 }
166 168
167 /* coordinate_readouts coordinate_readouts * 2 is for Y */ 169 /* 1 ... coordinate_readouts is for Y */
168 end_step = ts_dev->coordinate_readouts * 2; 170 end_step = first_step + ts_dev->coordinate_readouts;
169 for (i = ts_dev->coordinate_readouts; i < end_step; i++) { 171 for (i = first_step; i < end_step; i++) {
170 titsc_writel(ts_dev, REG_STEPCONFIG(i), config); 172 titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
171 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); 173 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
172 } 174 }
@@ -179,7 +181,7 @@ static void titsc_step_config(struct titsc *ts_dev)
179 titsc_writel(ts_dev, REG_CHARGECONFIG, config); 181 titsc_writel(ts_dev, REG_CHARGECONFIG, config);
180 titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); 182 titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY);
181 183
182 /* coordinate_readouts * 2 coordinate_readouts * 2 + 2 is for Z */ 184 /* coordinate_readouts + 1 ... coordinate_readouts + 2 is for Z */
183 config = STEPCONFIG_MODE_HWSYNC | 185 config = STEPCONFIG_MODE_HWSYNC |
184 STEPCONFIG_AVG_16 | ts_dev->bit_yp | 186 STEPCONFIG_AVG_16 | ts_dev->bit_yp |
185 ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | 187 ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM |
@@ -194,8 +196,11 @@ static void titsc_step_config(struct titsc *ts_dev)
194 titsc_writel(ts_dev, REG_STEPDELAY(end_step), 196 titsc_writel(ts_dev, REG_STEPDELAY(end_step),
195 STEPCONFIG_OPENDLY); 197 STEPCONFIG_OPENDLY);
196 198
197 /* The steps1 … end and bit 0 for TS_Charge */ 199 /* The steps end ... end - readouts * 2 + 2 and bit 0 for TS_Charge */
198 stepenable = (1 << (end_step + 2)) - 1; 200 stepenable = 1;
201 for (i = 0; i < tsc_steps; i++)
202 stepenable |= 1 << (first_step + i + 1);
203
199 ts_dev->step_mask = stepenable; 204 ts_dev->step_mask = stepenable;
200 am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask); 205 am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask);
201} 206}
@@ -209,6 +214,7 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
209 unsigned int read, diff; 214 unsigned int read, diff;
210 unsigned int i, channel; 215 unsigned int i, channel;
211 unsigned int creads = ts_dev->coordinate_readouts; 216 unsigned int creads = ts_dev->coordinate_readouts;
217 unsigned int first_step = TOTAL_STEPS - (creads * 2 + 2);
212 218
213 *z1 = *z2 = 0; 219 *z1 = *z2 = 0;
214 if (fifocount % (creads * 2 + 2)) 220 if (fifocount % (creads * 2 + 2))
@@ -226,7 +232,7 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
226 232
227 channel = (read & 0xf0000) >> 16; 233 channel = (read & 0xf0000) >> 16;
228 read &= 0xfff; 234 read &= 0xfff;
229 if (channel < creads) { 235 if (channel > first_step + creads + 2) {
230 diff = abs(read - prev_val_x); 236 diff = abs(read - prev_val_x);
231 if (diff < prev_diff_x) { 237 if (diff < prev_diff_x) {
232 prev_diff_x = diff; 238 prev_diff_x = diff;
@@ -234,19 +240,19 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
234 } 240 }
235 prev_val_x = read; 241 prev_val_x = read;
236 242
237 } else if (channel < creads * 2) { 243 } else if (channel == first_step + creads + 1) {
244 *z1 = read;
245
246 } else if (channel == first_step + creads + 2) {
247 *z2 = read;
248
249 } else if (channel > first_step) {
238 diff = abs(read - prev_val_y); 250 diff = abs(read - prev_val_y);
239 if (diff < prev_diff_y) { 251 if (diff < prev_diff_y) {
240 prev_diff_y = diff; 252 prev_diff_y = diff;
241 *y = read; 253 *y = read;
242 } 254 }
243 prev_val_y = read; 255 prev_val_y = read;
244
245 } else if (channel < creads * 2 + 1) {
246 *z1 = read;
247
248 } else if (channel < creads * 2 + 2) {
249 *z2 = read;
250 } 256 }
251 } 257 }
252} 258}