sync hh.org
[hh.org.git] / arch / arm / mach-pxa / htcsable / htcsable_ts2.c
blob358c75c031069ce008d402885fb1ae687e61f2bc
1 /* Touch screen driver for the TI something-or-other
3 * Copyright © 2005 SDG Systems, LLC
5 * Based on code that was based on the SAMCOP driver.
6 * Copyright © 2003, 2004 Compaq Computer Corporation.
8 * Use consistent with the GNU GPL is permitted,
9 * provided that this copyright notice is
10 * preserved in its entirety in all copies and derived works.
12 * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
13 * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
14 * FITNESS FOR ANY PARTICULAR PURPOSE.
16 * Author: Keith Packard <keith.packard@hp.com>
17 * May 2003
19 * Updates:
21 * 2004-02-11 Michael Opdenacker Renamed names from samcop to shamcop,
22 * Goal:support HAMCOP and SAMCOP.
23 * 2004-02-14 Michael Opdenacker Temporary fix for device id handling
25 * 2005-02-18 Aric Blumer Converted basic structure to support hx4700
27 * 2005-06-07 Aric Blumer Added tssim device handling so we can
28 * hook in the fbvncserver.
31 #include <linux/module.h>
32 #include <linux/version.h>
33 #include <linux/config.h>
35 #include <linux/init.h>
36 #include <linux/fs.h>
37 #include <linux/cdev.h>
38 #include <linux/interrupt.h>
39 #include <linux/sched.h>
40 #include <linux/pm.h>
41 #include <linux/delay.h>
42 #include <linux/input.h>
43 #include <linux/platform_device.h>
44 #include <linux/irq.h>
46 #include <asm/arch/hardware.h>
47 #include <asm/mach/irq.h>
48 #include <asm/io.h>
50 #include <asm/arch/pxa-regs.h>
51 #include <asm/arch/htcsable-gpio.h>
52 #include <asm/arch/htcsable-asic.h>
54 enum touchscreen_state {
55 STATE_WAIT_FOR_TOUCH, /* Waiting for a PEN interrupt */
56 STATE_SAMPLING /* Actively sampling ADC */
59 struct touchscreen_data {
60 enum touchscreen_state state;
61 struct timer_list timer;
62 int irq;
63 struct input_dev *input;
66 static unsigned long poll_sample_time = 10; /* Sample every 10 milliseconds */
68 static struct touchscreen_data *ts_data;
70 static int irqblock;
72 module_param(poll_sample_time, ulong, 0644);
73 MODULE_PARM_DESC(poll_sample_time, "Poll sample time");
75 static inline void
76 report_touchpanel(struct touchscreen_data *ts, int pressure, int x, int y)
78 input_report_abs(ts->input, ABS_PRESSURE, pressure);
79 input_report_abs(ts->input, ABS_X, x);
80 input_report_abs(ts->input, ABS_Y, y);
81 input_sync(ts->input);
84 static void start_read(struct touchscreen_data *touch);
86 static irqreturn_t
87 pen_isr(int irq, void *irq_desc, struct pt_regs *regs)
89 /* struct touchscreen_data *ts = dev_id->data; */
90 struct touchscreen_data *ts = ts_data;
92 // printk("in pen_isr: ts->irq=%d\n",ts->irq);
94 if(irq == ts->irq /* && !irqblock */) {
95 irqblock = 1;
98 * Disable the pen interrupt. It's reenabled when the user lifts the
99 * pen.
101 disable_irq(ts->irq);
103 if (ts->state == STATE_WAIT_FOR_TOUCH) {
104 ts->state = STATE_SAMPLING;
105 start_read(ts);
106 } else {
107 /* Shouldn't happen */
108 printk(KERN_ERR "Unexpected ts interrupt\n");
112 return IRQ_HANDLED;
115 static void
116 ssp_init(void)
119 pxa_set_cken(CKEN3_SSP2, 1);
121 /* *** Set up the SPI Registers *** */
122 SSCR0_P2 =
123 (1 << 20) /* Extended Data Size Select */
124 | (6 << 8) /* Serial Clock Rate */
125 | (0 << 7) /* Synchronous Serial Enable (Disable for now) */
126 | (0 << 4) /* Motorola SPI Interface */
127 | (7 << 0) /* Data Size Select (24-bit) */
129 SSCR1_P2 = 0;
130 SSPSP_P2 = 0;
132 /* Clear the Status */
133 SSSR_P2 = SSSR_P2 & 0x00fcfffc;
135 /* Now enable it */
136 SSCR0_P2 =
137 (1 << 20) /* Extended Data Size Select */
138 | (6 << 8) /* Serial Clock Rate */
139 | (1 << 7) /* Synchronous Serial Enable */
140 | (0 << 4) /* Motorola SPI Interface */
141 | (7 << 0) /* Data Size Select (24-bit) */
143 /* enable_irq(HX4700_IRQ(TOUCHPANEL_IRQ_N)); */
147 static void
148 start_read(struct touchscreen_data *touch)
150 unsigned long inc = (poll_sample_time * HZ) / 1000;
151 int i;
153 /* Write here to the serial port. We request X and Y only for now.
154 * Then we have to wait for poll_sample_time before we read out the serial
155 * port. Then, when we read it out, we check to see if the pen is still
156 * down. If so, then we issue another request here.
158 #define TS_SAMPLES 7
161 * We do four samples for each, and throw out the highest and lowest, then
162 * average the other two.
165 for(i = 0; i < TS_SAMPLES; i++) {
166 while(!(SSSR_P2 & (1 << 2)))
168 /* It's not full. Write the command for X */
169 SSDR_P2 = 0xd10000 /* | (lower_bits << 0) */; /* May want bits 0 and 1 set for keeping power up */
172 for(i = 0; i < TS_SAMPLES; i++) {
173 while(!(SSSR_P2 & (1 << 2)))
175 /* It's not full. Write the command for Y */
176 SSDR_P2 = 0x910000 /* | (lower_bits << 0) */; /* May want bits 0 and 1 set for keeping power up */
180 * Enable the timer. We should get an interrupt, but we want keep a timer
181 * to ensure that we can detect missing data
183 mod_timer(&touch->timer, jiffies + inc);
186 static void
187 ts_timer_callback(unsigned long data)
189 struct touchscreen_data *ts = (struct touchscreen_data *)data;
190 int x, a[TS_SAMPLES], y;
191 static int oldx, oldy;
192 int ssrval;
195 * Check here to see if there is anything in the SPI FIFO. If so,
196 * return it if there has been a change. If not, then we have a
197 * timeout. Generate an erro somehow.
199 ssrval = SSSR_P2;
201 // printk("SSSR_P2: %x\n",ssrval);
203 if(ssrval & (1 << 3)) { /* Look at Rx Not Empty bit */
204 int number_of_entries_in_fifo;
206 /* The FIFO is not emtpy. Good! Now make sure there are at least two
207 * entries. (Should be two exactly.) */
209 number_of_entries_in_fifo = ((ssrval >> 12) & 0xf) + 1;
211 // printk("in_fifo: %d\n",number_of_entries_in_fifo);
213 if(number_of_entries_in_fifo < TS_SAMPLES * 2) {
214 /* Not ready yet. Come back later. */
215 unsigned long inc = (poll_sample_time * HZ) / 1000;
216 mod_timer(&ts->timer, jiffies + inc);
217 return;
220 if(number_of_entries_in_fifo == TS_SAMPLES * 2) {
221 int i, j;
222 #if 0
223 int junk;
224 junk= SSDR_P2;
225 #endif
227 for(i = 0; i < TS_SAMPLES; i++) {
228 a[i] = SSDR_P2;
229 // printk("a[ %d ]= %d of %d\n",i,a[i],TS_SAMPLES);
231 /* Sort them (bubble) */
232 for(j = TS_SAMPLES - 1; j > 0; j--) {
233 for(i = 0; i < j; i++) {
234 if(a[i] > a[i + 1]) {
235 int tmp;
236 tmp = a[i+1];
237 a[i+1] = a[i];
238 a[i] = tmp;
243 /* Take the average of the middle two */
244 /* x = (a[TS_SAMPLES/2 - 1] + a[TS_SAMPLES/2] + a[TS_SAMPLES/2+1] + a[TS_SAMPLES/2+2]) >> 2; */
245 x = a[TS_SAMPLES/2];
247 for(i = 0; i < TS_SAMPLES; i++) {
248 a[i] = SSDR_P2;
250 /* Sort them (bubble) */
251 for(j = TS_SAMPLES - 1; j > 0; j--) {
252 for(i = 0; i < j; i++) {
253 if(a[i] > a[i + 1]) {
254 int tmp;
255 tmp = a[i+1];
256 a[i+1] = a[i];
257 a[i] = tmp;
263 /* Take the average of the middle two */
264 /* y = (a[TS_SAMPLES/2 - 1] + a[TS_SAMPLES/2] + a[TS_SAMPLES/2+1] + a[TS_SAMPLES/2+2]) >> 2; */
265 y = a[TS_SAMPLES/2];
266 } else {
267 /* We have an error! Too many entries. */
268 printk(KERN_ERR "TS: Expected %d entries. Got %d\n", TS_SAMPLES*2, number_of_entries_in_fifo);
269 /* Try to clear the FIFO */
270 while(number_of_entries_in_fifo--) {
271 (void)SSDR_P2;
273 if(GET_HTCSABLE_GPIO(TOUCHPANEL_IRQ_N) == 0) {
274 start_read(ts);
276 return;
278 } else {
279 /* Not ready yet. Come back later. */
280 unsigned long inc = (poll_sample_time * HZ) / 1000;
281 mod_timer(&ts->timer, jiffies + inc);
282 return;
286 * Now we check to see if the pen is still down. If it is, then call
287 * start_read().
290 // printk("statusa: %x bit=%x\n",statusa,statusa & (1<<GPIOA_TOUCHSCREEN_N));
292 if(GET_HTCSABLE_GPIO(TOUCHPANEL_IRQ_N) == 0) {
293 /* Still down */
294 if(oldx != x || oldy != y) {
295 oldx = x;
296 oldy = y;
297 report_touchpanel(ts, 1, x, y);
299 start_read(ts);
300 } else {
301 /* Up */
302 report_touchpanel(ts, 0, 0, 0);
303 irqblock = 0;
304 ts->state = STATE_WAIT_FOR_TOUCH;
305 /* Re-enable pen down interrupt */
306 enable_irq(ts->irq);
310 static int
311 ts_probe (struct device *dev)
313 int retval;
314 struct touchscreen_data *ts;
316 printk("htcsable: ts_probe\n");
318 ts = ts_data = kmalloc (sizeof (*ts), GFP_KERNEL);
319 if (ts == NULL) {
320 printk( KERN_NOTICE "htcsable_ts: unable to allocate memory\n" );
321 return -ENOMEM;
323 memset (ts, 0, sizeof (*ts));
326 /* *** Set up the input subsystem stuff *** */
327 // memset(ts->input, 0, sizeof(struct input_dev));
328 ts->input = input_allocate_device();
329 if (ts->input == NULL) {
330 printk( KERN_NOTICE "htcsable_ts: unable to allocation touchscreen input\n" );
331 kfree(ts);
332 return -ENOMEM;
334 ts->input->evbit[0] = BIT(EV_ABS);
335 ts->input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
336 ts->input->absmin[ABS_X] = 0;
337 ts->input->absmax[ABS_X] = 32767;
338 ts->input->absmin[ABS_Y] = 0;
339 ts->input->absmax[ABS_Y] = 32767;
340 ts->input->absmin[ABS_PRESSURE] = 0;
341 ts->input->absmax[ABS_PRESSURE] = 1;
343 ts->input->name = "htcsable_ts";
344 ts->input->phys = "touchscreen/htcsable_ts";
345 ts->input->private = ts;
347 input_register_device(ts->input);
349 ts->timer.function = ts_timer_callback;
350 ts->timer.data = (unsigned long)ts;
351 ts->state = STATE_WAIT_FOR_TOUCH;
352 init_timer (&ts->timer);
354 // INIT_WORK(&serial_work, start_read, ts);
356 dev_set_drvdata(dev, ts);
358 /* *** Initialize the SSP interface *** */
359 ssp_init();
361 // down(&serial_mutex);
362 /* Make sure the device is in such a state that it can give pen
363 * interrupts. */
364 while(!(SSSR_P2 & (1 << 2)))
366 SSDR_P2 = 0xd10000;
368 for(retval = 0; retval < 100; retval++) {
369 if(SSSR_P2 & (1 << 3)) {
370 while(SSSR_P2 & (1 << 3)) {
371 (void)SSDR_P2;
373 break;
375 mdelay(1);
377 // up(&serial_mutex);
380 ts->irq = HTCSABLE_IRQ( TOUCHPANEL_IRQ_N );
382 retval = request_irq(ts->irq, pen_isr, SA_INTERRUPT, "htcsable_ts", ts);
383 if(retval) {
384 printk("Unable to get interrupt\n");
385 input_unregister_device (ts->input);
386 return -ENODEV;
388 set_irq_type(ts->irq, IRQ_TYPE_EDGE_FALLING);
390 return 0;
393 static int
394 ts_remove (struct device *dev)
396 struct touchscreen_data *ts = dev_get_drvdata(dev);
398 input_unregister_device (ts->input);
399 del_timer_sync (&ts->timer);
400 free_irq (ts->irq, ts);
402 kfree(ts);
403 pxa_set_cken(CKEN3_SSP2, 0);
404 return 0;
407 static int
408 ts_suspend (struct device *dev, pm_message_t state)
410 struct touchscreen_data *ts = dev_get_drvdata(dev);
412 disable_irq(ts->irq);
414 printk("htcsable_ts2_suspend: called.\n");
415 return 0;
418 static int
419 ts_resume (struct device *dev)
421 struct touchscreen_data *ts = dev_get_drvdata(dev);
423 ts->state = STATE_WAIT_FOR_TOUCH;
424 ssp_init();
425 enable_irq(ts->irq);
427 printk("htcsable_ts2_resume: called.\n");
428 return 0;
431 static struct device_driver ts_driver = {
432 .name = "htcsable_ts",
433 .bus = &platform_bus_type,
434 .probe = ts_probe,
435 .remove = ts_remove,
436 .suspend = ts_suspend,
437 .resume = ts_resume
441 static int
442 ts_module_init (void)
444 printk(KERN_NOTICE "HTC Sable Touch Screen Driver\n");
446 return driver_register(&ts_driver);
449 static void
450 ts_module_cleanup (void)
452 driver_unregister (&ts_driver);
455 module_init(ts_module_init);
456 module_exit(ts_module_cleanup);
458 MODULE_LICENSE("GPL");
459 MODULE_AUTHOR("Aric Blumer, SDG Systems, LLC");
460 MODULE_DESCRIPTION("HTC Sable Touch Screen Driver");