Blame view

drivers/input/touchscreen/ads7846.c 30.2 KB
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1
2
3
4
  /*
   * ADS7846 based touchscreen and sensor driver
   *
   * Copyright (c) 2005 David Brownell
7de90a8cb   Imre Deak   Input: ads7846 - ...
5
6
   * Copyright (c) 2006 Nokia Corporation
   * Various changes: Imre Deak <imre.deak@nokia.com>
ffa458c1b   David Brownell   [PATCH] spi: ads7...
7
8
9
10
11
12
13
14
15
16
17
18
19
   *
   * Using code from:
   *  - corgi_ts.c
   *	Copyright (C) 2004-2005 Richard Purdie
   *  - omap_ts.[hc], ads7846.h, ts_osk.c
   *	Copyright (C) 2002 MontaVista Software
   *	Copyright (C) 2004 Texas Instruments
   *	Copyright (C) 2005 Dirk Behme
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License version 2 as
   *  published by the Free Software Foundation.
   */
2c8dc0715   David Brownell   Input: ads7846 - ...
20
  #include <linux/hwmon.h>
ffa458c1b   David Brownell   [PATCH] spi: ads7...
21
  #include <linux/init.h>
2c8dc0715   David Brownell   Input: ads7846 - ...
22
  #include <linux/err.h>
ffa458c1b   David Brownell   [PATCH] spi: ads7...
23
24
25
26
  #include <linux/delay.h>
  #include <linux/input.h>
  #include <linux/interrupt.h>
  #include <linux/slab.h>
4d5975e50   Eric Miao   Input: ads7846 - ...
27
  #include <linux/gpio.h>
ffa458c1b   David Brownell   [PATCH] spi: ads7...
28
29
  #include <linux/spi/spi.h>
  #include <linux/spi/ads7846.h>
3ac8bf077   Andrew Morton   [PATCH] ads7846: ...
30
  #include <asm/irq.h>
ffa458c1b   David Brownell   [PATCH] spi: ads7...
31

ffa458c1b   David Brownell   [PATCH] spi: ads7...
32
  /*
9084533e7   David Brownell   [PATCH] ads7846 c...
33
   * This code has been heavily tested on a Nokia 770, and lightly
52ce4eaa3   Pavel Machek   Input: ads7846 - ...
34
   * tested on other ads7846 devices (OSK/Mistral, Lubbock, Spitz).
bff0de5f5   David Brownell   Input: ads7846 - ...
35
   * TSC2046 is just newer ads7846 silicon.
969111e90   Nicolas Ferre   Input: ads7846 - ...
36
37
   * Support for ads7843 tested on Atmel at91sam926x-EK.
   * Support for ads7845 has only been stubbed in.
ffa458c1b   David Brownell   [PATCH] spi: ads7...
38
   *
7de90a8cb   Imre Deak   Input: ads7846 - ...
39
40
41
42
43
44
   * IRQ handling needs a workaround because of a shortcoming in handling
   * edge triggered IRQs on some platforms like the OMAP1/2. These
   * platforms don't handle the ARM lazy IRQ disabling properly, thus we
   * have to maintain our own SW IRQ disabled status. This should be
   * removed as soon as the affected platform's IRQ handling is fixed.
   *
52ce4eaa3   Pavel Machek   Input: ads7846 - ...
45
   * App note sbaa036 talks in more detail about accurate sampling...
ffa458c1b   David Brownell   [PATCH] spi: ads7...
46
47
   * that ought to help in situations like LCDs inducing noise (which
   * can also be helped by using synch signals) and more generally.
7de90a8cb   Imre Deak   Input: ads7846 - ...
48
49
50
   * This driver tries to utilize the measures described in the app
   * note. The strength of filtering can be set in the board-* specific
   * files.
ffa458c1b   David Brownell   [PATCH] spi: ads7...
51
   */
1936d590a   Imre Deak   Input: ads7846 - ...
52
53
  #define TS_POLL_DELAY	(1 * 1000000)	/* ns delay before the first sample */
  #define TS_POLL_PERIOD	(5 * 1000000)	/* ns delay between samples */
ffa458c1b   David Brownell   [PATCH] spi: ads7...
54

d93f70b2d   David Brownell   Input: ads7846 - ...
55
56
  /* this driver doesn't aim at the peak continuous sample rate */
  #define	SAMPLE_BITS	(8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
ffa458c1b   David Brownell   [PATCH] spi: ads7...
57
58
59
  struct ts_event {
  	/* For portability, we can't read 12 bit values using SPI (which
  	 * would make the controller deliver them as native byteorder u16
d93f70b2d   David Brownell   Input: ads7846 - ...
60
  	 * with msbs zeroed).  Instead, we read them as two 8-bit values,
da970e69e   Imre Deak   Input: ads7846 - ...
61
  	 * *** WHICH NEED BYTESWAPPING *** and range adjustment.
ffa458c1b   David Brownell   [PATCH] spi: ads7...
62
  	 */
da970e69e   Imre Deak   Input: ads7846 - ...
63
64
65
  	u16	x;
  	u16	y;
  	u16	z1, z2;
2c8dc0715   David Brownell   Input: ads7846 - ...
66
  	int	ignore;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
67
  };
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
68
69
70
71
72
73
74
75
76
77
  /*
   * We allocate this separately to avoid cache line sharing issues when
   * driver is used with DMA-based SPI controllers (like atmel_spi) on
   * systems where main memory is not DMA-coherent (most non-x86 boards).
   */
  struct ads7846_packet {
  	u8			read_x, read_y, read_z1, read_z2, pwrdown;
  	u16			dummy;		/* for the pwrdown read */
  	struct ts_event		tc;
  };
ffa458c1b   David Brownell   [PATCH] spi: ads7...
78
  struct ads7846 {
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
79
  	struct input_dev	*input;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
80
  	char			phys[32];
b58895f8b   Michael Roth   Input: ads7846 - ...
81
  	char			name[32];
ffa458c1b   David Brownell   [PATCH] spi: ads7...
82
83
  
  	struct spi_device	*spi;
2c8dc0715   David Brownell   Input: ads7846 - ...
84
85
  
  #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
8dd51650b   Dmitry Torokhov   Input: ads7846 - ...
86
  	struct attribute_group	*attr_group;
1beeffe43   Tony Jones   hwmon: Convert fr...
87
  	struct device		*hwmon;
2c8dc0715   David Brownell   Input: ads7846 - ...
88
  #endif
ffa458c1b   David Brownell   [PATCH] spi: ads7...
89
  	u16			model;
7c6d0ee14   David Brownell   Input: ads7846 - ...
90
  	u16			vref_mv;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
91
92
  	u16			vref_delay_usecs;
  	u16			x_plate_ohms;
d5b415c95   Imre Deak   Input: ads7846 - ...
93
  	u16			pressure_max;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
94

86579a4cc   Michael Roth   Input: ads7846 - ...
95
  	bool			swap_xy;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
96
  	struct ads7846_packet	*packet;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
97

e4f488619   Semih Hazar   Input: ads7846 - ...
98
  	struct spi_transfer	xfer[18];
0b7018aae   Imre Deak   Input: ads7846 - ...
99
  	struct spi_message	msg[5];
d5b415c95   Imre Deak   Input: ads7846 - ...
100
  	struct spi_message	*last_msg;
0b7018aae   Imre Deak   Input: ads7846 - ...
101
102
  	int			msg_idx;
  	int			read_cnt;
d5b415c95   Imre Deak   Input: ads7846 - ...
103
  	int			read_rep;
0b7018aae   Imre Deak   Input: ads7846 - ...
104
105
106
107
  	int			last_read;
  
  	u16			debounce_max;
  	u16			debounce_tol;
d5b415c95   Imre Deak   Input: ads7846 - ...
108
  	u16			debounce_rep;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
109

1d25891f3   Semih Hazar   Input: ads7846 - ...
110
  	u16			penirq_recheck_delay_usecs;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
111
  	spinlock_t		lock;
1936d590a   Imre Deak   Input: ads7846 - ...
112
  	struct hrtimer		timer;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
113
114
115
116
  	unsigned		pendown:1;	/* P: lock */
  	unsigned		pending:1;	/* P: lock */
  // FIXME remove "irq_disabled"
  	unsigned		irq_disabled:1;	/* P: lock */
7de90a8cb   Imre Deak   Input: ads7846 - ...
117
  	unsigned		disabled:1;
fbb38e30e   David Brownell   Input: ads7846 - ...
118
  	unsigned		is_suspended:1;
c9e617a56   Imre Deak   Input: ads7846 - ...
119

da970e69e   Imre Deak   Input: ads7846 - ...
120
121
122
  	int			(*filter)(void *data, int data_idx, int *val);
  	void			*filter_data;
  	void			(*filter_cleanup)(void *data);
c9e617a56   Imre Deak   Input: ads7846 - ...
123
  	int			(*get_pendown_state)(void);
4d5975e50   Eric Miao   Input: ads7846 - ...
124
  	int			gpio_pendown;
fd746d540   Eric Miao   Input: ads7846 - ...
125
126
  
  	void			(*wait_for_sync)(void);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  };
  
  /* leave chip selected when we're done, for quicker re-select? */
  #if	0
  #define	CS_CHANGE(xfer)	((xfer).cs_change = 1)
  #else
  #define	CS_CHANGE(xfer)	((xfer).cs_change = 0)
  #endif
  
  /*--------------------------------------------------------------------------*/
  
  /* The ADS7846 has touchscreen and other sensors.
   * Earlier ads784x chips are somewhat compatible.
   */
  #define	ADS_START		(1 << 7)
  #define	ADS_A2A1A0_d_y		(1 << 4)	/* differential */
  #define	ADS_A2A1A0_d_z1		(3 << 4)	/* differential */
  #define	ADS_A2A1A0_d_z2		(4 << 4)	/* differential */
  #define	ADS_A2A1A0_d_x		(5 << 4)	/* differential */
  #define	ADS_A2A1A0_temp0	(0 << 4)	/* non-differential */
  #define	ADS_A2A1A0_vbatt	(2 << 4)	/* non-differential */
  #define	ADS_A2A1A0_vaux		(6 << 4)	/* non-differential */
  #define	ADS_A2A1A0_temp1	(7 << 4)	/* non-differential */
  #define	ADS_8_BIT		(1 << 3)
  #define	ADS_12_BIT		(0 << 3)
  #define	ADS_SER			(1 << 2)	/* non-differential */
  #define	ADS_DFR			(0 << 2)	/* differential */
  #define	ADS_PD10_PDOWN		(0 << 0)	/* lowpower mode + penirq */
  #define	ADS_PD10_ADC_ON		(1 << 0)	/* ADC on */
  #define	ADS_PD10_REF_ON		(2 << 0)	/* vREF on + penirq */
  #define	ADS_PD10_ALL_ON		(3 << 0)	/* ADC + vREF on */
  
  #define	MAX_12BIT	((1<<12)-1)
  
  /* leave ADC powered up (disables penirq) between differential samples */
