~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/input/touchscreen/wm831x-ts.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Touchscreen driver for WM831x PMICs
 
3
 *
 
4
 * Copyright 2011 Wolfson Microelectronics plc.
 
5
 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
 
6
 *
 
7
 * This program is free software; you can redistribute  it and/or modify it
 
8
 * under  the terms of  the GNU General  Public License as published by the
 
9
 * Free Software Foundation;  either version 2 of the  License, or (at your
 
10
 * option) any later version.
 
11
 */
 
12
 
 
13
#include <linux/module.h>
 
14
#include <linux/moduleparam.h>
 
15
#include <linux/kernel.h>
 
16
#include <linux/init.h>
 
17
#include <linux/string.h>
 
18
#include <linux/pm.h>
 
19
#include <linux/input.h>
 
20
#include <linux/interrupt.h>
 
21
#include <linux/io.h>
 
22
#include <linux/mfd/wm831x/core.h>
 
23
#include <linux/mfd/wm831x/irq.h>
 
24
#include <linux/mfd/wm831x/pdata.h>
 
25
#include <linux/platform_device.h>
 
26
#include <linux/slab.h>
 
27
#include <linux/types.h>
 
28
 
 
29
/*
 
30
 * R16424 (0x4028) - Touch Control 1
 
31
 */
 
32
#define WM831X_TCH_ENA                          0x8000  /* TCH_ENA */
 
33
#define WM831X_TCH_CVT_ENA                      0x4000  /* TCH_CVT_ENA */
 
34
#define WM831X_TCH_SLPENA                       0x1000  /* TCH_SLPENA */
 
35
#define WM831X_TCH_Z_ENA                        0x0400  /* TCH_Z_ENA */
 
36
#define WM831X_TCH_Y_ENA                        0x0200  /* TCH_Y_ENA */
 
37
#define WM831X_TCH_X_ENA                        0x0100  /* TCH_X_ENA */
 
38
#define WM831X_TCH_DELAY_MASK                   0x00E0  /* TCH_DELAY - [7:5] */
 
39
#define WM831X_TCH_DELAY_SHIFT                       5  /* TCH_DELAY - [7:5] */
 
40
#define WM831X_TCH_DELAY_WIDTH                       3  /* TCH_DELAY - [7:5] */
 
41
#define WM831X_TCH_RATE_MASK                    0x001F  /* TCH_RATE - [4:0] */
 
42
#define WM831X_TCH_RATE_SHIFT                        0  /* TCH_RATE - [4:0] */
 
43
#define WM831X_TCH_RATE_WIDTH                        5  /* TCH_RATE - [4:0] */
 
44
 
 
45
/*
 
46
 * R16425 (0x4029) - Touch Control 2
 
47
 */
 
48
#define WM831X_TCH_PD_WK                        0x2000  /* TCH_PD_WK */
 
49
#define WM831X_TCH_5WIRE                        0x1000  /* TCH_5WIRE */
 
50
#define WM831X_TCH_PDONLY                       0x0800  /* TCH_PDONLY */
 
51
#define WM831X_TCH_ISEL                         0x0100  /* TCH_ISEL */
 
52
#define WM831X_TCH_RPU_MASK                     0x000F  /* TCH_RPU - [3:0] */
 
53
#define WM831X_TCH_RPU_SHIFT                         0  /* TCH_RPU - [3:0] */
 
54
#define WM831X_TCH_RPU_WIDTH                         4  /* TCH_RPU - [3:0] */
 
55
 
 
56
/*
 
57
 * R16426-8 (0x402A-C) - Touch Data X/Y/X
 
58
 */
 
59
#define WM831X_TCH_PD                           0x8000  /* TCH_PD1 */
 
60
#define WM831X_TCH_DATA_MASK                    0x0FFF  /* TCH_DATA - [11:0] */
 
61
#define WM831X_TCH_DATA_SHIFT                        0  /* TCH_DATA - [11:0] */
 
