aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2006-01-08 16:34:21 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-13 19:29:54 -0500
commitffa458c1bd9b6f653008d450f337602f3d52a646 (patch)
tree0e42f7d36790dd7088586b32d9c5290d34b10831 /drivers/input/touchscreen
parent8ae12a0d85987dc138f8c944cb78a92bf466cea0 (diff)
[PATCH] spi: ads7846 driver
This is a driver for the ADS7846 touchscreen sensor, derived from the corgi_ts and omap_ts drivers. Key differences from those two: - Uses the new SPI framework (minimalist version) - <linux/spi/ads7846.h> abstracts board-specific touchscreen info - Sysfs attributes for the temperature and voltage sensors - Uses fewer ARM-specific IRQ primitives The temperature and voltage sensors show up in sysfs like this: $ pwd /sys/devices/platform/omap-uwire/spi2.0 $ ls bus@ input:event0@ power/ temp1 vbatt driver@ modalias temp0 vaux $ cat modalias ads7846 $ cat temp0 991 $ cat temp1 1177 $ So far only basic testing has been done. There's a fair amount of hardware that uses this sensor, and which also runs Linux, which should eventually be able to use this driver. One portability note may be of special interest. It turns out that not all SPI controllers are happy issuing requests that do things like "write 8 bit command, read 12 bit response". Most of them seem happy to handle various word sizes, so the issue isn't "12 bit response" but rather "different rx and tx write sizes", despite that being a common MicroWire convention. So this version of the driver no longer reads 12 bit native-endian words; it reads 16-bit big-endian responses, then byteswaps them and shifts the results to discard the noise. Signed-off-by: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/Kconfig13
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/ads7846.c621
3 files changed, 635 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 21d55ed4b88a..2c674023a6ac 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -11,6 +11,19 @@ menuconfig INPUT_TOUCHSCREEN
11 11
12if INPUT_TOUCHSCREEN 12if INPUT_TOUCHSCREEN
13 13
14config TOUCHSCREEN_ADS7846
15 tristate "ADS 7846 based touchscreens"
16 depends on SPI_MASTER
17 help
18 Say Y here if you have a touchscreen interface using the
19 ADS7846 controller, and your board-specific initialization
20 code includes that in its table of SPI devices.
21
22 If unsure, say N (but it's safe to say "Y").
23
24 To compile this driver as a module, choose M here: the
25 module will be called ads7846.
26
14config TOUCHSCREEN_BITSY 27config TOUCHSCREEN_BITSY
15 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" 28 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
16 depends on SA1100_BITSY 29 depends on SA1100_BITSY
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 6842869c9a26..5e5557c43121 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -4,6 +4,7 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
7obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o 8obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
8obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o 9obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
9obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o 10obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
new file mode 100644
index 000000000000..24ff6c5a4021
--- /dev/null
+++ b/drivers/input/touchscreen/ads7846.c
@@ -0,0 +1,621 @@
1/*
2 * ADS7846 based touchscreen and sensor driver
3 *
4 * Copyright (c) 2005 David Brownell
5 *
6 * Using code from:
7 * - corgi_ts.c
8 * Copyright (C) 2004-2005 Richard Purdie
9 * - omap_ts.[hc], ads7846.h, ts_osk.c
10 * Copyright (C) 2002 MontaVista Software
11 * Copyright (C) 2004 Texas Instruments
12 * Copyright (C) 2005 Dirk Behme
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18#include <linux/device.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/input.h>
22#include <linux/interrupt.h>
23#include <linux/slab.h>
24#include <linux/spi/spi.h>
25#include <linux/spi/ads7846.h>
26
27#ifdef CONFIG_ARM
28#include <asm/mach-types.h>
29#ifdef CONFIG_ARCH_OMAP
30#include <asm/arch/gpio.h>
31#endif
32
33#else
34#define set_irq_type(irq,type) do{}while(0)
35#endif
36
37
38/*
39 * This code has been lightly tested on an ads7846.
40 * Support for ads7843 and ads7845 has only been stubbed in.
41 *
42 * Not yet done: investigate the values reported. Are x/y/pressure
43 * event values sane enough for X11? How accurate are the temperature
44 * and voltage readings? (System-specific calibration should support
45 * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.)
46 *
47 * app note sbaa036 talks in more detail about accurate sampling...
48 * that ought to help in situations like LCDs inducing noise (which
49 * can also be helped by using synch signals) and more generally.
50 */
51
52#define TS_POLL_PERIOD msecs_to_jiffies(10)
53
54struct ts_event {
55 /* For portability, we can't read 12 bit values using SPI (which
56 * would make the controller deliver them as native byteorder u16
57 * with msbs zeroed). Instead, we read them as two 8-byte values,
58 * which need byteswapping then range adjustment.
59 */
60 __be16 x;
61 __be16 y;
62 __be16 z1, z2;
63};
64
65struct ads7846 {
66 struct input_dev input;
67 char phys[32];
68
69 struct spi_device *spi;
70 u16 model;
71 u16 vref_delay_usecs;
72 u16 x_plate_ohms;
73
74 struct ts_event tc;
75
76 struct spi_transfer xfer[8];
77 struct spi_message msg;
78
79 spinlock_t lock;
80 struct timer_list timer; /* P: lock */
81 unsigned pendown:1; /* P: lock */
82 unsigned pending:1; /* P: lock */
83// FIXME remove "irq_disabled"
84 unsigned irq_disabled:1; /* P: lock */
85};
86
87/* leave chip selected when we're done, for quicker re-select? */
88#if 0
89#define CS_CHANGE(xfer) ((xfer).cs_change = 1)
90#else
91#define CS_CHANGE(xfer) ((xfer).cs_change = 0)
92#endif
93
94/*--------------------------------------------------------------------------*/
95
96/* The ADS7846 has touchscreen and other sensors.
97 * Earlier ads784x chips are somewhat compatible.
98 */
99#define ADS_START (1 << 7)
100#define ADS_A2A1A0_d_y (1 << 4) /* differential */
101#define ADS_A2A1A0_d_z1 (3 << 4) /* differential */
102#define ADS_A2A1A0_d_z2 (4 << 4) /* differential */
103#define ADS_A2A1A0_d_x (5 << 4) /* differential */
104#define ADS_A2A1A0_temp0 (0 << 4) /* non-differential */
105#define ADS_A2A1A0_vbatt (2 << 4) /* non-differential */
106#define ADS_A2A1A0_vaux (6 << 4) /* non-differential */
107#define ADS_A2A1A0_temp1 (7 << 4) /* non-differential */
108#define ADS_8_BIT (1 << 3)
109#define ADS_12_BIT (0 << 3)
110#define ADS_SER (1 << 2) /* non-differential */
111#define ADS_DFR (0 << 2) /* differential */
112#define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */
113#define ADS_PD10_ADC_ON (1 << 0) /* ADC on */
114#define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */
115#define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */
116
117#define MAX_12BIT ((1<<12)-1)
118
119/* leave ADC powered up (disables penirq) between differential samples */
120#define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \
121 | ADS_12_BIT | ADS_DFR)
122
123static const u8 read_y = READ_12BIT_DFR(y) | ADS_PD10_ADC_ON;
124static const u8 read_z1 = READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON;
125static const u8 read_z2 = READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON;
126static const u8 read_x = READ_12BIT_DFR(x) | ADS_PD10_PDOWN; /* LAST */
127
128/* single-ended samples need to first power up reference voltage;
129 * we leave both ADC and VREF powered
130 */
131#define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \
132 | ADS_12_BIT | ADS_SER)
133
134static const u8 ref_on = READ_12BIT_DFR(x) | ADS_PD10_ALL_ON;
135static const u8 ref_off = READ_12BIT_DFR(y) | ADS_PD10_PDOWN;
136
137/*--------------------------------------------------------------------------*/
138
139/*
140 * Non-touchscreen sensors only use single-ended conversions.
141 */