de2defd96   Imre Deak   Input: ads7846 - ...
162
163
164
  #define	READ_12BIT_DFR(x, adc, vref) (ADS_START | ADS_A2A1A0_d_ ## x \
  	| ADS_12_BIT | ADS_DFR | \
  	(adc ? ADS_PD10_ADC_ON : 0) | (vref ? ADS_PD10_REF_ON : 0))
ffa458c1b   David Brownell   [PATCH] spi: ads7...
165

de2defd96   Imre Deak   Input: ads7846 - ...
166
167
168
  #define	READ_Y(vref)	(READ_12BIT_DFR(y,  1, vref))
  #define	READ_Z1(vref)	(READ_12BIT_DFR(z1, 1, vref))
  #define	READ_Z2(vref)	(READ_12BIT_DFR(z2, 1, vref))
53a0ef89e   Imre Deak   Input: ads7846 - ...
169

de2defd96   Imre Deak   Input: ads7846 - ...
170
171
  #define	READ_X(vref)	(READ_12BIT_DFR(x,  1, vref))
  #define	PWRDOWN		(READ_12BIT_DFR(y,  0, 0))	/* LAST */
ffa458c1b   David Brownell   [PATCH] spi: ads7...
172
173
174
175
176
177
  
  /* single-ended samples need to first power up reference voltage;
   * we leave both ADC and VREF powered
   */
  #define	READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \
  	| ADS_12_BIT | ADS_SER)
de2defd96   Imre Deak   Input: ads7846 - ...
178
179
  #define	REF_ON	(READ_12BIT_DFR(x, 1, 1))
  #define	REF_OFF	(READ_12BIT_DFR(y, 0, 0))
ffa458c1b   David Brownell   [PATCH] spi: ads7...
180
181
182
183
184
  
  /*--------------------------------------------------------------------------*/
  
  /*
   * Non-touchscreen sensors only use single-ended conversions.
2c8dc0715   David Brownell   Input: ads7846 - ...
185
186
   * The range is GND..vREF. The ads7843 and ads7835 must use external vREF;
   * ads7846 lets that pin be unconnected, to use internal vREF.
ffa458c1b   David Brownell   [PATCH] spi: ads7...
187
188
189
   */
  
  struct ser_req {
d93f70b2d   David Brownell   Input: ads7846 - ...
190
  	u8			ref_on;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
191
  	u8			command;
d93f70b2d   David Brownell   Input: ads7846 - ...
192
  	u8			ref_off;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
193
194
195
196
197
  	u16			scratch;
  	__be16			sample;
  	struct spi_message	msg;
  	struct spi_transfer	xfer[6];
  };
7de90a8cb   Imre Deak   Input: ads7846 - ...
198
199
  static void ads7846_enable(struct ads7846 *ts);
  static void ads7846_disable(struct ads7846 *ts);
c9e617a56   Imre Deak   Input: ads7846 - ...
200
201
202
  static int device_suspended(struct device *dev)
  {
  	struct ads7846 *ts = dev_get_drvdata(dev);
fbb38e30e   David Brownell   Input: ads7846 - ...
203
  	return ts->is_suspended || ts->disabled;
c9e617a56   Imre Deak   Input: ads7846 - ...
204
  }
ffa458c1b   David Brownell   [PATCH] spi: ads7...
205
206
207
208
  static int ads7846_read12_ser(struct device *dev, unsigned command)
  {
  	struct spi_device	*spi = to_spi_device(dev);
  	struct ads7846		*ts = dev_get_drvdata(dev);
e94b17660   Christoph Lameter   [PATCH] slab: rem...
209
  	struct ser_req		*req = kzalloc(sizeof *req, GFP_KERNEL);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
210
  	int			status;
2c8dc0715   David Brownell   Input: ads7846 - ...
211
  	int			use_internal;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
212
213
214
  
  	if (!req)
  		return -ENOMEM;
0b7018aae   Imre Deak   Input: ads7846 - ...
215
  	spi_message_init(&req->msg);
8275c642c   Vitaly Wool   [PATCH] spi: use ...
216

2c8dc0715   David Brownell   Input: ads7846 - ...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  	/* FIXME boards with ads7846 might use external vref instead ... */
  	use_internal = (ts->model == 7846);
  
  	/* maybe turn on internal vREF, and let it settle */
  	if (use_internal) {
  		req->ref_on = REF_ON;
  		req->xfer[0].tx_buf = &req->ref_on;
  		req->xfer[0].len = 1;
  		spi_message_add_tail(&req->xfer[0], &req->msg);
  
  		req->xfer[1].rx_buf = &req->scratch;
  		req->xfer[1].len = 2;
  
  		/* for 1uF, settle for 800 usec; no cap, 100 usec.  */
  		req->xfer[1].delay_usecs = ts->vref_delay_usecs;
  		spi_message_add_tail(&req->xfer[1], &req->msg);
  	}
ffa458c1b   David Brownell   [PATCH] spi: ads7...
234
235
236
237
238
  
  	/* take sample */
  	req->command = (u8) command;
  	req->xfer[2].tx_buf = &req->command;
  	req->xfer[2].len = 1;
2c8dc0715   David Brownell   Input: ads7846 - ...
239
  	spi_message_add_tail(&req->xfer[2], &req->msg);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
240
241
  	req->xfer[3].rx_buf = &req->sample;
  	req->xfer[3].len = 2;
2c8dc0715   David Brownell   Input: ads7846 - ...
242
  	spi_message_add_tail(&req->xfer[3], &req->msg);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
243
244
  
  	/* REVISIT:  take a few more samples, and compare ... */
969111e90   Nicolas Ferre   Input: ads7846 - ...
245
246
247
248
249
250
251
252
253
254
  	/* converter in low power mode & enable PENIRQ */
  	req->ref_off = PWRDOWN;
  	req->xfer[4].tx_buf = &req->ref_off;
  	req->xfer[4].len = 1;
  	spi_message_add_tail(&req->xfer[4], &req->msg);
  
  	req->xfer[5].rx_buf = &req->scratch;
  	req->xfer[5].len = 2;
  	CS_CHANGE(req->xfer[5]);
  	spi_message_add_tail(&req->xfer[5], &req->msg);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
255

c9e617a56   Imre Deak   Input: ads7846 - ...
256
  	ts->irq_disabled = 1;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
257
258
  	disable_irq(spi->irq);
  	status = spi_sync(spi, &req->msg);
c9e617a56   Imre Deak   Input: ads7846 - ...
259
  	ts->irq_disabled = 0;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
260
  	enable_irq(spi->irq);
c24b2602a   Marc Pignat   spi: use simplifi...
261
262
  	if (status == 0) {
  		/* on-wire is a must-ignore bit, a BE12 value, then padding */
7c6d0ee14   David Brownell   Input: ads7846 - ...
263
264
265
  		status = be16_to_cpu(req->sample);
  		status = status >> 3;
  		status &= 0x0fff;
c24b2602a   Marc Pignat   spi: use simplifi...
266
  	}
ffa458c1b   David Brownell   [PATCH] spi: ads7...
267

9084533e7   David Brownell   [PATCH] ads7846 c...
268
  	kfree(req);
7c6d0ee14   David Brownell   Input: ads7846 - ...
269
  	return status;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
270
  }