62
#define WM831X_TCH_DATA_WIDTH                       12  /* TCH_DATA - [11:0] */
 
63
 
 
64
struct wm831x_ts {
 
65
        struct input_dev *input_dev;
 
66
        struct wm831x *wm831x;
 
67
        unsigned int data_irq;
 
68
        unsigned int pd_irq;
 
69
        bool pressure;
 
70
        bool pen_down;
 
71
        struct work_struct pd_data_work;
 
72
};
 
73
 
 
74
static void wm831x_pd_data_work(struct work_struct *work)
 
75
{
 
76
        struct wm831x_ts *wm831x_ts =
 
77
                container_of(work, struct wm831x_ts, pd_data_work);
 
78
 
 
79
        if (wm831x_ts->pen_down) {
 
80
                enable_irq(wm831x_ts->data_irq);
 
81
                dev_dbg(wm831x_ts->wm831x->dev, "IRQ PD->DATA done\n");
 
82
        } else {
 
83
                enable_irq(wm831x_ts->pd_irq);
 
84
                dev_dbg(wm831x_ts->wm831x->dev, "IRQ DATA->PD done\n");
 
85
        }
 
86
}
 
87
 
 
88
static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data)
 
89
{
 
90
        struct wm831x_ts *wm831x_ts = irq_data;
 
91
        struct wm831x *wm831x = wm831x_ts->wm831x;
 
92
        static int data_types[] = { ABS_X, ABS_Y, ABS_PRESSURE };
 
93
        u16 data[3];
 
94
        int count;
 
95
        int i, ret;
 
96
 
 
97
        if (wm831x_ts->pressure)
 
98
                count = 3;
 
99
        else
 
100
                count = 2;
 
101
 
 
102
        wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1,
 
103
                        WM831X_TCHDATA_EINT, WM831X_TCHDATA_EINT);
 
104
 
 
105
        ret = wm831x_bulk_read(wm831x, WM831X_TOUCH_DATA_X, count,
 
106
                               data);
 
107
        if (ret != 0) {
 
108
                dev_err(wm831x->dev, "Failed to read touch data: %d\n",
 
109
                        ret);
 
110
                return IRQ_NONE;
 
111
        }
 
112
 
 
113
        /*
 
114
         * We get a pen down reading on every reading, report pen up if any
 
115
         * individual reading does so.
 
116
         */
 
117
        wm831x_ts->pen_down = true;
 
118
        for (i = 0; i < count; i++) {
 
119
                if (!(data[i] & WM831X_TCH_PD)) {
 
120
                        wm831x_ts->pen_down = false;
 
121
                        continue;
 
122
                }
 
123
                input_report_abs(wm831x_ts->input_dev, data_types[i],
 
124
                                 data[i] & WM831X_TCH_DATA_MASK);
 
125
        }
 
126
 
 
127
        if (!wm831x_ts->pen_down) {
 
128
                /* Switch from data to pen down */
 
129
                dev_dbg(wm831x->dev, "IRQ DATA->PD\n");
 
130
 
 
131
                disable_irq_nosync(wm831x_ts->data_irq);
 
132
 
 
133
                /* Don't need data any more */
 
134
                wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
 
135
                                WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA |
 
136
                                WM831X_TCH_Z_ENA, 0);
 
137
 
 
138
                /* Flush any final samples that arrived while reading */
 
139
                wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1,
 
140
                                WM831X_TCHDATA_EINT, WM831X_TCHDATA_EINT);
 
141
 
 
142
                wm831x_bulk_read(wm831x, WM831X_TOUCH_DATA_X, count, data);
 
143
 
 
144
                if (wm831x_ts->pressure)
 
145
                        input_report_abs(wm831x_ts->input_dev,
 
146
                                         ABS_PRESSURE, 0);
 
147
 
 
148
                input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 0);
 
