linux-ti335x-psp: make all patches work with 'git am'
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.1 / adc / 0004-tscadc-Add-general-purpose-mode-untested-with-touchs.patch
1 From d987e3ae4bf83e8a46702ad44e435e6cbea183dc Mon Sep 17 00:00:00 2001
2 From: Joel A Fernandes <joelagnel@ti.com>
3 Date: Wed, 30 Nov 2011 15:00:40 +0100
4 Subject: [PATCH 4/9] tscadc: Add general purpose mode, untested with touchscreen functionality
6 Signed-off-by: Joel A Fernandes <joelagnel@ti.com>
7 ---
8  arch/arm/mach-omap2/board-am335xevm.c |    6 +
9  arch/arm/mach-omap2/mux33xx.c         |   12 ++
10  arch/arm/mach-omap2/mux33xx.h         |    4 +
11  drivers/input/touchscreen/ti_tscadc.c |  209 +++++++++++++++++++++++++--------
12  include/linux/input/ti_tscadc.h       |    4 +
13  5 files changed, 183 insertions(+), 52 deletions(-)
15 diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c
16 index d7af6dd..8221ba9 100644
17 --- a/arch/arm/mach-omap2/board-am335xevm.c
18 +++ b/arch/arm/mach-omap2/board-am335xevm.c
19 @@ -456,6 +456,10 @@ static struct pinmux_config tsc_pin_mux[] = {
20         {"ain1.ain1",           OMAP_MUX_MODE0 | AM33XX_INPUT_EN},
21         {"ain2.ain2",           OMAP_MUX_MODE0 | AM33XX_INPUT_EN},
22         {"ain3.ain3",           OMAP_MUX_MODE0 | AM33XX_INPUT_EN},
23 +       {"ain4.ain4",           OMAP_MUX_MODE0 | AM33XX_INPUT_EN},
24 +       {"ain5.ain5",           OMAP_MUX_MODE0 | AM33XX_INPUT_EN},
25 +       {"ain6.ain6",           OMAP_MUX_MODE0 | AM33XX_INPUT_EN},
26 +       {"ain7.ain7",           OMAP_MUX_MODE0 | AM33XX_INPUT_EN},
27         {"vrefp.vrefp",         OMAP_MUX_MODE0 | AM33XX_INPUT_EN},
28         {"vrefn.vrefn",         OMAP_MUX_MODE0 | AM33XX_INPUT_EN},
29         {NULL, 0},
30 @@ -1537,6 +1541,7 @@ static struct evm_dev_cfg beaglebone_old_dev_cfg[] = {
31         {i2c2_init,     DEV_ON_BASEBOARD, PROFILE_NONE},
32         {mmc0_init,     DEV_ON_BASEBOARD, PROFILE_NONE},
33         {boneleds_init, DEV_ON_BASEBOARD, PROFILE_ALL},
34 +       {tsc_init,      DEV_ON_BASEBOARD, PROFILE_ALL},
35         {NULL, 0, 0},
36  };
37  
38 @@ -1549,6 +1554,7 @@ static struct evm_dev_cfg beaglebone_dev_cfg[] = {
39         {i2c2_init,     DEV_ON_BASEBOARD, PROFILE_NONE},
40         {mmc0_init,     DEV_ON_BASEBOARD, PROFILE_NONE},
41         {boneleds_init, DEV_ON_BASEBOARD, PROFILE_ALL},
42 +       {tsc_init,      DEV_ON_BASEBOARD, PROFILE_ALL},
43         {NULL, 0, 0},
44  };
45  
46 diff --git a/arch/arm/mach-omap2/mux33xx.c b/arch/arm/mach-omap2/mux33xx.c
47 index 06719df..35986ca 100644
48 --- a/arch/arm/mach-omap2/mux33xx.c
49 +++ b/arch/arm/mach-omap2/mux33xx.c
50 @@ -587,6 +587,18 @@ static struct omap_mux __initdata am33xx_muxmodes[] = {
51         _AM33XX_MUXENTRY(AIN3, 0,
52                 "ain3", NULL, NULL, NULL,
53                 NULL, NULL, NULL, NULL),
54 +       _AM33XX_MUXENTRY(AIN4, 0,
55 +               "ain4", NULL, NULL, NULL,
56 +               NULL, NULL, NULL, NULL),
57 +       _AM33XX_MUXENTRY(AIN5, 0,
58 +               "ain5", NULL, NULL, NULL,
59 +               NULL, NULL, NULL, NULL),
60 +       _AM33XX_MUXENTRY(AIN6, 0,
61 +               "ain6", NULL, NULL, NULL,
62 +               NULL, NULL, NULL, NULL),
63 +       _AM33XX_MUXENTRY(AIN7, 0,
64 +               "ain7", NULL, NULL, NULL,
65 +               NULL, NULL, NULL, NULL),
66         _AM33XX_MUXENTRY(VREFP, 0,
67                 "vrefp", NULL, NULL, NULL,
68                 NULL, NULL, NULL, NULL),
69 diff --git a/arch/arm/mach-omap2/mux33xx.h b/arch/arm/mach-omap2/mux33xx.h
70 index 70a3012..348c8e5 100644
71 --- a/arch/arm/mach-omap2/mux33xx.h
72 +++ b/arch/arm/mach-omap2/mux33xx.h
73 @@ -228,6 +228,10 @@
74  #define AM33XX_CONTROL_PADCONF_DDR_DQSN1_OFFSET                        0x0AFC
75  #define AM33XX_CONTROL_PADCONF_DDR_VREF_OFFSET                 0x0B00
76  #define AM33XX_CONTROL_PADCONF_DDR_VTP_OFFSET                  0x0B04
77 +#define AM33XX_CONTROL_PADCONF_AIN7_OFFSET                     0x0B10
78 +#define AM33XX_CONTROL_PADCONF_AIN6_OFFSET                     0x0B14
79 +#define AM33XX_CONTROL_PADCONF_AIN5_OFFSET                     0x0B18
80 +#define AM33XX_CONTROL_PADCONF_AIN4_OFFSET                     0x0B1C
81  #define AM33XX_CONTROL_PADCONF_AIN3_OFFSET                     0x0B20
82  #define AM33XX_CONTROL_PADCONF_AIN2_OFFSET                     0x0B24
83  #define AM33XX_CONTROL_PADCONF_AIN1_OFFSET                     0x0B28
84 diff --git a/drivers/input/touchscreen/ti_tscadc.c b/drivers/input/touchscreen/ti_tscadc.c
85 index 9783435..76fc7b6 100644
86 --- a/drivers/input/touchscreen/ti_tscadc.c
87 +++ b/drivers/input/touchscreen/ti_tscadc.c
88 @@ -27,6 +27,8 @@
89  #include <linux/input/ti_tscadc.h>
90  #include <linux/delay.h>
91  
92 +/* Memory mapped registers here have incorrect offsets!
93 + * Correct after referring TRM */
94  #define TSCADC_REG_IRQEOI              0x020
95  #define TSCADC_REG_RAWIRQSTATUS                0x024
96  #define TSCADC_REG_IRQSTATUS           0x028
97 @@ -54,12 +56,18 @@
98  
99  /*     Register Bitfields      */
100  #define TSCADC_IRQWKUP_ENB             BIT(0)
101 -#define TSCADC_STPENB_STEPENB          0x7FFF
102 +#define TSCADC_STPENB_STEPENB_TOUCHSCREEN      0x7FFF
103 +#define TSCADC_STPENB_STEPENB_GENERAL          0x0400
104  #define TSCADC_IRQENB_FIFO0THRES       BIT(2)
105 +#define TSCADC_IRQENB_FIFO0OVERRUN     BIT(3)
106  #define TSCADC_IRQENB_FIFO1THRES       BIT(5)
107 +#define TSCADC_IRQENB_EOS              BIT(1)
108  #define TSCADC_IRQENB_PENUP            BIT(9)
109 -#define TSCADC_STEPCONFIG_MODE_HWSYNC  0x2
110 +#define TSCADC_STEPCONFIG_MODE_HWSYNC          0x2
111 +#define TSCADC_STEPCONFIG_MODE_SWCONT          0x1
112 +#define TSCADC_STEPCONFIG_MODE_SWONESHOT       0x0
113  #define TSCADC_STEPCONFIG_2SAMPLES_AVG (1 << 4)
114 +#define TSCADC_STEPCONFIG_NO_AVG       0
115  #define TSCADC_STEPCONFIG_XPP          BIT(5)
116  #define TSCADC_STEPCONFIG_XNN          BIT(6)
117  #define TSCADC_STEPCONFIG_YPP          BIT(7)
118 @@ -72,7 +80,7 @@
119  #define TSCADC_STEPCONFIG_INP          (1 << 20)
120  #define TSCADC_STEPCONFIG_INP_5                (1 << 21)
121  #define TSCADC_STEPCONFIG_FIFO1                (1 << 26)
122 -#define TSCADC_STEPCONFIG_IDLE_INP     (1 << 22)
123 +#define TSCADC_STEPCONFIG_IDLE_INP     0x0000
124  #define TSCADC_STEPCONFIG_OPENDLY      0x018
125  #define TSCADC_STEPCONFIG_SAMPLEDLY    0x88
126  #define TSCADC_STEPCONFIG_Z1           (3 << 19)
127 @@ -104,6 +112,7 @@ struct tscadc {
128         int                     wires;
129         int                     analog_input;
130         int                     x_plate_resistance;
131 +       int mode;
132         struct clk              *clk;
133         int                     irq;
134         void __iomem            *tsc_base;
135 @@ -120,6 +129,86 @@ static void tscadc_writel(struct tscadc *tsc, unsigned int reg,
136         writel(val, tsc->tsc_base + reg);
137  }
138  
139 +static void tsc_adc_step_config(struct tscadc *ts_dev)
140 +{
141 +       unsigned int    stepconfig = 0, delay = 0, chargeconfig = 0;
143 +       /*
144 +        * Step Configuration
145 +        * software-enabled continous mode
146 +        * 2 sample averaging
147 +        * sample channel 1 (SEL_INP mux bits = 0)
148 +        */
149 +       stepconfig = TSCADC_STEPCONFIG_MODE_SWONESHOT |
150 +               TSCADC_STEPCONFIG_2SAMPLES_AVG |
151 +               (0x7 << 19);
153 +       delay = TSCADC_STEPCONFIG_SAMPLEDLY | TSCADC_STEPCONFIG_OPENDLY;
155 +       tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG(10), stepconfig);
156 +       tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY(10), delay);
158 +       /* Get the ball rolling, this will trigger the FSM to step through
159 +        * as soon as TSC_ADC_SS is turned on */
160 +       tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB_GENERAL);
161 +}
163 +static irqreturn_t tsc_adc_interrupt(int irq, void *dev)
164 +{
165 +       struct tscadc           *ts_dev = (struct tscadc *)dev;
166 +       struct input_dev        *input_dev = ts_dev->input;
167 +       unsigned int            status, irqclr = 0;
168 +       int                     i;
169 +       int                     fsm = 0, fifo0count = 0, fifo1count = 0;
170 +       unsigned int            read_sample = 0, ready1 = 0;
171 +       unsigned int            prev_val_x = ~0, prev_val_y = ~0;
172 +       unsigned int            prev_diff_x = ~0, prev_diff_y = ~0;
173 +       unsigned int            cur_diff_x = 0, cur_diff_y = 0;
174 +       unsigned int            val_x = 0, val_y = 0, diffx = 0, diffy = 0;
176 +       status = tscadc_readl(ts_dev, TSCADC_REG_IRQSTATUS);
178 +       printk("interrupt! status=%x\n", status);
179 +       // if (status & TSCADC_IRQENB_EOS) {
180 +       //      irqclr |= TSCADC_IRQENB_EOS;
181 +       // }
183 +       if (status & TSCADC_IRQENB_FIFO0THRES) {
184 +               fifo1count = tscadc_readl(ts_dev, TSCADC_REG_FIFO0CNT);
185 +               printk("fifo 0 count = %d\n", fifo1count);
186 +       
187 +               for (i = 0; i < fifo1count; i++) {
188 +                       read_sample = tscadc_readl(ts_dev, TSCADC_REG_FIFO0);
189 +                       printk("sample: %d: %x\n", i, read_sample);
190 +               }
191 +               irqclr |= TSCADC_IRQENB_FIFO0THRES;
192 +       }
195 +       if (status & TSCADC_IRQENB_FIFO1THRES) {
196 +               fifo1count = tscadc_readl(ts_dev, TSCADC_REG_FIFO1CNT);
198 +               for (i = 0; i < fifo1count; i++) {
199 +                       read_sample = tscadc_readl(ts_dev, TSCADC_REG_FIFO1);
200 +                       // read_sample = read_sample & 0xfff;
201 +                       printk("sample: %d: %d\n", i, read_sample);
202 +                       panic("sample read from fifo1!");
203 +               }
204 +               irqclr |= TSCADC_IRQENB_FIFO1THRES;
205 +       }
207 +       mdelay(500);
209 +       tscadc_writel(ts_dev, TSCADC_REG_IRQSTATUS, irqclr);
211 +       /* check pending interrupts */
212 +       tscadc_writel(ts_dev, TSCADC_REG_IRQEOI, 0x0);
214 +       /* Turn on Step 1 again */
215 +       tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB_GENERAL);
216 +       return IRQ_HANDLED;
217 +}
219  static void tsc_step_config(struct tscadc *ts_dev)
220  {
221         unsigned int    stepconfigx = 0, stepconfigy = 0;
222 @@ -224,7 +313,7 @@ static void tsc_step_config(struct tscadc *ts_dev)
223         tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG14, stepconfigz2);
224         tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY14, delay);
225  
226 -       tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB);
227 +       tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB_TOUCHSCREEN);
228  }
229  
230  static void tsc_idle_config(struct tscadc *ts_config)
231 @@ -242,7 +331,7 @@ static void tsc_idle_config(struct tscadc *ts_config)
232         tscadc_writel(ts_config, TSCADC_REG_IDLECONFIG, idleconfig);
233  }
234  
235 -static irqreturn_t tscadc_interrupt(int irq, void *dev)
236 +static irqreturn_t tsc_interrupt(int irq, void *dev)
237  {
238         struct tscadc           *ts_dev = (struct tscadc *)dev;
239         struct input_dev        *input_dev = ts_dev->input;
240 @@ -362,7 +451,7 @@ static irqreturn_t tscadc_interrupt(int irq, void *dev)
241         /* check pending interrupts */
242         tscadc_writel(ts_dev, TSCADC_REG_IRQEOI, 0x0);
243  
244 -       tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB);
245 +       tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB_TOUCHSCREEN);
246         return IRQ_HANDLED;
247  }
248  
249 @@ -400,13 +489,15 @@ static    int __devinit tscadc_probe(struct platform_device *pdev)
250                 return -ENODEV;
251         }
252  
253 -       input_dev = input_allocate_device();
254 -       if (!input_dev) {
255 -               dev_err(&pdev->dev, "failed to allocate input device.\n");
256 -               err = -ENOMEM;
257 -               goto err_free_mem;
258 +       if(pdata->mode == TI_TSCADC_TSCMODE) {
259 +               input_dev = input_allocate_device();
260 +               if (!input_dev) {
261 +                       dev_err(&pdev->dev, "failed to allocate input device.\n");
262 +                       err = -ENOMEM;
263 +                       goto err_free_mem;
264 +               }
265 +               ts_dev->input = input_dev;
266         }
267 -       ts_dev->input = input_dev;
268  
269         ts_dev->tsc_base = ioremap(res->start, resource_size(res));
270         if (!ts_dev->tsc_base) {
271 @@ -415,8 +506,15 @@ static     int __devinit tscadc_probe(struct platform_device *pdev)
272                 goto err_release_mem;
273         }
274  
275 -       err = request_irq(ts_dev->irq, tscadc_interrupt, IRQF_DISABLED,
276 -                               pdev->dev.driver->name, ts_dev);
277 +       if(pdata->mode == TI_TSCADC_TSCMODE) {
278 +               err = request_irq(ts_dev->irq, tsc_interrupt, IRQF_DISABLED,
279 +                                       pdev->dev.driver->name, ts_dev);
280 +       }
281 +       else {
282 +               err = request_irq(ts_dev->irq, tsc_adc_interrupt, IRQF_DISABLED,
283 +                                       pdev->dev.driver->name, ts_dev);
284 +       }
286         if (err) {
287                 dev_err(&pdev->dev, "failed to allocate irq.\n");
288                 goto err_unmap_regs;
289 @@ -436,11 +534,15 @@ static    int __devinit tscadc_probe(struct platform_device *pdev)
290                 goto err_free_irq;
291         }
292         clock_rate = clk_get_rate(ts_dev->clk);
294 +       /* clk_value of atleast 21MHz required
295 +        * Clock verified on BeagleBone to be 24MHz */
296         clk_value = clock_rate / ADC_CLK;
297         if (clk_value < 7) {
298                 dev_err(&pdev->dev, "clock input less than min clock requirement\n");
299                 goto err_fail;
300         }
302         /* TSCADC_CLKDIV needs to be configured to the value minus 1 */
303         clk_value = clk_value - 1;
304         tscadc_writel(ts_dev, TSCADC_REG_CLKDIV, clk_value);
305 @@ -451,56 +553,59 @@ static    int __devinit tscadc_probe(struct platform_device *pdev)
306         ts_dev->wires = pdata->wires;
307         ts_dev->analog_input = pdata->analog_input;
308         ts_dev->x_plate_resistance = pdata->x_plate_resistance;
309 +       ts_dev->mode = pdata->mode;
310  
311 -       /* Set the control register bits */
312 +       /* Set the control register bits - 12.5.44 TRM */
313         ctrl = TSCADC_CNTRLREG_STEPCONFIGWRT |
314 -                       TSCADC_CNTRLREG_TSCENB |
315 -                       TSCADC_CNTRLREG_STEPID;
316 -       switch (ts_dev->wires) {
317 -       case 4:
318 -               ctrl |= TSCADC_CNTRLREG_4WIRE;
319 -               break;
320 -       case 5:
321 -               ctrl |= TSCADC_CNTRLREG_5WIRE;
322 -               break;
323 -       case 8:
324 -               ctrl |= TSCADC_CNTRLREG_8WIRE;
325 -               break;
326 +                               TSCADC_CNTRLREG_STEPID;
327 +       if(pdata->mode == TI_TSCADC_TSCMODE) {
328 +               ctrl |= TSCADC_CNTRLREG_TSCENB;
329 +               switch (ts_dev->wires) {
330 +                       case 4:
331 +                               ctrl |= TSCADC_CNTRLREG_4WIRE;
332 +                               break;
333 +                       case 5:
334 +                               ctrl |= TSCADC_CNTRLREG_5WIRE;
335 +                               break;
336 +                       case 8:
337 +                               ctrl |= TSCADC_CNTRLREG_8WIRE;
338 +                               break;
339 +               }
340         }
341         tscadc_writel(ts_dev, TSCADC_REG_CTRL, ctrl);
342  
343 -       /* Set register bits for Idel Config Mode */
344 -       tsc_idle_config(ts_dev);
346 -       /* IRQ Enable */
347 -       irqenable = TSCADC_IRQENB_FIFO1THRES;
348 +       /* Touch screen / ADC configuration */
349 +       if(pdata->mode == TI_TSCADC_TSCMODE) {
350 +               tsc_idle_config(ts_dev);
351 +               tsc_step_config(ts_dev);
352 +               tscadc_writel(ts_dev, TSCADC_REG_FIFO1THR, 6);
353 +               irqenable = TSCADC_IRQENB_FIFO1THRES;
354 +               /* Touch screen also needs an input_dev */
355 +               input_dev->name = "ti-tsc-adcc";
356 +               input_dev->dev.parent = &pdev->dev;
357 +               input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
358 +               input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
359 +               input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
360 +               input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
361 +               /* register to the input system */
362 +               err = input_register_device(input_dev);
363 +               if (err)
364 +                       goto err_fail;
365 +       }
366 +       else {
367 +               tsc_adc_step_config(ts_dev);
368 +               tscadc_writel(ts_dev, TSCADC_REG_FIFO0THR, 0);
369 +               irqenable = TSCADC_IRQENB_FIFO0THRES;
370 +       }
371         tscadc_writel(ts_dev, TSCADC_REG_IRQENABLE, irqenable);
372  
373 -       tsc_step_config(ts_dev);
375 -       tscadc_writel(ts_dev, TSCADC_REG_FIFO1THR, 6);
377         ctrl |= TSCADC_CNTRLREG_TSCSSENB;
378 -       tscadc_writel(ts_dev, TSCADC_REG_CTRL, ctrl);
380 -       input_dev->name = "ti-tsc-adcc";
381 -       input_dev->dev.parent = &pdev->dev;
383 -       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
384 -       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
386 -       input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
387 -       input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
388 -       input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
390 -       /* register to the input system */
391 -       err = input_register_device(input_dev);
392 -       if (err)
393 -               goto err_fail;
394 +       tscadc_writel(ts_dev, TSCADC_REG_CTRL, ctrl);   /* Turn on TSC_ADC */
395  
396         return 0;
397  
398  err_fail:
399 +       printk(KERN_ERR "Fatal error, shutting down TSC_ADC\n");
400         clk_disable(ts_dev->clk);
401         clk_put(ts_dev->clk);
402  err_free_irq:
403 diff --git a/include/linux/input/ti_tscadc.h b/include/linux/input/ti_tscadc.h
404 index 2c547bb..850cd4b 100644
405 --- a/include/linux/input/ti_tscadc.h
406 +++ b/include/linux/input/ti_tscadc.h
407 @@ -14,8 +14,12 @@
408   * @x_plate_resistance:        X plate resistance.
409   */
410  
411 +#define TI_TSCADC_TSCMODE 0
412 +#define TI_TSCADC_GENMODE 1
414  struct tsc_data {
415         int wires;
416         int analog_input;
417         int x_plate_resistance;
418 +       int mode;
419  };
420 -- 
421 1.7.2.5