2c8dc0715   David Brownell   Input: ads7846 - ...
271
272
273
  #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
  
  #define SHOW(name, var, adjust) static ssize_t \
ffa458c1b   David Brownell   [PATCH] spi: ads7...
274
275
  name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
  { \
2c8dc0715   David Brownell   Input: ads7846 - ...
276
  	struct ads7846 *ts = dev_get_drvdata(dev); \
ffa458c1b   David Brownell   [PATCH] spi: ads7...
277
  	ssize_t v = ads7846_read12_ser(dev, \
2c8dc0715   David Brownell   Input: ads7846 - ...
278
  			READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \
ffa458c1b   David Brownell   [PATCH] spi: ads7...
279
280
  	if (v < 0) \
  		return v; \
2c8dc0715   David Brownell   Input: ads7846 - ...
281
282
  	return sprintf(buf, "%u
  ", adjust(ts, v)); \
ffa458c1b   David Brownell   [PATCH] spi: ads7...
283
284
  } \
  static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
2c8dc0715   David Brownell   Input: ads7846 - ...
285

b731d7b6a   Adam Buchbinder   trivial: Fix miss...
286
  /* Sysfs conventions report temperatures in millidegrees Celsius.
2c8dc0715   David Brownell   Input: ads7846 - ...
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
   * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high
   * accuracy scheme without calibration data.  For now we won't try either;
   * userspace sees raw sensor values, and must scale/calibrate appropriately.
   */
  static inline unsigned null_adjust(struct ads7846 *ts, ssize_t v)
  {
  	return v;
  }
  
  SHOW(temp0, temp0, null_adjust)		/* temp1_input */
  SHOW(temp1, temp1, null_adjust)		/* temp2_input */
  
  
  /* sysfs conventions report voltages in millivolts.  We can convert voltages
   * if we know vREF.  userspace may need to scale vAUX to match the board's
   * external resistors; we assume that vBATT only uses the internal ones.
   */
  static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v)
  {
  	unsigned retval = v;
  
  	/* external resistors may scale vAUX into 0..vREF */
7c6d0ee14   David Brownell   Input: ads7846 - ...
309
  	retval *= ts->vref_mv;
2c8dc0715   David Brownell   Input: ads7846 - ...
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
  	retval = retval >> 12;
  	return retval;
  }
  
  static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v)
  {
  	unsigned retval = vaux_adjust(ts, v);
  
  	/* ads7846 has a resistor ladder to scale this signal down */
  	if (ts->model == 7846)
  		retval *= 4;
  	return retval;
  }
  
  SHOW(in0_input, vaux, vaux_adjust)
  SHOW(in1_input, vbatt, vbatt_adjust)
  
  
  static struct attribute *ads7846_attributes[] = {
  	&dev_attr_temp0.attr,
  	&dev_attr_temp1.attr,
  	&dev_attr_in0_input.attr,
  	&dev_attr_in1_input.attr,
  	NULL,
  };
  
  static struct attribute_group ads7846_attr_group = {
  	.attrs = ads7846_attributes,
  };
  
  static struct attribute *ads7843_attributes[] = {
  	&dev_attr_in0_input.attr,
  	&dev_attr_in1_input.attr,
  	NULL,
  };
  
  static struct attribute_group ads7843_attr_group = {
  	.attrs = ads7843_attributes,
  };
  
  static struct attribute *ads7845_attributes[] = {
  	&dev_attr_in0_input.attr,
  	NULL,
  };
  
  static struct attribute_group ads7845_attr_group = {
  	.attrs = ads7845_attributes,
  };
  
  static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts)
  {
1beeffe43   Tony Jones   hwmon: Convert fr...
361
  	struct device *hwmon;
2c8dc0715   David Brownell   Input: ads7846 - ...
362
363
364
365
366
  	int err;
  
  	/* hwmon sensors need a reference voltage */
  	switch (ts->model) {
  	case 7846:
7c6d0ee14   David Brownell   Input: ads7846 - ...
367
  		if (!ts->vref_mv) {
2c8dc0715   David Brownell   Input: ads7846 - ...
368
369
  			dev_dbg(&spi->dev, "assuming 2.5V internal vREF
  ");
7c6d0ee14   David Brownell   Input: ads7846 - ...
370
  			ts->vref_mv = 2500;
2c8dc0715   David Brownell   Input: ads7846 - ...
371
372
373
374
  		}
  		break;
  	case 7845:
  	case 7843:
7c6d0ee14   David Brownell   Input: ads7846 - ...
375
  		if (!ts->vref_mv) {
2c8dc0715   David Brownell   Input: ads7846 - ...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
  			dev_warn(&spi->dev,
  				"external vREF for ADS%d not specified
  ",
  				ts->model);
  			return 0;
  		}
  		break;
  	}
  
  	/* different chips have different sensor groups */
  	switch (ts->model) {
  	case 7846:
  		ts->attr_group = &ads7846_attr_group;
  		break;
  	case 7845:
  		ts->attr_group = &ads7845_attr_group;
  		break;
  	case 7843:
  		ts->attr_group = &ads7843_attr_group;
  		break;
  	default:
  		dev_dbg(&spi->dev, "ADS%d not recognized
  ", ts->model);
  		return 0;
  	}
  
  	err = sysfs_create_group(&spi->dev.kobj, ts->attr_group);
  	if (err)
  		return err;
  
  	hwmon = hwmon_device_register(&spi->dev);
  	if (IS_ERR(hwmon)) {
  		sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
  		return PTR_ERR(hwmon);
  	}
  
  	ts->hwmon = hwmon;
  	return 0;
  }
  
  static void ads784x_hwmon_unregister(struct spi_device *spi,
  				     struct ads7846 *ts)
  {
  	if (ts->hwmon) {
  		sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
  		hwmon_device_unregister(ts->hwmon);
  	}
  }
  
  #else
  static inline int ads784x_hwmon_register(struct spi_device *spi,
  					 struct ads7846 *ts)
  {
  	return 0;
  }
  
  static inline void ads784x_hwmon_unregister(struct spi_device *spi,
  					    struct ads7846 *ts)
  {
  }
  #endif
ffa458c1b   David Brownell   [PATCH] spi: ads7...
437

438f2a740   Imre Deak   Input: ads7846 - ...
438
439
  static int is_pen_down(struct device *dev)
  {
2c8dc0715   David Brownell   Input: ads7846 - ...
440
  	struct ads7846	*ts = dev_get_drvdata(dev);
438f2a740   Imre Deak   Input: ads7846 - ...
441
442
443
444
445
446
447
448
449
450
451
452
  
  	return ts->pendown;
  }
  
  static ssize_t ads7846_pen_down_show(struct device *dev,
  				     struct device_attribute *attr, char *buf)
  {
  	return sprintf(buf, "%u
  ", is_pen_down(dev));
  }
  
  static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL);
7de90a8cb   Imre Deak   Input: ads7846 - ...
453
454
455
456
457
458
459
460
461
462
463
464
465
466
  static ssize_t ads7846_disable_show(struct device *dev,
  				     struct device_attribute *attr, char *buf)
  {
  	struct ads7846	*ts = dev_get_drvdata(dev);
  
  	return sprintf(buf, "%u
  ", ts->disabled);
  }
  
  static ssize_t ads7846_disable_store(struct device *dev,
  				     struct device_attribute *attr,
  				     const char *buf, size_t count)
  {
  	struct ads7846 *ts = dev_get_drvdata(dev);
3a0c58ddc   Harvey Harrison   Input: ads7846 - ...
467
  	unsigned long i;
160f1fef7   Joe Rouvier   Input: convert dr...
468
469
470
  
  	if (strict_strtoul(buf, 10, &i))
  		return -EINVAL;
7de90a8cb   Imre Deak   Input: ads7846 - ...
471

7de90a8cb   Imre Deak   Input: ads7846 - ...
472
473
474
475
476
477
478
479
480
481
482
483
484
  	spin_lock_irq(&ts->lock);
  
  	if (i)
  		ads7846_disable(ts);
  	else
  		ads7846_enable(ts);
  
  	spin_unlock_irq(&ts->lock);
  
  	return count;
  }
  
  static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store);
2c8dc0715   David Brownell   Input: ads7846 - ...
485
  static struct attribute *ads784x_attributes[] = {
8dd51650b   Dmitry Torokhov   Input: ads7846 - ...
486
487
488
489
  	&dev_attr_pen_down.attr,
  	&dev_attr_disable.attr,
  	NULL,
  };
2c8dc0715   David Brownell   Input: ads7846 - ...
490
491
  static struct attribute_group ads784x_attr_group = {
  	.attrs = ads784x_attributes,
8dd51650b   Dmitry Torokhov   Input: ads7846 - ...
492
  };
ffa458c1b   David Brownell   [PATCH] spi: ads7...
493
  /*--------------------------------------------------------------------------*/
4d5975e50   Eric Miao   Input: ads7846 - ...
494
495
496
497
498
499
500
  static int get_pendown_state(struct ads7846 *ts)
  {
  	if (ts->get_pendown_state)
  		return ts->get_pendown_state();
  
  	return !gpio_get_value(ts->gpio_pendown);
  }
fd746d540   Eric Miao   Input: ads7846 - ...
501
502
503
  static void null_wait_for_sync(void)
  {
  }
ffa458c1b   David Brownell   [PATCH] spi: ads7...
504
505
506
507
508
509
510
511
512
513
  /*
   * PENIRQ only kicks the timer.  The timer only reissues the SPI transfer,
   * to retrieve touchscreen status.
   *
   * The SPI transfer completion callback does the real work.  It reports
   * touchscreen events and reactivates the timer (or IRQ) as appropriate.
   */
  
  static void ads7846_rx(void *ads)
  {
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
514
  	struct ads7846		*ts = ads;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
515
  	struct ads7846_packet	*packet = ts->packet;
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
516
  	unsigned		Rt;
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
517
  	u16			x, y, z1, z2;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
518

da970e69e   Imre Deak   Input: ads7846 - ...
519
520
  	/* ads7846_rx_val() did in-place conversion (including byteswap) from
  	 * on-the-wire format as part of debouncing to get stable readings.
ffa458c1b   David Brownell   [PATCH] spi: ads7...
521
  	 */
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
522
523
524
525
  	x = packet->tc.x;
  	y = packet->tc.y;
  	z1 = packet->tc.z1;
  	z2 = packet->tc.z2;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
526
527
528
529
  
  	/* range filtering */
  	if (x == MAX_12BIT)
  		x = 0;
9460b6529   Hans-Christian Egtvedt   Input: ads7846 - ...
530
531
532
  	if (ts->model == 7843) {
  		Rt = ts->pressure_max / 2;
  	} else if (likely(x && z1)) {
ffa458c1b   David Brownell   [PATCH] spi: ads7...
533
534
535
536
537
538
539
  		/* compute touch pressure resistance using equation #2 */
  		Rt = z2;
  		Rt -= z1;
  		Rt *= x;
  		Rt *= ts->x_plate_ohms;
  		Rt /= z1;
  		Rt = (Rt + 2047) >> 12;
9460b6529   Hans-Christian Egtvedt   Input: ads7846 - ...
540
  	} else {
ffa458c1b   David Brownell   [PATCH] spi: ads7...
541
  		Rt = 0;
9460b6529   Hans-Christian Egtvedt   Input: ads7846 - ...
542
  	}
969111e90   Nicolas Ferre   Input: ads7846 - ...
543

d5b415c95   Imre Deak   Input: ads7846 - ...
544
  	/* Sample found inconsistent by debouncing or pressure is beyond
1936d590a   Imre Deak   Input: ads7846 - ...
545
546
547
  	 * the maximum. Don't report it to user space, repeat at least
  	 * once more the measurement
  	 */
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
548
  	if (packet->tc.ignore || Rt > ts->pressure_max) {
52ce4eaa3   Pavel Machek   Input: ads7846 - ...
549
550
551
  		dev_vdbg(&ts->spi->dev, "ignored %d pressure %d
  ",
  			 packet->tc.ignore, Rt);
1936d590a   Imre Deak   Input: ads7846 - ...
552
  		hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
553
  			      HRTIMER_MODE_REL);
d5b415c95   Imre Deak   Input: ads7846 - ...
554
555
  		return;
  	}
1d25891f3   Semih Hazar   Input: ads7846 - ...
556
557
558
559
560
  	/* Maybe check the pendown state before reporting. This discards
  	 * false readings when the pen is lifted.
  	 */
  	if (ts->penirq_recheck_delay_usecs) {
  		udelay(ts->penirq_recheck_delay_usecs);
4d5975e50   Eric Miao   Input: ads7846 - ...
561
  		if (!get_pendown_state(ts))
1d25891f3   Semih Hazar   Input: ads7846 - ...
562
563
  			Rt = 0;
  	}
15e3589e5   Imre Deak   Input: ads7846 - ...
564
565
566
567
  	/* NOTE: We can't rely on the pressure to determine the pen down
  	 * state, even this controller has a pressure sensor.  The pressure
  	 * value can fluctuate for quite a while after lifting the pen and
  	 * in some cases may not even settle at the expected value.
ffa458c1b   David Brownell   [PATCH] spi: ads7...
568
  	 *
15e3589e5   Imre Deak   Input: ads7846 - ...
569
570
  	 * The only safe way to check for the pen up condition is in the
  	 * timer by reading the pen signal state (it's a GPIO _and_ IRQ).
ffa458c1b   David Brownell   [PATCH] spi: ads7...
571
  	 */
ffa458c1b   David Brownell   [PATCH] spi: ads7...
572
  	if (Rt) {
15e3589e5   Imre Deak   Input: ads7846 - ...
573
  		struct input_dev *input = ts->input;
ae82d5ab0   Imre Deak   Input: ads7846 - ...
574

15e3589e5   Imre Deak   Input: ads7846 - ...
575
576
577
  		if (!ts->pendown) {
  			input_report_key(input, BTN_TOUCH, 1);
  			ts->pendown = 1;
52ce4eaa3   Pavel Machek   Input: ads7846 - ...
578
579
  			dev_vdbg(&ts->spi->dev, "DOWN
  ");
15e3589e5   Imre Deak   Input: ads7846 - ...
580
  		}
86579a4cc   Michael Roth   Input: ads7846 - ...
581
582
583
  
  		if (ts->swap_xy)
  			swap(x, y);
15e3589e5   Imre Deak   Input: ads7846 - ...
584
585
  		input_report_abs(input, ABS_X, x);
  		input_report_abs(input, ABS_Y, y);
30ad7ba0a   Pavel Machek   Input: ads7846 - ...
586
  		input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
587

15e3589e5   Imre Deak   Input: ads7846 - ...
588
  		input_sync(input);
52ce4eaa3   Pavel Machek   Input: ads7846 - ...
589
590
  		dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d
  ", x, y, Rt);
15e3589e5   Imre Deak   Input: ads7846 - ...
591
  	}
ffa458c1b   David Brownell   [PATCH] spi: ads7...
592

c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
593
594
  	hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
  			HRTIMER_MODE_REL);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
595
  }
da970e69e   Imre Deak   Input: ads7846 - ...
596
  static int ads7846_debounce(void *ads, int data_idx, int *val)
0b7018aae   Imre Deak   Input: ads7846 - ...
597
598
  {
  	struct ads7846		*ts = ads;
0b7018aae   Imre Deak   Input: ads7846 - ...
599

da970e69e   Imre Deak   Input: ads7846 - ...
600
601
602
  	if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) {
  		/* Start over collecting consistent readings. */
  		ts->read_rep = 0;
d5b415c95   Imre Deak   Input: ads7846 - ...
603
604
605
  		/* Repeat it, if this was the first read or the read
  		 * wasn't consistent enough. */
  		if (ts->read_cnt < ts->debounce_max) {
da970e69e   Imre Deak   Input: ads7846 - ...
606
  			ts->last_read = *val;
d5b415c95   Imre Deak   Input: ads7846 - ...
607
  			ts->read_cnt++;
da970e69e   Imre Deak   Input: ads7846 - ...
608
  			return ADS7846_FILTER_REPEAT;
d5b415c95   Imre Deak   Input: ads7846 - ...
609
610
611
612
613
614
  		} else {
  			/* Maximum number of debouncing reached and still
  			 * not enough number of consistent readings. Abort
  			 * the whole sample, repeat it in the next sampling
  			 * period.
  			 */
d5b415c95   Imre Deak   Input: ads7846 - ...
615
  			ts->read_cnt = 0;
da970e69e   Imre Deak   Input: ads7846 - ...
616
  			return ADS7846_FILTER_IGNORE;
d5b415c95   Imre Deak   Input: ads7846 - ...
617
  		}
0b7018aae   Imre Deak   Input: ads7846 - ...
618
  	} else {
d5b415c95   Imre Deak   Input: ads7846 - ...
619
620
621
  		if (++ts->read_rep > ts->debounce_rep) {
  			/* Got a good reading for this coordinate,
  			 * go for the next one. */
d5b415c95   Imre Deak   Input: ads7846 - ...
622
623
  			ts->read_cnt = 0;
  			ts->read_rep = 0;
da970e69e   Imre Deak   Input: ads7846 - ...
624
625
  			return ADS7846_FILTER_OK;
  		} else {
d5b415c95   Imre Deak   Input: ads7846 - ...
626
627
  			/* Read more values that are consistent. */
  			ts->read_cnt++;
da970e69e   Imre Deak   Input: ads7846 - ...
628
629
630
631
632
633
634
635
636
637
638
639
640
  			return ADS7846_FILTER_REPEAT;
  		}
  	}
  }
  
  static int ads7846_no_filter(void *ads, int data_idx, int *val)
  {
  	return ADS7846_FILTER_OK;
  }
  
  static void ads7846_rx_val(void *ads)
  {
  	struct ads7846 *ts = ads;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
641
  	struct ads7846_packet *packet = ts->packet;
da970e69e   Imre Deak   Input: ads7846 - ...
642
643
  	struct spi_message *m;
  	struct spi_transfer *t;
da970e69e   Imre Deak   Input: ads7846 - ...
644
645
646
647
648
649
  	int val;
  	int action;
  	int status;
  
  	m = &ts->msg[ts->msg_idx];
  	t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
da970e69e   Imre Deak   Input: ads7846 - ...
650
651
652
653
  
  	/* adjust:  on-wire is a must-ignore bit, a BE12 value, then padding;
  	 * built from two 8 bit values written msb-first.
  	 */
494f68577   Harvey Harrison   Input: ads7846 - ...
654
  	val = be16_to_cpup((__be16 *)t->rx_buf) >> 3;
da970e69e   Imre Deak   Input: ads7846 - ...
655
656
657
658
659
660
  
  	action = ts->filter(ts->filter_data, ts->msg_idx, &val);
  	switch (action) {
  	case ADS7846_FILTER_REPEAT:
  		break;
  	case ADS7846_FILTER_IGNORE:
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
661
  		packet->tc.ignore = 1;
da970e69e   Imre Deak   Input: ads7846 - ...
662
663
664
665
666
667
  		/* Last message will contain ads7846_rx() as the
  		 * completion function.
  		 */
  		m = ts->last_msg;
  		break;
  	case ADS7846_FILTER_OK:
494f68577   Harvey Harrison   Input: ads7846 - ...
668
  		*(u16 *)t->rx_buf = val;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
669
  		packet->tc.ignore = 0;
da970e69e   Imre Deak   Input: ads7846 - ...
670
671
672
673
  		m = &ts->msg[++ts->msg_idx];
  		break;
  	default:
  		BUG();
0b7018aae   Imre Deak   Input: ads7846 - ...
674
  	}
fd746d540   Eric Miao   Input: ads7846 - ...
675
  	ts->wait_for_sync();
0b7018aae   Imre Deak   Input: ads7846 - ...
676
677
678
679
680
681
  	status = spi_async(ts->spi, m);
  	if (status)
  		dev_err(&ts->spi->dev, "spi_async --> %d
  ",
  				status);
  }