149
 
 
150
                schedule_work(&wm831x_ts->pd_data_work);
 
151
        } else {
 
152
                input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1);
 
153
        }
 
154
 
 
155
        input_sync(wm831x_ts->input_dev);
 
156
 
 
157
        return IRQ_HANDLED;
 
158
}
 
159
 
 
160
static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data)
 
161
{
 
162
        struct wm831x_ts *wm831x_ts = irq_data;
 
163
        struct wm831x *wm831x = wm831x_ts->wm831x;
 
164
        int ena = 0;
 
165
 
 
166
        if (wm831x_ts->pen_down)
 
167
                return IRQ_HANDLED;
 
168
 
 
169
        disable_irq_nosync(wm831x_ts->pd_irq);
 
170
 
 
171
        /* Start collecting data */
 
172
        if (wm831x_ts->pressure)
 
173
                ena |= WM831X_TCH_Z_ENA;
 
174
 
 
175
        wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
 
176
                        WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA,
 
177
                        WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | ena);
 
178
 
 
179
        wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1,
 
180
                        WM831X_TCHPD_EINT, WM831X_TCHPD_EINT);
 
181
 
 
182
        wm831x_ts->pen_down = true;
 
183
 
 
184
        /* Switch from pen down to data */
 
185
        dev_dbg(wm831x->dev, "IRQ PD->DATA\n");
 
186
        schedule_work(&wm831x_ts->pd_data_work);
 
187
 
 
188
        return IRQ_HANDLED;
 
189
}
 
190
 
 
191
static int wm831x_ts_input_open(struct input_dev *idev)
 
192
{
 
193
        struct wm831x_ts *wm831x_ts = input_get_drvdata(idev);
 
194
        struct wm831x *wm831x = wm831x_ts->wm831x;
 
195
 
 
196
        wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
 
197
                        WM831X_TCH_ENA | WM831X_TCH_CVT_ENA |
 
198
                        WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA |
 
199
                        WM831X_TCH_Z_ENA, WM831X_TCH_ENA);
 
200
 
 
201
        wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
 
202
                        WM831X_TCH_CVT_ENA, WM831X_TCH_CVT_ENA);
 
203
 
 
204
        return 0;
 
205
}
 
206
 
 
207
static void wm831x_ts_input_close(struct input_dev *idev)
 
208
{
 
209
        struct wm831x_ts *wm831x_ts = input_get_drvdata(idev);
 
210
        struct wm831x *wm831x = wm831x_ts->wm831x;
 
211
 
 
212
        /* Shut the controller down, disabling all other functionality too */
 
213
        wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
 
214
                        WM831X_TCH_ENA | WM831X_TCH_X_ENA |
 
215
                        WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, 0);
 
216
 
 
217
        /* Make sure any pending IRQs are done, the above will prevent
 
218
         * new ones firing.
 
219
         */
 
220
        synchronize_irq(wm831x_ts->data_irq);
 
221
        synchronize_irq(wm831x_ts->pd_irq);
 
222
 
 
223
        /* Make sure the IRQ completion work is quiesced */
 
224
        flush_work_sync(&wm831x_ts->pd_data_work);
 
225
 
 
226
        /* If we ended up with the pen down then make sure we revert back
 
227
         * to pen detection state for the next time we start up.
 
228
         */
 
229
        if (wm831x_ts->pen_down) {
 
230
                disable_irq(wm831x_ts->data_irq);
 
231
                enable_irq(wm831x_ts->pd_irq);
 
232
                wm831x_ts->pen_down = false;
 
233
        }
 
234
}
 
235
 
 
236
static __devinit int wm831x_ts_probe(struct platform_device *pdev)
 
237
{
 
238
        struct wm831x_ts *wm831x_ts;
 
239
        struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 
240
        struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent);
 
241
        struct wm831x_touch_pdata *pdata = NULL;
 
242
        struct input_dev *input_dev;
 
243
        int error, irqf;
 
