diff options
| author | David Brownell <david-b@pacbell.net> | 2006-01-08 16:34:21 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-13 19:29:54 -0500 |
| commit | ffa458c1bd9b6f653008d450f337602f3d52a646 (patch) | |
| tree | 0e42f7d36790dd7088586b32d9c5290d34b10831 /drivers/input/touchscreen | |
| parent | 8ae12a0d85987dc138f8c944cb78a92bf466cea0 (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/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/input/touchscreen/Makefile | 1 | ||||
| -rw-r--r-- | drivers/input/touchscreen/ads7846.c | 621 |
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 | ||
| 12 | if INPUT_TOUCHSCREEN | 12 | if INPUT_TOUCHSCREEN |
| 13 | 13 | ||
| 14 | config 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 | |||
| 14 | config TOUCHSCREEN_BITSY | 27 | config 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 | ||
| 7 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o | ||
| 7 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o | 8 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o |
| 8 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o | 9 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o |
| 9 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 10 | obj-$(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 | |||
| 54 | struct 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 | |||
| 65 | struct 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 | |||
| 123 | static const u8 read_y = READ_12BIT_DFR(y) | ADS_PD10_ADC_ON; | ||
| 124 | static const u8 read_z1 = READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON; | ||
| 125 | static const u8 read_z2 = READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON; | ||
| 126 | static 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 | |||
| 134 | static const u8 ref_on = READ_12BIT_DFR(x) | ADS_PD10_ALL_ON; | ||
| 135 | static 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 | */ | ||