c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
682
  static enum hrtimer_restart ads7846_timer(struct hrtimer *handle)
ffa458c1b   David Brownell   [PATCH] spi: ads7...
683
  {
1936d590a   Imre Deak   Input: ads7846 - ...
684
  	struct ads7846	*ts = container_of(handle, struct ads7846, timer);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
685
  	int		status = 0;
0b7018aae   Imre Deak   Input: ads7846 - ...
686

ca109491f   Peter Zijlstra   hrtimer: removing...
687
  	spin_lock(&ts->lock);
c9e617a56   Imre Deak   Input: ads7846 - ...
688

4d5975e50   Eric Miao   Input: ads7846 - ...
689
  	if (unlikely(!get_pendown_state(ts) ||
15e3589e5   Imre Deak   Input: ads7846 - ...
690
691
692
693
694
695
696
697
698
  		     device_suspended(&ts->spi->dev))) {
  		if (ts->pendown) {
  			struct input_dev *input = ts->input;
  
  			input_report_key(input, BTN_TOUCH, 0);
  			input_report_abs(input, ABS_PRESSURE, 0);
  			input_sync(input);
  
  			ts->pendown = 0;
52ce4eaa3   Pavel Machek   Input: ads7846 - ...
699
700
  			dev_vdbg(&ts->spi->dev, "UP
  ");
15e3589e5   Imre Deak   Input: ads7846 - ...
701
  		}
9084533e7   David Brownell   [PATCH] ads7846 c...
702
  		/* measurement cycle ended */
c9e617a56   Imre Deak   Input: ads7846 - ...
703
704
705
706
707
  		if (!device_suspended(&ts->spi->dev)) {
  			ts->irq_disabled = 0;
  			enable_irq(ts->spi->irq);
  		}
  		ts->pending = 0;
c9e617a56   Imre Deak   Input: ads7846 - ...
708
709
710
  	} else {
  		/* pen is still down, continue with the measurement */
  		ts->msg_idx = 0;
fd746d540   Eric Miao   Input: ads7846 - ...
711
  		ts->wait_for_sync();
c9e617a56   Imre Deak   Input: ads7846 - ...
712
713
714
715
716
  		status = spi_async(ts->spi, &ts->msg[0]);
  		if (status)
  			dev_err(&ts->spi->dev, "spi_async --> %d
  ", status);
  	}
ca109491f   Peter Zijlstra   hrtimer: removing...
717
  	spin_unlock(&ts->lock);
1936d590a   Imre Deak   Input: ads7846 - ...
718
  	return HRTIMER_NORESTART;
0b7018aae   Imre Deak   Input: ads7846 - ...
719
  }
7d12e780e   David Howells   IRQ: Maintain reg...
720
  static irqreturn_t ads7846_irq(int irq, void *handle)
0b7018aae   Imre Deak   Input: ads7846 - ...
721
722
723
  {
  	struct ads7846 *ts = handle;
  	unsigned long flags;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
724
725
  
  	spin_lock_irqsave(&ts->lock, flags);
4d5975e50   Eric Miao   Input: ads7846 - ...
726
  	if (likely(get_pendown_state(ts))) {
ffa458c1b   David Brownell   [PATCH] spi: ads7...
727
  		if (!ts->irq_disabled) {
9084533e7   David Brownell   [PATCH] ads7846 c...
728
729
730
731
  			/* The ARM do_simple_IRQ() dispatcher doesn't act
  			 * like the other dispatchers:  it will report IRQs
  			 * even after they've been disabled.  We work around
  			 * that here.  (The "generic irq" framework may help...)
0b7018aae   Imre Deak   Input: ads7846 - ...
732
  			 */
ffa458c1b   David Brownell   [PATCH] spi: ads7...
733
  			ts->irq_disabled = 1;
3f3e7c6e1   Ben Nizette   Input: ads7846 - ...
734
  			disable_irq_nosync(ts->spi->irq);
0b7018aae   Imre Deak   Input: ads7846 - ...
735
  			ts->pending = 1;
1936d590a   Imre Deak   Input: ads7846 - ...
736
  			hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
737
  					HRTIMER_MODE_REL);
0b7018aae   Imre Deak   Input: ads7846 - ...
738
  		}
ffa458c1b   David Brownell   [PATCH] spi: ads7...
739
740
  	}
  	spin_unlock_irqrestore(&ts->lock, flags);
7de90a8cb   Imre Deak   Input: ads7846 - ...
741
742
  
  	return IRQ_HANDLED;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
743
744
745
  }
  
  /*--------------------------------------------------------------------------*/
7de90a8cb   Imre Deak   Input: ads7846 - ...
746
747
  /* Must be called with ts->lock held */
  static void ads7846_disable(struct ads7846 *ts)
ffa458c1b   David Brownell   [PATCH] spi: ads7...
748
  {
7de90a8cb   Imre Deak   Input: ads7846 - ...
749
750
  	if (ts->disabled)
  		return;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
751

c9e617a56   Imre Deak   Input: ads7846 - ...
752
  	ts->disabled = 1;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
753
  	/* are we waiting for IRQ, or polling? */
c9e617a56   Imre Deak   Input: ads7846 - ...
754
755
756
  	if (!ts->pending) {
  		ts->irq_disabled = 1;
  		disable_irq(ts->spi->irq);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
757
  	} else {
c9e617a56   Imre Deak   Input: ads7846 - ...
758
759
  		/* the timer will run at least once more, and
  		 * leave everything in a clean state, IRQ disabled
ffa458c1b   David Brownell   [PATCH] spi: ads7...
760
  		 */
c9e617a56   Imre Deak   Input: ads7846 - ...
761
  		while (ts->pending) {
7de90a8cb   Imre Deak   Input: ads7846 - ...
762
  			spin_unlock_irq(&ts->lock);
c4febb94d   Juha Yrjola   Input: ads7846 - ...
763
  			msleep(1);
7de90a8cb   Imre Deak   Input: ads7846 - ...
764
  			spin_lock_irq(&ts->lock);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
765
766
767
768
769
770
  		}
  	}
  
  	/* we know the chip's in lowpower mode since we always
  	 * leave it that way after every request
  	 */
7de90a8cb   Imre Deak   Input: ads7846 - ...
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
  }
  
  /* Must be called with ts->lock held */
  static void ads7846_enable(struct ads7846 *ts)
  {
  	if (!ts->disabled)
  		return;
  
  	ts->disabled = 0;
  	ts->irq_disabled = 0;
  	enable_irq(ts->spi->irq);
  }
  
  static int ads7846_suspend(struct spi_device *spi, pm_message_t message)
  {
  	struct ads7846 *ts = dev_get_drvdata(&spi->dev);
  
  	spin_lock_irq(&ts->lock);
fbb38e30e   David Brownell   Input: ads7846 - ...
789
  	ts->is_suspended = 1;
7de90a8cb   Imre Deak   Input: ads7846 - ...
790
791
792
  	ads7846_disable(ts);
  
  	spin_unlock_irq(&ts->lock);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
793
  	return 0;
7de90a8cb   Imre Deak   Input: ads7846 - ...
794

ffa458c1b   David Brownell   [PATCH] spi: ads7...
795
  }
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
796
  static int ads7846_resume(struct spi_device *spi)
ffa458c1b   David Brownell   [PATCH] spi: ads7...
797
  {
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
798
  	struct ads7846 *ts = dev_get_drvdata(&spi->dev);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
799

7de90a8cb   Imre Deak   Input: ads7846 - ...
800
  	spin_lock_irq(&ts->lock);
fbb38e30e   David Brownell   Input: ads7846 - ...
801
  	ts->is_suspended = 0;
7de90a8cb   Imre Deak   Input: ads7846 - ...
802
803
804
  	ads7846_enable(ts);
  
  	spin_unlock_irq(&ts->lock);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
805
806
  	return 0;
  }
4d5975e50   Eric Miao   Input: ads7846 - ...
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
  static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts)
  {
  	struct ads7846_platform_data *pdata = spi->dev.platform_data;
  	int err;
  
  	/* REVISIT when the irq can be triggered active-low, or if for some
  	 * reason the touchscreen isn't hooked up, we don't need to access
  	 * the pendown state.
  	 */
  	if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) {
  		dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?
  ");
  		return -EINVAL;
  	}
  
  	if (pdata->get_pendown_state) {
  		ts->get_pendown_state = pdata->get_pendown_state;
  		return 0;
  	}
  
  	err = gpio_request(pdata->gpio_pendown, "ads7846_pendown");
  	if (err) {
  		dev_err(&spi->dev, "failed to request pendown GPIO%d
  ",
  				pdata->gpio_pendown);
  		return err;
  	}
  
  	ts->gpio_pendown = pdata->gpio_pendown;
  	return 0;
  }
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
838
  static int __devinit ads7846_probe(struct spi_device *spi)