244
 
 
245
        if (core_pdata)
 
246
                pdata = core_pdata->touch;
 
247
 
 
248
        wm831x_ts = kzalloc(sizeof(struct wm831x_ts), GFP_KERNEL);
 
249
        input_dev = input_allocate_device();
 
250
        if (!wm831x_ts || !input_dev) {
 
251
                error = -ENOMEM;
 
252
                goto err_alloc;
 
253
        }
 
254
 
 
255
        wm831x_ts->wm831x = wm831x;
 
256
        wm831x_ts->input_dev = input_dev;
 
257
        INIT_WORK(&wm831x_ts->pd_data_work, wm831x_pd_data_work);
 
258
 
 
259
        /*
 
260
         * If we have a direct IRQ use it, otherwise use the interrupt
 
261
         * from the WM831x IRQ controller.
 
262
         */
 
263
        if (pdata && pdata->data_irq)
 
264
                wm831x_ts->data_irq = pdata->data_irq;
 
265
        else
 
266
                wm831x_ts->data_irq = platform_get_irq_byname(pdev, "TCHDATA");
 
267
 
 
268
        if (pdata && pdata->pd_irq)
 
269
                wm831x_ts->pd_irq = pdata->pd_irq;
 
270
        else
 
271
                wm831x_ts->pd_irq = platform_get_irq_byname(pdev, "TCHPD");
 
272
 
 
273
        if (pdata)
 
274
                wm831x_ts->pressure = pdata->pressure;
 
275
        else
 
276
                wm831x_ts->pressure = true;
 
277
 
 
278
        /* Five wire touchscreens can't report pressure */
 
279
        if (pdata && pdata->fivewire) {
 
280
                wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2,
 
281
                                WM831X_TCH_5WIRE, WM831X_TCH_5WIRE);
 
282
 
 
283
                /* Pressure measurements are not possible for five wire mode */
 
284
                WARN_ON(pdata->pressure && pdata->fivewire);
 
285
                wm831x_ts->pressure = false;
 
286
        } else {
 
287
                wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2,
 
288
                                WM831X_TCH_5WIRE, 0);
 
289
        }
 
290
 
 
291
        if (pdata) {
 
292
                switch (pdata->isel) {
 
293
                default:
 
294
                        dev_err(&pdev->dev, "Unsupported ISEL setting: %d\n",
 
295
                                pdata->isel);
 
296
                        /* Fall through */
 
297
                case 200:
 
298
                case 0:
 
299
                        wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2,
 
300
                                        WM831X_TCH_ISEL, 0);
 
301
                        break;
 
302
                case 400:
 
303
                        wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2,
 
304
                                        WM831X_TCH_ISEL, WM831X_TCH_ISEL);
 
305
                        break;
 
306
                }
 
307
        }
 
308
 
 
309
        wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2,
 
310
                        WM831X_TCH_PDONLY, 0);
 
311
 
 
312
        /* Default to 96 samples/sec */
 
313
        wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
 
314
                        WM831X_TCH_RATE_MASK, 6);
 
315
 
 
316
        if (pdata && pdata->data_irqf)
 
317
                irqf = pdata->data_irqf;
 
318
        else
 
319
                irqf = IRQF_TRIGGER_HIGH;
 
320
 
 
321
        error = request_threaded_irq(wm831x_ts->data_irq,
 
322
                                     NULL, wm831x_ts_data_irq,
 
323
                                     irqf | IRQF_ONESHOT,
 
324
                                     "Touchscreen data", wm831x_ts);
 
325
        if (error) {
 
326
                dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n",
 
327
                        wm831x_ts->data_irq, error);
 
328
                goto err_alloc;
 
329
        }
 
330
        disable_irq(wm831x_ts->data_irq);
 
331
 
 
332
        if (pdata && pdata->pd_irqf)
 
333
                irqf = pdata->pd_irqf;
 
334
        else
 
