Commit e823ec6f7b5555c65b2b89742fcd705014e8e467
Committed by
Sekhar Nori
1 parent
01a15b744d
Exists in
ti-linux-3.14.y
and in
2 other branches
input: touchscreen: ti_am335x_tsc: Remove udelay in interrupt handler
TSC interrupt handler had udelay to avoid reporting of false pen-up interrupt to user space. This patch implements workaround suggesting in Advisory 1.0.31 of silicon errata for am335x, thus eliminating udelay and touchscreen lag. This also improves performance of touchscreen and eliminates sudden jump of cursor at touch release. IDLECONFIG and CHARGECONFIG registers are to be configured with same values in order to eliminate false pen-up events. This workaround may result in false pen-down to be detected, hence considerable charge step delay needs to be added. TSC steps are disabled at the end of every sampling cycle and EOS bit is set. Once the EOS bit is set, the TSC steps need to be re-enabled to begin next sampling cycle. In one shot mode, sequencer automatically disables all enabled steps at the end of each cycle. (both ADC steps and TSC steps) Hence these steps need not be saved in reg_se_cache for clearing these steps at a later stage. Signed-off-by: Brad Griffis <bgriffis@ti.com> [vigneshr@ti.com: Ported patch from v3.12 to v3.14] Signed-off-by: Vignesh R <vigneshr@ti.com> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Showing 3 changed files with 30 additions and 37 deletions Side-by-side Diff
drivers/input/touchscreen/ti_am335x_tsc.c
... | ... | @@ -173,11 +173,9 @@ |
173 | 173 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); |
174 | 174 | } |
175 | 175 | |
176 | - /* Charge step configuration */ | |
177 | - config = ts_dev->bit_xp | ts_dev->bit_yn | | |
178 | - STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | | |
179 | - STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp); | |
176 | + /* Make CHARGECONFIG same as IDLECONFIG */ | |
180 | 177 | |
178 | + config = titsc_readl(ts_dev, REG_IDLECONFIG); | |
181 | 179 | titsc_writel(ts_dev, REG_CHARGECONFIG, config); |
182 | 180 | titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); |
183 | 181 | |
184 | 182 | |
... | ... | @@ -264,9 +262,26 @@ |
264 | 262 | unsigned int status, irqclr = 0; |
265 | 263 | unsigned int x = 0, y = 0; |
266 | 264 | unsigned int z1, z2, z; |
267 | - unsigned int fsm; | |
268 | 265 | |
269 | - status = titsc_readl(ts_dev, REG_IRQSTATUS); | |
266 | + status = titsc_readl(ts_dev, REG_RAWIRQSTATUS); | |
267 | + if (status & IRQENB_HW_PEN) { | |
268 | + ts_dev->pen_down = true; | |
269 | + titsc_writel(ts_dev, REG_IRQWAKEUP, 0x00); | |
270 | + titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN); | |
271 | + irqclr |= IRQENB_HW_PEN; | |
272 | + } | |
273 | + | |
274 | + if (status & IRQENB_PENUP) { | |
275 | + ts_dev->pen_down = false; | |
276 | + input_report_key(input_dev, BTN_TOUCH, 0); | |
277 | + input_report_abs(input_dev, ABS_PRESSURE, 0); | |
278 | + input_sync(input_dev); | |
279 | + irqclr |= IRQENB_PENUP; | |
280 | + } | |
281 | + | |
282 | + if (status & IRQENB_EOS) | |
283 | + irqclr |= IRQENB_EOS; | |
284 | + | |
270 | 285 | /* |
271 | 286 | * ADC and touchscreen share the IRQ line. |
272 | 287 | * FIFO1 interrupts are used by ADC. Handle FIFO0 IRQs here only |
... | ... | @@ -297,34 +312,6 @@ |
297 | 312 | } |
298 | 313 | irqclr |= IRQENB_FIFO0THRES; |
299 | 314 | } |
300 | - | |
301 | - /* | |
302 | - * Time for sequencer to settle, to read | |
303 | - * correct state of the sequencer. | |
304 | - */ | |
305 | - udelay(SEQ_SETTLE); | |
306 | - | |
307 | - status = titsc_readl(ts_dev, REG_RAWIRQSTATUS); | |
308 | - if (status & IRQENB_PENUP) { | |
309 | - /* Pen up event */ | |
310 | - fsm = titsc_readl(ts_dev, REG_ADCFSM); | |
311 | - if (fsm == ADCFSM_STEPID) { | |
312 | - ts_dev->pen_down = false; | |
313 | - input_report_key(input_dev, BTN_TOUCH, 0); | |
314 | - input_report_abs(input_dev, ABS_PRESSURE, 0); | |
315 | - input_sync(input_dev); | |
316 | - } else { | |
317 | - ts_dev->pen_down = true; | |
318 | - } | |
319 | - irqclr |= IRQENB_PENUP; | |
320 | - } | |
321 | - | |
322 | - if (status & IRQENB_HW_PEN) { | |
323 | - | |
324 | - titsc_writel(ts_dev, REG_IRQWAKEUP, 0x00); | |
325 | - titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN); | |
326 | - } | |
327 | - | |
328 | 315 | if (irqclr) { |
329 | 316 | titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); |
330 | 317 | am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask); |
... | ... | @@ -414,6 +401,7 @@ |
414 | 401 | } |
415 | 402 | |
416 | 403 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); |
404 | + titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_EOS); | |
417 | 405 | err = titsc_config_wires(ts_dev); |
418 | 406 | if (err) { |
419 | 407 | dev_err(&pdev->dev, "wrong i/p wire configuration\n"); |
drivers/mfd/ti_am335x_tscadc.c
... | ... | @@ -87,8 +87,12 @@ |
87 | 87 | spin_lock_irq(&tsadc->reg_lock); |
88 | 88 | finish_wait(&tsadc->reg_se_wait, &wait); |
89 | 89 | |
90 | + /* | |
91 | + * Sequencer should either be idle or | |
92 | + * busy applying the charge step. | |
93 | + */ | |
90 | 94 | reg = tscadc_readl(tsadc, REG_ADCFSM); |
91 | - WARN_ON(reg & SEQ_STATUS); | |
95 | + WARN_ON(reg & SEQ_STATUS & (!CHARGE_STEP)); | |
92 | 96 | tsadc->adc_waiting = false; |
93 | 97 | } |
94 | 98 | tsadc->adc_in_use = true; |
... | ... | @@ -97,7 +101,6 @@ |
97 | 101 | void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val) |
98 | 102 | { |
99 | 103 | spin_lock_irq(&tsadc->reg_lock); |
100 | - tsadc->reg_se_cache |= val; | |
101 | 104 | am335x_tscadc_need_adc(tsadc); |
102 | 105 | |
103 | 106 | tscadc_writel(tsadc, REG_SE, val); |
include/linux/mfd/ti_am335x_tscadc.h
... | ... | @@ -52,6 +52,7 @@ |
52 | 52 | |
53 | 53 | /* IRQ enable */ |
54 | 54 | #define IRQENB_HW_PEN BIT(0) |
55 | +#define IRQENB_EOS BIT(1) | |
55 | 56 | #define IRQENB_FIFO0THRES BIT(2) |
56 | 57 | #define IRQENB_FIFO0OVRRUN BIT(3) |
57 | 58 | #define IRQENB_FIFO0UNDRFLW BIT(4) |
... | ... | @@ -107,7 +108,7 @@ |
107 | 108 | /* Charge delay */ |
108 | 109 | #define CHARGEDLY_OPEN_MASK (0x3FFFF << 0) |
109 | 110 | #define CHARGEDLY_OPEN(val) ((val) << 0) |
110 | -#define CHARGEDLY_OPENDLY CHARGEDLY_OPEN(1) | |
111 | +#define CHARGEDLY_OPENDLY CHARGEDLY_OPEN(0x400) | |
111 | 112 | |
112 | 113 | /* Control register */ |
113 | 114 | #define CNTRLREG_TSCSSENB BIT(0) |
... | ... | @@ -127,6 +128,7 @@ |
127 | 128 | |
128 | 129 | /* Sequencer Status */ |
129 | 130 | #define SEQ_STATUS BIT(5) |
131 | +#define CHARGE_STEP 0x11 | |
130 | 132 | |
131 | 133 | #define ADC_CLK 3000000 |
132 | 134 | #define TOTAL_STEPS 16 |