blob: 54d4334778602df6b5ad4c1d36b3b1e17c696ee5 [file] [log] [blame]
David Brownellffa458c2006-01-08 13:34:21 -08001/*
2 * ADS7846 based touchscreen and sensor driver
3 *
4 * Copyright (c) 2005 David Brownell
5 *
6 * Using code from:
7 * - corgi_ts.c
8 * Copyright (C) 2004-2005 Richard Purdie
9 * - omap_ts.[hc], ads7846.h, ts_osk.c
10 * Copyright (C) 2002 MontaVista Software
11 * Copyright (C) 2004 Texas Instruments
12 * Copyright (C) 2005 Dirk Behme
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18#include <linux/device.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/input.h>
22#include <linux/interrupt.h>
23#include <linux/slab.h>
24#include <linux/spi/spi.h>
25#include <linux/spi/ads7846.h>
Andrew Morton3ac8bf02006-03-26 01:37:33 -080026#include <asm/irq.h>
David Brownellffa458c2006-01-08 13:34:21 -080027
28#ifdef CONFIG_ARM
29#include <asm/mach-types.h>
30#ifdef CONFIG_ARCH_OMAP
31#include <asm/arch/gpio.h>
32#endif
David Brownellffa458c2006-01-08 13:34:21 -080033#endif
34
35
36/*
37 * This code has been lightly tested on an ads7846.
38 * Support for ads7843 and ads7845 has only been stubbed in.
39 *
40 * Not yet done: investigate the values reported. Are x/y/pressure
41 * event values sane enough for X11? How accurate are the temperature
42 * and voltage readings? (System-specific calibration should support
43 * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.)
44 *
45 * app note sbaa036 talks in more detail about accurate sampling...
46 * that ought to help in situations like LCDs inducing noise (which
47 * can also be helped by using synch signals) and more generally.
48 */
49
50#define TS_POLL_PERIOD msecs_to_jiffies(10)
51
David Brownelld93f70b2006-02-15 00:49:35 -050052/* this driver doesn't aim at the peak continuous sample rate */
53#define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
54
David Brownellffa458c2006-01-08 13:34:21 -080055struct ts_event {
56 /* For portability, we can't read 12 bit values using SPI (which
57 * would make the controller deliver them as native byteorder u16
David Brownelld93f70b2006-02-15 00:49:35 -050058 * with msbs zeroed). Instead, we read them as two 8-bit values,
David Brownellffa458c2006-01-08 13:34:21 -080059 * which need byteswapping then range adjustment.
60 */
61 __be16 x;
62 __be16 y;
63 __be16 z1, z2;
64};
65
66struct ads7846 {
Dmitry Torokhova90f7e92006-02-15 00:49:22 -050067 struct input_dev *input;
David Brownellffa458c2006-01-08 13:34:21 -080068 char phys[32];
69
70 struct spi_device *spi;
71 u16 model;
72 u16 vref_delay_usecs;
73 u16 x_plate_ohms;
74
Imre Deak53a0ef892006-04-11 23:41:49 -040075 u8 read_x, read_y, read_z1, read_z2, pwrdown;
76 u16 dummy; /* for the pwrdown read */
David Brownellffa458c2006-01-08 13:34:21 -080077 struct ts_event tc;
78
Imre Deak53a0ef892006-04-11 23:41:49 -040079 struct spi_transfer xfer[10];
David Brownellffa458c2006-01-08 13:34:21 -080080 struct spi_message msg;
81
82 spinlock_t lock;
83 struct timer_list timer; /* P: lock */
84 unsigned pendown:1; /* P: lock */
85 unsigned pending:1; /* P: lock */
86// FIXME remove "irq_disabled"
87 unsigned irq_disabled:1; /* P: lock */
88};
89
90/* leave chip selected when we're done, for quicker re-select? */
91#if 0
92#define CS_CHANGE(xfer) ((xfer).cs_change = 1)
93#else
94#define CS_CHANGE(xfer) ((xfer).cs_change = 0)
95#endif
96
97/*--------------------------------------------------------------------------*/
98
99/* The ADS7846 has touchscreen and other sensors.
100 * Earlier ads784x chips are somewhat compatible.
101 */
102#define ADS_START (1 << 7)
103#define ADS_A2A1A0_d_y (1 << 4) /* differential */
104#define ADS_A2A1A0_d_z1 (3 << 4) /* differential */
105#define ADS_A2A1A0_d_z2 (4 << 4) /* differential */
106#define ADS_A2A1A0_d_x (5 << 4) /* differential */
107#define ADS_A2A1A0_temp0 (0 << 4) /* non-differential */
108#define ADS_A2A1A0_vbatt (2 << 4) /* non-differential */
109#define ADS_A2A1A0_vaux (6 << 4) /* non-differential */
110#define ADS_A2A1A0_temp1 (7 << 4) /* non-differential */
111#define ADS_8_BIT (1 << 3)
112#define ADS_12_BIT (0 << 3)
113#define ADS_SER (1 << 2) /* non-differential */
114#define ADS_DFR (0 << 2) /* differential */
115#define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */
116#define ADS_PD10_ADC_ON (1 << 0) /* ADC on */
117#define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */
118#define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */
119
120#define MAX_12BIT ((1<<12)-1)
121
122/* leave ADC powered up (disables penirq) between differential samples */
123#define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \
124 | ADS_12_BIT | ADS_DFR)
125
David Brownelld93f70b2006-02-15 00:49:35 -0500126#define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON)
127#define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON)
128#define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON)
Imre Deak53a0ef892006-04-11 23:41:49 -0400129
130#define READ_X (READ_12BIT_DFR(x) | ADS_PD10_ADC_ON)
131#define PWRDOWN (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) /* LAST */
David Brownellffa458c2006-01-08 13:34:21 -0800132
133/* single-ended samples need to first power up reference voltage;
134 * we leave both ADC and VREF powered
135 */
136#define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \
137 | ADS_12_BIT | ADS_SER)
138
David Brownelld93f70b2006-02-15 00:49:35 -0500139#define REF_ON (READ_12BIT_DFR(x) | ADS_PD10_ALL_ON)
140#define REF_OFF (READ_12BIT_DFR(y) | ADS_PD10_PDOWN)
David Brownellffa458c2006-01-08 13:34:21 -0800141
142/*--------------------------------------------------------------------------*/
143
144/*
145 * Non-touchscreen sensors only use single-ended conversions.
146 */
147
148struct ser_req {
David Brownelld93f70b2006-02-15 00:49:35 -0500149 u8 ref_on;
David Brownellffa458c2006-01-08 13:34:21 -0800150 u8 command;
David Brownelld93f70b2006-02-15 00:49:35 -0500151 u8 ref_off;
David Brownellffa458c2006-01-08 13:34:21 -0800152 u16 scratch;
153 __be16 sample;
154 struct spi_message msg;
155 struct spi_transfer xfer[6];
156};
157
158static int ads7846_read12_ser(struct device *dev, unsigned command)
159{
160 struct spi_device *spi = to_spi_device(dev);
161 struct ads7846 *ts = dev_get_drvdata(dev);
162 struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL);
163 int status;
164 int sample;
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500165 int i;
David Brownellffa458c2006-01-08 13:34:21 -0800166
167 if (!req)
168 return -ENOMEM;
169
Vitaly Wool8275c642006-01-08 13:34:28 -0800170 INIT_LIST_HEAD(&req->msg.transfers);
171
David Brownellffa458c2006-01-08 13:34:21 -0800172 /* activate reference, so it has time to settle; */
David Brownelld93f70b2006-02-15 00:49:35 -0500173 req->ref_on = REF_ON;
174 req->xfer[0].tx_buf = &req->ref_on;
David Brownellffa458c2006-01-08 13:34:21 -0800175 req->xfer[0].len = 1;
176 req->xfer[1].rx_buf = &req->scratch;
177 req->xfer[1].len = 2;
178
179 /*
180 * for external VREF, 0 usec (and assume it's always on);
181 * for 1uF, use 800 usec;
182 * no cap, 100 usec.
183 */
184 req->xfer[1].delay_usecs = ts->vref_delay_usecs;
185
186 /* take sample */
187 req->command = (u8) command;
188 req->xfer[2].tx_buf = &req->command;
189 req->xfer[2].len = 1;
190 req->xfer[3].rx_buf = &req->sample;
191 req->xfer[3].len = 2;
192
193 /* REVISIT: take a few more samples, and compare ... */
194
195 /* turn off reference */
David Brownelld93f70b2006-02-15 00:49:35 -0500196 req->ref_off = REF_OFF;
197 req->xfer[4].tx_buf = &req->ref_off;
David Brownellffa458c2006-01-08 13:34:21 -0800198 req->xfer[4].len = 1;
199 req->xfer[5].rx_buf = &req->scratch;
200 req->xfer[5].len = 2;
201
202 CS_CHANGE(req->xfer[5]);
203
204 /* group all the transfers together, so we can't interfere with
205 * reading touchscreen state; disable penirq while sampling
206 */
Vitaly Wool8275c642006-01-08 13:34:28 -0800207 for (i = 0; i < 6; i++)
208 spi_message_add_tail(&req->xfer[i], &req->msg);
David Brownellffa458c2006-01-08 13:34:21 -0800209
210 disable_irq(spi->irq);
211 status = spi_sync(spi, &req->msg);
212 enable_irq(spi->irq);
213
214 if (req->msg.status)
215 status = req->msg.status;
216 sample = be16_to_cpu(req->sample);
217 sample = sample >> 4;
218 kfree(req);
219
220 return status ? status : sample;
221}
222
223#define SHOW(name) static ssize_t \
224name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
225{ \
226 ssize_t v = ads7846_read12_ser(dev, \
227 READ_12BIT_SER(name) | ADS_PD10_ALL_ON); \
228 if (v < 0) \
229 return v; \
230 return sprintf(buf, "%u\n", (unsigned) v); \
231} \
232static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
233
234SHOW(temp0)
235SHOW(temp1)
236SHOW(vaux)
237SHOW(vbatt)
238
Imre Deak438f2a72006-04-11 23:41:32 -0400239static int is_pen_down(struct device *dev)
240{
241 struct ads7846 *ts = dev_get_drvdata(dev);
242
243 return ts->pendown;
244}
245
246static ssize_t ads7846_pen_down_show(struct device *dev,
247 struct device_attribute *attr, char *buf)
248{
249 return sprintf(buf, "%u\n", is_pen_down(dev));
250}
251
252static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL);
253
David Brownellffa458c2006-01-08 13:34:21 -0800254/*--------------------------------------------------------------------------*/
255
256/*
257 * PENIRQ only kicks the timer. The timer only reissues the SPI transfer,
258 * to retrieve touchscreen status.
259 *
260 * The SPI transfer completion callback does the real work. It reports
261 * touchscreen events and reactivates the timer (or IRQ) as appropriate.
262 */
263
264static void ads7846_rx(void *ads)
265{
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500266 struct ads7846 *ts = ads;
267 struct input_dev *input_dev = ts->input;
268 unsigned Rt;
269 unsigned sync = 0;
270 u16 x, y, z1, z2;
271 unsigned long flags;
David Brownellffa458c2006-01-08 13:34:21 -0800272
273 /* adjust: 12 bit samples (left aligned), built from
274 * two 8 bit values writen msb-first.
275 */
276 x = be16_to_cpu(ts->tc.x) >> 4;
277 y = be16_to_cpu(ts->tc.y) >> 4;
278 z1 = be16_to_cpu(ts->tc.z1) >> 4;
279 z2 = be16_to_cpu(ts->tc.z2) >> 4;
280
281 /* range filtering */
282 if (x == MAX_12BIT)
283 x = 0;
284
285 if (x && z1 && ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
286 /* compute touch pressure resistance using equation #2 */
287 Rt = z2;
288 Rt -= z1;
289 Rt *= x;
290 Rt *= ts->x_plate_ohms;
291 Rt /= z1;
292 Rt = (Rt + 2047) >> 12;
293 } else
294 Rt = 0;
295
296 /* NOTE: "pendown" is inferred from pressure; we don't rely on
297 * being able to check nPENIRQ status, or "friendly" trigger modes
298 * (both-edges is much better than just-falling or low-level).
299 *
300 * REVISIT: some boards may require reading nPENIRQ; it's
301 * needed on 7843. and 7845 reads pressure differently...
302 *
303 * REVISIT: the touchscreen might not be connected; this code
304 * won't notice that, even if nPENIRQ never fires ...
305 */
306 if (!ts->pendown && Rt != 0) {
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500307 input_report_key(input_dev, BTN_TOUCH, 1);
David Brownellffa458c2006-01-08 13:34:21 -0800308 sync = 1;
309 } else if (ts->pendown && Rt == 0) {
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500310 input_report_key(input_dev, BTN_TOUCH, 0);
David Brownellffa458c2006-01-08 13:34:21 -0800311 sync = 1;
312 }
313
314 if (Rt) {
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500315 input_report_abs(input_dev, ABS_X, x);
316 input_report_abs(input_dev, ABS_Y, y);
317 input_report_abs(input_dev, ABS_PRESSURE, Rt);
David Brownellffa458c2006-01-08 13:34:21 -0800318 sync = 1;
319 }
320 if (sync)
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500321 input_sync(input_dev);
David Brownellffa458c2006-01-08 13:34:21 -0800322
323#ifdef VERBOSE
324 if (Rt || ts->pendown)
325 pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id,
326 x, y, Rt, Rt ? "" : " UP");
327#endif
328
329 /* don't retrigger while we're suspended */
330 spin_lock_irqsave(&ts->lock, flags);
331
332 ts->pendown = (Rt != 0);
333 ts->pending = 0;
334
335 if (ts->spi->dev.power.power_state.event == PM_EVENT_ON) {
336 if (ts->pendown)
337 mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
338 else if (ts->irq_disabled) {
339 ts->irq_disabled = 0;
340 enable_irq(ts->spi->irq);
341 }
342 }
343
344 spin_unlock_irqrestore(&ts->lock, flags);
345}
346
347static void ads7846_timer(unsigned long handle)
348{
349 struct ads7846 *ts = (void *)handle;
350 int status = 0;
351 unsigned long flags;
352
353 spin_lock_irqsave(&ts->lock, flags);
354 if (!ts->pending) {
355 ts->pending = 1;
356 if (!ts->irq_disabled) {
357 ts->irq_disabled = 1;
358 disable_irq(ts->spi->irq);
359 }
360 status = spi_async(ts->spi, &ts->msg);
361 if (status)
362 dev_err(&ts->spi->dev, "spi_async --> %d\n",
363 status);
364 }
365 spin_unlock_irqrestore(&ts->lock, flags);
366}
367
368static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
369{
370 ads7846_timer((unsigned long) handle);
371 return IRQ_HANDLED;
372}
373
374/*--------------------------------------------------------------------------*/
375
David Brownellffa458c2006-01-08 13:34:21 -0800376static int
David Brownell2e5a7bd2006-01-08 13:34:25 -0800377ads7846_suspend(struct spi_device *spi, pm_message_t message)
David Brownellffa458c2006-01-08 13:34:21 -0800378{
David Brownell2e5a7bd2006-01-08 13:34:25 -0800379 struct ads7846 *ts = dev_get_drvdata(&spi->dev);
David Brownellffa458c2006-01-08 13:34:21 -0800380 unsigned long flags;
381
382 spin_lock_irqsave(&ts->lock, flags);
383
David Brownell2e5a7bd2006-01-08 13:34:25 -0800384 spi->dev.power.power_state = message;
David Brownellffa458c2006-01-08 13:34:21 -0800385
386 /* are we waiting for IRQ, or polling? */
387 if (!ts->pendown) {
388 if (!ts->irq_disabled) {
389 ts->irq_disabled = 1;
390 disable_irq(ts->spi->irq);
391 }
392 } else {
393 /* polling; force a final SPI completion;
394 * that will clean things up neatly
395 */
396 if (!ts->pending)
397 mod_timer(&ts->timer, jiffies);
398
399 while (ts->pendown || ts->pending) {
400 spin_unlock_irqrestore(&ts->lock, flags);
401 udelay(10);
402 spin_lock_irqsave(&ts->lock, flags);
403 }
404 }
405
406 /* we know the chip's in lowpower mode since we always
407 * leave it that way after every request
408 */
409
410 spin_unlock_irqrestore(&ts->lock, flags);
411 return 0;
412}
413
David Brownell2e5a7bd2006-01-08 13:34:25 -0800414static int ads7846_resume(struct spi_device *spi)
David Brownellffa458c2006-01-08 13:34:21 -0800415{
David Brownell2e5a7bd2006-01-08 13:34:25 -0800416 struct ads7846 *ts = dev_get_drvdata(&spi->dev);
David Brownellffa458c2006-01-08 13:34:21 -0800417
418 ts->irq_disabled = 0;
419 enable_irq(ts->spi->irq);
David Brownell2e5a7bd2006-01-08 13:34:25 -0800420 spi->dev.power.power_state = PMSG_ON;
David Brownellffa458c2006-01-08 13:34:21 -0800421 return 0;
422}
423
David Brownell2e5a7bd2006-01-08 13:34:25 -0800424static int __devinit ads7846_probe(struct spi_device *spi)
David Brownellffa458c2006-01-08 13:34:21 -0800425{
David Brownellffa458c2006-01-08 13:34:21 -0800426 struct ads7846 *ts;
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500427 struct input_dev *input_dev;
David Brownell2e5a7bd2006-01-08 13:34:25 -0800428 struct ads7846_platform_data *pdata = spi->dev.platform_data;
David Brownellffa458c2006-01-08 13:34:21 -0800429 struct spi_transfer *x;
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500430 int err;
David Brownellffa458c2006-01-08 13:34:21 -0800431
432 if (!spi->irq) {
David Brownell2e5a7bd2006-01-08 13:34:25 -0800433 dev_dbg(&spi->dev, "no IRQ?\n");
David Brownellffa458c2006-01-08 13:34:21 -0800434 return -ENODEV;
435 }
436
437 if (!pdata) {
David Brownell2e5a7bd2006-01-08 13:34:25 -0800438 dev_dbg(&spi->dev, "no platform data?\n");
David Brownellffa458c2006-01-08 13:34:21 -0800439 return -ENODEV;
440 }
441
442 /* don't exceed max specified sample rate */
David Brownelld93f70b2006-02-15 00:49:35 -0500443 if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) {
David Brownell2e5a7bd2006-01-08 13:34:25 -0800444 dev_dbg(&spi->dev, "f(sample) %d KHz?\n",
David Brownelld93f70b2006-02-15 00:49:35 -0500445 (spi->max_speed_hz/SAMPLE_BITS)/1000);
David Brownellffa458c2006-01-08 13:34:21 -0800446 return -EINVAL;
447 }
448
449 /* We'd set the wordsize to 12 bits ... except that some controllers
450 * will then treat the 8 bit command words as 12 bits (and drop the
451 * four MSBs of the 12 bit result). Result: inputs must be shifted
452 * to discard the four garbage LSBs.
453 */
454
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500455 ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
456 input_dev = input_allocate_device();
457 if (!ts || !input_dev) {
458 err = -ENOMEM;
459 goto err_free_mem;
460 }
David Brownellffa458c2006-01-08 13:34:21 -0800461
David Brownell2e5a7bd2006-01-08 13:34:25 -0800462 dev_set_drvdata(&spi->dev, ts);
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500463 spi->dev.power.power_state = PMSG_ON;
David Brownellffa458c2006-01-08 13:34:21 -0800464
465 ts->spi = spi;
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500466 ts->input = input_dev;
David Brownellffa458c2006-01-08 13:34:21 -0800467
468 init_timer(&ts->timer);
469 ts->timer.data = (unsigned long) ts;
470 ts->timer.function = ads7846_timer;
471
472 ts->model = pdata->model ? : 7846;
473 ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
474 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
475
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500476 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id);
David Brownellffa458c2006-01-08 13:34:21 -0800477
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500478 input_dev->name = "ADS784x Touchscreen";
479 input_dev->phys = ts->phys;
480 input_dev->cdev.dev = &spi->dev;
David Brownellffa458c2006-01-08 13:34:21 -0800481
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500482 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
483 input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
484 input_set_abs_params(input_dev, ABS_X,
David Brownellffa458c2006-01-08 13:34:21 -0800485 pdata->x_min ? : 0,
486 pdata->x_max ? : MAX_12BIT,
487 0, 0);
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500488 input_set_abs_params(input_dev, ABS_Y,
David Brownellffa458c2006-01-08 13:34:21 -0800489 pdata->y_min ? : 0,
490 pdata->y_max ? : MAX_12BIT,
491 0, 0);
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500492 input_set_abs_params(input_dev, ABS_PRESSURE,
David Brownellffa458c2006-01-08 13:34:21 -0800493 pdata->pressure_min, pdata->pressure_max, 0, 0);
494
David Brownellffa458c2006-01-08 13:34:21 -0800495 /* set up the transfers to read touchscreen state; this assumes we
496 * use formula #2 for pressure, not #3.
497 */
David Brownelld93f70b2006-02-15 00:49:35 -0500498 INIT_LIST_HEAD(&ts->msg.transfers);
David Brownellffa458c2006-01-08 13:34:21 -0800499 x = ts->xfer;
500
501 /* y- still on; turn on only y+ (and ADC) */
David Brownelld93f70b2006-02-15 00:49:35 -0500502 ts->read_y = READ_Y;
503 x->tx_buf = &ts->read_y;
David Brownellffa458c2006-01-08 13:34:21 -0800504 x->len = 1;
David Brownelld93f70b2006-02-15 00:49:35 -0500505 spi_message_add_tail(x, &ts->msg);
506
David Brownellffa458c2006-01-08 13:34:21 -0800507 x++;
508 x->rx_buf = &ts->tc.y;
509 x->len = 2;
David Brownelld93f70b2006-02-15 00:49:35 -0500510 spi_message_add_tail(x, &ts->msg);
David Brownellffa458c2006-01-08 13:34:21 -0800511
512 /* turn y+ off, x- on; we'll use formula #2 */
513 if (ts->model == 7846) {
David Brownelld93f70b2006-02-15 00:49:35 -0500514 x++;
515 ts->read_z1 = READ_Z1;
516 x->tx_buf = &ts->read_z1;
David Brownellffa458c2006-01-08 13:34:21 -0800517 x->len = 1;
David Brownelld93f70b2006-02-15 00:49:35 -0500518 spi_message_add_tail(x, &ts->msg);
519
David Brownellffa458c2006-01-08 13:34:21 -0800520 x++;
521 x->rx_buf = &ts->tc.z1;
522 x->len = 2;
David Brownelld93f70b2006-02-15 00:49:35 -0500523 spi_message_add_tail(x, &ts->msg);
David Brownellffa458c2006-01-08 13:34:21 -0800524
David Brownelld93f70b2006-02-15 00:49:35 -0500525 x++;
526 ts->read_z2 = READ_Z2;
527 x->tx_buf = &ts->read_z2;
David Brownellffa458c2006-01-08 13:34:21 -0800528 x->len = 1;
David Brownelld93f70b2006-02-15 00:49:35 -0500529 spi_message_add_tail(x, &ts->msg);
530
David Brownellffa458c2006-01-08 13:34:21 -0800531 x++;
532 x->rx_buf = &ts->tc.z2;
533 x->len = 2;
David Brownelld93f70b2006-02-15 00:49:35 -0500534 spi_message_add_tail(x, &ts->msg);
David Brownellffa458c2006-01-08 13:34:21 -0800535 }
536
537 /* turn y- off, x+ on, then leave in lowpower */
David Brownelld93f70b2006-02-15 00:49:35 -0500538 x++;
539 ts->read_x = READ_X;
540 x->tx_buf = &ts->read_x;
David Brownellffa458c2006-01-08 13:34:21 -0800541 x->len = 1;
David Brownelld93f70b2006-02-15 00:49:35 -0500542 spi_message_add_tail(x, &ts->msg);
543
David Brownellffa458c2006-01-08 13:34:21 -0800544 x++;
545 x->rx_buf = &ts->tc.x;
546 x->len = 2;
Imre Deak53a0ef892006-04-11 23:41:49 -0400547 spi_message_add_tail(x, &ts->msg);
548
549 /* power down */
550 x++;
551 ts->pwrdown = PWRDOWN;
552 x->tx_buf = &ts->pwrdown;
553 x->len = 1;
554 spi_message_add_tail(x, &ts->msg);
555
556 x++;
557 x->rx_buf = &ts->dummy;
558 x->len = 2;
David Brownelld93f70b2006-02-15 00:49:35 -0500559 CS_CHANGE(*x);
560 spi_message_add_tail(x, &ts->msg);
David Brownellffa458c2006-01-08 13:34:21 -0800561
David Brownellffa458c2006-01-08 13:34:21 -0800562 ts->msg.complete = ads7846_rx;
563 ts->msg.context = ts;
564
Russell Kingf43aaba2006-01-19 12:26:57 +0000565 if (request_irq(spi->irq, ads7846_irq,
566 SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING,
567 spi->dev.bus_id, ts)) {
David Brownell2e5a7bd2006-01-08 13:34:25 -0800568 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500569 err = -EBUSY;
570 goto err_free_mem;
David Brownellffa458c2006-01-08 13:34:21 -0800571 }
David Brownellffa458c2006-01-08 13:34:21 -0800572
David Brownell2e5a7bd2006-01-08 13:34:25 -0800573 dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq);
David Brownellffa458c2006-01-08 13:34:21 -0800574
575 /* take a first sample, leaving nPENIRQ active; avoid
576 * the touchscreen, in case it's not connected.
577 */
David Brownell2e5a7bd2006-01-08 13:34:25 -0800578 (void) ads7846_read12_ser(&spi->dev,
David Brownellffa458c2006-01-08 13:34:21 -0800579 READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
580
581 /* ads7843/7845 don't have temperature sensors, and
582 * use the other sensors a bit differently too
583 */
584 if (ts->model == 7846) {
David Brownell2e5a7bd2006-01-08 13:34:25 -0800585 device_create_file(&spi->dev, &dev_attr_temp0);
586 device_create_file(&spi->dev, &dev_attr_temp1);
David Brownellffa458c2006-01-08 13:34:21 -0800587 }
588 if (ts->model != 7845)
David Brownell2e5a7bd2006-01-08 13:34:25 -0800589 device_create_file(&spi->dev, &dev_attr_vbatt);
590 device_create_file(&spi->dev, &dev_attr_vaux);
David Brownellffa458c2006-01-08 13:34:21 -0800591
Imre Deak438f2a72006-04-11 23:41:32 -0400592 device_create_file(&spi->dev, &dev_attr_pen_down);
593
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500594 err = input_register_device(input_dev);
595 if (err)
596 goto err_free_irq;
597
David Brownellffa458c2006-01-08 13:34:21 -0800598 return 0;
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500599
600 err_free_irq:
601 free_irq(spi->irq, ts);
602 err_free_mem:
603 input_free_device(input_dev);
604 kfree(ts);
605 return err;
David Brownellffa458c2006-01-08 13:34:21 -0800606}
607
David Brownell2e5a7bd2006-01-08 13:34:25 -0800608static int __devexit ads7846_remove(struct spi_device *spi)
David Brownellffa458c2006-01-08 13:34:21 -0800609{
David Brownell2e5a7bd2006-01-08 13:34:25 -0800610 struct ads7846 *ts = dev_get_drvdata(&spi->dev);
David Brownellffa458c2006-01-08 13:34:21 -0800611
David Brownell2e5a7bd2006-01-08 13:34:25 -0800612 ads7846_suspend(spi, PMSG_SUSPEND);
David Brownellffa458c2006-01-08 13:34:21 -0800613 free_irq(ts->spi->irq, ts);
614 if (ts->irq_disabled)
615 enable_irq(ts->spi->irq);
616
Imre Deak438f2a72006-04-11 23:41:32 -0400617 device_remove_file(&spi->dev, &dev_attr_pen_down);
618
David Brownellffa458c2006-01-08 13:34:21 -0800619 if (ts->model == 7846) {
David Brownell2e5a7bd2006-01-08 13:34:25 -0800620 device_remove_file(&spi->dev, &dev_attr_temp0);
621 device_remove_file(&spi->dev, &dev_attr_temp1);
David Brownellffa458c2006-01-08 13:34:21 -0800622 }
623 if (ts->model != 7845)
David Brownell2e5a7bd2006-01-08 13:34:25 -0800624 device_remove_file(&spi->dev, &dev_attr_vbatt);
625 device_remove_file(&spi->dev, &dev_attr_vaux);
David Brownellffa458c2006-01-08 13:34:21 -0800626
Dmitry Torokhova90f7e92006-02-15 00:49:22 -0500627 input_unregister_device(ts->input);
David Brownellffa458c2006-01-08 13:34:21 -0800628 kfree(ts);
629
David Brownell2e5a7bd2006-01-08 13:34:25 -0800630 dev_dbg(&spi->dev, "unregistered touchscreen\n");
David Brownellffa458c2006-01-08 13:34:21 -0800631 return 0;
632}
633
David Brownell2e5a7bd2006-01-08 13:34:25 -0800634static struct spi_driver ads7846_driver = {
635 .driver = {
636 .name = "ads7846",
637 .bus = &spi_bus_type,
638 .owner = THIS_MODULE,
639 },
David Brownellffa458c2006-01-08 13:34:21 -0800640 .probe = ads7846_probe,
David Brownell2e5a7bd2006-01-08 13:34:25 -0800641 .remove = __devexit_p(ads7846_remove),
David Brownellffa458c2006-01-08 13:34:21 -0800642 .suspend = ads7846_suspend,
643 .resume = ads7846_resume,
644};
645
646static int __init ads7846_init(void)
647{
648 /* grr, board-specific init should stay out of drivers!! */
649
650#ifdef CONFIG_ARCH_OMAP
651 if (machine_is_omap_osk()) {
652 /* GPIO4 = PENIRQ; GPIO6 = BUSY */
653 omap_request_gpio(4);
654 omap_set_gpio_direction(4, 1);
655 omap_request_gpio(6);
656 omap_set_gpio_direction(6, 1);
657 }
658 // also TI 1510 Innovator, bitbanging through FPGA
659 // also Nokia 770
660 // also Palm Tungsten T2
661#endif
662
663 // PXA:
664 // also Dell Axim X50
665 // also HP iPaq H191x/H192x/H415x/H435x
David Brownell2e5a7bd2006-01-08 13:34:25 -0800666 // also Intel Lubbock (additional to UCB1400; as temperature sensor)
David Brownellffa458c2006-01-08 13:34:21 -0800667 // also Sharp Zaurus C7xx, C8xx (corgi/sheperd/husky)
668
David Brownell2e5a7bd2006-01-08 13:34:25 -0800669 // Atmel at91sam9261-EK uses ads7843
670
David Brownellffa458c2006-01-08 13:34:21 -0800671 // also various AMD Au1x00 devel boards
672
David Brownell2e5a7bd2006-01-08 13:34:25 -0800673 return spi_register_driver(&ads7846_driver);
David Brownellffa458c2006-01-08 13:34:21 -0800674}
675module_init(ads7846_init);
676
677static void __exit ads7846_exit(void)
678{
David Brownell2e5a7bd2006-01-08 13:34:25 -0800679 spi_unregister_driver(&ads7846_driver);
David Brownellffa458c2006-01-08 13:34:21 -0800680
681#ifdef CONFIG_ARCH_OMAP
682 if (machine_is_omap_osk()) {
683 omap_free_gpio(4);
684 omap_free_gpio(6);
685 }
686#endif
687
688}
689module_exit(ads7846_exit);
690
691MODULE_DESCRIPTION("ADS7846 TouchScreen Driver");
692MODULE_LICENSE("GPL");