Commit e823ec6f7b5555c65b2b89742fcd705014e8e467

Authored by Brad Griffis
Committed by Sekhar Nori
1 parent 01a15b744d

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