ffa458c1b   David Brownell   [PATCH] spi: ads7...
839
  {
ffa458c1b   David Brownell   [PATCH] spi: ads7...
840
  	struct ads7846			*ts;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
841
  	struct ads7846_packet		*packet;
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
842
  	struct input_dev		*input_dev;
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
843
  	struct ads7846_platform_data	*pdata = spi->dev.platform_data;
0b7018aae   Imre Deak   Input: ads7846 - ...
844
  	struct spi_message		*m;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
845
  	struct spi_transfer		*x;
de2defd96   Imre Deak   Input: ads7846 - ...
846
  	int				vref;
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
847
  	int				err;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
848
849
  
  	if (!spi->irq) {
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
850
851
  		dev_dbg(&spi->dev, "no IRQ?
  ");
ffa458c1b   David Brownell   [PATCH] spi: ads7...
852
853
854
855
  		return -ENODEV;
  	}
  
  	if (!pdata) {
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
856
857
  		dev_dbg(&spi->dev, "no platform data?
  ");
ffa458c1b   David Brownell   [PATCH] spi: ads7...
858
859
860
861
  		return -ENODEV;
  	}
  
  	/* don't exceed max specified sample rate */
d93f70b2d   David Brownell   Input: ads7846 - ...
862
  	if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) {
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
863
864
  		dev_dbg(&spi->dev, "f(sample) %d KHz?
  ",
d93f70b2d   David Brownell   Input: ads7846 - ...
865
  				(spi->max_speed_hz/SAMPLE_BITS)/1000);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
866
867
  		return -EINVAL;
  	}
9084533e7   David Brownell   [PATCH] ads7846 c...
868
869
870
  	/* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except
  	 * that even if the hardware can do that, the SPI controller driver
  	 * may not.  So we stick to very-portable 8 bit words, both RX and TX.
ffa458c1b   David Brownell   [PATCH] spi: ads7...
871
  	 */
9084533e7   David Brownell   [PATCH] ads7846 c...
872
  	spi->bits_per_word = 8;
230ffc8e3   Semih Hazar   Input: ads7846 - ...
873
  	spi->mode = SPI_MODE_0;
7937e86a7   Imre Deak   Input: ads7846 - ...
874
875
876
  	err = spi_setup(spi);
  	if (err < 0)
  		return err;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
877

a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
878
  	ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
879
  	packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL);
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
880
  	input_dev = input_allocate_device();
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
881
  	if (!ts || !packet || !input_dev) {
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
882
883
884
  		err = -ENOMEM;
  		goto err_free_mem;
  	}
ffa458c1b   David Brownell   [PATCH] spi: ads7...
885

2e5a7bd97   David Brownell   [PATCH] spi: ads7...
886
  	dev_set_drvdata(&spi->dev, ts);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
887

e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
888
  	ts->packet = packet;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
889
  	ts->spi = spi;
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
890
  	ts->input = input_dev;
7c6d0ee14   David Brownell   Input: ads7846 - ...
891
  	ts->vref_mv = pdata->vref_mv;
86579a4cc   Michael Roth   Input: ads7846 - ...
892
  	ts->swap_xy = pdata->swap_xy;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
893

c9cb2e3d7   Thomas Gleixner   [PATCH] hrtimers:...
894
  	hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
895
  	ts->timer.function = ads7846_timer;
7de90a8cb   Imre Deak   Input: ads7846 - ...
896
  	spin_lock_init(&ts->lock);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
897
898
899
  	ts->model = pdata->model ? : 7846;
  	ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
  	ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
d5b415c95   Imre Deak   Input: ads7846 - ...
900
  	ts->pressure_max = pdata->pressure_max ? : ~0;
da970e69e   Imre Deak   Input: ads7846 - ...
901
902
903
904
905
906
907
908
909
910
  
  	if (pdata->filter != NULL) {
  		if (pdata->filter_init != NULL) {
  			err = pdata->filter_init(pdata, &ts->filter_data);
  			if (err < 0)
  				goto err_free_mem;
  		}
  		ts->filter = pdata->filter;
  		ts->filter_cleanup = pdata->filter_cleanup;
  	} else if (pdata->debounce_max) {
d5b415c95   Imre Deak   Input: ads7846 - ...
911
  		ts->debounce_max = pdata->debounce_max;
da970e69e   Imre Deak   Input: ads7846 - ...
912
913
  		if (ts->debounce_max < 2)
  			ts->debounce_max = 2;
d5b415c95   Imre Deak   Input: ads7846 - ...
914
915
  		ts->debounce_tol = pdata->debounce_tol;
  		ts->debounce_rep = pdata->debounce_rep;
da970e69e   Imre Deak   Input: ads7846 - ...
916
917
  		ts->filter = ads7846_debounce;
  		ts->filter_data = ts;
d5b415c95   Imre Deak   Input: ads7846 - ...
918
  	} else
da970e69e   Imre Deak   Input: ads7846 - ...
919
  		ts->filter = ads7846_no_filter;
4d5975e50   Eric Miao   Input: ads7846 - ...
920
921
922
923
  
  	err = setup_pendown(spi, ts);
  	if (err)
  		goto err_cleanup_filter;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
924

1d25891f3   Semih Hazar   Input: ads7846 - ...
925
926
927
  	if (pdata->penirq_recheck_delay_usecs)
  		ts->penirq_recheck_delay_usecs =
  				pdata->penirq_recheck_delay_usecs;
fd746d540   Eric Miao   Input: ads7846 - ...
928
  	ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync;
a6c2490f0   Kay Sievers   Input: struct dev...
929
  	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev));
