Merge current mainline tree into linux-omap tree
[pandora-kernel.git] / drivers / input / touchscreen / omap / ts_hx.c
1 /*
2  * input/touchscreen/omap/ts_hx.c
3  * touchscreen support for OMAP H3 and H2  boards
4  *
5  * Copyright (c) 2002 MontaVista Software Inc.
6  * Copyright (c) 2004 Texas Instruments, Inc.
7  *
8  * Assembled using driver code copyright the companies above.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  *
24  * History:
25  * 9/12/2004    Srinath Modified and integrated  H2 and H3 code
26  *
27  */
28
29 #include <linux/input.h>
30 #include <linux/device.h>
31 #include <asm/mach-types.h>
32 #include <asm/arch/gpio.h>
33 #include <asm/arch/mux.h>
34 #include <asm/arch/hardware.h>
35 #include <asm/hardware/tsc2101.h>
36
37 #include "../drivers/ssi/omap-tsc2101.h"
38 #include "omap_ts.h"
39
40 #define H2_GPIO_NUM             4
41 #define H3_GPIO_NUM             48
42
43 #define OMAP_TSC2101_XRES                      500
44 #define TOUCHSCREEN_DATA_REGISTERS_PAGE  0x0
45 #define TOUCHSCREEN_CONTROL_REGISTERS_PAGE      0x1
46 #define OMAP_TSC2101_READ_MAX              0x4
47 #define TSC2101_GETSTATUS(ret)            (((ret) >> 11) & 0x1)
48 #define TSC2101_MASKVAL                  0xFFF
49 #define TSC2101_PRESSUREVAL(x)            ((x) << 12)
50
51 static int hx_ts_penup(void);
52 static int hx_ts_probe(struct omap_ts_t *ts);
53 static void hx_ts_read(u16 * data);
54 static void hx_ts_enable(void);
55 static void hx_ts_disable(void);
56 #ifdef  MODULE
57 static void hx_ts_remove(void);
58 #endif
59
60 struct ts_device hx_ts = {
61         .probe          = hx_ts_probe,
62         .read           = hx_ts_read,
63         .enable         = hx_ts_enable,
64         .disable        = hx_ts_disable,
65         .remove         = __exit_p(hx_ts_remove),
66         .penup          = hx_ts_penup,
67 };
68
69 static int hx_ts_penup(void)
70 {
71         int ret = 0;
72         /* Read the status register */
73         ret = omap_tsc2101_read(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,
74                                 TSC2101_TS_STATUS);
75         /* Check for availability of data in status register */
76         ret = TSC2101_GETSTATUS(ret);
77         return !ret;
78
79 }
80
81 static int __init hx_ts_probe(struct omap_ts_t *ts)
82 {
83         unsigned        gpio;
84
85         if (machine_is_omap_h2()) {
86                 gpio = H2_GPIO_NUM;
87                 omap_cfg_reg(P20_1610_GPIO4);
88         } else if (machine_is_omap_h3()) {
89                 gpio = H3_GPIO_NUM;
90                 omap_cfg_reg(W19_1610_GPIO48);
91         } else
92                 return -ENODEV;
93
94         ts->irq = OMAP_GPIO_IRQ(gpio);
95         if (omap_request_gpio(gpio) != 0) {
96                 printk(KERN_ERR "hX_ts_init.c: Could not reserve GPIO!\n");
97                 return -EINVAL;
98         };
99
100         omap_set_gpio_direction(gpio, 1);
101         ts->irq_type = IRQF_TRIGGER_FALLING;
102         return 0;
103 }
104
105 static void hx_ts_read(u16 * values)
106 {
107         s32 t, p = 0;
108         int i;
109
110         /* Read X, Y, Z1 and Z2 */
111         omap_tsc2101_reads(TOUCHSCREEN_DATA_REGISTERS_PAGE, TSC2101_TS_X,
112                            values, OMAP_TSC2101_READ_MAX);
113
114         for (i = 0; i < OMAP_TSC2101_READ_MAX; i++)
115                 values[i] &= TSC2101_MASKVAL;
116
117         /* Calculate Pressure */
118         if (values[TSC2101_TS_Z1] != 0) {
119                 t = ((OMAP_TSC2101_XRES * values[TSC2101_TS_X]) *
120                      (values[TSC2101_TS_Z2] - values[TSC2101_TS_Z1]));
121                 p = t / (u32) (TSC2101_PRESSUREVAL(values[TSC2101_TS_Z1]));
122                 if (p < 0)
123                         p = 0;
124         }
125
126         values[TSC2101_TS_Z1] = p;
127 }
128
129 static void hx_ts_enable(void)
130 {
131         int ret = omap_tsc2101_enable();
132         if (ret) {
133                 printk(KERN_ERR "FAILED TO INITIALIZE TSC CODEC\n");
134                 return;
135         }
136
137         /* PINTDAV is data available only */
138         omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,
139                            TSC2101_TS_STATUS, TSC2101_DATA_AVAILABLE);
140         /* disable buffer mode */
141         omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,
142                            TSC2101_TS_BUFFER_CTRL, TSC2101_BUFFERMODE_DISABLE);
143         /* use internal reference, 100 usec power-up delay,
144          *        * power down between conversions, 1.25V internal reference */
145         omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,
146                            TSC2101_TS_REF_CTRL, TSC2101_REF_POWERUP);
147         /* enable touch detection, 84usec precharge time, 32 usec sense time */
148         omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,
149                            TSC2101_TS_CONFIG_CTRL, TSC2101_ENABLE_TOUCHDETECT);
150         /* 3 msec conversion delays  */
151         omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,
152                            TSC2101_TS_PROG_DELAY, TSC2101_PRG_DELAY);
153         /*
154          * TSC2101-controlled conversions
155          * 12-bit samples
156          * continuous X,Y,Z1,Z2 scan mode
157          * average (mean) 4 samples per coordinate
158          * 1 MHz internal conversion clock
159          * 500 usec panel voltage stabilization delay
160          */
161         omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,
162                            TSC2101_TS_ADC_CTRL, TSC2101_ADC_CONTROL);
163
164         return;
165
166 }
167
168 static void hx_ts_disable(void)
169 {
170         /* stop conversions and power down */
171         omap_tsc2101_write(TOUCHSCREEN_CONTROL_REGISTERS_PAGE,
172                            TSC2101_TS_ADC_CTRL, TSC2101_ADC_POWERDOWN);
173         omap_tsc2101_disable();
174 }
175
176 #ifdef  MODULE
177 static void __exit hx_ts_remove(void)
178 {
179         if (machine_is_omap_h2())
180                 omap_free_gpio(H2_GPIO_NUM);
181         else if (machine_is_omap_h3())
182                 omap_free_gpio(H3_GPIO_NUM);
183 }
184 #endif