xref: /linux/drivers/input/touchscreen/ads7846.c (revision fbb38e30e414c9ccd8b5d04344264522551008bc)
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  */
202c8dc071SDavid Brownell #include <linux/hwmon.h>
21ffa458c1SDavid Brownell #include <linux/init.h>
222c8dc071SDavid Brownell #include <linux/err.h>
23ffa458c1SDavid Brownell #include <linux/delay.h>
24ffa458c1SDavid Brownell #include <linux/input.h>
25ffa458c1SDavid Brownell #include <linux/interrupt.h>
26ffa458c1SDavid Brownell #include <linux/slab.h>
27ffa458c1SDavid Brownell #include <linux/spi/spi.h>
28ffa458c1SDavid Brownell #include <linux/spi/ads7846.h>
293ac8bf07SAndrew Morton #include <asm/irq.h>
30ffa458c1SDavid Brownell 
31ffa458c1SDavid Brownell #ifdef	CONFIG_ARM
32ffa458c1SDavid Brownell #include <asm/mach-types.h>
33ffa458c1SDavid Brownell #ifdef	CONFIG_ARCH_OMAP
34ffa458c1SDavid Brownell #include <asm/arch/gpio.h>
35ffa458c1SDavid Brownell #endif
36ffa458c1SDavid Brownell #endif
37ffa458c1SDavid Brownell 
38ffa458c1SDavid Brownell 
39ffa458c1SDavid Brownell /*
409084533eSDavid Brownell  * This code has been heavily tested on a Nokia 770, and lightly
419084533eSDavid Brownell  * tested on other ads7846 devices (OSK/Mistral, Lubbock).
42bff0de5fSDavid Brownell  * TSC2046 is just newer ads7846 silicon.
43969111e9SNicolas Ferre  * Support for ads7843 tested on Atmel at91sam926x-EK.
44969111e9SNicolas Ferre  * Support for ads7845 has only been stubbed in.
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 
601936d590SImre Deak #define TS_POLL_DELAY	(1 * 1000000)	/* ns delay before the first sample */
611936d590SImre Deak #define TS_POLL_PERIOD	(5 * 1000000)	/* ns delay between samples */
62ffa458c1SDavid Brownell 
63d93f70b2SDavid Brownell /* this driver doesn't aim at the peak continuous sample rate */
64d93f70b2SDavid Brownell #define	SAMPLE_BITS	(8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
65d93f70b2SDavid Brownell 
66ffa458c1SDavid Brownell struct ts_event {
67ffa458c1SDavid Brownell 	/* For portability, we can't read 12 bit values using SPI (which
68ffa458c1SDavid Brownell 	 * would make the controller deliver them as native byteorder u16
69d93f70b2SDavid Brownell 	 * with msbs zeroed).  Instead, we read them as two 8-bit values,
70da970e69SImre Deak 	 * *** WHICH NEED BYTESWAPPING *** and range adjustment.
71ffa458c1SDavid Brownell 	 */
72da970e69SImre Deak 	u16	x;
73da970e69SImre Deak 	u16	y;
74da970e69SImre Deak 	u16	z1, z2;
75d5b415c9SImre Deak 	int	ignore;
76ffa458c1SDavid Brownell };
77ffa458c1SDavid Brownell 
78ffa458c1SDavid Brownell struct ads7846 {
79a90f7e98SDmitry Torokhov 	struct input_dev	*input;
80ffa458c1SDavid Brownell 	char			phys[32];
81ffa458c1SDavid Brownell 
82ffa458c1SDavid Brownell 	struct spi_device	*spi;
832c8dc071SDavid Brownell 
842c8dc071SDavid Brownell #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
858dd51650SDmitry Torokhov 	struct attribute_group	*attr_group;
861beeffe4STony Jones 	struct device		*hwmon;
872c8dc071SDavid Brownell #endif
882c8dc071SDavid Brownell 
89ffa458c1SDavid Brownell 	u16			model;
90ffa458c1SDavid Brownell 	u16			vref_delay_usecs;
91ffa458c1SDavid Brownell 	u16			x_plate_ohms;
92d5b415c9SImre Deak 	u16			pressure_max;
93ffa458c1SDavid Brownell 
9453a0ef89SImre Deak 	u8			read_x, read_y, read_z1, read_z2, pwrdown;
9553a0ef89SImre Deak 	u16			dummy;		/* for the pwrdown read */
96ffa458c1SDavid Brownell 	struct ts_event		tc;
97ffa458c1SDavid Brownell 
98e4f48861SSemih Hazar 	struct spi_transfer	xfer[18];
990b7018aaSImre Deak 	struct spi_message	msg[5];
100d5b415c9SImre Deak 	struct spi_message	*last_msg;
1010b7018aaSImre Deak 	int			msg_idx;
1020b7018aaSImre Deak 	int			read_cnt;
103d5b415c9SImre Deak 	int			read_rep;
1040b7018aaSImre Deak 	int			last_read;
1050b7018aaSImre Deak 
1060b7018aaSImre Deak 	u16			debounce_max;
1070b7018aaSImre Deak 	u16			debounce_tol;
108d5b415c9SImre Deak 	u16			debounce_rep;
109ffa458c1SDavid Brownell 
1101d25891fSSemih Hazar 	u16			penirq_recheck_delay_usecs;
1111d25891fSSemih Hazar 
112ffa458c1SDavid Brownell 	spinlock_t		lock;
1131936d590SImre Deak 	struct hrtimer		timer;
114ffa458c1SDavid Brownell 	unsigned		pendown:1;	/* P: lock */
115ffa458c1SDavid Brownell 	unsigned		pending:1;	/* P: lock */
116ffa458c1SDavid Brownell // FIXME remove "irq_disabled"
117ffa458c1SDavid Brownell 	unsigned		irq_disabled:1;	/* P: lock */
1187de90a8cSImre Deak 	unsigned		disabled:1;
119*fbb38e30SDavid Brownell 	unsigned		is_suspended:1;
120c9e617a5SImre Deak 
121da970e69SImre Deak 	int			(*filter)(void *data, int data_idx, int *val);
122da970e69SImre Deak 	void			*filter_data;
123da970e69SImre Deak 	void			(*filter_cleanup)(void *data);
124c9e617a5SImre Deak 	int			(*get_pendown_state)(void);
125ffa458c1SDavid Brownell };
126ffa458c1SDavid Brownell 
127ffa458c1SDavid Brownell /* leave chip selected when we're done, for quicker re-select? */
128ffa458c1SDavid Brownell #if	0
129ffa458c1SDavid Brownell #define	CS_CHANGE(xfer)	((xfer).cs_change = 1)
130ffa458c1SDavid Brownell #else
131ffa458c1SDavid Brownell #define	CS_CHANGE(xfer)	((xfer).cs_change = 0)
132ffa458c1SDavid Brownell #endif
133ffa458c1SDavid Brownell 
134ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/
135ffa458c1SDavid Brownell 
136ffa458c1SDavid Brownell /* The ADS7846 has touchscreen and other sensors.
137ffa458c1SDavid Brownell  * Earlier ads784x chips are somewhat compatible.
138ffa458c1SDavid Brownell  */
139ffa458c1SDavid Brownell #define	ADS_START		(1 << 7)
140ffa458c1SDavid Brownell #define	ADS_A2A1A0_d_y		(1 << 4)	/* differential */
141ffa458c1SDavid Brownell #define	ADS_A2A1A0_d_z1		(3 << 4)	/* differential */
142ffa458c1SDavid Brownell #define	ADS_A2A1A0_d_z2		(4 << 4)	/* differential */
143ffa458c1SDavid Brownell #define	ADS_A2A1A0_d_x		(5 << 4)	/* differential */
144ffa458c1SDavid Brownell #define	ADS_A2A1A0_temp0	(0 << 4)	/* non-differential */
145ffa458c1SDavid Brownell #define	ADS_A2A1A0_vbatt	(2 << 4)	/* non-differential */
146ffa458c1SDavid Brownell #define	ADS_A2A1A0_vaux		(6 << 4)	/* non-differential */
147ffa458c1SDavid Brownell #define	ADS_A2A1A0_temp1	(7 << 4)	/* non-differential */
148ffa458c1SDavid Brownell #define	ADS_8_BIT		(1 << 3)
149ffa458c1SDavid Brownell #define	ADS_12_BIT		(0 << 3)
150ffa458c1SDavid Brownell #define	ADS_SER			(1 << 2)	/* non-differential */
151ffa458c1SDavid Brownell #define	ADS_DFR			(0 << 2)	/* differential */
152ffa458c1SDavid Brownell #define	ADS_PD10_PDOWN		(0 << 0)	/* lowpower mode + penirq */
153ffa458c1SDavid Brownell #define	ADS_PD10_ADC_ON		(1 << 0)	/* ADC on */
154ffa458c1SDavid Brownell #define	ADS_PD10_REF_ON		(2 << 0)	/* vREF on + penirq */
155ffa458c1SDavid Brownell #define	ADS_PD10_ALL_ON		(3 << 0)	/* ADC + vREF on */
156ffa458c1SDavid Brownell 
157ffa458c1SDavid Brownell #define	MAX_12BIT	((1<<12)-1)
158ffa458c1SDavid Brownell 
159ffa458c1SDavid Brownell /* leave ADC powered up (disables penirq) between differential samples */
160de2defd9SImre Deak #define	READ_12BIT_DFR(x, adc, vref) (ADS_START | ADS_A2A1A0_d_ ## x \
161de2defd9SImre Deak 	| ADS_12_BIT | ADS_DFR | \
162de2defd9SImre Deak 	(adc ? ADS_PD10_ADC_ON : 0) | (vref ? ADS_PD10_REF_ON : 0))
163ffa458c1SDavid Brownell 
164de2defd9SImre Deak #define	READ_Y(vref)	(READ_12BIT_DFR(y,  1, vref))
165de2defd9SImre Deak #define	READ_Z1(vref)	(READ_12BIT_DFR(z1, 1, vref))
166de2defd9SImre Deak #define	READ_Z2(vref)	(READ_12BIT_DFR(z2, 1, vref))
16753a0ef89SImre Deak 
168de2defd9SImre Deak #define	READ_X(vref)	(READ_12BIT_DFR(x,  1, vref))
169de2defd9SImre Deak #define	PWRDOWN		(READ_12BIT_DFR(y,  0, 0))	/* LAST */
170ffa458c1SDavid Brownell 
171ffa458c1SDavid Brownell /* single-ended samples need to first power up reference voltage;
172ffa458c1SDavid Brownell  * we leave both ADC and VREF powered
173ffa458c1SDavid Brownell  */
174ffa458c1SDavid Brownell #define	READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \
175ffa458c1SDavid Brownell 	| ADS_12_BIT | ADS_SER)
176ffa458c1SDavid Brownell 
177de2defd9SImre Deak #define	REF_ON	(READ_12BIT_DFR(x, 1, 1))
178de2defd9SImre Deak #define	REF_OFF	(READ_12BIT_DFR(y, 0, 0))
179ffa458c1SDavid Brownell 
180ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/
181ffa458c1SDavid Brownell 
182ffa458c1SDavid Brownell /*
183ffa458c1SDavid Brownell  * Non-touchscreen sensors only use single-ended conversions.
1842c8dc071SDavid Brownell  * The range is GND..vREF. The ads7843 and ads7835 must use external vREF;
1852c8dc071SDavid Brownell  * ads7846 lets that pin be unconnected, to use internal vREF.
186ffa458c1SDavid Brownell  */
1872c8dc071SDavid Brownell static unsigned vREF_mV;
1882c8dc071SDavid Brownell module_param(vREF_mV, uint, 0);
1892c8dc071SDavid Brownell MODULE_PARM_DESC(vREF_mV, "external vREF voltage, in milliVolts");
190ffa458c1SDavid Brownell 
191ffa458c1SDavid Brownell struct ser_req {
192d93f70b2SDavid Brownell 	u8			ref_on;
193ffa458c1SDavid Brownell 	u8			command;
194d93f70b2SDavid Brownell 	u8			ref_off;
195ffa458c1SDavid Brownell 	u16			scratch;
196ffa458c1SDavid Brownell 	__be16			sample;
197ffa458c1SDavid Brownell 	struct spi_message	msg;
198ffa458c1SDavid Brownell 	struct spi_transfer	xfer[6];
199ffa458c1SDavid Brownell };
200ffa458c1SDavid Brownell 
2017de90a8cSImre Deak static void ads7846_enable(struct ads7846 *ts);
2027de90a8cSImre Deak static void ads7846_disable(struct ads7846 *ts);
2037de90a8cSImre Deak 
204c9e617a5SImre Deak static int device_suspended(struct device *dev)
205c9e617a5SImre Deak {
206c9e617a5SImre Deak 	struct ads7846 *ts = dev_get_drvdata(dev);
207*fbb38e30SDavid Brownell 	return ts->is_suspended || ts->disabled;
208c9e617a5SImre Deak }
209c9e617a5SImre Deak 
210ffa458c1SDavid Brownell static int ads7846_read12_ser(struct device *dev, unsigned command)
211ffa458c1SDavid Brownell {
212ffa458c1SDavid Brownell 	struct spi_device	*spi = to_spi_device(dev);
213ffa458c1SDavid Brownell 	struct ads7846		*ts = dev_get_drvdata(dev);
214e94b1766SChristoph Lameter 	struct ser_req		*req = kzalloc(sizeof *req, GFP_KERNEL);
215ffa458c1SDavid Brownell 	int			status;
216ffa458c1SDavid Brownell 	int			sample;
2172c8dc071SDavid Brownell 	int			use_internal;
218ffa458c1SDavid Brownell 
219ffa458c1SDavid Brownell 	if (!req)
220ffa458c1SDavid Brownell 		return -ENOMEM;
221ffa458c1SDavid Brownell 
2220b7018aaSImre Deak 	spi_message_init(&req->msg);
2238275c642SVitaly Wool 
2242c8dc071SDavid Brownell 	/* FIXME boards with ads7846 might use external vref instead ... */
2252c8dc071SDavid Brownell 	use_internal = (ts->model == 7846);
2262c8dc071SDavid Brownell 
2272c8dc071SDavid Brownell 	/* maybe turn on internal vREF, and let it settle */
2282c8dc071SDavid Brownell 	if (use_internal) {
229d93f70b2SDavid Brownell 		req->ref_on = REF_ON;
230d93f70b2SDavid Brownell 		req->xfer[0].tx_buf = &req->ref_on;
231ffa458c1SDavid Brownell 		req->xfer[0].len = 1;
2322c8dc071SDavid Brownell 		spi_message_add_tail(&req->xfer[0], &req->msg);
2332c8dc071SDavid Brownell 
234ffa458c1SDavid Brownell 		req->xfer[1].rx_buf = &req->scratch;
235ffa458c1SDavid Brownell 		req->xfer[1].len = 2;
236ffa458c1SDavid Brownell 
2372c8dc071SDavid Brownell 		/* for 1uF, settle for 800 usec; no cap, 100 usec.  */
238ffa458c1SDavid Brownell 		req->xfer[1].delay_usecs = ts->vref_delay_usecs;
2392c8dc071SDavid Brownell 		spi_message_add_tail(&req->xfer[1], &req->msg);
2402c8dc071SDavid Brownell 	}
241ffa458c1SDavid Brownell 
242ffa458c1SDavid Brownell 	/* take sample */
243ffa458c1SDavid Brownell 	req->command = (u8) command;
244ffa458c1SDavid Brownell 	req->xfer[2].tx_buf = &req->command;
245ffa458c1SDavid Brownell 	req->xfer[2].len = 1;
2462c8dc071SDavid Brownell 	spi_message_add_tail(&req->xfer[2], &req->msg);
2472c8dc071SDavid Brownell 
248ffa458c1SDavid Brownell 	req->xfer[3].rx_buf = &req->sample;
249ffa458c1SDavid Brownell 	req->xfer[3].len = 2;
2502c8dc071SDavid Brownell 	spi_message_add_tail(&req->xfer[3], &req->msg);
251ffa458c1SDavid Brownell 
252ffa458c1SDavid Brownell 	/* REVISIT:  take a few more samples, and compare ... */
253ffa458c1SDavid Brownell 
254969111e9SNicolas Ferre 	/* converter in low power mode & enable PENIRQ */
255969111e9SNicolas Ferre 	req->ref_off = PWRDOWN;
256d93f70b2SDavid Brownell 	req->xfer[4].tx_buf = &req->ref_off;
257ffa458c1SDavid Brownell 	req->xfer[4].len = 1;
2582c8dc071SDavid Brownell 	spi_message_add_tail(&req->xfer[4], &req->msg);
2592c8dc071SDavid Brownell 
260ffa458c1SDavid Brownell 	req->xfer[5].rx_buf = &req->scratch;
261ffa458c1SDavid Brownell 	req->xfer[5].len = 2;
262ffa458c1SDavid Brownell 	CS_CHANGE(req->xfer[5]);
2632c8dc071SDavid Brownell 	spi_message_add_tail(&req->xfer[5], &req->msg);
264ffa458c1SDavid Brownell 
265c9e617a5SImre Deak 	ts->irq_disabled = 1;
266ffa458c1SDavid Brownell 	disable_irq(spi->irq);
267ffa458c1SDavid Brownell 	status = spi_sync(spi, &req->msg);
268c9e617a5SImre Deak 	ts->irq_disabled = 0;
269ffa458c1SDavid Brownell 	enable_irq(spi->irq);
270ffa458c1SDavid Brownell 
271ffa458c1SDavid Brownell 	if (req->msg.status)
272ffa458c1SDavid Brownell 		status = req->msg.status;
273ffa458c1SDavid Brownell 
2749084533eSDavid Brownell 	/* on-wire is a must-ignore bit, a BE12 value, then padding */
2759084533eSDavid Brownell 	sample = be16_to_cpu(req->sample);
2769084533eSDavid Brownell 	sample = sample >> 3;
2779084533eSDavid Brownell 	sample &= 0x0fff;
2789084533eSDavid Brownell 
2799084533eSDavid Brownell 	kfree(req);
280ffa458c1SDavid Brownell 	return status ? status : sample;
281ffa458c1SDavid Brownell }
282ffa458c1SDavid Brownell 
2832c8dc071SDavid Brownell #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
2842c8dc071SDavid Brownell 
2852c8dc071SDavid Brownell #define SHOW(name, var, adjust) static ssize_t \
286ffa458c1SDavid Brownell name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
287ffa458c1SDavid Brownell { \
2882c8dc071SDavid Brownell 	struct ads7846 *ts = dev_get_drvdata(dev); \
289ffa458c1SDavid Brownell 	ssize_t v = ads7846_read12_ser(dev, \
2902c8dc071SDavid Brownell 			READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \
291ffa458c1SDavid Brownell 	if (v < 0) \
292ffa458c1SDavid Brownell 		return v; \
2932c8dc071SDavid Brownell 	return sprintf(buf, "%u\n", adjust(ts, v)); \
294ffa458c1SDavid Brownell } \
295ffa458c1SDavid Brownell static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
296ffa458c1SDavid Brownell 
2972c8dc071SDavid Brownell 
2982c8dc071SDavid Brownell /* Sysfs conventions report temperatures in millidegrees Celcius.
2992c8dc071SDavid Brownell  * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high
3002c8dc071SDavid Brownell  * accuracy scheme without calibration data.  For now we won't try either;
3012c8dc071SDavid Brownell  * userspace sees raw sensor values, and must scale/calibrate appropriately.
3022c8dc071SDavid Brownell  */
3032c8dc071SDavid Brownell static inline unsigned null_adjust(struct ads7846 *ts, ssize_t v)
3042c8dc071SDavid Brownell {
3052c8dc071SDavid Brownell 	return v;
3062c8dc071SDavid Brownell }
3072c8dc071SDavid Brownell 
3082c8dc071SDavid Brownell SHOW(temp0, temp0, null_adjust)		/* temp1_input */
3092c8dc071SDavid Brownell SHOW(temp1, temp1, null_adjust)		/* temp2_input */
3102c8dc071SDavid Brownell 
3112c8dc071SDavid Brownell 
3122c8dc071SDavid Brownell /* sysfs conventions report voltages in millivolts.  We can convert voltages
3132c8dc071SDavid Brownell  * if we know vREF.  userspace may need to scale vAUX to match the board's
3142c8dc071SDavid Brownell  * external resistors; we assume that vBATT only uses the internal ones.
3152c8dc071SDavid Brownell  */
3162c8dc071SDavid Brownell static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v)
3172c8dc071SDavid Brownell {
3182c8dc071SDavid Brownell 	unsigned retval = v;
3192c8dc071SDavid Brownell 
3202c8dc071SDavid Brownell 	/* external resistors may scale vAUX into 0..vREF */
3212c8dc071SDavid Brownell 	retval *= vREF_mV;
3222c8dc071SDavid Brownell 	retval = retval >> 12;
3232c8dc071SDavid Brownell 	return retval;
3242c8dc071SDavid Brownell }
3252c8dc071SDavid Brownell 
3262c8dc071SDavid Brownell static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v)
3272c8dc071SDavid Brownell {
3282c8dc071SDavid Brownell 	unsigned retval = vaux_adjust(ts, v);
3292c8dc071SDavid Brownell 
3302c8dc071SDavid Brownell 	/* ads7846 has a resistor ladder to scale this signal down */
3312c8dc071SDavid Brownell 	if (ts->model == 7846)
3322c8dc071SDavid Brownell 		retval *= 4;
3332c8dc071SDavid Brownell 	return retval;
3342c8dc071SDavid Brownell }
3352c8dc071SDavid Brownell 
3362c8dc071SDavid Brownell SHOW(in0_input, vaux, vaux_adjust)
3372c8dc071SDavid Brownell SHOW(in1_input, vbatt, vbatt_adjust)
3382c8dc071SDavid Brownell 
3392c8dc071SDavid Brownell 
3402c8dc071SDavid Brownell static struct attribute *ads7846_attributes[] = {
3412c8dc071SDavid Brownell 	&dev_attr_temp0.attr,
3422c8dc071SDavid Brownell 	&dev_attr_temp1.attr,
3432c8dc071SDavid Brownell 	&dev_attr_in0_input.attr,
3442c8dc071SDavid Brownell 	&dev_attr_in1_input.attr,
3452c8dc071SDavid Brownell 	NULL,
3462c8dc071SDavid Brownell };
3472c8dc071SDavid Brownell 
3482c8dc071SDavid Brownell static struct attribute_group ads7846_attr_group = {
3492c8dc071SDavid Brownell 	.attrs = ads7846_attributes,
3502c8dc071SDavid Brownell };
3512c8dc071SDavid Brownell 
3522c8dc071SDavid Brownell static struct attribute *ads7843_attributes[] = {
3532c8dc071SDavid Brownell 	&dev_attr_in0_input.attr,
3542c8dc071SDavid Brownell 	&dev_attr_in1_input.attr,
3552c8dc071SDavid Brownell 	NULL,
3562c8dc071SDavid Brownell };
3572c8dc071SDavid Brownell 
3582c8dc071SDavid Brownell static struct attribute_group ads7843_attr_group = {
3592c8dc071SDavid Brownell 	.attrs = ads7843_attributes,
3602c8dc071SDavid Brownell };
3612c8dc071SDavid Brownell 
3622c8dc071SDavid Brownell static struct attribute *ads7845_attributes[] = {
3632c8dc071SDavid Brownell 	&dev_attr_in0_input.attr,
3642c8dc071SDavid Brownell 	NULL,
3652c8dc071SDavid Brownell };
3662c8dc071SDavid Brownell 
3672c8dc071SDavid Brownell static struct attribute_group ads7845_attr_group = {
3682c8dc071SDavid Brownell 	.attrs = ads7845_attributes,
3692c8dc071SDavid Brownell };
3702c8dc071SDavid Brownell 
3712c8dc071SDavid Brownell static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts)
3722c8dc071SDavid Brownell {
3731beeffe4STony Jones 	struct device *hwmon;
3742c8dc071SDavid Brownell 	int err;
3752c8dc071SDavid Brownell 
3762c8dc071SDavid Brownell 	/* hwmon sensors need a reference voltage */
3772c8dc071SDavid Brownell 	switch (ts->model) {
3782c8dc071SDavid Brownell 	case 7846:
3792c8dc071SDavid Brownell 		if (!vREF_mV) {
3802c8dc071SDavid Brownell 			dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n");
3812c8dc071SDavid Brownell 			vREF_mV = 2500;
3822c8dc071SDavid Brownell 		}
3832c8dc071SDavid Brownell 		break;
3842c8dc071SDavid Brownell 	case 7845:
3852c8dc071SDavid Brownell 	case 7843:
3862c8dc071SDavid Brownell 		if (!vREF_mV) {
3872c8dc071SDavid Brownell 			dev_warn(&spi->dev,
3882c8dc071SDavid Brownell 				"external vREF for ADS%d not specified\n",
3892c8dc071SDavid Brownell 				ts->model);
3902c8dc071SDavid Brownell 			return 0;
3912c8dc071SDavid Brownell 		}
3922c8dc071SDavid Brownell 		break;
3932c8dc071SDavid Brownell 	}
3942c8dc071SDavid Brownell 
3952c8dc071SDavid Brownell 	/* different chips have different sensor groups */
3962c8dc071SDavid Brownell 	switch (ts->model) {
3972c8dc071SDavid Brownell 	case 7846:
3982c8dc071SDavid Brownell 		ts->attr_group = &ads7846_attr_group;
3992c8dc071SDavid Brownell 		break;
4002c8dc071SDavid Brownell 	case 7845:
4012c8dc071SDavid Brownell 		ts->attr_group = &ads7845_attr_group;
4022c8dc071SDavid Brownell 		break;
4032c8dc071SDavid Brownell 	case 7843:
4042c8dc071SDavid Brownell 		ts->attr_group = &ads7843_attr_group;
4052c8dc071SDavid Brownell 		break;
4062c8dc071SDavid Brownell 	default:
4072c8dc071SDavid Brownell 		dev_dbg(&spi->dev, "ADS%d not recognized\n", ts->model);
4082c8dc071SDavid Brownell 		return 0;
4092c8dc071SDavid Brownell 	}
4102c8dc071SDavid Brownell 
4112c8dc071SDavid Brownell 	err = sysfs_create_group(&spi->dev.kobj, ts->attr_group);
4122c8dc071SDavid Brownell 	if (err)
4132c8dc071SDavid Brownell 		return err;
4142c8dc071SDavid Brownell 
4152c8dc071SDavid Brownell 	hwmon = hwmon_device_register(&spi->dev);
4162c8dc071SDavid Brownell 	if (IS_ERR(hwmon)) {
4172c8dc071SDavid Brownell 		sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
4182c8dc071SDavid Brownell 		return PTR_ERR(hwmon);
4192c8dc071SDavid Brownell 	}
4202c8dc071SDavid Brownell 
4212c8dc071SDavid Brownell 	ts->hwmon = hwmon;
4222c8dc071SDavid Brownell 	return 0;
4232c8dc071SDavid Brownell }
4242c8dc071SDavid Brownell 
4252c8dc071SDavid Brownell static void ads784x_hwmon_unregister(struct spi_device *spi,
4262c8dc071SDavid Brownell 				     struct ads7846 *ts)
4272c8dc071SDavid Brownell {
4282c8dc071SDavid Brownell 	if (ts->hwmon) {
4292c8dc071SDavid Brownell 		sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
4302c8dc071SDavid Brownell 		hwmon_device_unregister(ts->hwmon);
4312c8dc071SDavid Brownell 	}
4322c8dc071SDavid Brownell }
4332c8dc071SDavid Brownell 
4342c8dc071SDavid Brownell #else
4352c8dc071SDavid Brownell static inline int ads784x_hwmon_register(struct spi_device *spi,
4362c8dc071SDavid Brownell 					 struct ads7846 *ts)
4372c8dc071SDavid Brownell {
4382c8dc071SDavid Brownell 	return 0;
4392c8dc071SDavid Brownell }
4402c8dc071SDavid Brownell 
4412c8dc071SDavid Brownell static inline void ads784x_hwmon_unregister(struct spi_device *spi,
4422c8dc071SDavid Brownell 					    struct ads7846 *ts)
4432c8dc071SDavid Brownell {
4442c8dc071SDavid Brownell }
4452c8dc071SDavid Brownell #endif
446ffa458c1SDavid Brownell 
447438f2a74SImre Deak static int is_pen_down(struct device *dev)
448438f2a74SImre Deak {
449438f2a74SImre Deak 	struct ads7846	*ts = dev_get_drvdata(dev);
450438f2a74SImre Deak 
451438f2a74SImre Deak 	return ts->pendown;
452438f2a74SImre Deak }
453438f2a74SImre Deak 
454438f2a74SImre Deak static ssize_t ads7846_pen_down_show(struct device *dev,
455438f2a74SImre Deak 				     struct device_attribute *attr, char *buf)
456438f2a74SImre Deak {
457438f2a74SImre Deak 	return sprintf(buf, "%u\n", is_pen_down(dev));
458438f2a74SImre Deak }
459438f2a74SImre Deak 
460438f2a74SImre Deak static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL);
461438f2a74SImre Deak 
4627de90a8cSImre Deak static ssize_t ads7846_disable_show(struct device *dev,
4637de90a8cSImre Deak 				     struct device_attribute *attr, char *buf)
4647de90a8cSImre Deak {
4657de90a8cSImre Deak 	struct ads7846	*ts = dev_get_drvdata(dev);
4667de90a8cSImre Deak 
4677de90a8cSImre Deak 	return sprintf(buf, "%u\n", ts->disabled);
4687de90a8cSImre Deak }
4697de90a8cSImre Deak 
4707de90a8cSImre Deak static ssize_t ads7846_disable_store(struct device *dev,
4717de90a8cSImre Deak 				     struct device_attribute *attr,
4727de90a8cSImre Deak 				     const char *buf, size_t count)
4737de90a8cSImre Deak {
4747de90a8cSImre Deak 	struct ads7846 *ts = dev_get_drvdata(dev);
4757de90a8cSImre Deak 	char *endp;
4767de90a8cSImre Deak 	int i;
4777de90a8cSImre Deak 
4787de90a8cSImre Deak 	i = simple_strtoul(buf, &endp, 10);
4797de90a8cSImre Deak 	spin_lock_irq(&ts->lock);
4807de90a8cSImre Deak 
4817de90a8cSImre Deak 	if (i)
4827de90a8cSImre Deak 		ads7846_disable(ts);
4837de90a8cSImre Deak 	else
4847de90a8cSImre Deak 		ads7846_enable(ts);
4857de90a8cSImre Deak 
4867de90a8cSImre Deak 	spin_unlock_irq(&ts->lock);
4877de90a8cSImre Deak 
4887de90a8cSImre Deak 	return count;
4897de90a8cSImre Deak }
4907de90a8cSImre Deak 
4917de90a8cSImre Deak static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store);
4927de90a8cSImre Deak 
4932c8dc071SDavid Brownell static struct attribute *ads784x_attributes[] = {
4948dd51650SDmitry Torokhov 	&dev_attr_pen_down.attr,
4958dd51650SDmitry Torokhov 	&dev_attr_disable.attr,
4968dd51650SDmitry Torokhov 	NULL,
4978dd51650SDmitry Torokhov };
4988dd51650SDmitry Torokhov 
4992c8dc071SDavid Brownell static struct attribute_group ads784x_attr_group = {
5002c8dc071SDavid Brownell 	.attrs = ads784x_attributes,
5018dd51650SDmitry Torokhov };
5028dd51650SDmitry Torokhov 
503ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/
504ffa458c1SDavid Brownell 
505ffa458c1SDavid Brownell /*
506ffa458c1SDavid Brownell  * PENIRQ only kicks the timer.  The timer only reissues the SPI transfer,
507ffa458c1SDavid Brownell  * to retrieve touchscreen status.
508ffa458c1SDavid Brownell  *
509ffa458c1SDavid Brownell  * The SPI transfer completion callback does the real work.  It reports
510ffa458c1SDavid Brownell  * touchscreen events and reactivates the timer (or IRQ) as appropriate.
511ffa458c1SDavid Brownell  */
512ffa458c1SDavid Brownell 
513ffa458c1SDavid Brownell static void ads7846_rx(void *ads)
514ffa458c1SDavid Brownell {
515ffa458c1SDavid Brownell 	struct ads7846		*ts = ads;
516ffa458c1SDavid Brownell 	unsigned		Rt;
517ffa458c1SDavid Brownell 	u16			x, y, z1, z2;
518ffa458c1SDavid Brownell 
519da970e69SImre Deak 	/* ads7846_rx_val() did in-place conversion (including byteswap) from
520da970e69SImre Deak 	 * on-the-wire format as part of debouncing to get stable readings.
521ffa458c1SDavid Brownell 	 */
522da970e69SImre Deak 	x = ts->tc.x;
523da970e69SImre Deak 	y = ts->tc.y;
524da970e69SImre Deak 	z1 = ts->tc.z1;
525da970e69SImre Deak 	z2 = ts->tc.z2;
526ffa458c1SDavid Brownell 
527ffa458c1SDavid Brownell 	/* range filtering */
528ffa458c1SDavid Brownell 	if (x == MAX_12BIT)
529ffa458c1SDavid Brownell 		x = 0;
530ffa458c1SDavid Brownell 
53115e3589eSImre Deak 	if (likely(x && z1)) {
532ffa458c1SDavid Brownell 		/* compute touch pressure resistance using equation #2 */
533ffa458c1SDavid Brownell 		Rt = z2;
534ffa458c1SDavid Brownell 		Rt -= z1;
535ffa458c1SDavid Brownell 		Rt *= x;
536ffa458c1SDavid Brownell 		Rt *= ts->x_plate_ohms;
537ffa458c1SDavid Brownell 		Rt /= z1;
538ffa458c1SDavid Brownell 		Rt = (Rt + 2047) >> 12;
539ffa458c1SDavid Brownell 	} else
540ffa458c1SDavid Brownell 		Rt = 0;
541ffa458c1SDavid Brownell 
542969111e9SNicolas Ferre 	if (ts->model == 7843)
543969111e9SNicolas Ferre 		Rt = ts->pressure_max / 2;
544969111e9SNicolas Ferre 
545d5b415c9SImre Deak 	/* Sample found inconsistent by debouncing or pressure is beyond
546d5b415c9SImre Deak 	 * the maximum. Don't report it to user space, repeat at least
5471936d590SImre Deak 	 * once more the measurement
5481936d590SImre Deak 	 */
549d5b415c9SImre Deak 	if (ts->tc.ignore || Rt > ts->pressure_max) {
55015e3589eSImre Deak #ifdef VERBOSE
55115e3589eSImre Deak 		pr_debug("%s: ignored %d pressure %d\n",
55215e3589eSImre Deak 			ts->spi->dev.bus_id, ts->tc.ignore, Rt);
55315e3589eSImre Deak #endif
5541936d590SImre Deak 		hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
555c9cb2e3dSThomas Gleixner 			      HRTIMER_MODE_REL);
556d5b415c9SImre Deak 		return;
557d5b415c9SImre Deak 	}
558d5b415c9SImre Deak 
5591d25891fSSemih Hazar 	/* Maybe check the pendown state before reporting. This discards
5601d25891fSSemih Hazar 	 * false readings when the pen is lifted.
5611d25891fSSemih Hazar 	 */
5621d25891fSSemih Hazar 	if (ts->penirq_recheck_delay_usecs) {
5631d25891fSSemih Hazar 		udelay(ts->penirq_recheck_delay_usecs);
5641d25891fSSemih Hazar 		if (!ts->get_pendown_state())
5651d25891fSSemih Hazar 			Rt = 0;
5661d25891fSSemih Hazar 	}
5671d25891fSSemih Hazar 
56815e3589eSImre Deak 	/* NOTE: We can't rely on the pressure to determine the pen down
56915e3589eSImre Deak 	 * state, even this controller has a pressure sensor.  The pressure
57015e3589eSImre Deak 	 * value can fluctuate for quite a while after lifting the pen and
57115e3589eSImre Deak 	 * in some cases may not even settle at the expected value.
572ffa458c1SDavid Brownell 	 *
57315e3589eSImre Deak 	 * The only safe way to check for the pen up condition is in the
57415e3589eSImre Deak 	 * timer by reading the pen signal state (it's a GPIO _and_ IRQ).
575ffa458c1SDavid Brownell 	 */
576ffa458c1SDavid Brownell 	if (Rt) {
57715e3589eSImre Deak 		struct input_dev *input = ts->input;
578ae82d5abSImre Deak 
57915e3589eSImre Deak 		if (!ts->pendown) {
58015e3589eSImre Deak 			input_report_key(input, BTN_TOUCH, 1);
58115e3589eSImre Deak 			ts->pendown = 1;
582ffa458c1SDavid Brownell #ifdef VERBOSE
58315e3589eSImre Deak 			dev_dbg(&ts->spi->dev, "DOWN\n");
584ffa458c1SDavid Brownell #endif
58515e3589eSImre Deak 		}
58615e3589eSImre Deak 		input_report_abs(input, ABS_X, x);
58715e3589eSImre Deak 		input_report_abs(input, ABS_Y, y);
58815e3589eSImre Deak 		input_report_abs(input, ABS_PRESSURE, Rt);
589ffa458c1SDavid Brownell 
59015e3589eSImre Deak 		input_sync(input);
59115e3589eSImre Deak #ifdef VERBOSE
59215e3589eSImre Deak 		dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt);
59315e3589eSImre Deak #endif
59415e3589eSImre Deak 	}
595ffa458c1SDavid Brownell 
596c9cb2e3dSThomas Gleixner 	hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
597c9cb2e3dSThomas Gleixner 			HRTIMER_MODE_REL);
598ffa458c1SDavid Brownell }
599ffa458c1SDavid Brownell 
600da970e69SImre Deak static int ads7846_debounce(void *ads, int data_idx, int *val)
601ffa458c1SDavid Brownell {
6020b7018aaSImre Deak 	struct ads7846		*ts = ads;
603ffa458c1SDavid Brownell 
604da970e69SImre Deak 	if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) {
605da970e69SImre Deak 		/* Start over collecting consistent readings. */
606da970e69SImre Deak 		ts->read_rep = 0;
607d5b415c9SImre Deak 		/* Repeat it, if this was the first read or the read
608d5b415c9SImre Deak 		 * wasn't consistent enough. */
609d5b415c9SImre Deak 		if (ts->read_cnt < ts->debounce_max) {
610da970e69SImre Deak 			ts->last_read = *val;
611d5b415c9SImre Deak 			ts->read_cnt++;
612da970e69SImre Deak 			return ADS7846_FILTER_REPEAT;
6130b7018aaSImre Deak 		} else {
614d5b415c9SImre Deak 			/* Maximum number of debouncing reached and still
615d5b415c9SImre Deak 			 * not enough number of consistent readings. Abort
616d5b415c9SImre Deak 			 * the whole sample, repeat it in the next sampling
617d5b415c9SImre Deak 			 * period.
618d5b415c9SImre Deak 			 */
619d5b415c9SImre Deak 			ts->read_cnt = 0;
620da970e69SImre Deak 			return ADS7846_FILTER_IGNORE;
621d5b415c9SImre Deak 		}
622d5b415c9SImre Deak 	} else {
623d5b415c9SImre Deak 		if (++ts->read_rep > ts->debounce_rep) {
624d5b415c9SImre Deak 			/* Got a good reading for this coordinate,
625d5b415c9SImre Deak 			 * go for the next one. */
6260b7018aaSImre Deak 			ts->read_cnt = 0;
627d5b415c9SImre Deak 			ts->read_rep = 0;
628da970e69SImre Deak 			return ADS7846_FILTER_OK;
629da970e69SImre Deak 		} else {
630d5b415c9SImre Deak 			/* Read more values that are consistent. */
631d5b415c9SImre Deak 			ts->read_cnt++;
632da970e69SImre Deak 			return ADS7846_FILTER_REPEAT;
633da970e69SImre Deak 		}
634da970e69SImre Deak 	}
635da970e69SImre Deak }
636da970e69SImre Deak 
637da970e69SImre Deak static int ads7846_no_filter(void *ads, int data_idx, int *val)
638da970e69SImre Deak {
639da970e69SImre Deak 	return ADS7846_FILTER_OK;
640da970e69SImre Deak }
641da970e69SImre Deak 
642da970e69SImre Deak static void ads7846_rx_val(void *ads)
643da970e69SImre Deak {
644da970e69SImre Deak 	struct ads7846 *ts = ads;
645da970e69SImre Deak 	struct spi_message *m;
646da970e69SImre Deak 	struct spi_transfer *t;
647da970e69SImre Deak 	u16 *rx_val;
648da970e69SImre Deak 	int val;
649da970e69SImre Deak 	int action;
650da970e69SImre Deak 	int status;
651da970e69SImre Deak 
652da970e69SImre Deak 	m = &ts->msg[ts->msg_idx];
653da970e69SImre Deak 	t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
654da970e69SImre Deak 	rx_val = t->rx_buf;
655da970e69SImre Deak 
656da970e69SImre Deak 	/* adjust:  on-wire is a must-ignore bit, a BE12 value, then padding;
657da970e69SImre Deak 	 * built from two 8 bit values written msb-first.
658da970e69SImre Deak 	 */
659da970e69SImre Deak 	val = be16_to_cpu(*rx_val) >> 3;
660da970e69SImre Deak 
661da970e69SImre Deak 	action = ts->filter(ts->filter_data, ts->msg_idx, &val);
662da970e69SImre Deak 	switch (action) {
663da970e69SImre Deak 	case ADS7846_FILTER_REPEAT:
664da970e69SImre Deak 		break;
665da970e69SImre Deak 	case ADS7846_FILTER_IGNORE:
666da970e69SImre Deak 		ts->tc.ignore = 1;
667da970e69SImre Deak 		/* Last message will contain ads7846_rx() as the
668da970e69SImre Deak 		 * completion function.
669da970e69SImre Deak 		 */
670da970e69SImre Deak 		m = ts->last_msg;
671da970e69SImre Deak 		break;
672da970e69SImre Deak 	case ADS7846_FILTER_OK:
673da970e69SImre Deak 		*rx_val = val;
674da970e69SImre Deak 		ts->tc.ignore = 0;
675da970e69SImre Deak 		m = &ts->msg[++ts->msg_idx];
676da970e69SImre Deak 		break;
677da970e69SImre Deak 	default:
678da970e69SImre Deak 		BUG();
679ffa458c1SDavid Brownell 	}
6800b7018aaSImre Deak 	status = spi_async(ts->spi, m);
681ffa458c1SDavid Brownell 	if (status)
682ffa458c1SDavid Brownell 		dev_err(&ts->spi->dev, "spi_async --> %d\n",
683ffa458c1SDavid Brownell 				status);
684ffa458c1SDavid Brownell }
6850b7018aaSImre Deak 
686c9cb2e3dSThomas Gleixner static enum hrtimer_restart ads7846_timer(struct hrtimer *handle)
6870b7018aaSImre Deak {
6881936d590SImre Deak 	struct ads7846	*ts = container_of(handle, struct ads7846, timer);
6890b7018aaSImre Deak 	int		status = 0;
6900b7018aaSImre Deak 
691c9e617a5SImre Deak 	spin_lock_irq(&ts->lock);
692c9e617a5SImre Deak 
69315e3589eSImre Deak 	if (unlikely(!ts->get_pendown_state() ||
69415e3589eSImre Deak 		     device_suspended(&ts->spi->dev))) {
69515e3589eSImre Deak 		if (ts->pendown) {
69615e3589eSImre Deak 			struct input_dev *input = ts->input;
69715e3589eSImre Deak 
69815e3589eSImre Deak 			input_report_key(input, BTN_TOUCH, 0);
69915e3589eSImre Deak 			input_report_abs(input, ABS_PRESSURE, 0);
70015e3589eSImre Deak 			input_sync(input);
70115e3589eSImre Deak 
70215e3589eSImre Deak 			ts->pendown = 0;
70315e3589eSImre Deak #ifdef VERBOSE
70415e3589eSImre Deak 			dev_dbg(&ts->spi->dev, "UP\n");
70515e3589eSImre Deak #endif
70615e3589eSImre Deak 		}
70715e3589eSImre Deak 
7089084533eSDavid Brownell 		/* measurement cycle ended */
709c9e617a5SImre Deak 		if (!device_suspended(&ts->spi->dev)) {
710c9e617a5SImre Deak 			ts->irq_disabled = 0;
711c9e617a5SImre Deak 			enable_irq(ts->spi->irq);
712c9e617a5SImre Deak 		}
713c9e617a5SImre Deak 		ts->pending = 0;
714c9e617a5SImre Deak 	} else {
715c9e617a5SImre Deak 		/* pen is still down, continue with the measurement */
7160b7018aaSImre Deak 		ts->msg_idx = 0;
7170b7018aaSImre Deak 		status = spi_async(ts->spi, &ts->msg[0]);
7180b7018aaSImre Deak 		if (status)
7190b7018aaSImre Deak 			dev_err(&ts->spi->dev, "spi_async --> %d\n", status);
720ffa458c1SDavid Brownell 	}
721ffa458c1SDavid Brownell 
722c9e617a5SImre Deak 	spin_unlock_irq(&ts->lock);
7231936d590SImre Deak 	return HRTIMER_NORESTART;
724c9e617a5SImre Deak }
725c9e617a5SImre Deak 
7267d12e780SDavid Howells static irqreturn_t ads7846_irq(int irq, void *handle)
727ffa458c1SDavid Brownell {
7280b7018aaSImre Deak 	struct ads7846 *ts = handle;
7290b7018aaSImre Deak 	unsigned long flags;
7300b7018aaSImre Deak 
7310b7018aaSImre Deak 	spin_lock_irqsave(&ts->lock, flags);
732c9e617a5SImre Deak 	if (likely(ts->get_pendown_state())) {
7330b7018aaSImre Deak 		if (!ts->irq_disabled) {
7349084533eSDavid Brownell 			/* The ARM do_simple_IRQ() dispatcher doesn't act
7359084533eSDavid Brownell 			 * like the other dispatchers:  it will report IRQs
7369084533eSDavid Brownell 			 * even after they've been disabled.  We work around
7379084533eSDavid Brownell 			 * that here.  (The "generic irq" framework may help...)
7380b7018aaSImre Deak 			 */
7390b7018aaSImre Deak 			ts->irq_disabled = 1;
7400b7018aaSImre Deak 			disable_irq(ts->spi->irq);
7410b7018aaSImre Deak 			ts->pending = 1;
7421936d590SImre Deak 			hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
743c9cb2e3dSThomas Gleixner 					HRTIMER_MODE_REL);
7440b7018aaSImre Deak 		}
7450b7018aaSImre Deak 	}
7460b7018aaSImre Deak 	spin_unlock_irqrestore(&ts->lock, flags);
7477de90a8cSImre Deak 
7487de90a8cSImre Deak 	return IRQ_HANDLED;
749ffa458c1SDavid Brownell }
750ffa458c1SDavid Brownell 
751ffa458c1SDavid Brownell /*--------------------------------------------------------------------------*/
752ffa458c1SDavid Brownell 
7537de90a8cSImre Deak /* Must be called with ts->lock held */
7547de90a8cSImre Deak static void ads7846_disable(struct ads7846 *ts)
755ffa458c1SDavid Brownell {
7567de90a8cSImre Deak 	if (ts->disabled)
7577de90a8cSImre Deak 		return;
758ffa458c1SDavid Brownell 
759c9e617a5SImre Deak 	ts->disabled = 1;
760c9e617a5SImre Deak 
761ffa458c1SDavid Brownell 	/* are we waiting for IRQ, or polling? */
762c9e617a5SImre Deak 	if (!ts->pending) {
763ffa458c1SDavid Brownell 		ts->irq_disabled = 1;
764ffa458c1SDavid Brownell 		disable_irq(ts->spi->irq);
765ffa458c1SDavid Brownell 	} else {
766c9e617a5SImre Deak 		/* the timer will run at least once more, and
767c9e617a5SImre Deak 		 * leave everything in a clean state, IRQ disabled
768ffa458c1SDavid Brownell 		 */
769c9e617a5SImre Deak 		while (ts->pending) {
7707de90a8cSImre Deak 			spin_unlock_irq(&ts->lock);
771c4febb94SJuha Yrjola 			msleep(1);
7727de90a8cSImre Deak 			spin_lock_irq(&ts->lock);
773ffa458c1SDavid Brownell 		}
774ffa458c1SDavid Brownell 	}
775ffa458c1SDavid Brownell 
776ffa458c1SDavid Brownell 	/* we know the chip's in lowpower mode since we always
777ffa458c1SDavid Brownell 	 * leave it that way after every request
778ffa458c1SDavid Brownell 	 */
779ffa458c1SDavid Brownell 
7807de90a8cSImre Deak }
7817de90a8cSImre Deak 
7827de90a8cSImre Deak /* Must be called with ts->lock held */
7837de90a8cSImre Deak static void ads7846_enable(struct ads7846 *ts)
7847de90a8cSImre Deak {
7857de90a8cSImre Deak 	if (!ts->disabled)
7867de90a8cSImre Deak 		return;
7877de90a8cSImre Deak 
7887de90a8cSImre Deak 	ts->disabled = 0;
7897de90a8cSImre Deak 	ts->irq_disabled = 0;
7907de90a8cSImre Deak 	enable_irq(ts->spi->irq);
7917de90a8cSImre Deak }
7927de90a8cSImre Deak 
7937de90a8cSImre Deak static int ads7846_suspend(struct spi_device *spi, pm_message_t message)
7947de90a8cSImre Deak {
7957de90a8cSImre Deak 	struct ads7846 *ts = dev_get_drvdata(&spi->dev);
7967de90a8cSImre Deak 
7977de90a8cSImre Deak 	spin_lock_irq(&ts->lock);
7987de90a8cSImre Deak 
799*fbb38e30SDavid Brownell 	ts->is_suspended = 1;
8007de90a8cSImre Deak 	ads7846_disable(ts);
8017de90a8cSImre Deak 
8027de90a8cSImre Deak 	spin_unlock_irq(&ts->lock);
8037de90a8cSImre Deak 
804ffa458c1SDavid Brownell 	return 0;
8057de90a8cSImre Deak 
806ffa458c1SDavid Brownell }
807ffa458c1SDavid Brownell 
8082e5a7bd9SDavid Brownell static int ads7846_resume(struct spi_device *spi)
809ffa458c1SDavid Brownell {
8102e5a7bd9SDavid Brownell 	struct ads7846 *ts = dev_get_drvdata(&spi->dev);
811ffa458c1SDavid Brownell 
8127de90a8cSImre Deak 	spin_lock_irq(&ts->lock);
8137de90a8cSImre Deak 
814*fbb38e30SDavid Brownell 	ts->is_suspended = 0;
8157de90a8cSImre Deak 	ads7846_enable(ts);
8167de90a8cSImre Deak 
8177de90a8cSImre Deak 	spin_unlock_irq(&ts->lock);
8187de90a8cSImre Deak 
819ffa458c1SDavid Brownell 	return 0;
820ffa458c1SDavid Brownell }
821ffa458c1SDavid Brownell 
8222e5a7bd9SDavid Brownell static int __devinit ads7846_probe(struct spi_device *spi)
823ffa458c1SDavid Brownell {
824ffa458c1SDavid Brownell 	struct ads7846			*ts;
825a90f7e98SDmitry Torokhov 	struct input_dev		*input_dev;
8262e5a7bd9SDavid Brownell 	struct ads7846_platform_data	*pdata = spi->dev.platform_data;
8270b7018aaSImre Deak 	struct spi_message		*m;
828ffa458c1SDavid Brownell 	struct spi_transfer		*x;
829de2defd9SImre Deak 	int				vref;
830a90f7e98SDmitry Torokhov 	int				err;
831ffa458c1SDavid Brownell 
832ffa458c1SDavid Brownell 	if (!spi->irq) {
8332e5a7bd9SDavid Brownell 		dev_dbg(&spi->dev, "no IRQ?\n");
834ffa458c1SDavid Brownell 		return -ENODEV;
835ffa458c1SDavid Brownell 	}
836ffa458c1SDavid Brownell 
837ffa458c1SDavid Brownell 	if (!pdata) {
8382e5a7bd9SDavid Brownell 		dev_dbg(&spi->dev, "no platform data?\n");
839ffa458c1SDavid Brownell 		return -ENODEV;
840ffa458c1SDavid Brownell 	}
841ffa458c1SDavid Brownell 
842ffa458c1SDavid Brownell 	/* don't exceed max specified sample rate */
843d93f70b2SDavid Brownell 	if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) {
8442e5a7bd9SDavid Brownell 		dev_dbg(&spi->dev, "f(sample) %d KHz?\n",
845d93f70b2SDavid Brownell 				(spi->max_speed_hz/SAMPLE_BITS)/1000);
846ffa458c1SDavid Brownell 		return -EINVAL;
847ffa458c1SDavid Brownell 	}
848ffa458c1SDavid Brownell 
8499084533eSDavid Brownell 	/* REVISIT when the irq can be triggered active-low, or if for some
8509084533eSDavid Brownell 	 * reason the touchscreen isn't hooked up, we don't need to access
8519084533eSDavid Brownell 	 * the pendown state.
8529084533eSDavid Brownell 	 */
853c9e617a5SImre Deak 	if (pdata->get_pendown_state == NULL) {
854c9e617a5SImre Deak 		dev_dbg(&spi->dev, "no get_pendown_state function?\n");
855c9e617a5SImre Deak 		return -EINVAL;
856c9e617a5SImre Deak 	}
857c9e617a5SImre Deak 
8589084533eSDavid Brownell 	/* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except
8599084533eSDavid Brownell 	 * that even if the hardware can do that, the SPI controller driver
8609084533eSDavid Brownell 	 * may not.  So we stick to very-portable 8 bit words, both RX and TX.
861ffa458c1SDavid Brownell 	 */
8629084533eSDavid Brownell 	spi->bits_per_word = 8;
863230ffc8eSSemih Hazar 	spi->mode = SPI_MODE_0;
8647937e86aSImre Deak 	err = spi_setup(spi);
8657937e86aSImre Deak 	if (err < 0)
8667937e86aSImre Deak 		return err;
867ffa458c1SDavid Brownell 
868a90f7e98SDmitry Torokhov 	ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
869a90f7e98SDmitry Torokhov 	input_dev = input_allocate_device();
870a90f7e98SDmitry Torokhov 	if (!ts || !input_dev) {
871a90f7e98SDmitry Torokhov 		err = -ENOMEM;
872a90f7e98SDmitry Torokhov 		goto err_free_mem;
873a90f7e98SDmitry Torokhov 	}
874ffa458c1SDavid Brownell 
8752e5a7bd9SDavid Brownell 	dev_set_drvdata(&spi->dev, ts);
876ffa458c1SDavid Brownell 
877ffa458c1SDavid Brownell 	ts->spi = spi;
878a90f7e98SDmitry Torokhov 	ts->input = input_dev;
879ffa458c1SDavid Brownell 
880c9cb2e3dSThomas Gleixner 	hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
881ffa458c1SDavid Brownell 	ts->timer.function = ads7846_timer;
882ffa458c1SDavid Brownell 
8837de90a8cSImre Deak 	spin_lock_init(&ts->lock);
8847de90a8cSImre Deak 
885ffa458c1SDavid Brownell 	ts->model = pdata->model ? : 7846;
886ffa458c1SDavid Brownell 	ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
887ffa458c1SDavid Brownell 	ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
888d5b415c9SImre Deak 	ts->pressure_max = pdata->pressure_max ? : ~0;
889da970e69SImre Deak 
890da970e69SImre Deak 	if (pdata->filter != NULL) {
891da970e69SImre Deak 		if (pdata->filter_init != NULL) {
892da970e69SImre Deak 			err = pdata->filter_init(pdata, &ts->filter_data);
893da970e69SImre Deak 			if (err < 0)
894da970e69SImre Deak 				goto err_free_mem;
895da970e69SImre Deak 		}
896da970e69SImre Deak 		ts->filter = pdata->filter;
897da970e69SImre Deak 		ts->filter_cleanup = pdata->filter_cleanup;
898da970e69SImre Deak 	} else if (pdata->debounce_max) {
899d5b415c9SImre Deak 		ts->debounce_max = pdata->debounce_max;
900da970e69SImre Deak 		if (ts->debounce_max < 2)
901da970e69SImre Deak 			ts->debounce_max = 2;
902d5b415c9SImre Deak 		ts->debounce_tol = pdata->debounce_tol;
903d5b415c9SImre Deak 		ts->debounce_rep = pdata->debounce_rep;
904da970e69SImre Deak 		ts->filter = ads7846_debounce;
905da970e69SImre Deak 		ts->filter_data = ts;
906d5b415c9SImre Deak 	} else
907da970e69SImre Deak 		ts->filter = ads7846_no_filter;
908c9e617a5SImre Deak 	ts->get_pendown_state = pdata->get_pendown_state;
909ffa458c1SDavid Brownell 
9101d25891fSSemih Hazar 	if (pdata->penirq_recheck_delay_usecs)
9111d25891fSSemih Hazar 		ts->penirq_recheck_delay_usecs =
9121d25891fSSemih Hazar 				pdata->penirq_recheck_delay_usecs;
9131d25891fSSemih Hazar 
914a90f7e98SDmitry Torokhov 	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id);
915ffa458c1SDavid Brownell 
916a90f7e98SDmitry Torokhov 	input_dev->name = "ADS784x Touchscreen";
917a90f7e98SDmitry Torokhov 	input_dev->phys = ts->phys;
918a5394fb0SDmitry Torokhov 	input_dev->dev.parent = &spi->dev;
919ffa458c1SDavid Brownell 
9207b19ada2SJiri Slaby 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
9217b19ada2SJiri Slaby 	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
922a90f7e98SDmitry Torokhov 	input_set_abs_params(input_dev, ABS_X,
923ffa458c1SDavid Brownell 			pdata->x_min ? : 0,
924ffa458c1SDavid Brownell 			pdata->x_max ? : MAX_12BIT,
925ffa458c1SDavid Brownell 			0, 0);
926a90f7e98SDmitry Torokhov 	input_set_abs_params(input_dev, ABS_Y,
927ffa458c1SDavid Brownell 			pdata->y_min ? : 0,
928ffa458c1SDavid Brownell 			pdata->y_max ? : MAX_12BIT,
929ffa458c1SDavid Brownell 			0, 0);
930a90f7e98SDmitry Torokhov 	input_set_abs_params(input_dev, ABS_PRESSURE,
931ffa458c1SDavid Brownell 			pdata->pressure_min, pdata->pressure_max, 0, 0);
932ffa458c1SDavid Brownell 
933de2defd9SImre Deak 	vref = pdata->keep_vref_on;
934de2defd9SImre Deak 
935ffa458c1SDavid Brownell 	/* set up the transfers to read touchscreen state; this assumes we
936ffa458c1SDavid Brownell 	 * use formula #2 for pressure, not #3.
937ffa458c1SDavid Brownell 	 */
9380b7018aaSImre Deak 	m = &ts->msg[0];
939ffa458c1SDavid Brownell 	x = ts->xfer;
940ffa458c1SDavid Brownell 
9410b7018aaSImre Deak 	spi_message_init(m);
9420b7018aaSImre Deak 
943ffa458c1SDavid Brownell 	/* y- still on; turn on only y+ (and ADC) */
944de2defd9SImre Deak 	ts->read_y = READ_Y(vref);
945d93f70b2SDavid Brownell 	x->tx_buf = &ts->read_y;
946ffa458c1SDavid Brownell 	x->len = 1;
9470b7018aaSImre Deak 	spi_message_add_tail(x, m);
948d93f70b2SDavid Brownell 
949ffa458c1SDavid Brownell 	x++;
950ffa458c1SDavid Brownell 	x->rx_buf = &ts->tc.y;
951ffa458c1SDavid Brownell 	x->len = 2;
9520b7018aaSImre Deak 	spi_message_add_tail(x, m);
953ffa458c1SDavid Brownell 
954e4f48861SSemih Hazar 	/* the first sample after switching drivers can be low quality;
955e4f48861SSemih Hazar 	 * optionally discard it, using a second one after the signals
956e4f48861SSemih Hazar 	 * have had enough time to stabilize.
957e4f48861SSemih Hazar 	 */
958e4f48861SSemih Hazar 	if (pdata->settle_delay_usecs) {
959e4f48861SSemih Hazar 		x->delay_usecs = pdata->settle_delay_usecs;
960e4f48861SSemih Hazar 
961e4f48861SSemih Hazar 		x++;
962e4f48861SSemih Hazar 		x->tx_buf = &ts->read_y;
963e4f48861SSemih Hazar 		x->len = 1;
964e4f48861SSemih Hazar 		spi_message_add_tail(x, m);
965e4f48861SSemih Hazar 
966e4f48861SSemih Hazar 		x++;
967e4f48861SSemih Hazar 		x->rx_buf = &ts->tc.y;
968e4f48861SSemih Hazar 		x->len = 2;
969e4f48861SSemih Hazar 		spi_message_add_tail(x, m);
970e4f48861SSemih Hazar 	}
971e4f48861SSemih Hazar 
972da970e69SImre Deak 	m->complete = ads7846_rx_val;
9730b7018aaSImre Deak 	m->context = ts;
974d93f70b2SDavid Brownell 
9750b7018aaSImre Deak 	m++;
9760b7018aaSImre Deak 	spi_message_init(m);
977ffa458c1SDavid Brownell 
978ffa458c1SDavid Brownell 	/* turn y- off, x+ on, then leave in lowpower */
979d93f70b2SDavid Brownell 	x++;
980de2defd9SImre Deak 	ts->read_x = READ_X(vref);
981d93f70b2SDavid Brownell 	x->tx_buf = &ts->read_x;
982ffa458c1SDavid Brownell 	x->len = 1;
9830b7018aaSImre Deak 	spi_message_add_tail(x, m);
984d93f70b2SDavid Brownell 
985ffa458c1SDavid Brownell 	x++;
986ffa458c1SDavid Brownell 	x->rx_buf = &ts->tc.x;
987ffa458c1SDavid Brownell 	x->len = 2;
9880b7018aaSImre Deak 	spi_message_add_tail(x, m);
9890b7018aaSImre Deak 
990e4f48861SSemih Hazar 	/* ... maybe discard first sample ... */
991e4f48861SSemih Hazar 	if (pdata->settle_delay_usecs) {
992e4f48861SSemih Hazar 		x->delay_usecs = pdata->settle_delay_usecs;
993e4f48861SSemih Hazar 
994e4f48861SSemih Hazar 		x++;
995e4f48861SSemih Hazar 		x->tx_buf = &ts->read_x;
996e4f48861SSemih Hazar 		x->len = 1;
997e4f48861SSemih Hazar 		spi_message_add_tail(x, m);
998e4f48861SSemih Hazar 
999e4f48861SSemih Hazar 		x++;
1000e4f48861SSemih Hazar 		x->rx_buf = &ts->tc.x;
1001e4f48861SSemih Hazar 		x->len = 2;
1002e4f48861SSemih Hazar 		spi_message_add_tail(x, m);
1003e4f48861SSemih Hazar 	}
1004e4f48861SSemih Hazar 
1005da970e69SImre Deak 	m->complete = ads7846_rx_val;
10060b7018aaSImre Deak 	m->context = ts;
10070b7018aaSImre Deak 
10080b7018aaSImre Deak 	/* turn y+ off, x- on; we'll use formula #2 */
10090b7018aaSImre Deak 	if (ts->model == 7846) {
10100b7018aaSImre Deak 		m++;
10110b7018aaSImre Deak 		spi_message_init(m);
10120b7018aaSImre Deak 
10130b7018aaSImre Deak 		x++;
1014de2defd9SImre Deak 		ts->read_z1 = READ_Z1(vref);
10150b7018aaSImre Deak 		x->tx_buf = &ts->read_z1;
10160b7018aaSImre Deak 		x->len = 1;
10170b7018aaSImre Deak 		spi_message_add_tail(x, m);
10180b7018aaSImre Deak 
10190b7018aaSImre Deak 		x++;
10200b7018aaSImre Deak 		x->rx_buf = &ts->tc.z1;
10210b7018aaSImre Deak 		x->len = 2;
10220b7018aaSImre Deak 		spi_message_add_tail(x, m);
10230b7018aaSImre Deak 
1024e4f48861SSemih Hazar 		/* ... maybe discard first sample ... */
1025e4f48861SSemih Hazar 		if (pdata->settle_delay_usecs) {
1026e4f48861SSemih Hazar 			x->delay_usecs = pdata->settle_delay_usecs;
1027e4f48861SSemih Hazar 
1028e4f48861SSemih Hazar 			x++;
1029e4f48861SSemih Hazar 			x->tx_buf = &ts->read_z1;
1030e4f48861SSemih Hazar 			x->len = 1;
1031e4f48861SSemih Hazar 			spi_message_add_tail(x, m);
1032e4f48861SSemih Hazar 
1033e4f48861SSemih Hazar 			x++;
1034e4f48861SSemih Hazar 			x->rx_buf = &ts->tc.z1;
1035e4f48861SSemih Hazar 			x->len = 2;
1036e4f48861SSemih Hazar 			spi_message_add_tail(x, m);
1037e4f48861SSemih Hazar 		}
1038e4f48861SSemih Hazar 
1039da970e69SImre Deak 		m->complete = ads7846_rx_val;
10400b7018aaSImre Deak 		m->context = ts;
10410b7018aaSImre Deak 
10420b7018aaSImre Deak 		m++;
10430b7018aaSImre Deak 		spi_message_init(m);
10440b7018aaSImre Deak 
10450b7018aaSImre Deak 		x++;
1046de2defd9SImre Deak 		ts->read_z2 = READ_Z2(vref);
10470b7018aaSImre Deak 		x->tx_buf = &ts->read_z2;
10480b7018aaSImre Deak 		x->len = 1;
10490b7018aaSImre Deak 		spi_message_add_tail(x, m);
10500b7018aaSImre Deak 
10510b7018aaSImre Deak 		x++;
10520b7018aaSImre Deak 		x->rx_buf = &ts->tc.z2;
10530b7018aaSImre Deak 		x->len = 2;
10540b7018aaSImre Deak 		spi_message_add_tail(x, m);
10550b7018aaSImre Deak 
1056e4f48861SSemih Hazar 		/* ... maybe discard first sample ... */
1057e4f48861SSemih Hazar 		if (pdata->settle_delay_usecs) {
1058e4f48861SSemih Hazar 			x->delay_usecs = pdata->settle_delay_usecs;
1059e4f48861SSemih Hazar 
1060e4f48861SSemih Hazar 			x++;
1061e4f48861SSemih Hazar 			x->tx_buf = &ts->read_z2;
1062e4f48861SSemih Hazar 			x->len = 1;
1063e4f48861SSemih Hazar 			spi_message_add_tail(x, m);
1064e4f48861SSemih Hazar 
1065e4f48861SSemih Hazar 			x++;
1066e4f48861SSemih Hazar 			x->rx_buf = &ts->tc.z2;
1067e4f48861SSemih Hazar 			x->len = 2;
1068e4f48861SSemih Hazar 			spi_message_add_tail(x, m);
1069e4f48861SSemih Hazar 		}
1070e4f48861SSemih Hazar 
1071da970e69SImre Deak 		m->complete = ads7846_rx_val;
10720b7018aaSImre Deak 		m->context = ts;
10730b7018aaSImre Deak 	}
107453a0ef89SImre Deak 
107553a0ef89SImre Deak 	/* power down */
10760b7018aaSImre Deak 	m++;
10770b7018aaSImre Deak 	spi_message_init(m);
10780b7018aaSImre Deak 
107953a0ef89SImre Deak 	x++;
108053a0ef89SImre Deak 	ts->pwrdown = PWRDOWN;
108153a0ef89SImre Deak 	x->tx_buf = &ts->pwrdown;
108253a0ef89SImre Deak 	x->len = 1;
10830b7018aaSImre Deak 	spi_message_add_tail(x, m);
108453a0ef89SImre Deak 
108553a0ef89SImre Deak 	x++;
108653a0ef89SImre Deak 	x->rx_buf = &ts->dummy;
108753a0ef89SImre Deak 	x->len = 2;
1088d93f70b2SDavid Brownell 	CS_CHANGE(*x);
10890b7018aaSImre Deak 	spi_message_add_tail(x, m);
1090ffa458c1SDavid Brownell 
10910b7018aaSImre Deak 	m->complete = ads7846_rx;
10920b7018aaSImre Deak 	m->context = ts;
1093ffa458c1SDavid Brownell 
1094d5b415c9SImre Deak 	ts->last_msg = m;
1095d5b415c9SImre Deak 
1096dace1453SThomas Gleixner 	if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING,
10979084533eSDavid Brownell 			spi->dev.driver->name, ts)) {
10982e5a7bd9SDavid Brownell 		dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
1099a90f7e98SDmitry Torokhov 		err = -EBUSY;
1100da970e69SImre Deak 		goto err_cleanup_filter;
1101ffa458c1SDavid Brownell 	}
1102ffa458c1SDavid Brownell 
11032c8dc071SDavid Brownell 	err = ads784x_hwmon_register(spi, ts);
11042c8dc071SDavid Brownell 	if (err)
11052c8dc071SDavid Brownell 		goto err_free_irq;
11062c8dc071SDavid Brownell 
11072e5a7bd9SDavid Brownell 	dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq);
1108ffa458c1SDavid Brownell 
11092c8dc071SDavid Brownell 	/* take a first sample, leaving nPENIRQ active and vREF off; avoid
1110ffa458c1SDavid Brownell 	 * the touchscreen, in case it's not connected.
1111ffa458c1SDavid Brownell 	 */
11122e5a7bd9SDavid Brownell 	(void) ads7846_read12_ser(&spi->dev,
1113ffa458c1SDavid Brownell 			  READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
1114ffa458c1SDavid Brownell 
11152c8dc071SDavid Brownell 	err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group);
11168dd51650SDmitry Torokhov 	if (err)
11172c8dc071SDavid Brownell 		goto err_remove_hwmon;
11187de90a8cSImre Deak 
1119a90f7e98SDmitry Torokhov 	err = input_register_device(input_dev);
1120a90f7e98SDmitry Torokhov 	if (err)
11218dd51650SDmitry Torokhov 		goto err_remove_attr_group;
1122a90f7e98SDmitry Torokhov 
1123ffa458c1SDavid Brownell 	return 0;
1124a90f7e98SDmitry Torokhov 
11258dd51650SDmitry Torokhov  err_remove_attr_group:
11262c8dc071SDavid Brownell 	sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group);
11272c8dc071SDavid Brownell  err_remove_hwmon:
11282c8dc071SDavid Brownell 	ads784x_hwmon_unregister(spi, ts);
11298dd51650SDmitry Torokhov  err_free_irq:
1130a90f7e98SDmitry Torokhov 	free_irq(spi->irq, ts);
1131da970e69SImre Deak  err_cleanup_filter:
1132da970e69SImre Deak 	if (ts->filter_cleanup)
1133da970e69SImre Deak 		ts->filter_cleanup(ts->filter_data);
1134a90f7e98SDmitry Torokhov  err_free_mem:
1135a90f7e98SDmitry Torokhov 	input_free_device(input_dev);
1136a90f7e98SDmitry Torokhov 	kfree(ts);
1137a90f7e98SDmitry Torokhov 	return err;
1138ffa458c1SDavid Brownell }
1139ffa458c1SDavid Brownell 
11402e5a7bd9SDavid Brownell static int __devexit ads7846_remove(struct spi_device *spi)
1141ffa458c1SDavid Brownell {
11422e5a7bd9SDavid Brownell 	struct ads7846		*ts = dev_get_drvdata(&spi->dev);
1143ffa458c1SDavid Brownell 
11442c8dc071SDavid Brownell 	ads784x_hwmon_unregister(spi, ts);
11457de90a8cSImre Deak 	input_unregister_device(ts->input);
11467de90a8cSImre Deak 
11472e5a7bd9SDavid Brownell 	ads7846_suspend(spi, PMSG_SUSPEND);
1148ffa458c1SDavid Brownell 
11492c8dc071SDavid Brownell 	sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group);
1150ffa458c1SDavid Brownell 
11517de90a8cSImre Deak 	free_irq(ts->spi->irq, ts);
1152c9e617a5SImre Deak 	/* suspend left the IRQ disabled */
11537de90a8cSImre Deak 	enable_irq(ts->spi->irq);
11547de90a8cSImre Deak 
1155da970e69SImre Deak 	if (ts->filter_cleanup)
1156da970e69SImre Deak 		ts->filter_cleanup(ts->filter_data);
1157da970e69SImre Deak 
1158ffa458c1SDavid Brownell 	kfree(ts);
1159ffa458c1SDavid Brownell 
11602e5a7bd9SDavid Brownell 	dev_dbg(&spi->dev, "unregistered touchscreen\n");
1161ffa458c1SDavid Brownell 	return 0;
1162ffa458c1SDavid Brownell }
1163ffa458c1SDavid Brownell 
11642e5a7bd9SDavid Brownell static struct spi_driver ads7846_driver = {
11652e5a7bd9SDavid Brownell 	.driver = {
1166ffa458c1SDavid Brownell 		.name	= "ads7846",
1167ffa458c1SDavid Brownell 		.bus	= &spi_bus_type,
11682e5a7bd9SDavid Brownell 		.owner	= THIS_MODULE,
11692e5a7bd9SDavid Brownell 	},
1170ffa458c1SDavid Brownell 	.probe		= ads7846_probe,
11712e5a7bd9SDavid Brownell 	.remove		= __devexit_p(ads7846_remove),
1172ffa458c1SDavid Brownell 	.suspend	= ads7846_suspend,
1173ffa458c1SDavid Brownell 	.resume		= ads7846_resume,
1174ffa458c1SDavid Brownell };
1175ffa458c1SDavid Brownell 
1176ffa458c1SDavid Brownell static int __init ads7846_init(void)
1177ffa458c1SDavid Brownell {
1178ffa458c1SDavid Brownell 	/* grr, board-specific init should stay out of drivers!! */
1179ffa458c1SDavid Brownell 
1180ffa458c1SDavid Brownell #ifdef	CONFIG_ARCH_OMAP
1181ffa458c1SDavid Brownell 	if (machine_is_omap_osk()) {
1182ffa458c1SDavid Brownell 		/* GPIO4 = PENIRQ; GPIO6 = BUSY */
1183ffa458c1SDavid Brownell 		omap_request_gpio(4);
1184ffa458c1SDavid Brownell 		omap_set_gpio_direction(4, 1);
1185ffa458c1SDavid Brownell 		omap_request_gpio(6);
1186ffa458c1SDavid Brownell 		omap_set_gpio_direction(6, 1);
1187ffa458c1SDavid Brownell 	}
1188ffa458c1SDavid Brownell 	// also TI 1510 Innovator, bitbanging through FPGA
1189ffa458c1SDavid Brownell 	// also Nokia 770
1190ffa458c1SDavid Brownell 	// also Palm Tungsten T2
1191ffa458c1SDavid Brownell #endif
1192ffa458c1SDavid Brownell 
1193ffa458c1SDavid Brownell 	// PXA:
1194ffa458c1SDavid Brownell 	// also Dell Axim X50
1195ffa458c1SDavid Brownell 	// also HP iPaq H191x/H192x/H415x/H435x
11962e5a7bd9SDavid Brownell 	// also Intel Lubbock (additional to UCB1400; as temperature sensor)
1197ffa458c1SDavid Brownell 	// also Sharp Zaurus C7xx, C8xx (corgi/sheperd/husky)
1198ffa458c1SDavid Brownell 
11992e5a7bd9SDavid Brownell 	// Atmel at91sam9261-EK uses ads7843
12002e5a7bd9SDavid Brownell 
1201ffa458c1SDavid Brownell 	// also various AMD Au1x00 devel boards
1202ffa458c1SDavid Brownell 
12032e5a7bd9SDavid Brownell 	return spi_register_driver(&ads7846_driver);
1204ffa458c1SDavid Brownell }
1205ffa458c1SDavid Brownell module_init(ads7846_init);
1206ffa458c1SDavid Brownell 
1207ffa458c1SDavid Brownell static void __exit ads7846_exit(void)
1208ffa458c1SDavid Brownell {
12092e5a7bd9SDavid Brownell 	spi_unregister_driver(&ads7846_driver);
1210ffa458c1SDavid Brownell 
1211ffa458c1SDavid Brownell #ifdef	CONFIG_ARCH_OMAP
1212ffa458c1SDavid Brownell 	if (machine_is_omap_osk()) {
1213ffa458c1SDavid Brownell 		omap_free_gpio(4);
1214ffa458c1SDavid Brownell 		omap_free_gpio(6);
1215ffa458c1SDavid Brownell 	}
1216ffa458c1SDavid Brownell #endif
1217ffa458c1SDavid Brownell 
1218ffa458c1SDavid Brownell }
1219ffa458c1SDavid Brownell module_exit(ads7846_exit);
1220ffa458c1SDavid Brownell 
1221ffa458c1SDavid Brownell MODULE_DESCRIPTION("ADS7846 TouchScreen Driver");
1222ffa458c1SDavid Brownell MODULE_LICENSE("GPL");
1223