b58895f8b   Michael Roth   Input: ads7846 - ...
930
  	snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
931

b58895f8b   Michael Roth   Input: ads7846 - ...
932
  	input_dev->name = ts->name;
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
933
  	input_dev->phys = ts->phys;
a5394fb07   Dmitry Torokhov   Input: touchscree...
934
  	input_dev->dev.parent = &spi->dev;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
935

7b19ada2e   Jiri Slaby   get rid of input ...
936
937
  	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
938
  	input_set_abs_params(input_dev, ABS_X,
ffa458c1b   David Brownell   [PATCH] spi: ads7...
939
940
941
  			pdata->x_min ? : 0,
  			pdata->x_max ? : MAX_12BIT,
  			0, 0);
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
942
  	input_set_abs_params(input_dev, ABS_Y,
ffa458c1b   David Brownell   [PATCH] spi: ads7...
943
944
945
  			pdata->y_min ? : 0,
  			pdata->y_max ? : MAX_12BIT,
  			0, 0);
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
946
  	input_set_abs_params(input_dev, ABS_PRESSURE,
ffa458c1b   David Brownell   [PATCH] spi: ads7...
947
  			pdata->pressure_min, pdata->pressure_max, 0, 0);
de2defd96   Imre Deak   Input: ads7846 - ...
948
  	vref = pdata->keep_vref_on;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
