sync hh.org
[hh.org.git] / arch / arm / mach-pxa / himalaya / himalaya_ts3.c
blob004695559eee433cd4d7a13b7733cdafc3ee9788
1 /*
2 * Driver interface to the touchscreen on the HTC Himalaya
4 * Copyright (C) 2004 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
5 * Copyright (C) 2004 w4xy@xanadux.org
7 * Use consistent with the GNU GPL is permitted,
8 * provided that this copyright notice is
9 * preserved in its entirety in all copies and derived works.
11 * HAL code based on h5400_asic_io.c, which is
12 * Copyright (C) 2003 Compaq Computer Corporation.
14 * Driver based on the h1900_ts.c, which is
15 * Copyright (C) 2003, Joshua Wise <joshua at joshuawise.com>
19 #include <linux/module.h>
20 #include <linux/version.h>
21 #include <linux/config.h>
23 #include <linux/init.h>
24 #include <linux/fs.h>
25 #include <linux/interrupt.h>
26 #include <linux/sched.h>
27 #include <linux/pm.h>
28 #include <linux/sysctl.h>
29 #include <linux/proc_fs.h>
30 #include <linux/delay.h>
31 #include <linux/input.h>
33 #if 0
34 #include <asm/arch/hardware.h>
35 //#include <asm/arch-sa1100/h3600.h>
36 //#include <asm/arch-sa1100/SA-1100.h>
38 #include <asm/mach/irq.h>
39 /*#include <asm/arch-pxa/himalaya-gpio.h>*/
40 #include <asm/hardware/ipaq-asic3.h>
41 #endif
43 #include <asm/irq.h>
44 #include <asm/arch/hardware.h>
46 #include <asm/mach-types.h>
47 #include <asm/mach/irq.h>
48 #include <asm/mach/arch.h>
49 #include <asm/mach/map.h>
50 #include <asm/arch/udc.h>
52 #include <asm/arch/himalaya-gpio.h>
53 #include <asm/hardware/ipaq-asic3.h>
54 #include <asm/arch-pxa/h3900-asic.h>
55 #include <linux/soc/asic3_base.h>
56 #include "tsc2200.h"
57 #include "pxa_nssp.h"
58 #include <asm/arch/pxa-regs.h>
59 #include <asm/apm.h>
61 extern struct platform_device himalaya_asic3;
63 static char ts_name[] = "tsc2200_ts";
64 static char ts_phys[] = "touchscreen/tsc2200";
66 struct input_dev ts_input_dev;
67 static struct work_struct ts_workqueue;
68 static struct work_struct ts_readworkqueue;
69 static int protected;
71 #define SAMPLE_TIMEOUT 8 /* sample every 10ms */
72 #define CONVERSION_TIMEOUT 2 /* wait 1ms for a conversion */
73 #undef UBERDEBUGGY
75 #define GPIO_NR_HIMALAYA_TS_IRQ_N 5
76 #define HIMALAYA_TS_IRQ IRQ_GPIO(GPIO_NR_HIMALAYA_TS_IRQ_N)
78 //static struct timer_list ts_timer;
80 typedef enum
82 TSC_DO_NOTHING = 0,
83 TSC_PEN_DOWN_EXPECT_CONVERT,
84 TSC_PEN_DOWN_CONVERT_DONE,
85 TSC_PEN_UP,
87 } TSC_PEN_STATE;
89 static int tsc_state = TSC_DO_NOTHING;
91 static void ts_tsc2200_start_conv(void)
93 tsc2200_write(TSC2200_CTRLREG_ADC,
94 // TSC2200_CTRLREG_ADC_PSM_TSC2200 |
95 TSC2200_CTRLREG_ADC_AD0 |
96 TSC2200_CTRLREG_ADC_RES (TSC2200_CTRLREG_ADC_RES_12BITP) |
97 TSC2200_CTRLREG_ADC_AVG (TSC2200_CTRLREG_ADC_8AVG) |
98 TSC2200_CTRLREG_ADC_CL (TSC2200_CTRLREG_ADC_CL_2MHZ_12BIT) |
99 TSC2200_CTRLREG_ADC_PV (TSC2200_CTRLREG_ADC_PV_500uS) );
100 // printk("%s: %X.\n", __FUNCTION__, tsc2200_read(TSC2200_CTRLREG_ADC));
103 static void ts_read(struct input_dev *dev)
105 unsigned int bytes[4];
107 /* read positions. */
108 bytes[0] = tsc2200_read(TSC2200_DATAREG_X);
109 bytes[1] = tsc2200_read(TSC2200_DATAREG_Y);
110 bytes[2] = tsc2200_read(TSC2200_DATAREG_Z1);
111 bytes[3] = tsc2200_read(TSC2200_DATAREG_Z2);
113 input_report_abs(dev, ABS_X, bytes[0] & 0xfff);
114 input_report_abs(dev, ABS_Y, bytes[1] & 0xfff);
115 input_report_abs(dev, ABS_PRESSURE, 0xfff);
116 // input_report_abs(dev, ABS_PRESSURE, bytes[2] & 0xfff);
117 input_sync(dev);
119 #if 0
120 printk("%s: %03X-%03x-%03x-%03x / %i\n", __FUNCTION__, bytes[0], bytes[1], bytes[2], bytes[3], tsc2200_dav());
121 printk("%s: BAT1: %03X\nBAT2: %03x\nAUX1: %03x\nAUX2: %03x\nTEMP1: %03x\nTEMP2: %03x\n", __FUNCTION__, tsc2200_read(TSC2200_DATAREG_BAT1), tsc2200_read(TSC2200_DATAREG_BAT2), tsc2200_read(TSC2200_DATAREG_AUX1), tsc2200_read(TSC2200_DATAREG_AUX2), tsc2200_read(TSC2200_DATAREG_TEMP1), tsc2200_read(TSC2200_DATAREG_TEMP2));
122 #endif
125 static void ts_up(struct input_dev *dev)
127 input_report_abs(dev, ABS_PRESSURE, 0x0);
128 input_sync(dev);
131 static int ts_pressed(void)
133 return ( GPLR(GPIO_NR_HIMALAYA_TS_IRQ_N) & GPIO_bit(GPIO_NR_HIMALAYA_TS_IRQ_N) ) ? 0 : 1;
136 static irqreturn_t ts_irq(int irq, void* data, struct pt_regs *regs)
138 // printk("%s: got interrupt...\n", __FUNCTION__);
139 disable_irq(HIMALAYA_TS_IRQ);
140 schedule_work(&ts_workqueue);
142 return IRQ_HANDLED;
145 static void ts_work(void* data)
147 struct input_dev *dev = (struct input_dev *)data;
149 printk("ASIC3 A: %X.\n", asic3_get_gpio_status_a(&himalaya_asic3.dev));
150 // printk("%i: workqueue fired...\n", jiffies);
151 if ( !protected ) {
152 down_interruptible(&tsc2200_sem);
153 // printk("protected.\n");
154 protected++;
155 // ts_tsc2200_initialise();
156 // printk("initialised.\n");
157 // tsc2200_write(TSC2200_CTRLREG_ADC, 0x8506);
158 ts_tsc2200_start_conv();
160 // printk("0: %X\n", tsc2200_read(TSC2200_CTRLREG_ADC));
161 // printk("%s: DAV=%i, pressed=%i.\n", __FUNCTION__, tsc2200_dav(), ts_pressed());
162 // msleep(3);
163 while ( !(tsc2200_read(TSC2200_CTRLREG_ADC) & 0x4000) && !tsc2200_dav()) {
164 // printk("1: %X\n", tsc2200_read(TSC2200_CTRLREG_ADC));
165 msleep(1);
167 #if 0
168 while ( !tsc2200_dav() ) {
169 // printk("2: %X\n", tsc2200_read(TSC2200_CTRLREG_ADC));
171 #endif
172 if ( ts_pressed() ) {
173 // printk("3: %X\n", tsc2200_read(TSC2200_CTRLREG_ADC));
174 schedule_work(&ts_workqueue);
175 ts_read(dev);
176 } else {
177 // printk("4: %X\n", tsc2200_read(TSC2200_CTRLREG_ADC));
178 protected--;
179 ts_up(dev);
180 // printk("unprotecting.\n");
181 up(&tsc2200_sem);
182 enable_irq(HIMALAYA_TS_IRQ);
186 int ts_tsc2200_open( struct input_dev *dev )
188 if ( !machine_is_himalaya() ) {
189 printk("%s: unknown iPAQ model %s\n", __FUNCTION__, h3600_generic_name() );
190 return -ENODEV;
193 printk("%s: init work queue...\n", __FUNCTION__);
194 INIT_WORK(&ts_workqueue, ts_work, dev);
195 // INIT_WORK(&ts_readworkqueue, ts_readwork, dev);
197 printk("%s: set irq...\n", __FUNCTION__);
198 /* now set up the pen action GPIO */
200 pxa_gpio_mode(GPIO_NR_HIMALAYA_TS_IRQ_N | GPIO_IN);
201 set_irq_type(HIMALAYA_TS_IRQ, IRQT_FALLING);
202 request_irq (HIMALAYA_TS_IRQ, ts_irq, SA_SAMPLE_RANDOM, "himalaya_ts", (void*)&ts_input_dev);
204 udelay(300);
205 printk("%s: %X\n", __FUNCTION__, tsc2200_read(TSC2200_CTRLREG_ADC) );
206 udelay(300);
207 // enable_irq(HIMALAYA_TS_IRQ);
209 return 0;
212 void ts_tsc2200_close( struct input_dev *dev )
214 printk("%s: closing tsc2200.\n", __FUNCTION__);
216 disable_irq(HIMALAYA_TS_IRQ);
218 /* make sure to free the IRQ... */
219 free_irq(HIMALAYA_TS_IRQ, dev);
221 flush_scheduled_work();
223 /* now free the timer... */
224 // del_timer_sync (&ts_timer);
227 static void ts_release(struct device *dev)
232 struct device ts_tsc2200_dev = {
233 .parent = &nssp_bus,
234 .bus = &nssp_bus_type,
235 .bus_id = "ts_tsc2200",
236 .release = ts_release,
239 static int ts_setup(struct input_dev *dev)
241 memset(dev, 0x0, sizeof(*dev));
243 init_input_dev(dev);
245 dev->private = dev;
247 dev->name = ts_name;
248 dev->phys = ts_phys;
249 dev->open = ts_tsc2200_open;
250 dev->close = ts_tsc2200_close;
252 set_bit(EV_ABS, dev->evbit);
254 set_bit(ABS_X, dev->absbit);
255 set_bit(ABS_Y, dev->absbit);
256 set_bit(ABS_PRESSURE, dev->absbit);
257 dev->absmin[ABS_PRESSURE] = 0;
258 dev->absmax[ABS_PRESSURE] = 0xfff;
259 dev->absmax[ABS_X] = 0xfff;
260 dev->absmax[ABS_Y] = 0xfff;
261 dev->absfuzz[ABS_X] = 2;
262 dev->absfuzz[ABS_Y] = 2;
263 dev->absflat[ABS_X] = 4;
264 dev->absflat[ABS_Y] = 4;
266 dev->id.bustype = BUS_PXA_NSSP;
267 dev->id.vendor = 0xffff;
268 dev->id.product = 0xffff;
269 dev->id.version = 0xffff;
271 dev->dev = &ts_tsc2200_dev;
273 device_register(dev->dev);
274 input_register_device(dev);
276 return 0;
279 static int __init ts_init(void)
281 ts_setup (&ts_input_dev);
283 return 0;
286 static void __exit ts_exit(void)
288 device_unregister(&ts_tsc2200_dev);
289 input_unregister_device(&ts_input_dev);
292 module_init(ts_init)
293 module_exit(ts_exit)
295 MODULE_AUTHOR("Matthias Burghardt");
296 MODULE_DESCRIPTION("Touchscreen (TI TSC2200) support for the HTC Himalaya");