9e7331621d27a65bbd80e8cdb76fc94a84126f64
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.1 / adc / 0003-AM335x-Add-support-for-pressure-measurement-on-TSC.patch
1 From b086fa2754f2c5f4f05a9690f170e2ef86207b4e Mon Sep 17 00:00:00 2001
2 From: Patil, Rachna <rachna@ti.com>
3 Date: Fri, 11 Nov 2011 18:28:54 +0530
4 Subject: [PATCH 3/9] AM335x: Add support for pressure measurement on TSC.
6 This patch adds support for pressure measurement configurations
7 on TSC. Along with X and Y co-ordinates pressure is also reported to
8 the sub-system.
10 Signed-off-by: Patil, Rachna <rachna@ti.com>
11 ---
12  arch/arm/mach-omap2/board-am335xevm.c |    1 +
13  drivers/input/touchscreen/ti_tscadc.c |   77 +++++++++++++++++++++++++++------
14  include/linux/input/ti_tscadc.h       |    3 +-
15  3 files changed, 66 insertions(+), 15 deletions(-)
17 diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c
18 index d6bf7b1..46fce3e 100644
19 --- a/arch/arm/mach-omap2/board-am335xevm.c
20 +++ b/arch/arm/mach-omap2/board-am335xevm.c
21 @@ -194,6 +194,7 @@ static struct resource tsc_resources[]  = {
22  
23  static struct tsc_data am335x_touchscreen_data  = {
24         .wires  = 4,
25 +       .x_plate_resistance = 200,
26  };
27  
28  static struct platform_device tsc_device = {
29 diff --git a/drivers/input/touchscreen/ti_tscadc.c b/drivers/input/touchscreen/ti_tscadc.c
30 index 021db7f..9783435 100644
31 --- a/drivers/input/touchscreen/ti_tscadc.c
32 +++ b/drivers/input/touchscreen/ti_tscadc.c
33 @@ -41,6 +41,10 @@
34  #define TSCADC_REG_CHARGEDELAY         0x060
35  #define TSCADC_REG_STEPCONFIG(n)       (0x64 + ((n-1) * 8))
36  #define TSCADC_REG_STEPDELAY(n)                (0x68 + ((n-1) * 8))
37 +#define TSCADC_REG_STEPCONFIG13                0x0C4
38 +#define TSCADC_REG_STEPDELAY13         0x0C8
39 +#define TSCADC_REG_STEPCONFIG14                0x0CC
40 +#define TSCADC_REG_STEPDELAY14         0x0D0
41  #define TSCADC_REG_FIFO0CNT            0xE4
42  #define TSCADC_REG_FIFO0THR            0xE8
43  #define TSCADC_REG_FIFO1CNT            0xF0
44 @@ -50,7 +54,7 @@
45  
46  /*     Register Bitfields      */
47  #define TSCADC_IRQWKUP_ENB             BIT(0)
48 -#define TSCADC_STPENB_STEPENB          0x1fFF
49 +#define TSCADC_STPENB_STEPENB          0x7FFF
50  #define TSCADC_IRQENB_FIFO0THRES       BIT(2)
51  #define TSCADC_IRQENB_FIFO1THRES       BIT(5)
52  #define TSCADC_IRQENB_PENUP            BIT(9)
53 @@ -71,10 +75,11 @@
54  #define TSCADC_STEPCONFIG_IDLE_INP     (1 << 22)
55  #define TSCADC_STEPCONFIG_OPENDLY      0x018
56  #define TSCADC_STEPCONFIG_SAMPLEDLY    0x88
57 -#define TSCADC_STEPCHARGE_INM_SWAP     BIT(16)
58 -#define TSCADC_STEPCHARGE_INM          BIT(15)
59 -#define TSCADC_STEPCHARGE_INP_SWAP     BIT(20)
60 -#define TSCADC_STEPCHARGE_INP          BIT(19)
61 +#define TSCADC_STEPCONFIG_Z1           (3 << 19)
62 +#define TSCADC_STEPCHARGE_INM_SWAP     BIT(16)
63 +#define TSCADC_STEPCHARGE_INM          BIT(15)
64 +#define TSCADC_STEPCHARGE_INP_SWAP     BIT(20)
65 +#define TSCADC_STEPCHARGE_INP          BIT(19)
66  #define TSCADC_STEPCHARGE_RFM          (1 << 23)
67  #define TSCADC_STEPCHARGE_DELAY                0x1
68  #define TSCADC_CNTRLREG_TSCSSENB       BIT(0)
69 @@ -98,6 +103,7 @@ struct tscadc {
70         struct input_dev        *input;
71         int                     wires;
72         int                     analog_input;
73 +       int                     x_plate_resistance;
74         struct clk              *clk;
75         int                     irq;
76         void __iomem            *tsc_base;
77 @@ -118,6 +124,7 @@ static void tsc_step_config(struct tscadc *ts_dev)
78  {
79         unsigned int    stepconfigx = 0, stepconfigy = 0;
80         unsigned int    delay, chargeconfig = 0;
81 +       unsigned int    stepconfigz1 = 0, stepconfigz2 = 0;
82         int i;
83  
84         /* Configure the Step registers */
85 @@ -205,6 +212,18 @@ static void tsc_step_config(struct tscadc *ts_dev)
86         tscadc_writel(ts_dev, TSCADC_REG_CHARGECONFIG, chargeconfig);
87         tscadc_writel(ts_dev, TSCADC_REG_CHARGEDELAY, TSCADC_STEPCHARGE_DELAY);
88  
89 +        /* Configure to calculate pressure */
90 +       stepconfigz1 = TSCADC_STEPCONFIG_MODE_HWSYNC |
91 +                               TSCADC_STEPCONFIG_2SAMPLES_AVG |
92 +                               TSCADC_STEPCONFIG_XNP |
93 +                               TSCADC_STEPCONFIG_YPN | TSCADC_STEPCONFIG_INM;
94 +       stepconfigz2 = stepconfigz1 | TSCADC_STEPCONFIG_Z1 |
95 +                               TSCADC_STEPCONFIG_FIFO1;
96 +       tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG13, stepconfigz1);
97 +       tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY13, delay);
98 +       tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG14, stepconfigz2);
99 +       tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY14, delay);
101         tscadc_writel(ts_dev, TSCADC_REG_SE, TSCADC_STPENB_STEPENB);
102  }
103  
104 @@ -235,14 +254,14 @@ static irqreturn_t tscadc_interrupt(int irq, void *dev)
105         unsigned int            prev_diff_x = ~0, prev_diff_y = ~0;
106         unsigned int            cur_diff_x = 0, cur_diff_y = 0;
107         unsigned int            val_x = 0, val_y = 0, diffx = 0, diffy = 0;
108 +       unsigned int            z1 = 0, z2 = 0, z = 0;
109  
110         status = tscadc_readl(ts_dev, TSCADC_REG_IRQSTATUS);
111  
112         if (status & TSCADC_IRQENB_FIFO1THRES) {
113                 fifo0count = tscadc_readl(ts_dev, TSCADC_REG_FIFO0CNT);
114                 fifo1count = tscadc_readl(ts_dev, TSCADC_REG_FIFO1CNT);
116 -               for (i = 0; i < fifo0count; i++) {
117 +               for (i = 0; i < (fifo0count-1); i++) {
118                         readx1 = tscadc_readl(ts_dev, TSCADC_REG_FIFO0);
119                         readx1 = readx1 & 0xfff;
120                         if (readx1 > prev_val_x)
121 @@ -281,12 +300,39 @@ static irqreturn_t tscadc_interrupt(int irq, void *dev)
122                 bckup_x = val_x;
123                 bckup_y = val_y;
124  
125 -               if (pen == 0) {
126 -                       if ((diffx < 15) && (diffy < 15)) {
127 -                               input_report_abs(input_dev, ABS_X, val_x);
128 -                               input_report_abs(input_dev, ABS_Y, val_y);
129 -                               input_report_key(input_dev, BTN_TOUCH, 1);
130 -                               input_sync(input_dev);
131 +               z1 = ((tscadc_readl(ts_dev, TSCADC_REG_FIFO0)) & 0xfff);
132 +               z2 = ((tscadc_readl(ts_dev, TSCADC_REG_FIFO1)) & 0xfff);
134 +               if ((z1 != 0) && (z2 != 0)) {
135 +                       /*
136 +                        * cal pressure using formula
137 +                        * Resistance(touch) = x plate resistance *
138 +                        * x postion/4096 * ((z2 / z1) - 1)
139 +                        */
140 +                       z = z2 - z1;
141 +                       z *= val_x;
142 +                       z *= ts_dev->x_plate_resistance;
143 +                       z /= z1;
144 +                       z = (z + 2047) >> 12;
146 +                       /*
147 +                        * Sample found inconsistent by debouncing
148 +                        * or pressure is beyond the maximum.
149 +                        * Don't report it to user space.
150 +                        */
151 +                       if (pen == 0) {
152 +                               if ((diffx < 15) && (diffy < 15)
153 +                                               && (z <= MAX_12BIT)) {
154 +                                       input_report_abs(input_dev, ABS_X,
155 +                                                       val_x);
156 +                                       input_report_abs(input_dev, ABS_Y,
157 +                                                       val_y);
158 +                                       input_report_abs(input_dev, ABS_PRESSURE,
159 +                                                       z);
160 +                                       input_report_key(input_dev, BTN_TOUCH,
161 +                                                       1);
162 +                                       input_sync(input_dev);
163 +                               }
164                         }
165                 }
166                 irqclr |= TSCADC_IRQENB_FIFO1THRES;
167 @@ -303,6 +349,7 @@ static irqreturn_t tscadc_interrupt(int irq, void *dev)
168                         bckup_x = 0;
169                         bckup_y = 0;
170                         input_report_key(input_dev, BTN_TOUCH, 0);
171 +                       input_report_abs(input_dev, ABS_PRESSURE, 0);
172                         input_sync(input_dev);
173                 } else {
174                         pen = 0;
175 @@ -403,6 +450,7 @@ static      int __devinit tscadc_probe(struct platform_device *pdev)
176  
177         ts_dev->wires = pdata->wires;
178         ts_dev->analog_input = pdata->analog_input;
179 +       ts_dev->x_plate_resistance = pdata->x_plate_resistance;
180  
181         /* Set the control register bits */
182         ctrl = TSCADC_CNTRLREG_STEPCONFIGWRT |
183 @@ -430,7 +478,7 @@ static      int __devinit tscadc_probe(struct platform_device *pdev)
184  
185         tsc_step_config(ts_dev);
186  
187 -       tscadc_writel(ts_dev, TSCADC_REG_FIFO1THR, 5);
188 +       tscadc_writel(ts_dev, TSCADC_REG_FIFO1THR, 6);
189  
190         ctrl |= TSCADC_CNTRLREG_TSCSSENB;
191         tscadc_writel(ts_dev, TSCADC_REG_CTRL, ctrl);
192 @@ -443,6 +491,7 @@ static      int __devinit tscadc_probe(struct platform_device *pdev)
193  
194         input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
195         input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
196 +       input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
197  
198         /* register to the input system */
199         err = input_register_device(input_dev);
200 diff --git a/include/linux/input/ti_tscadc.h b/include/linux/input/ti_tscadc.h
201 index b9d9a46..2c547bb 100644
202 --- a/include/linux/input/ti_tscadc.h
203 +++ b/include/linux/input/ti_tscadc.h
204 @@ -11,10 +11,11 @@
205   *                     XPUL = AN0,YPLL = AN1,XNUR = AN2,
206   *                     YNLR = AN3, then set this variable to
207   *                     0.
208 + * @x_plate_resistance:        X plate resistance.
209   */
210  
211  struct tsc_data {
212         int wires;
213         int analog_input;
215 +       int x_plate_resistance;
216  };
217 -- 
218 1.7.4.1