Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ucb1x00-ts.c
Go to the documentation of this file.
1 /*
2  * Touchscreen driver for UCB1x00-based touchscreens
3  *
4  * Copyright (C) 2001 Russell King, All Rights Reserved.
5  * Copyright (C) 2005 Pavel Machek
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * 21-Jan-2002 <[email protected]> :
12  *
13  * Added support for synchronous A/D mode. This mode is useful to
14  * avoid noise induced in the touchpanel by the LCD, provided that
15  * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin.
16  * It is important to note that the signal connected to the ADCSYNC
17  * pin should provide pulses even when the LCD is blanked, otherwise
18  * a pen touch needed to unblank the LCD will never be read.
19  */
20 #include <linux/module.h>
21 #include <linux/moduleparam.h>
22 #include <linux/init.h>
23 #include <linux/interrupt.h>
24 #include <linux/sched.h>
25 #include <linux/spinlock.h>
26 #include <linux/completion.h>
27 #include <linux/delay.h>
28 #include <linux/string.h>
29 #include <linux/input.h>
30 #include <linux/device.h>
31 #include <linux/freezer.h>
32 #include <linux/slab.h>
33 #include <linux/kthread.h>
34 #include <linux/mfd/ucb1x00.h>
35 
36 #include <mach/collie.h>
37 #include <asm/mach-types.h>
38 
39 
40 
41 struct ucb1x00_ts {
42  struct input_dev *idev;
43  struct ucb1x00 *ucb;
44 
46  unsigned irq_disabled;
48  struct task_struct *rtask;
51 
52  unsigned int adcsync:1;
53 };
54 
55 static int adcsync;
56 
57 static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
58 {
59  struct input_dev *idev = ts->idev;
60 
61  input_report_abs(idev, ABS_X, x);
62  input_report_abs(idev, ABS_Y, y);
63  input_report_abs(idev, ABS_PRESSURE, pressure);
64  input_report_key(idev, BTN_TOUCH, 1);
65  input_sync(idev);
66 }
67 
68 static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
69 {
70  struct input_dev *idev = ts->idev;
71 
72  input_report_abs(idev, ABS_PRESSURE, 0);
73  input_report_key(idev, BTN_TOUCH, 0);
74  input_sync(idev);
75 }
76 
77 /*
78  * Switch to interrupt mode.
79  */
80 static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
81 {
82  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
86 }
87 
88 /*
89  * Switch to pressure mode, and read pressure. We don't need to wait
90  * here, since both plates are being driven.
91  */
92 static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
93 {
94  if (machine_is_collie()) {
96  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
99 
100  udelay(55);
101 
102  return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync);
103  } else {
104  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
108 
109  return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
110  }
111 }
112 
113 /*
114  * Switch to X position mode and measure Y plate. We switch the plate
115  * configuration in pressure mode, then switch to position mode. This
116  * gives a faster response time. Even so, we need to wait about 55us
117  * for things to stabilise.
118  */
119 static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
120 {
121  if (machine_is_collie())
123  else {
124  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
127  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
130  }
131  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
134 
135  udelay(55);
136 
137  return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
138 }
139 
140 /*
141  * Switch to Y position mode and measure X plate. We switch the plate
142  * configuration in pressure mode, then switch to position mode. This
143  * gives a faster response time. Even so, we need to wait about 55us
144  * for things to stabilise.
145  */
146 static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
147 {
148  if (machine_is_collie())
150  else {
151  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
154  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
157  }
158 
159  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
162 
163  udelay(55);
164 
165  return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
166 }
167 
168 /*
169  * Switch to X plate resistance mode. Set MX to ground, PX to
170  * supply. Measure current.
171  */
172 static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts)
173 {
174  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
177  return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
178 }
179 
180 /*
181  * Switch to Y plate resistance mode. Set MY to ground, PY to
182  * supply. Measure current.
183  */
184 static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
185 {
186  ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
189  return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
190 }
191 
192 static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts)
193 {
194  unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
195 
196  if (machine_is_collie())
197  return (!(val & (UCB_TS_CR_TSPX_LOW)));
198  else
199  return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW));
200 }
201 
202 /*
203  * This is a RT kernel thread that handles the ADC accesses
204  * (mainly so we can use semaphores in the UCB1200 core code
205  * to serialise accesses to the ADC).
206  */
207 static int ucb1x00_thread(void *_ts)
208 {
209  struct ucb1x00_ts *ts = _ts;
211  bool frozen, ignore = false;
212  int valid = 0;
213 
214  set_freezable();
215  add_wait_queue(&ts->irq_wait, &wait);
216  while (!kthread_freezable_should_stop(&frozen)) {
217  unsigned int x, y, p;
218  signed long timeout;
219 
220  if (frozen)
221  ignore = true;
222 
223  ucb1x00_adc_enable(ts->ucb);
224 
225  x = ucb1x00_ts_read_xpos(ts);
226  y = ucb1x00_ts_read_ypos(ts);
227  p = ucb1x00_ts_read_pressure(ts);
228 
229  /*
230  * Switch back to interrupt mode.
231  */
232  ucb1x00_ts_mode_int(ts);
234 
235  msleep(10);
236 
237  ucb1x00_enable(ts->ucb);
238 
239 
240  if (ucb1x00_ts_pen_down(ts)) {
242 
243  spin_lock_irq(&ts->irq_lock);
244  if (ts->irq_disabled) {
245  ts->irq_disabled = 0;
246  enable_irq(ts->ucb->irq_base + UCB_IRQ_TSPX);
247  }
248  spin_unlock_irq(&ts->irq_lock);
249  ucb1x00_disable(ts->ucb);
250 
251  /*
252  * If we spat out a valid sample set last time,
253  * spit out a "pen off" sample here.
254  */
255  if (valid) {
256  ucb1x00_ts_event_release(ts);
257  valid = 0;
258  }
259 
260  timeout = MAX_SCHEDULE_TIMEOUT;
261  } else {
262  ucb1x00_disable(ts->ucb);
263 
264  /*
265  * Filtering is policy. Policy belongs in user
266  * space. We therefore leave it to user space
267  * to do any filtering they please.
268  */
269  if (!ignore) {
270  ucb1x00_ts_evt_add(ts, p, x, y);
271  valid = 1;
272  }
273 
275  timeout = HZ / 100;
276  }
277 
278  schedule_timeout(timeout);
279  }
280 
282 
283  ts->rtask = NULL;
284  return 0;
285 }
286 
287 /*
288  * We only detect touch screen _touches_ with this interrupt
289  * handler, and even then we just schedule our task.
290  */
291 static irqreturn_t ucb1x00_ts_irq(int irq, void *id)
292 {
293  struct ucb1x00_ts *ts = id;
294 
295  spin_lock(&ts->irq_lock);
296  ts->irq_disabled = 1;
297  disable_irq_nosync(ts->ucb->irq_base + UCB_IRQ_TSPX);
298  spin_unlock(&ts->irq_lock);
299  wake_up(&ts->irq_wait);
300 
301  return IRQ_HANDLED;
302 }
303 
304 static int ucb1x00_ts_open(struct input_dev *idev)
305 {
306  struct ucb1x00_ts *ts = input_get_drvdata(idev);
307  unsigned long flags = 0;
308  int ret = 0;
309 
310  BUG_ON(ts->rtask);
311 
312  if (machine_is_collie())
313  flags = IRQF_TRIGGER_RISING;
314  else
315  flags = IRQF_TRIGGER_FALLING;
316 
317  ts->irq_disabled = 0;
318 
320  ret = request_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ucb1x00_ts_irq,
321  flags, "ucb1x00-ts", ts);
322  if (ret < 0)
323  goto out;
324 
325  /*
326  * If we do this at all, we should allow the user to
327  * measure and read the X and Y resistance at any time.
328  */
329  ucb1x00_adc_enable(ts->ucb);
330  ts->x_res = ucb1x00_ts_read_xres(ts);
331  ts->y_res = ucb1x00_ts_read_yres(ts);
333 
334  ts->rtask = kthread_run(ucb1x00_thread, ts, "ktsd");
335  if (!IS_ERR(ts->rtask)) {
336  ret = 0;
337  } else {
338  free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts);
339  ts->rtask = NULL;
340  ret = -EFAULT;
341  }
342 
343  out:
344  return ret;
345 }
346 
347 /*
348  * Release touchscreen resources. Disable IRQs.
349  */
350 static void ucb1x00_ts_close(struct input_dev *idev)
351 {
352  struct ucb1x00_ts *ts = input_get_drvdata(idev);
353 
354  if (ts->rtask)
355  kthread_stop(ts->rtask);
356 
357  ucb1x00_enable(ts->ucb);
358  free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts);
359  ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
360  ucb1x00_disable(ts->ucb);
361 }
362 
363 
364 /*
365  * Initialisation.
366  */
367 static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
368 {
369  struct ucb1x00_ts *ts;
370  struct input_dev *idev;
371  int err;
372 
373  ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
374  idev = input_allocate_device();
375  if (!ts || !idev) {
376  err = -ENOMEM;
377  goto fail;
378  }
379 
380  ts->ucb = dev->ucb;
381  ts->idev = idev;
382  ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
383  spin_lock_init(&ts->irq_lock);
384 
385  idev->name = "Touchscreen panel";
386  idev->id.product = ts->ucb->id;
387  idev->open = ucb1x00_ts_open;
388  idev->close = ucb1x00_ts_close;
389  idev->dev.parent = &ts->ucb->dev;
390 
391  idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
392  idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
393 
394  input_set_drvdata(idev, ts);
395 
396  ucb1x00_adc_enable(ts->ucb);
397  ts->x_res = ucb1x00_ts_read_xres(ts);
398  ts->y_res = ucb1x00_ts_read_yres(ts);
400 
401  input_set_abs_params(idev, ABS_X, 0, ts->x_res, 0, 0);
402  input_set_abs_params(idev, ABS_Y, 0, ts->y_res, 0, 0);
403  input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0);
404 
405  err = input_register_device(idev);
406  if (err)
407  goto fail;
408 
409  dev->priv = ts;
410 
411  return 0;
412 
413  fail:
414  input_free_device(idev);
415  kfree(ts);
416  return err;
417 }
418 
419 static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
420 {
421  struct ucb1x00_ts *ts = dev->priv;
422 
423  input_unregister_device(ts->idev);
424  kfree(ts);
425 }
426 
427 static struct ucb1x00_driver ucb1x00_ts_driver = {
428  .add = ucb1x00_ts_add,
429  .remove = ucb1x00_ts_remove,
430 };
431 
432 static int __init ucb1x00_ts_init(void)
433 {
434  return ucb1x00_register_driver(&ucb1x00_ts_driver);
435 }
436 
437 static void __exit ucb1x00_ts_exit(void)
438 {
439  ucb1x00_unregister_driver(&ucb1x00_ts_driver);
440 }
441 
442 module_param(adcsync, int, 0444);
443 module_init(ucb1x00_ts_init);
444 module_exit(ucb1x00_ts_exit);
445 
446 MODULE_AUTHOR("Russell King <[email protected]>");
447 MODULE_DESCRIPTION("UCB1x00 touchscreen driver");
448 MODULE_LICENSE("GPL");