xref: /linux/drivers/input/touchscreen/ads7846.c (revision c9e617a563ad646239270fa2222cdb06966cf1fa)
1ffa458c1SDavid Brownell /*
2ffa458c1SDavid Brownell  * ADS7846 based touchscreen and sensor driver
3ffa458c1SDavid Brownell  *
4ffa458c1SDavid Brownell  * Copyright (c) 2005 David Brownell
57de90a8cSImre Deak  * Copyright (c) 2006 Nokia Corporation
67de90a8cSImre Deak  * Various changes: Imre Deak <imre.deak@nokia.com>
7ffa458c1SDavid Brownell  *
8ffa458c1SDavid Brownell  * Using code from:
9ffa458c1SDavid Brownell  *  - corgi_ts.c
10ffa458c1SDavid Brownell  *	Copyright (C) 2004-2005 Richard Purdie
11ffa458c1SDavid Brownell  *  - omap_ts.[hc], ads7846.h, ts_osk.c
12ffa458c1SDavid Brownell  *	Copyright (C) 2002 MontaVista Software
13ffa458c1SDavid Brownell  *	Copyright (C) 2004 Texas Instruments
14ffa458c1SDavid Brownell  *	Copyright (C) 2005 Dirk Behme
15ffa458c1SDavid Brownell  *
16ffa458c1SDavid Brownell  *  This program is free software; you can redistribute it and/or modify
17ffa458c1SDavid Brownell  *  it under the terms of the GNU General Public License version 2 as
18ffa458c1SDavid Brownell  *  published by the Free Software Foundation.
19ffa458c1SDavid Brownell  */
20ffa458c1SDavid Brownell #include <linux/device.h>
21ffa458c1SDavid Brownell #include <linux/init.h>
22ffa458c1SDavid Brownell #include <linux/delay.h>
23ffa458c1SDavid Brownell #include <linux/input.h>
24ffa458c1SDavid Brownell #include <linux/interrupt.h>
25ffa458c1SDavid Brownell #include <linux/slab.h>
26ffa458c1SDavid Brownell #include <linux/spi/spi.h>
27ffa458c1SDavid Brownell #include <linux/spi/ads7846.h>
283ac8bf07SAndrew Morton #include <asm/irq.h>
29ffa458c1SDavid Brownell 
30ffa458c1SDavid Brownell #ifdef	CONFIG_ARM
31ffa458c1SDavid Brownell #include <asm/mach-types.h>
32ffa458c1SDavid Brownell #ifdef	CONFIG_ARCH_OMAP
33ffa458c1SDavid Brownell #include <asm/arch/gpio.h>
34ffa458c1SDavid Brownell #endif
35ffa458c1SDavid Brownell #endif
36ffa458c1SDavid Brownell 
37ffa458c1SDavid Brownell 
38ffa458c1SDavid Brownell /*
397de90a8cSImre Deak  * This code has been tested on an ads7846 / N770 device.
40ffa458c1SDavid Brownell  * Support for ads7843 and ads7845 has only been stubbed in.
41ffa458c1SDavid Brownell  *
427de90a8cSImre Deak  * Not yet done:  How accurate are the temperature and voltage
437de90a8cSImre Deak  * readings? (System-specific calibration should support
44ffa458c1SDavid Brownell  * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.)
45ffa458c1SDavid Brownell  *
467de90a8cSImre Deak  * IRQ handling needs a workaround because of a shortcoming in handling
477de90a8cSImre Deak  * edge triggered IRQs on some platforms like the OMAP1/2. These
487de90a8cSImre Deak  * platforms don't handle the ARM lazy IRQ disabling properly, thus we
497de90a8cSImre Deak  * have to maintain our own SW IRQ disabled status. This should be
507de90a8cSImre Deak  * removed as soon as the affected platform's IRQ handling is fixed.
517de90a8cSImre Deak  *
52ffa458c1SDavid Brownell  * app note sbaa036 talks in more detail about accurate sampling...
53ffa458c1SDavid Brownell  * that ought to help in situations like LCDs inducing noise (which
54ffa458c1SDavid Brownell  * can also be helped by using synch signals) and more generally.
557de90a8cSImre Deak  * This driver tries to utilize the measures described in the app
567de90a8cSImre Deak  * note. The strength of filtering can be set in the board-* specific
577de90a8cSImre Deak  * files.
58ffa458c1SDavid Brownell  */
59ffa458c1SDavid Brownell 
60ffa458c1SDavid Brownell #define	TS_POLL_PERIOD	msecs_to_jiffies(10)
61ffa458c1SDavid Brownell 
62d93f70b2SDavid Brownell /* this driver doesn't aim at the peak continuous sample rate */
63d93f70b2SDavid Brownell #define	SAMPLE_BITS	(8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
64d93f70b2SDavid Brownell 
65ffa458c1SDavid Brownell struct ts_event {
66ffa458c1SDavid Brownell 	/* For portability, we can't read 12 bit values using SPI (which
67ffa458c1SDavid Brownell 	 * would make the controller deliver them as native byteorder u16
68d93f70b2SDavid Brownell 	 * with msbs zeroed).  Instead, we read them as two 8-bit values,
69ffa458c1SDavid Brownell 	 * which need byteswapping then range adjustment.
70ffa458c1SDavid Brownell 	 */
71ffa458c1SDavid Brownell 	__be16 x;
72ffa458c1SDavid Brownell 	__be16 y;
73ffa458c1SDavid Brownell 	__be16 z1, z2;
74ffa458c1SDavid Brownell };
75ffa458c1SDavid Brownell 
76ffa458c1SDavid Brownell struct ads7846 {
77a90f7e98SDmitry Torokhov 	struct input_dev	*input;
78ffa458c1SDavid Brownell 	char			phys[32];
79ffa458c1SDavid Brownell 
80ffa458c1SDavid Brownell 	struct spi_device	*spi;
81ffa458c1SDavid Brownell 	u16			model;
82ffa458c1SDavid Brownell 	u16			vref_delay_usecs;
83ffa458c1SDavid Brownell 	u16			x_plate_ohms;
84ffa458c1SDavid Brownell 
8553a0ef89SImre Deak 	u8			read_x, read_y, read_z1, read_z2, pwrdown;
8653a0ef89SImre Deak 	u16			dummy;		/* for the pwrdown read */
87ffa458c1SDavid Brownell 	struct ts_event		tc;
88ffa458c1SDavid Brownell 
8953a0ef89SImre Deak 	struct spi_transfer	xfer[10];
900b7018aaSImre Deak 	struct spi_message	msg[5];
910b7018aaSImre Deak 	int			msg_idx;
920b7018aaSImre Deak 	int			read_cnt;
930b7018aaSImre Deak 	int			last_read;
940b7018aaSImre Deak 
950b7018aaSImre Deak 	u16			debounce_max;
960b7018aaSImre Deak 	u16			debounce_tol;
97ffa458c1SDavid Brownell 
98ffa458c1SDavid Brownell 	spinlock_t		lock;
99ffa458c1SDavid Brownell 	struct timer_list	timer;		/* P: lock */
100ffa458c1SDavid Brownell 	unsigned		pendown:1;	/* P: lock */
101ffa458c1SDavid Brownell 	unsigned		pending:1;	/* P: lock */
102ffa458c1SDavid Brownell // FIXME remove "irq_disabled"
103ffa458c1SDavid Brownell 	unsigned		irq_disabled:1;	/* P: lock */
1047de90a8cSImre Deak 	unsigned		disabled:1;
105*c9e617a5SImre Deak 
106*c9e617a5SImre Deak 	int			(*get_pendown_state)(void);
107ffa458c1SDavid Brownell };
108ffa458c1SDavid Brownell 
109ffa458c1SDavid Brownell /* leave chip selected when we're done, for quicker re-select? */
110ffa458c1SDavid Brownell #if	0
111ffa458c1SDavid Brownell #define	CS_CHANGE(xfer)	((xfer).cs_change = 1)
112ffa458c1SDavid Brownell #else
113ffa458c1SDavid Brownell #define	CS_CHANGE(xfer)	((xfer).cs_change = 0)
114ffa458c1SDavid Brownell #endif
115ffa458c1SDavid Brownell 
116ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/
117ffa458c1SDavid Brownell 
118ffa458c1SDavid Brownell /* The ADS7846 has touchscreen and other sensors.
119ffa458c1SDavid Brownell  * Earlier ads784x chips are somewhat compatible.
120ffa458c1SDavid Brownell  */
121ffa458c1SDavid Brownell #define	ADS_START		(1 << 7)
122ffa458c1SDavid Brownell #define	ADS_A2A1A0_d_y		(1 << 4)	/* differential */
123ffa458c1SDavid Brownell #define	ADS_A2A1A0_d_z1		(3 << 4)	/* differential */
124ffa458c1SDavid Brownell #define	ADS_A2A1A0_d_z2		(4 << 4)	/* differential */
125ffa458c1SDavid Brownell #define	ADS_A2A1A0_d_x		(5 << 4)	/* differential */
126ffa458c1SDavid Brownell #define	ADS_A2A1A0_temp0	(0 << 4)	/* non-differential */
127ffa458c1SDavid Brownell #define	ADS_A2A1A0_vbatt	(2 << 4)	/* non-differential */
128ffa458c1SDavid Brownell #define	ADS_A2A1A0_vaux		(6 << 4)	/* non-differential */
129ffa458c1SDavid Brownell #define	ADS_A2A1A0_temp1	(7 << 4)	/* non-differential */
130ffa458c1SDavid Brownell #define	ADS_8_BIT		(1 << 3)
131ffa458c1SDavid Brownell #define	ADS_12_BIT		(0 << 3)
132ffa458c1SDavid Brownell #define	ADS_SER			(1 << 2)	/* non-differential */
133ffa458c1SDavid Brownell #define	ADS_DFR			(0 << 2)	/* differential */
134ffa458c1SDavid Brownell #define	ADS_PD10_PDOWN		(0 << 0)	/* lowpower mode + penirq */
135ffa458c1SDavid Brownell #define	ADS_PD10_ADC_ON		(1 << 0)	/* ADC on */
136ffa458c1SDavid Brownell #define	ADS_PD10_REF_ON		(2 << 0)	/* vREF on + penirq */
137ffa458c1SDavid Brownell #define	ADS_PD10_ALL_ON		(3 << 0)	/* ADC + vREF on */
138ffa458c1SDavid Brownell 
139ffa458c1SDavid Brownell #define	MAX_12BIT	((1<<12)-1)
140ffa458c1SDavid Brownell 
141ffa458c1SDavid Brownell /* leave ADC powered up (disables penirq) between differential samples */
142ffa458c1SDavid Brownell #define	READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \
143ffa458c1SDavid Brownell 	| ADS_12_BIT | ADS_DFR)
144ffa458c1SDavid Brownell 
145d93f70b2SDavid Brownell #define	READ_Y	(READ_12BIT_DFR(y)  | ADS_PD10_ADC_ON)
146d93f70b2SDavid Brownell #define	READ_Z1	(READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON)
147d93f70b2SDavid Brownell #define	READ_Z2	(READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON)
14853a0ef89SImre Deak 
14953a0ef89SImre Deak #define	READ_X	(READ_12BIT_DFR(x)  | ADS_PD10_ADC_ON)
15053a0ef89SImre Deak #define	PWRDOWN	(READ_12BIT_DFR(y)  | ADS_PD10_PDOWN)	/* LAST */
151ffa458c1SDavid Brownell 
152ffa458c1SDavid Brownell /* single-ended samples need to first power up reference voltage;
153ffa458c1SDavid Brownell  * we leave both ADC and VREF powered
154ffa458c1SDavid Brownell  */
155ffa458c1SDavid Brownell #define	READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \
156ffa458c1SDavid Brownell 	| ADS_12_BIT | ADS_SER)
157ffa458c1SDavid Brownell 
158d93f70b2SDavid Brownell #define	REF_ON	(READ_12BIT_DFR(x) | ADS_PD10_ALL_ON)
159d93f70b2SDavid Brownell #define	REF_OFF	(READ_12BIT_DFR(y) | ADS_PD10_PDOWN)
160ffa458c1SDavid Brownell 
161ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/
162ffa458c1SDavid Brownell 
163ffa458c1SDavid Brownell /*
164ffa458c1SDavid Brownell  * Non-touchscreen sensors only use single-ended conversions.
165ffa458c1SDavid Brownell  */
166ffa458c1SDavid Brownell 
167ffa458c1SDavid Brownell struct ser_req {
168d93f70b2SDavid Brownell 	u8			ref_on;
169ffa458c1SDavid Brownell 	u8			command;
170d93f70b2SDavid Brownell 	u8			ref_off;
171ffa458c1SDavid Brownell 	u16			scratch;
172ffa458c1SDavid Brownell 	__be16			sample;
173ffa458c1SDavid Brownell 	struct spi_message	msg;
174ffa458c1SDavid Brownell 	struct spi_transfer	xfer[6];
175ffa458c1SDavid Brownell };
176ffa458c1SDavid Brownell 
1777de90a8cSImre Deak static void ads7846_enable(struct ads7846 *ts);
1787de90a8cSImre Deak static void ads7846_disable(struct ads7846 *ts);
1797de90a8cSImre Deak 
180*c9e617a5SImre Deak static int device_suspended(struct device *dev)
181*c9e617a5SImre Deak {
182*c9e617a5SImre Deak 	struct ads7846 *ts = dev_get_drvdata(dev);
183*c9e617a5SImre Deak 	return dev->power.power_state.event != PM_EVENT_ON || ts->disabled;
184*c9e617a5SImre Deak }
185*c9e617a5SImre Deak 
186ffa458c1SDavid Brownell static int ads7846_read12_ser(struct device *dev, unsigned command)
187ffa458c1SDavid Brownell {
188ffa458c1SDavid Brownell 	struct spi_device	*spi = to_spi_device(dev);
189ffa458c1SDavid Brownell 	struct ads7846		*ts = dev_get_drvdata(dev);
190ffa458c1SDavid Brownell 	struct ser_req		*req = kzalloc(sizeof *req, SLAB_KERNEL);
191ffa458c1SDavid Brownell 	int			status;
192ffa458c1SDavid Brownell 	int			sample;
1938275c642SVitaly Wool 	int			i;
194ffa458c1SDavid Brownell 
195ffa458c1SDavid Brownell 	if (!req)
196ffa458c1SDavid Brownell 		return -ENOMEM;
197ffa458c1SDavid Brownell 
1980b7018aaSImre Deak 	spi_message_init(&req->msg);
1998275c642SVitaly Wool 
200ffa458c1SDavid Brownell 	/* activate reference, so it has time to settle; */
201d93f70b2SDavid Brownell 	req->ref_on = REF_ON;
202d93f70b2SDavid Brownell 	req->xfer[0].tx_buf = &req->ref_on;
203ffa458c1SDavid Brownell 	req->xfer[0].len = 1;
204ffa458c1SDavid Brownell 	req->xfer[1].rx_buf = &req->scratch;
205ffa458c1SDavid Brownell 	req->xfer[1].len = 2;
206ffa458c1SDavid Brownell 
207ffa458c1SDavid Brownell 	/*
208ffa458c1SDavid Brownell 	 * for external VREF, 0 usec (and assume it's always on);
209ffa458c1SDavid Brownell 	 * for 1uF, use 800 usec;
210ffa458c1SDavid Brownell 	 * no cap, 100 usec.
211ffa458c1SDavid Brownell 	 */
212ffa458c1SDavid Brownell 	req->xfer[1].delay_usecs = ts->vref_delay_usecs;
213ffa458c1SDavid Brownell 
214ffa458c1SDavid Brownell 	/* take sample */
215ffa458c1SDavid Brownell 	req->command = (u8) command;
216ffa458c1SDavid Brownell 	req->xfer[2].tx_buf = &req->command;
217ffa458c1SDavid Brownell 	req->xfer[2].len = 1;
218ffa458c1SDavid Brownell 	req->xfer[3].rx_buf = &req->sample;
219ffa458c1SDavid Brownell 	req->xfer[3].len = 2;
220ffa458c1SDavid Brownell 
221ffa458c1SDavid Brownell 	/* REVISIT:  take a few more samples, and compare ... */
222ffa458c1SDavid Brownell 
223ffa458c1SDavid Brownell 	/* turn off reference */
224d93f70b2SDavid Brownell 	req->ref_off = REF_OFF;
225d93f70b2SDavid Brownell 	req->xfer[4].tx_buf = &req->ref_off;
226ffa458c1SDavid Brownell 	req->xfer[4].len = 1;
227ffa458c1SDavid Brownell 	req->xfer[5].rx_buf = &req->scratch;
228ffa458c1SDavid Brownell 	req->xfer[5].len = 2;
229ffa458c1SDavid Brownell 
230ffa458c1SDavid Brownell 	CS_CHANGE(req->xfer[5]);
231ffa458c1SDavid Brownell 
232ffa458c1SDavid Brownell 	/* group all the transfers together, so we can't interfere with
233ffa458c1SDavid Brownell 	 * reading touchscreen state; disable penirq while sampling
234ffa458c1SDavid Brownell 	 */
2358275c642SVitaly Wool 	for (i = 0; i < 6; i++)
2368275c642SVitaly Wool 		spi_message_add_tail(&req->xfer[i], &req->msg);
237ffa458c1SDavid Brownell 
238*c9e617a5SImre Deak 	ts->irq_disabled = 1;
239ffa458c1SDavid Brownell 	disable_irq(spi->irq);
240ffa458c1SDavid Brownell 	status = spi_sync(spi, &req->msg);
241*c9e617a5SImre Deak 	ts->irq_disabled = 0;
242ffa458c1SDavid Brownell 	enable_irq(spi->irq);
243ffa458c1SDavid Brownell 
244ffa458c1SDavid Brownell 	if (req->msg.status)
245ffa458c1SDavid Brownell 		status = req->msg.status;
246ffa458c1SDavid Brownell 	sample = be16_to_cpu(req->sample);
247ffa458c1SDavid Brownell 	sample = sample >> 4;
248ffa458c1SDavid Brownell 	kfree(req);
249ffa458c1SDavid Brownell 
250ffa458c1SDavid Brownell 	return status ? status : sample;
251ffa458c1SDavid Brownell }
252ffa458c1SDavid Brownell 
253ffa458c1SDavid Brownell #define SHOW(name) static ssize_t \
254ffa458c1SDavid Brownell name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
255ffa458c1SDavid Brownell { \
256ffa458c1SDavid Brownell 	ssize_t v = ads7846_read12_ser(dev, \
257ffa458c1SDavid Brownell 			READ_12BIT_SER(name) | ADS_PD10_ALL_ON); \
258ffa458c1SDavid Brownell 	if (v < 0) \
259ffa458c1SDavid Brownell 		return v; \
260ffa458c1SDavid Brownell 	return sprintf(buf, "%u\n", (unsigned) v); \
261ffa458c1SDavid Brownell } \
262ffa458c1SDavid Brownell static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
263ffa458c1SDavid Brownell 
264ffa458c1SDavid Brownell SHOW(temp0)
265ffa458c1SDavid Brownell SHOW(temp1)
266ffa458c1SDavid Brownell SHOW(vaux)
267ffa458c1SDavid Brownell SHOW(vbatt)
268ffa458c1SDavid Brownell 
269438f2a74SImre Deak static int is_pen_down(struct device *dev)
270438f2a74SImre Deak {
271438f2a74SImre Deak 	struct ads7846		*ts = dev_get_drvdata(dev);
272438f2a74SImre Deak 
273438f2a74SImre Deak 	return ts->pendown;
274438f2a74SImre Deak }
275438f2a74SImre Deak 
276438f2a74SImre Deak static ssize_t ads7846_pen_down_show(struct device *dev,
277438f2a74SImre Deak 				     struct device_attribute *attr, char *buf)
278438f2a74SImre Deak {
279438f2a74SImre Deak 	return sprintf(buf, "%u\n", is_pen_down(dev));
280438f2a74SImre Deak }
281438f2a74SImre Deak 
282438f2a74SImre Deak static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL);
283438f2a74SImre Deak 
2847de90a8cSImre Deak static ssize_t ads7846_disable_show(struct device *dev,
2857de90a8cSImre Deak 				     struct device_attribute *attr, char *buf)
2867de90a8cSImre Deak {
2877de90a8cSImre Deak 	struct ads7846	*ts = dev_get_drvdata(dev);
2887de90a8cSImre Deak 
2897de90a8cSImre Deak 	return sprintf(buf, "%u\n", ts->disabled);
2907de90a8cSImre Deak }
2917de90a8cSImre Deak 
2927de90a8cSImre Deak static ssize_t ads7846_disable_store(struct device *dev,
2937de90a8cSImre Deak 				     struct device_attribute *attr,
2947de90a8cSImre Deak 				     const char *buf, size_t count)
2957de90a8cSImre Deak {
2967de90a8cSImre Deak 	struct ads7846 *ts = dev_get_drvdata(dev);
2977de90a8cSImre Deak 	char *endp;
2987de90a8cSImre Deak 	int i;
2997de90a8cSImre Deak 
3007de90a8cSImre Deak 	i = simple_strtoul(buf, &endp, 10);
3017de90a8cSImre Deak 	spin_lock_irq(&ts->lock);
3027de90a8cSImre Deak 
3037de90a8cSImre Deak 	if (i)
3047de90a8cSImre Deak 		ads7846_disable(ts);
3057de90a8cSImre Deak 	else
3067de90a8cSImre Deak 		ads7846_enable(ts);
3077de90a8cSImre Deak 
3087de90a8cSImre Deak 	spin_unlock_irq(&ts->lock);
3097de90a8cSImre Deak 
3107de90a8cSImre Deak 	return count;
3117de90a8cSImre Deak }
3127de90a8cSImre Deak 
3137de90a8cSImre Deak static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store);
3147de90a8cSImre Deak 
315ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/
316ffa458c1SDavid Brownell 
317ffa458c1SDavid Brownell /*
318ffa458c1SDavid Brownell  * PENIRQ only kicks the timer.  The timer only reissues the SPI transfer,
319ffa458c1SDavid Brownell  * to retrieve touchscreen status.
320ffa458c1SDavid Brownell  *
321ffa458c1SDavid Brownell  * The SPI transfer completion callback does the real work.  It reports
322ffa458c1SDavid Brownell  * touchscreen events and reactivates the timer (or IRQ) as appropriate.
323ffa458c1SDavid Brownell  */
324ffa458c1SDavid Brownell 
325ffa458c1SDavid Brownell static void ads7846_rx(void *ads)
326ffa458c1SDavid Brownell {
327ffa458c1SDavid Brownell 	struct ads7846		*ts = ads;
328a90f7e98SDmitry Torokhov 	struct input_dev	*input_dev = ts->input;
329ffa458c1SDavid Brownell 	unsigned		Rt;
330ffa458c1SDavid Brownell 	unsigned		sync = 0;
331ffa458c1SDavid Brownell 	u16			x, y, z1, z2;
332ffa458c1SDavid Brownell 	unsigned long		flags;
333ffa458c1SDavid Brownell 
334ffa458c1SDavid Brownell 	/* adjust:  12 bit samples (left aligned), built from
335ffa458c1SDavid Brownell 	 * two 8 bit values writen msb-first.
336ffa458c1SDavid Brownell 	 */
337ffa458c1SDavid Brownell 	x = be16_to_cpu(ts->tc.x) >> 4;
338ffa458c1SDavid Brownell 	y = be16_to_cpu(ts->tc.y) >> 4;
339ffa458c1SDavid Brownell 	z1 = be16_to_cpu(ts->tc.z1) >> 4;
340ffa458c1SDavid Brownell 	z2 = be16_to_cpu(ts->tc.z2) >> 4;
341ffa458c1SDavid Brownell 
342ffa458c1SDavid Brownell 	/* range filtering */
343ffa458c1SDavid Brownell 	if (x == MAX_12BIT)
344ffa458c1SDavid Brownell 		x = 0;
345ffa458c1SDavid Brownell 
346*c9e617a5SImre Deak 	if (likely(x && z1 && !device_suspended(&ts->spi->dev))) {
347ffa458c1SDavid Brownell 		/* compute touch pressure resistance using equation #2 */
348ffa458c1SDavid Brownell 		Rt = z2;
349ffa458c1SDavid Brownell 		Rt -= z1;
350ffa458c1SDavid Brownell 		Rt *= x;
351ffa458c1SDavid Brownell 		Rt *= ts->x_plate_ohms;
352ffa458c1SDavid Brownell 		Rt /= z1;
353ffa458c1SDavid Brownell 		Rt = (Rt + 2047) >> 12;
354ffa458c1SDavid Brownell 	} else
355ffa458c1SDavid Brownell 		Rt = 0;
356ffa458c1SDavid Brownell 
357ffa458c1SDavid Brownell 	/* NOTE:  "pendown" is inferred from pressure; we don't rely on
358ffa458c1SDavid Brownell 	 * being able to check nPENIRQ status, or "friendly" trigger modes
359ffa458c1SDavid Brownell 	 * (both-edges is much better than just-falling or low-level).
360ffa458c1SDavid Brownell 	 *
361ffa458c1SDavid Brownell 	 * REVISIT:  some boards may require reading nPENIRQ; it's
362ffa458c1SDavid Brownell 	 * needed on 7843.  and 7845 reads pressure differently...
363ffa458c1SDavid Brownell 	 *
364ffa458c1SDavid Brownell 	 * REVISIT:  the touchscreen might not be connected; this code
365ffa458c1SDavid Brownell 	 * won't notice that, even if nPENIRQ never fires ...
366ffa458c1SDavid Brownell 	 */
367ffa458c1SDavid Brownell 	if (!ts->pendown && Rt != 0) {
368a90f7e98SDmitry Torokhov 		input_report_key(input_dev, BTN_TOUCH, 1);
369ffa458c1SDavid Brownell 		sync = 1;
370ffa458c1SDavid Brownell 	} else if (ts->pendown && Rt == 0) {
371a90f7e98SDmitry Torokhov 		input_report_key(input_dev, BTN_TOUCH, 0);
372ffa458c1SDavid Brownell 		sync = 1;
373ffa458c1SDavid Brownell 	}
374ffa458c1SDavid Brownell 
375ffa458c1SDavid Brownell 	if (Rt) {
376a90f7e98SDmitry Torokhov 		input_report_abs(input_dev, ABS_X, x);
377a90f7e98SDmitry Torokhov 		input_report_abs(input_dev, ABS_Y, y);
378a90f7e98SDmitry Torokhov 		input_report_abs(input_dev, ABS_PRESSURE, Rt);
379ffa458c1SDavid Brownell 		sync = 1;
380ffa458c1SDavid Brownell 	}
381ffa458c1SDavid Brownell 	if (sync)
382a90f7e98SDmitry Torokhov 		input_sync(input_dev);
383ffa458c1SDavid Brownell 
384ffa458c1SDavid Brownell #ifdef	VERBOSE
385ffa458c1SDavid Brownell 	if (Rt || ts->pendown)
386ffa458c1SDavid Brownell 		pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id,
387ffa458c1SDavid Brownell 			x, y, Rt, Rt ? "" : " UP");
388ffa458c1SDavid Brownell #endif
389ffa458c1SDavid Brownell 
390ffa458c1SDavid Brownell 	spin_lock_irqsave(&ts->lock, flags);
391ffa458c1SDavid Brownell 
392ffa458c1SDavid Brownell 	ts->pendown = (Rt != 0);
393ffa458c1SDavid Brownell 	mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
394ffa458c1SDavid Brownell 
395ffa458c1SDavid Brownell 	spin_unlock_irqrestore(&ts->lock, flags);
396ffa458c1SDavid Brownell }
397ffa458c1SDavid Brownell 
3980b7018aaSImre Deak static void ads7846_debounce(void *ads)
399ffa458c1SDavid Brownell {
4000b7018aaSImre Deak 	struct ads7846		*ts = ads;
4010b7018aaSImre Deak 	struct spi_message	*m;
4020b7018aaSImre Deak 	struct spi_transfer	*t;
4030b7018aaSImre Deak 	u16			val;
4040b7018aaSImre Deak 	int			status;
405ffa458c1SDavid Brownell 
4060b7018aaSImre Deak 	m = &ts->msg[ts->msg_idx];
4070b7018aaSImre Deak 	t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
4080b7018aaSImre Deak 	val = (*(u16 *)t->rx_buf) >> 3;
4090b7018aaSImre Deak 
4100b7018aaSImre Deak 	if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol
4110b7018aaSImre Deak 				&& ts->read_cnt < ts->debounce_max)) {
4120b7018aaSImre Deak 		/* Repeat it, if this was the first read or the read wasn't
4130b7018aaSImre Deak 		 * consistent enough
4140b7018aaSImre Deak 		 */
4150b7018aaSImre Deak 		ts->read_cnt++;
4160b7018aaSImre Deak 		ts->last_read = val;
4170b7018aaSImre Deak 	} else {
4180b7018aaSImre Deak 		/* Go for the next read */
4190b7018aaSImre Deak 		ts->msg_idx++;
4200b7018aaSImre Deak 		ts->read_cnt = 0;
4210b7018aaSImre Deak 		m++;
422ffa458c1SDavid Brownell 	}
4230b7018aaSImre Deak 	status = spi_async(ts->spi, m);
424ffa458c1SDavid Brownell 	if (status)
425ffa458c1SDavid Brownell 		dev_err(&ts->spi->dev, "spi_async --> %d\n",
426ffa458c1SDavid Brownell 				status);
427ffa458c1SDavid Brownell }
4280b7018aaSImre Deak 
4290b7018aaSImre Deak static void ads7846_timer(unsigned long handle)
4300b7018aaSImre Deak {
4310b7018aaSImre Deak 	struct ads7846	*ts = (void *)handle;
4320b7018aaSImre Deak 	int		status = 0;
4330b7018aaSImre Deak 
434*c9e617a5SImre Deak 	spin_lock_irq(&ts->lock);
435*c9e617a5SImre Deak 
436*c9e617a5SImre Deak 	if (unlikely(ts->msg_idx && !ts->pendown)) {
437*c9e617a5SImre Deak 		/* measurment cycle ended */
438*c9e617a5SImre Deak 		if (!device_suspended(&ts->spi->dev)) {
439*c9e617a5SImre Deak 			ts->irq_disabled = 0;
440*c9e617a5SImre Deak 			enable_irq(ts->spi->irq);
441*c9e617a5SImre Deak 		}
442*c9e617a5SImre Deak 		ts->pending = 0;
443*c9e617a5SImre Deak 		ts->msg_idx = 0;
444*c9e617a5SImre Deak 	} else {
445*c9e617a5SImre Deak 		/* pen is still down, continue with the measurement */
4460b7018aaSImre Deak 		ts->msg_idx = 0;
4470b7018aaSImre Deak 		status = spi_async(ts->spi, &ts->msg[0]);
4480b7018aaSImre Deak 		if (status)
4490b7018aaSImre Deak 			dev_err(&ts->spi->dev, "spi_async --> %d\n", status);
450ffa458c1SDavid Brownell 	}
451ffa458c1SDavid Brownell 
452*c9e617a5SImre Deak 	spin_unlock_irq(&ts->lock);
453*c9e617a5SImre Deak }
454*c9e617a5SImre Deak 
455ffa458c1SDavid Brownell static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
456ffa458c1SDavid Brownell {
4570b7018aaSImre Deak 	struct ads7846 *ts = handle;
4580b7018aaSImre Deak 	unsigned long flags;
4590b7018aaSImre Deak 
4600b7018aaSImre Deak 	spin_lock_irqsave(&ts->lock, flags);
461*c9e617a5SImre Deak 	if (likely(ts->get_pendown_state())) {
4620b7018aaSImre Deak 		if (!ts->irq_disabled) {
4630b7018aaSImre Deak 			/* REVISIT irq logic for many ARM chips has cloned a
4640b7018aaSImre Deak 			 * bug wherein disabling an irq in its handler won't
4650b7018aaSImre Deak 			 * work;(it's disabled lazily, and too late to work.
4660b7018aaSImre Deak 			 * until all their irq logic is fixed, we must shadow
4670b7018aaSImre Deak 			 * that state here.
4680b7018aaSImre Deak 			 */
4690b7018aaSImre Deak 			ts->irq_disabled = 1;
4700b7018aaSImre Deak 			disable_irq(ts->spi->irq);
4710b7018aaSImre Deak 			ts->pending = 1;
4720b7018aaSImre Deak 			mod_timer(&ts->timer, jiffies);
4730b7018aaSImre Deak 		}
4740b7018aaSImre Deak 	}
4750b7018aaSImre Deak 	spin_unlock_irqrestore(&ts->lock, flags);
4767de90a8cSImre Deak 
4777de90a8cSImre Deak 	return IRQ_HANDLED;
478ffa458c1SDavid Brownell }
479ffa458c1SDavid Brownell 
480ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/
481ffa458c1SDavid Brownell 
4827de90a8cSImre Deak /* Must be called with ts->lock held */
4837de90a8cSImre Deak static void ads7846_disable(struct ads7846 *ts)
484ffa458c1SDavid Brownell {
4857de90a8cSImre Deak 	if (ts->disabled)
4867de90a8cSImre Deak 		return;
487ffa458c1SDavid Brownell 
488*c9e617a5SImre Deak 	ts->disabled = 1;
489*c9e617a5SImre Deak 
490ffa458c1SDavid Brownell 	/* are we waiting for IRQ, or polling? */
491*c9e617a5SImre Deak 	if (!ts->pending) {
492ffa458c1SDavid Brownell 		ts->irq_disabled = 1;
493ffa458c1SDavid Brownell 		disable_irq(ts->spi->irq);
494ffa458c1SDavid Brownell 	} else {
495*c9e617a5SImre Deak 		/* the timer will run at least once more, and
496*c9e617a5SImre Deak 		 * leave everything in a clean state, IRQ disabled
497ffa458c1SDavid Brownell 		 */
498*c9e617a5SImre Deak 		while (ts->pending) {
4997de90a8cSImre Deak 			spin_unlock_irq(&ts->lock);
500c4febb94SJuha Yrjola 			msleep(1);
5017de90a8cSImre Deak 			spin_lock_irq(&ts->lock);
502ffa458c1SDavid Brownell 		}
503ffa458c1SDavid Brownell 	}
504ffa458c1SDavid Brownell 
505ffa458c1SDavid Brownell 	/* we know the chip's in lowpower mode since we always
506ffa458c1SDavid Brownell 	 * leave it that way after every request
507ffa458c1SDavid Brownell 	 */
508ffa458c1SDavid Brownell 
5097de90a8cSImre Deak }
5107de90a8cSImre Deak 
5117de90a8cSImre Deak /* Must be called with ts->lock held */
5127de90a8cSImre Deak static void ads7846_enable(struct ads7846 *ts)
5137de90a8cSImre Deak {
5147de90a8cSImre Deak 	if (!ts->disabled)
5157de90a8cSImre Deak 		return;
5167de90a8cSImre Deak 
5177de90a8cSImre Deak 	ts->disabled = 0;
5187de90a8cSImre Deak 	ts->irq_disabled = 0;
5197de90a8cSImre Deak 	enable_irq(ts->spi->irq);
5207de90a8cSImre Deak }
5217de90a8cSImre Deak 
5227de90a8cSImre Deak static int ads7846_suspend(struct spi_device *spi, pm_message_t message)
5237de90a8cSImre Deak {
5247de90a8cSImre Deak 	struct ads7846 *ts = dev_get_drvdata(&spi->dev);
5257de90a8cSImre Deak 
5267de90a8cSImre Deak 	spin_lock_irq(&ts->lock);
5277de90a8cSImre Deak 
5287de90a8cSImre Deak 	spi->dev.power.power_state = message;
5297de90a8cSImre Deak 	ads7846_disable(ts);
5307de90a8cSImre Deak 
5317de90a8cSImre Deak 	spin_unlock_irq(&ts->lock);
5327de90a8cSImre Deak 
533ffa458c1SDavid Brownell 	return 0;
5347de90a8cSImre Deak 
535ffa458c1SDavid Brownell }
536ffa458c1SDavid Brownell 
5372e5a7bd9SDavid Brownell static int ads7846_resume(struct spi_device *spi)
538ffa458c1SDavid Brownell {
5392e5a7bd9SDavid Brownell 	struct ads7846 *ts = dev_get_drvdata(&spi->dev);
540ffa458c1SDavid Brownell 
5417de90a8cSImre Deak 	spin_lock_irq(&ts->lock);
5427de90a8cSImre Deak 
5432e5a7bd9SDavid Brownell 	spi->dev.power.power_state = PMSG_ON;
5447de90a8cSImre Deak 	ads7846_enable(ts);
5457de90a8cSImre Deak 
5467de90a8cSImre Deak 	spin_unlock_irq(&ts->lock);
5477de90a8cSImre Deak 
548ffa458c1SDavid Brownell 	return 0;
549ffa458c1SDavid Brownell }
550ffa458c1SDavid Brownell 
5512e5a7bd9SDavid Brownell static int __devinit ads7846_probe(struct spi_device *spi)
552ffa458c1SDavid Brownell {
553ffa458c1SDavid Brownell 	struct ads7846			*ts;
554a90f7e98SDmitry Torokhov 	struct input_dev		*input_dev;
5552e5a7bd9SDavid Brownell 	struct ads7846_platform_data	*pdata = spi->dev.platform_data;
5560b7018aaSImre Deak 	struct spi_message		*m;
557ffa458c1SDavid Brownell 	struct spi_transfer		*x;
558a90f7e98SDmitry Torokhov 	int				err;
559ffa458c1SDavid Brownell 
560ffa458c1SDavid Brownell 	if (!spi->irq) {
5612e5a7bd9SDavid Brownell 		dev_dbg(&spi->dev, "no IRQ?\n");
562ffa458c1SDavid Brownell 		return -ENODEV;
563ffa458c1SDavid Brownell 	}
564ffa458c1SDavid Brownell 
565ffa458c1SDavid Brownell 	if (!pdata) {
5662e5a7bd9SDavid Brownell 		dev_dbg(&spi->dev, "no platform data?\n");
567ffa458c1SDavid Brownell 		return -ENODEV;
568ffa458c1SDavid Brownell 	}
569ffa458c1SDavid Brownell 
570ffa458c1SDavid Brownell 	/* don't exceed max specified sample rate */
571d93f70b2SDavid Brownell 	if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) {
5722e5a7bd9SDavid Brownell 		dev_dbg(&spi->dev, "f(sample) %d KHz?\n",
573d93f70b2SDavid Brownell 				(spi->max_speed_hz/SAMPLE_BITS)/1000);
574ffa458c1SDavid Brownell 		return -EINVAL;
575ffa458c1SDavid Brownell 	}
576ffa458c1SDavid Brownell 
577*c9e617a5SImre Deak 	if (pdata->get_pendown_state == NULL) {
578*c9e617a5SImre Deak 		dev_dbg(&spi->dev, "no get_pendown_state function?\n");
579*c9e617a5SImre Deak 		return -EINVAL;
580*c9e617a5SImre Deak 	}
581*c9e617a5SImre Deak 
582ffa458c1SDavid Brownell 	/* We'd set the wordsize to 12 bits ... except that some controllers
583ffa458c1SDavid Brownell 	 * will then treat the 8 bit command words as 12 bits (and drop the
584ffa458c1SDavid Brownell 	 * four MSBs of the 12 bit result).  Result: inputs must be shifted
585ffa458c1SDavid Brownell 	 * to discard the four garbage LSBs.
586ffa458c1SDavid Brownell 	 */
587ffa458c1SDavid Brownell 
588a90f7e98SDmitry Torokhov 	ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
589a90f7e98SDmitry Torokhov 	input_dev = input_allocate_device();
590a90f7e98SDmitry Torokhov 	if (!ts || !input_dev) {
591a90f7e98SDmitry Torokhov 		err = -ENOMEM;
592a90f7e98SDmitry Torokhov 		goto err_free_mem;
593a90f7e98SDmitry Torokhov 	}
594ffa458c1SDavid Brownell 
5952e5a7bd9SDavid Brownell 	dev_set_drvdata(&spi->dev, ts);
596a90f7e98SDmitry Torokhov 	spi->dev.power.power_state = PMSG_ON;
597ffa458c1SDavid Brownell 
598ffa458c1SDavid Brownell 	ts->spi = spi;
599a90f7e98SDmitry Torokhov 	ts->input = input_dev;
600ffa458c1SDavid Brownell 
601ffa458c1SDavid Brownell 	init_timer(&ts->timer);
602ffa458c1SDavid Brownell 	ts->timer.data = (unsigned long) ts;
603ffa458c1SDavid Brownell 	ts->timer.function = ads7846_timer;
604ffa458c1SDavid Brownell 
6057de90a8cSImre Deak 	spin_lock_init(&ts->lock);
6067de90a8cSImre Deak 
607ffa458c1SDavid Brownell 	ts->model = pdata->model ? : 7846;
608ffa458c1SDavid Brownell 	ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
609ffa458c1SDavid Brownell 	ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
6100b7018aaSImre Deak 	ts->debounce_max = pdata->debounce_max ? : 1;
6110b7018aaSImre Deak 	ts->debounce_tol = pdata->debounce_tol ? : 10;
612*c9e617a5SImre Deak 	ts->get_pendown_state = pdata->get_pendown_state;
613ffa458c1SDavid Brownell 
614a90f7e98SDmitry Torokhov 	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id);
615ffa458c1SDavid Brownell 
616a90f7e98SDmitry Torokhov 	input_dev->name = "ADS784x Touchscreen";
617a90f7e98SDmitry Torokhov 	input_dev->phys = ts->phys;
618a90f7e98SDmitry Torokhov 	input_dev->cdev.dev = &spi->dev;
619ffa458c1SDavid Brownell 
620a90f7e98SDmitry Torokhov 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
621a90f7e98SDmitry Torokhov 	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
622a90f7e98SDmitry Torokhov 	input_set_abs_params(input_dev, ABS_X,
623ffa458c1SDavid Brownell 			pdata->x_min ? : 0,
624ffa458c1SDavid Brownell 			pdata->x_max ? : MAX_12BIT,
625ffa458c1SDavid Brownell 			0, 0);
626a90f7e98SDmitry Torokhov 	input_set_abs_params(input_dev, ABS_Y,
627ffa458c1SDavid Brownell 			pdata->y_min ? : 0,
628ffa458c1SDavid Brownell 			pdata->y_max ? : MAX_12BIT,
629ffa458c1SDavid Brownell 			0, 0);
630a90f7e98SDmitry Torokhov 	input_set_abs_params(input_dev, ABS_PRESSURE,
631ffa458c1SDavid Brownell 			pdata->pressure_min, pdata->pressure_max, 0, 0);
632ffa458c1SDavid Brownell 
633ffa458c1SDavid Brownell 	/* set up the transfers to read touchscreen state; this assumes we
634ffa458c1SDavid Brownell 	 * use formula #2 for pressure, not #3.
635ffa458c1SDavid Brownell 	 */
6360b7018aaSImre Deak 	m = &ts->msg[0];
637ffa458c1SDavid Brownell 	x = ts->xfer;
638ffa458c1SDavid Brownell 
6390b7018aaSImre Deak 	spi_message_init(m);
6400b7018aaSImre Deak 
641ffa458c1SDavid Brownell 	/* y- still on; turn on only y+ (and ADC) */
642d93f70b2SDavid Brownell 	ts->read_y = READ_Y;
643d93f70b2SDavid Brownell 	x->tx_buf = &ts->read_y;
644ffa458c1SDavid Brownell 	x->len = 1;
6450b7018aaSImre Deak 	spi_message_add_tail(x, m);
646d93f70b2SDavid Brownell 
647ffa458c1SDavid Brownell 	x++;
648ffa458c1SDavid Brownell 	x->rx_buf = &ts->tc.y;
649ffa458c1SDavid Brownell 	x->len = 2;
6500b7018aaSImre Deak 	spi_message_add_tail(x, m);
651ffa458c1SDavid Brownell 
6520b7018aaSImre Deak 	m->complete = ads7846_debounce;
6530b7018aaSImre Deak 	m->context = ts;
654d93f70b2SDavid Brownell 
6550b7018aaSImre Deak 	m++;
6560b7018aaSImre Deak 	spi_message_init(m);
657ffa458c1SDavid Brownell 
658ffa458c1SDavid Brownell 	/* turn y- off, x+ on, then leave in lowpower */
659d93f70b2SDavid Brownell 	x++;
660d93f70b2SDavid Brownell 	ts->read_x = READ_X;
661d93f70b2SDavid Brownell 	x->tx_buf = &ts->read_x;
662ffa458c1SDavid Brownell 	x->len = 1;
6630b7018aaSImre Deak 	spi_message_add_tail(x, m);
664d93f70b2SDavid Brownell 
665ffa458c1SDavid Brownell 	x++;
666ffa458c1SDavid Brownell 	x->rx_buf = &ts->tc.x;
667ffa458c1SDavid Brownell 	x->len = 2;
6680b7018aaSImre Deak 	spi_message_add_tail(x, m);
6690b7018aaSImre Deak 
6700b7018aaSImre Deak 	m->complete = ads7846_debounce;
6710b7018aaSImre Deak 	m->context = ts;
6720b7018aaSImre Deak 
6730b7018aaSImre Deak 	/* turn y+ off, x- on; we'll use formula #2 */
6740b7018aaSImre Deak 	if (ts->model == 7846) {
6750b7018aaSImre Deak 		m++;
6760b7018aaSImre Deak 		spi_message_init(m);
6770b7018aaSImre Deak 
6780b7018aaSImre Deak 		x++;
6790b7018aaSImre Deak 		ts->read_z1 = READ_Z1;
6800b7018aaSImre Deak 		x->tx_buf = &ts->read_z1;
6810b7018aaSImre Deak 		x->len = 1;
6820b7018aaSImre Deak 		spi_message_add_tail(x, m);
6830b7018aaSImre Deak 
6840b7018aaSImre Deak 		x++;
6850b7018aaSImre Deak 		x->rx_buf = &ts->tc.z1;
6860b7018aaSImre Deak 		x->len = 2;
6870b7018aaSImre Deak 		spi_message_add_tail(x, m);
6880b7018aaSImre Deak 
6890b7018aaSImre Deak 		m->complete = ads7846_debounce;
6900b7018aaSImre Deak 		m->context = ts;
6910b7018aaSImre Deak 
6920b7018aaSImre Deak 		m++;
6930b7018aaSImre Deak 		spi_message_init(m);
6940b7018aaSImre Deak 
6950b7018aaSImre Deak 		x++;
6960b7018aaSImre Deak 		ts->read_z2 = READ_Z2;
6970b7018aaSImre Deak 		x->tx_buf = &ts->read_z2;
6980b7018aaSImre Deak 		x->len = 1;
6990b7018aaSImre Deak 		spi_message_add_tail(x, m);
7000b7018aaSImre Deak 
7010b7018aaSImre Deak 		x++;
7020b7018aaSImre Deak 		x->rx_buf = &ts->tc.z2;
7030b7018aaSImre Deak 		x->len = 2;
7040b7018aaSImre Deak 		spi_message_add_tail(x, m);
7050b7018aaSImre Deak 
7060b7018aaSImre Deak 		m->complete = ads7846_debounce;
7070b7018aaSImre Deak 		m->context = ts;
7080b7018aaSImre Deak 	}
70953a0ef89SImre Deak 
71053a0ef89SImre Deak 	/* power down */
7110b7018aaSImre Deak 	m++;
7120b7018aaSImre Deak 	spi_message_init(m);
7130b7018aaSImre Deak 
71453a0ef89SImre Deak 	x++;
71553a0ef89SImre Deak 	ts->pwrdown = PWRDOWN;
71653a0ef89SImre Deak 	x->tx_buf = &ts->pwrdown;
71753a0ef89SImre Deak 	x->len = 1;
7180b7018aaSImre Deak 	spi_message_add_tail(x, m);
71953a0ef89SImre Deak 
72053a0ef89SImre Deak 	x++;
72153a0ef89SImre Deak 	x->rx_buf = &ts->dummy;
72253a0ef89SImre Deak 	x->len = 2;
723d93f70b2SDavid Brownell 	CS_CHANGE(*x);
7240b7018aaSImre Deak 	spi_message_add_tail(x, m);
725ffa458c1SDavid Brownell 
7260b7018aaSImre Deak 	m->complete = ads7846_rx;
7270b7018aaSImre Deak 	m->context = ts;
728ffa458c1SDavid Brownell 
729f43aaba1SRussell King 	if (request_irq(spi->irq, ads7846_irq,
730f43aaba1SRussell King 			SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING,
7312e5a7bd9SDavid Brownell 			spi->dev.bus_id, ts)) {
7322e5a7bd9SDavid Brownell 		dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
733a90f7e98SDmitry Torokhov 		err = -EBUSY;
734a90f7e98SDmitry Torokhov 		goto err_free_mem;
735ffa458c1SDavid Brownell 	}
736ffa458c1SDavid Brownell 
7372e5a7bd9SDavid Brownell 	dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq);
738ffa458c1SDavid Brownell 
739ffa458c1SDavid Brownell 	/* take a first sample, leaving nPENIRQ active; avoid
740ffa458c1SDavid Brownell 	 * the touchscreen, in case it's not connected.
741ffa458c1SDavid Brownell 	 */
7422e5a7bd9SDavid Brownell 	(void) ads7846_read12_ser(&spi->dev,
743ffa458c1SDavid Brownell 			  READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
744ffa458c1SDavid Brownell 
745ffa458c1SDavid Brownell 	/* ads7843/7845 don't have temperature sensors, and
746ffa458c1SDavid Brownell 	 * use the other sensors a bit differently too
747ffa458c1SDavid Brownell 	 */
748ffa458c1SDavid Brownell 	if (ts->model == 7846) {
7492e5a7bd9SDavid Brownell 		device_create_file(&spi->dev, &dev_attr_temp0);
7502e5a7bd9SDavid Brownell 		device_create_file(&spi->dev, &dev_attr_temp1);
751ffa458c1SDavid Brownell 	}
752ffa458c1SDavid Brownell 	if (ts->model != 7845)
7532e5a7bd9SDavid Brownell 		device_create_file(&spi->dev, &dev_attr_vbatt);
7542e5a7bd9SDavid Brownell 	device_create_file(&spi->dev, &dev_attr_vaux);
755ffa458c1SDavid Brownell 
756438f2a74SImre Deak 	device_create_file(&spi->dev, &dev_attr_pen_down);
757438f2a74SImre Deak 
7587de90a8cSImre Deak 	device_create_file(&spi->dev, &dev_attr_disable);
7597de90a8cSImre Deak 
760a90f7e98SDmitry Torokhov 	err = input_register_device(input_dev);
761a90f7e98SDmitry Torokhov 	if (err)
7627de90a8cSImre Deak 		goto err_remove_attr;
763a90f7e98SDmitry Torokhov 
764ffa458c1SDavid Brownell 	return 0;
765a90f7e98SDmitry Torokhov 
7667de90a8cSImre Deak  err_remove_attr:
7677de90a8cSImre Deak 	device_remove_file(&spi->dev, &dev_attr_disable);
7687de90a8cSImre Deak 	device_remove_file(&spi->dev, &dev_attr_pen_down);
7697de90a8cSImre Deak 	if (ts->model == 7846) {
7707de90a8cSImre Deak 		device_remove_file(&spi->dev, &dev_attr_temp1);
7717de90a8cSImre Deak 		device_remove_file(&spi->dev, &dev_attr_temp0);
7727de90a8cSImre Deak 	}
7737de90a8cSImre Deak 	if (ts->model != 7845)
7747de90a8cSImre Deak 		device_remove_file(&spi->dev, &dev_attr_vbatt);
7757de90a8cSImre Deak 	device_remove_file(&spi->dev, &dev_attr_vaux);
7767de90a8cSImre Deak 
777a90f7e98SDmitry Torokhov 	free_irq(spi->irq, ts);
778a90f7e98SDmitry Torokhov  err_free_mem:
779a90f7e98SDmitry Torokhov 	input_free_device(input_dev);
780a90f7e98SDmitry Torokhov 	kfree(ts);
781a90f7e98SDmitry Torokhov 	return err;
782ffa458c1SDavid Brownell }
783ffa458c1SDavid Brownell 
7842e5a7bd9SDavid Brownell static int __devexit ads7846_remove(struct spi_device *spi)
785ffa458c1SDavid Brownell {
7862e5a7bd9SDavid Brownell 	struct ads7846		*ts = dev_get_drvdata(&spi->dev);
787ffa458c1SDavid Brownell 
7887de90a8cSImre Deak 	input_unregister_device(ts->input);
7897de90a8cSImre Deak 
7902e5a7bd9SDavid Brownell 	ads7846_suspend(spi, PMSG_SUSPEND);
791ffa458c1SDavid Brownell 
7927de90a8cSImre Deak 	device_remove_file(&spi->dev, &dev_attr_disable);
793438f2a74SImre Deak 	device_remove_file(&spi->dev, &dev_attr_pen_down);
794ffa458c1SDavid Brownell 	if (ts->model == 7846) {
7952e5a7bd9SDavid Brownell 		device_remove_file(&spi->dev, &dev_attr_temp1);
7967de90a8cSImre Deak 		device_remove_file(&spi->dev, &dev_attr_temp0);
797ffa458c1SDavid Brownell 	}
798ffa458c1SDavid Brownell 	if (ts->model != 7845)
7992e5a7bd9SDavid Brownell 		device_remove_file(&spi->dev, &dev_attr_vbatt);
8002e5a7bd9SDavid Brownell 	device_remove_file(&spi->dev, &dev_attr_vaux);
801ffa458c1SDavid Brownell 
8027de90a8cSImre Deak 	free_irq(ts->spi->irq, ts);
803*c9e617a5SImre Deak 	/* suspend left the IRQ disabled */
8047de90a8cSImre Deak 	enable_irq(ts->spi->irq);
8057de90a8cSImre Deak 
806ffa458c1SDavid Brownell 	kfree(ts);
807ffa458c1SDavid Brownell 
8082e5a7bd9SDavid Brownell 	dev_dbg(&spi->dev, "unregistered touchscreen\n");
809ffa458c1SDavid Brownell 	return 0;
810ffa458c1SDavid Brownell }
811ffa458c1SDavid Brownell 
8122e5a7bd9SDavid Brownell static struct spi_driver ads7846_driver = {
8132e5a7bd9SDavid Brownell 	.driver = {
814ffa458c1SDavid Brownell 		.name	= "ads7846",
815ffa458c1SDavid Brownell 		.bus	= &spi_bus_type,
8162e5a7bd9SDavid Brownell 		.owner	= THIS_MODULE,
8172e5a7bd9SDavid Brownell 	},
818ffa458c1SDavid Brownell 	.probe		= ads7846_probe,
8192e5a7bd9SDavid Brownell 	.remove		= __devexit_p(ads7846_remove),
820ffa458c1SDavid Brownell 	.suspend	= ads7846_suspend,
821ffa458c1SDavid Brownell 	.resume		= ads7846_resume,
822ffa458c1SDavid Brownell };
823ffa458c1SDavid Brownell 
824ffa458c1SDavid Brownell static int __init ads7846_init(void)
825ffa458c1SDavid Brownell {
826ffa458c1SDavid Brownell 	/* grr, board-specific init should stay out of drivers!! */
827ffa458c1SDavid Brownell 
828ffa458c1SDavid Brownell #ifdef	CONFIG_ARCH_OMAP
829ffa458c1SDavid Brownell 	if (machine_is_omap_osk()) {
830ffa458c1SDavid Brownell 		/* GPIO4 = PENIRQ; GPIO6 = BUSY */
831ffa458c1SDavid Brownell 		omap_request_gpio(4);
832ffa458c1SDavid Brownell 		omap_set_gpio_direction(4, 1);
833ffa458c1SDavid Brownell 		omap_request_gpio(6);
834ffa458c1SDavid Brownell 		omap_set_gpio_direction(6, 1);
835ffa458c1SDavid Brownell 	}
836ffa458c1SDavid Brownell 	// also TI 1510 Innovator, bitbanging through FPGA
837ffa458c1SDavid Brownell 	// also Nokia 770
838ffa458c1SDavid Brownell 	// also Palm Tungsten T2
839ffa458c1SDavid Brownell #endif
840ffa458c1SDavid Brownell 
841ffa458c1SDavid Brownell 	// PXA:
842ffa458c1SDavid Brownell 	// also Dell Axim X50
843ffa458c1SDavid Brownell 	// also HP iPaq H191x/H192x/H415x/H435x
8442e5a7bd9SDavid Brownell 	// also Intel Lubbock (additional to UCB1400; as temperature sensor)
845ffa458c1SDavid Brownell 	// also Sharp Zaurus C7xx, C8xx (corgi/sheperd/husky)
846ffa458c1SDavid Brownell 
8472e5a7bd9SDavid Brownell 	// Atmel at91sam9261-EK uses ads7843
8482e5a7bd9SDavid Brownell 
849ffa458c1SDavid Brownell 	// also various AMD Au1x00 devel boards
850ffa458c1SDavid Brownell 
8512e5a7bd9SDavid Brownell 	return spi_register_driver(&ads7846_driver);
852ffa458c1SDavid Brownell }
853ffa458c1SDavid Brownell module_init(ads7846_init);
854ffa458c1SDavid Brownell 
855ffa458c1SDavid Brownell static void __exit ads7846_exit(void)
856ffa458c1SDavid Brownell {
8572e5a7bd9SDavid Brownell 	spi_unregister_driver(&ads7846_driver);
858ffa458c1SDavid Brownell 
859ffa458c1SDavid Brownell #ifdef	CONFIG_ARCH_OMAP
860ffa458c1SDavid Brownell 	if (machine_is_omap_osk()) {
861ffa458c1SDavid Brownell 		omap_free_gpio(4);
862ffa458c1SDavid Brownell 		omap_free_gpio(6);
863ffa458c1SDavid Brownell 	}
864ffa458c1SDavid Brownell #endif
865ffa458c1SDavid Brownell 
866ffa458c1SDavid Brownell }
867ffa458c1SDavid Brownell module_exit(ads7846_exit);
868ffa458c1SDavid Brownell 
869ffa458c1SDavid Brownell MODULE_DESCRIPTION("ADS7846 TouchScreen Driver");
870ffa458c1SDavid Brownell MODULE_LICENSE("GPL");
871