949
950
951
  	/* set up the transfers to read touchscreen state; this assumes we
  	 * use formula #2 for pressure, not #3.
  	 */
0b7018aae   Imre Deak   Input: ads7846 - ...
952
  	m = &ts->msg[0];
ffa458c1b   David Brownell   [PATCH] spi: ads7...
953
  	x = ts->xfer;
0b7018aae   Imre Deak   Input: ads7846 - ...
954
  	spi_message_init(m);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
955
  	/* y- still on; turn on only y+ (and ADC) */
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
956
957
  	packet->read_y = READ_Y(vref);
  	x->tx_buf = &packet->read_y;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
958
  	x->len = 1;
0b7018aae   Imre Deak   Input: ads7846 - ...
959
  	spi_message_add_tail(x, m);
d93f70b2d   David Brownell   Input: ads7846 - ...
960

ffa458c1b   David Brownell   [PATCH] spi: ads7...
961
  	x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
962
  	x->rx_buf = &packet->tc.y;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
963
  	x->len = 2;
0b7018aae   Imre Deak   Input: ads7846 - ...
964
  	spi_message_add_tail(x, m);
e4f488619   Semih Hazar   Input: ads7846 - ...
965
966
967
968
969
970
971
972
  	/* the first sample after switching drivers can be low quality;
  	 * optionally discard it, using a second one after the signals
  	 * have had enough time to stabilize.
  	 */
  	if (pdata->settle_delay_usecs) {
  		x->delay_usecs = pdata->settle_delay_usecs;
  
  		x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
973
  		x->tx_buf = &packet->read_y;
e4f488619   Semih Hazar   Input: ads7846 - ...
974
975
976
977
  		x->len = 1;
  		spi_message_add_tail(x, m);
  
  		x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
978
  		x->rx_buf = &packet->tc.y;
e4f488619   Semih Hazar   Input: ads7846 - ...
979
980
981
  		x->len = 2;
  		spi_message_add_tail(x, m);
  	}
da970e69e   Imre Deak   Input: ads7846 - ...
982
  	m->complete = ads7846_rx_val;
0b7018aae   Imre Deak   Input: ads7846 - ...
983
984
985
986
987
988
989
  	m->context = ts;
  
  	m++;
  	spi_message_init(m);
  
  	/* turn y- off, x+ on, then leave in lowpower */
  	x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
990
991
  	packet->read_x = READ_X(vref);
  	x->tx_buf = &packet->read_x;
0b7018aae   Imre Deak   Input: ads7846 - ...
992
993
994
995
  	x->len = 1;
  	spi_message_add_tail(x, m);
  
  	x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
996
  	x->rx_buf = &packet->tc.x;
0b7018aae   Imre Deak   Input: ads7846 - ...
997
998
  	x->len = 2;
  	spi_message_add_tail(x, m);
e4f488619   Semih Hazar   Input: ads7846 - ...
999
1000
1001
1002
1003
  	/* ... maybe discard first sample ... */
  	if (pdata->settle_delay_usecs) {
  		x->delay_usecs = pdata->settle_delay_usecs;
  
  		x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1004
  		x->tx_buf = &packet->read_x;
e4f488619   Semih Hazar   Input: ads7846 - ...
1005
1006
1007
1008
  		x->len = 1;
  		spi_message_add_tail(x, m);
  
  		x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1009
  		x->rx_buf = &packet->tc.x;
e4f488619   Semih Hazar   Input: ads7846 - ...
1010
1011
1012
  		x->len = 2;
  		spi_message_add_tail(x, m);
  	}
da970e69e   Imre Deak   Input: ads7846 - ...
1013
  	m->complete = ads7846_rx_val;
0b7018aae   Imre Deak   Input: ads7846 - ...
1014
  	m->context = ts;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1015
1016
1017
  
  	/* turn y+ off, x- on; we'll use formula #2 */
  	if (ts->model == 7846) {
0b7018aae   Imre Deak   Input: ads7846 - ...
1018
1019
  		m++;
  		spi_message_init(m);
d93f70b2d   David Brownell   Input: ads7846 - ...
1020
  		x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1021
1022
  		packet->read_z1 = READ_Z1(vref);
  		x->tx_buf = &packet->read_z1;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1023
  		x->len = 1;
0b7018aae   Imre Deak   Input: ads7846 - ...
1024
  		spi_message_add_tail(x, m);
d93f70b2d   David Brownell   Input: ads7846 - ...
1025

ffa458c1b   David Brownell   [PATCH] spi: ads7...
1026
  		x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1027
  		x->rx_buf = &packet->tc.z1;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1028
  		x->len = 2;
0b7018aae   Imre Deak   Input: ads7846 - ...
1029
  		spi_message_add_tail(x, m);
e4f488619   Semih Hazar   Input: ads7846 - ...
1030
1031
1032
1033
1034
  		/* ... maybe discard first sample ... */
  		if (pdata->settle_delay_usecs) {
  			x->delay_usecs = pdata->settle_delay_usecs;
  
  			x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1035
  			x->tx_buf = &packet->read_z1;
e4f488619   Semih Hazar   Input: ads7846 - ...
1036
1037
1038
1039
  			x->len = 1;
  			spi_message_add_tail(x, m);
  
  			x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1040
  			x->rx_buf = &packet->tc.z1;
e4f488619   Semih Hazar   Input: ads7846 - ...
1041
1042
1043
  			x->len = 2;
  			spi_message_add_tail(x, m);
  		}
da970e69e   Imre Deak   Input: ads7846 - ...
1044
  		m->complete = ads7846_rx_val;
0b7018aae   Imre Deak   Input: ads7846 - ...
1045
1046
1047
1048
  		m->context = ts;
  
  		m++;
  		spi_message_init(m);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1049

d93f70b2d   David Brownell   Input: ads7846 - ...
1050
  		x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1051
1052
  		packet->read_z2 = READ_Z2(vref);
  		x->tx_buf = &packet->read_z2;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1053
  		x->len = 1;
0b7018aae   Imre Deak   Input: ads7846 - ...
1054
  		spi_message_add_tail(x, m);
d93f70b2d   David Brownell   Input: ads7846 - ...
1055

ffa458c1b   David Brownell   [PATCH] spi: ads7...
1056
  		x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1057
  		x->rx_buf = &packet->tc.z2;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1058
  		x->len = 2;
0b7018aae   Imre Deak   Input: ads7846 - ...
1059
  		spi_message_add_tail(x, m);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1060

e4f488619   Semih Hazar   Input: ads7846 - ...
1061
1062
1063
1064
1065
  		/* ... maybe discard first sample ... */
  		if (pdata->settle_delay_usecs) {
  			x->delay_usecs = pdata->settle_delay_usecs;
  
  			x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1066
  			x->tx_buf = &packet->read_z2;
e4f488619   Semih Hazar   Input: ads7846 - ...
1067
1068
1069
1070
  			x->len = 1;
  			spi_message_add_tail(x, m);
  
  			x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1071
  			x->rx_buf = &packet->tc.z2;
e4f488619   Semih Hazar   Input: ads7846 - ...
1072
1073
1074
  			x->len = 2;
  			spi_message_add_tail(x, m);
  		}
da970e69e   Imre Deak   Input: ads7846 - ...
1075
  		m->complete = ads7846_rx_val;
0b7018aae   Imre Deak   Input: ads7846 - ...
1076
1077
  		m->context = ts;
  	}