335
                irqf = IRQF_TRIGGER_HIGH;
 
336
 
 
337
        error = request_threaded_irq(wm831x_ts->pd_irq,
 
338
                                     NULL, wm831x_ts_pen_down_irq,
 
339
                                     irqf | IRQF_ONESHOT,
 
340
                                     "Touchscreen pen down", wm831x_ts);
 
341
        if (error) {
 
342
                dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n",
 
343
                        wm831x_ts->pd_irq, error);
 
344
                goto err_data_irq;
 
345
        }
 
346
 
 
347
        /* set up touch configuration */
 
348
        input_dev->name = "WM831x touchscreen";
 
349
        input_dev->phys = "wm831x";
 
350
        input_dev->open = wm831x_ts_input_open;
 
351
        input_dev->close = wm831x_ts_input_close;
 
352
 
 
353
        __set_bit(EV_ABS, input_dev->evbit);
 
354
        __set_bit(EV_KEY, input_dev->evbit);
 
355
        __set_bit(BTN_TOUCH, input_dev->keybit);
 
356
 
 
357
        input_set_abs_params(input_dev, ABS_X, 0, 4095, 5, 0);
 
358
        input_set_abs_params(input_dev, ABS_Y, 0, 4095, 5, 0);
 
359
        if (wm831x_ts->pressure)
 
360
                input_set_abs_params(input_dev, ABS_PRESSURE, 0, 4095, 5, 0);
 
361
 
 
362
        input_set_drvdata(input_dev, wm831x_ts);
 
363
        input_dev->dev.parent = &pdev->dev;
 
364
 
 
365
        error = input_register_device(input_dev);
 
366
        if (error)
 
367
                goto err_pd_irq;
 
368
 
 
369
        platform_set_drvdata(pdev, wm831x_ts);
 
370
        return 0;
 
371
 
 
372
err_pd_irq:
 
373
        free_irq(wm831x_ts->pd_irq, wm831x_ts);
 
374
err_data_irq:
 
375
        free_irq(wm831x_ts->data_irq, wm831x_ts);
 
376
err_alloc:
 
377
        input_free_device(input_dev);
 
378
        kfree(wm831x_ts);
 
379
 
 
380
        return error;
 
381
}
 
382
 
 
383
static __devexit int wm831x_ts_remove(struct platform_device *pdev)
 
384
{
 
385
        struct wm831x_ts *wm831x_ts = platform_get_drvdata(pdev);
 
386
 
 
387
        free_irq(wm831x_ts->pd_irq, wm831x_ts);
 
388
        free_irq(wm831x_ts->data_irq, wm831x_ts);
 
389
        input_unregister_device(wm831x_ts->input_dev);
 
390
        kfree(wm831x_ts);
 
391
 
 
392
        platform_set_drvdata(pdev, NULL);
 
393
        return 0;
 
394
}
 
395
 
 
396
static struct platform_driver wm831x_ts_driver = {
 
397
        .driver = {
 
398
                .name = "wm831x-touch",
 
399
                .owner = THIS_MODULE,
 
400
        },
 
401
        .probe = wm831x_ts_probe,
 
402
        .remove = __devexit_p(wm831x_ts_remove),
 
403
};
 
404
 
 
405
static int __init wm831x_ts_init(void)
 
406
{
 
407
        return platform_driver_register(&wm831x_ts_driver);
 
408
}
 
409
module_init(wm831x_ts_init);
 
410
 
 
411
static void __exit wm831x_ts_exit(void)
 
412
{
 
413
        platform_driver_unregister(&wm831x_ts_driver);
 
414
}
 
415
module_exit(wm831x_ts_exit);
 
416
 
 
417
/* Module information */
 
418
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 
419
MODULE_DESCRIPTION("WM831x PMIC touchscreen driver");
 
420
MODULE_LICENSE("GPL");
 
421
MODULE_ALIAS("platform:wm831x-touch");