53a0ef89e   Imre Deak   Input: ads7846 - ...
1078
1079
  
  	/* power down */
0b7018aae   Imre Deak   Input: ads7846 - ...
1080
1081
  	m++;
  	spi_message_init(m);
53a0ef89e   Imre Deak   Input: ads7846 - ...
1082
  	x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1083
1084
  	packet->pwrdown = PWRDOWN;
  	x->tx_buf = &packet->pwrdown;
53a0ef89e   Imre Deak   Input: ads7846 - ...
1085
  	x->len = 1;
0b7018aae   Imre Deak   Input: ads7846 - ...
1086
  	spi_message_add_tail(x, m);
53a0ef89e   Imre Deak   Input: ads7846 - ...
1087
1088
  
  	x++;
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1089
  	x->rx_buf = &packet->dummy;
53a0ef89e   Imre Deak   Input: ads7846 - ...
1090
  	x->len = 2;
d93f70b2d   David Brownell   Input: ads7846 - ...
1091
  	CS_CHANGE(*x);
0b7018aae   Imre Deak   Input: ads7846 - ...
1092
  	spi_message_add_tail(x, m);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1093

0b7018aae   Imre Deak   Input: ads7846 - ...
1094
1095
  	m->complete = ads7846_rx;
  	m->context = ts;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1096

d5b415c95   Imre Deak   Input: ads7846 - ...
1097
  	ts->last_msg = m;
dace14537   Thomas Gleixner   [PATCH] irq-flags...
1098
  	if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING,
9084533e7   David Brownell   [PATCH] ads7846 c...
1099
  			spi->dev.driver->name, ts)) {
c57c0a2a0   Michael Roth   Input: ads7846 - ...
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
  		dev_info(&spi->dev,
  			"trying pin change workaround on irq %d
  ", spi->irq);
  		err = request_irq(spi->irq, ads7846_irq,
  				  IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
  				  spi->dev.driver->name, ts);
  		if (err) {
  			dev_dbg(&spi->dev, "irq %d busy?
  ", spi->irq);
  			goto err_free_gpio;
  		}
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1111
  	}
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1112

2c8dc0715   David Brownell   Input: ads7846 - ...
1113
1114
1115
  	err = ads784x_hwmon_register(spi, ts);
  	if (err)
  		goto err_free_irq;
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
1116
1117
  	dev_info(&spi->dev, "touchscreen, irq %d
  ", spi->irq);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1118

2c8dc0715   David Brownell   Input: ads7846 - ...
1119
  	/* take a first sample, leaving nPENIRQ active and vREF off; avoid
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1120
1121
  	 * the touchscreen, in case it's not connected.
  	 */
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
1122
  	(void) ads7846_read12_ser(&spi->dev,
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1123
  			  READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
2c8dc0715   David Brownell   Input: ads7846 - ...
1124
  	err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group);
8dd51650b   Dmitry Torokhov   Input: ads7846 - ...
1125
  	if (err)
2c8dc0715   David Brownell   Input: ads7846 - ...
1126
  		goto err_remove_hwmon;
7de90a8cb   Imre Deak   Input: ads7846 - ...
1127

a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
1128
1129
  	err = input_register_device(input_dev);
  	if (err)
8dd51650b   Dmitry Torokhov   Input: ads7846 - ...
1130
  		goto err_remove_attr_group;
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
1131

ffa458c1b   David Brownell   [PATCH] spi: ads7...
1132
  	return 0;
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
1133

8dd51650b   Dmitry Torokhov   Input: ads7846 - ...
1134
   err_remove_attr_group:
2c8dc0715   David Brownell   Input: ads7846 - ...
1135
1136
1137
  	sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group);
   err_remove_hwmon:
  	ads784x_hwmon_unregister(spi, ts);
8dd51650b   Dmitry Torokhov   Input: ads7846 - ...
1138
   err_free_irq:
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
1139
  	free_irq(spi->irq, ts);
4d5975e50   Eric Miao   Input: ads7846 - ...
1140
1141
1142
   err_free_gpio:
  	if (ts->gpio_pendown != -1)
  		gpio_free(ts->gpio_pendown);
da970e69e   Imre Deak   Input: ads7846 - ...
1143
1144
1145
   err_cleanup_filter:
  	if (ts->filter_cleanup)
  		ts->filter_cleanup(ts->filter_data);
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
1146
1147
   err_free_mem:
  	input_free_device(input_dev);
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1148
  	kfree(packet);
a90f7e98b   Dmitry Torokhov   Input: ads7846 - ...
1149
1150
  	kfree(ts);
  	return err;
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1151
  }
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
1152
  static int __devexit ads7846_remove(struct spi_device *spi)
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1153
  {
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
1154
  	struct ads7846		*ts = dev_get_drvdata(&spi->dev);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1155

2c8dc0715   David Brownell   Input: ads7846 - ...
1156
  	ads784x_hwmon_unregister(spi, ts);
7de90a8cb   Imre Deak   Input: ads7846 - ...
1157
  	input_unregister_device(ts->input);
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
1158
  	ads7846_suspend(spi, PMSG_SUSPEND);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1159

2c8dc0715   David Brownell   Input: ads7846 - ...
1160
  	sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1161

7de90a8cb   Imre Deak   Input: ads7846 - ...
1162
  	free_irq(ts->spi->irq, ts);
c9e617a56   Imre Deak   Input: ads7846 - ...
1163
1164
  	/* suspend left the IRQ disabled */
  	enable_irq(ts->spi->irq);
7de90a8cb   Imre Deak   Input: ads7846 - ...
1165

4d5975e50   Eric Miao   Input: ads7846 - ...
1166
1167
  	if (ts->gpio_pendown != -1)
  		gpio_free(ts->gpio_pendown);
da970e69e   Imre Deak   Input: ads7846 - ...
1168
1169
  	if (ts->filter_cleanup)
  		ts->filter_cleanup(ts->filter_data);
e8f462d20   Dmitry Torokhov   Input: ads7846 - ...
1170
  	kfree(ts->packet);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1171
  	kfree(ts);
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
1172
1173
  	dev_dbg(&spi->dev, "unregistered touchscreen
  ");
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1174
1175
  	return 0;
  }
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
1176
1177
1178
1179
1180
1181
  static struct spi_driver ads7846_driver = {
  	.driver = {
  		.name	= "ads7846",
  		.bus	= &spi_bus_type,
  		.owner	= THIS_MODULE,
  	},
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1182
  	.probe		= ads7846_probe,
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
1183
  	.remove		= __devexit_p(ads7846_remove),
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1184
1185
1186
1187
1188
1189
  	.suspend	= ads7846_suspend,
  	.resume		= ads7846_resume,
  };
  
  static int __init ads7846_init(void)
  {
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
1190
  	return spi_register_driver(&ads7846_driver);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1191
1192
1193
1194
1195
  }
  module_init(ads7846_init);
  
  static void __exit ads7846_exit(void)
  {
2e5a7bd97   David Brownell   [PATCH] spi: ads7...
1196
  	spi_unregister_driver(&ads7846_driver);
ffa458c1b   David Brownell   [PATCH] spi: ads7...
1197
1198
1199
1200
1201
  }
  module_exit(ads7846_exit);
  
  MODULE_DESCRIPTION("ADS7846 TouchScreen Driver");
  MODULE_LICENSE("GPL");
e0626e384   Anton Vorontsov   spi: prefix modal...
1202
  MODULE_ALIAS("spi:ads7846");