~ubuntu-branches/ubuntu/utopic/linux-ti-omap/utopic

« back to all changes in this revision

Viewing changes to drivers/input/touchscreen/elo.c

  • Committer: Bazaar Package Importer
  • Author(s): Amit Kucheria, Amit Kucheria
  • Date: 2010-03-10 02:28:15 UTC
  • Revision ID: james.westby@ubuntu.com-20100310022815-7sd3gwvn5kenaq33
Tags: 2.6.33-500.1
[ Amit Kucheria ]

* Initial release of a 2.6.33-based OMAP kernel
* UBUNTU: [Upstream] Fix omap 1-wire driver compilation
* UBUNTU: ubuntu: AppArmor -- update to mainline 2010-03-04

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Elo serial touchscreen driver
 
3
 *
 
4
 * Copyright (c) 2004 Vojtech Pavlik
 
5
 */
 
6
 
 
7
/*
 
8
 * This program is free software; you can redistribute it and/or modify it
 
9
 * under the terms of the GNU General Public License version 2 as published by
 
10
 * the Free Software Foundation.
 
11
 */
 
12
 
 
13
/*
 
14
 * This driver can handle serial Elo touchscreens using either the Elo standard
 
15
 * 'E271-2210' 10-byte protocol, Elo legacy 'E281A-4002' 6-byte protocol, Elo
 
16
 * legacy 'E271-140' 4-byte protocol and Elo legacy 'E261-280' 3-byte protocol.
 
17
 */
 
18
 
 
19
#include <linux/errno.h>
 
20
#include <linux/kernel.h>
 
21
#include <linux/module.h>
 
22
#include <linux/slab.h>
 
23
#include <linux/input.h>
 
24
#include <linux/serio.h>
 
25
#include <linux/init.h>
 
26
#include <linux/ctype.h>
 
27
 
 
28
#define DRIVER_DESC     "Elo serial touchscreen driver"
 
29
 
 
30
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 
31
MODULE_DESCRIPTION(DRIVER_DESC);
 
32
MODULE_LICENSE("GPL");
 
33
 
 
34
/*
 
35
 * Definitions & global arrays.
 
36
 */
 
37
 
 
38
#define ELO_MAX_LENGTH          10
 
39
 
 
40
#define ELO10_PACKET_LEN        8
 
41
#define ELO10_TOUCH             0x03
 
42
#define ELO10_PRESSURE          0x80
 
43
 
 
44
#define ELO10_LEAD_BYTE         'U'
 
45
 
 
46
#define ELO10_ID_CMD            'i'
 
47
 
 
48
#define ELO10_TOUCH_PACKET      'T'
 
49
#define ELO10_ACK_PACKET        'A'
 
50
#define ELI10_ID_PACKET         'I'
 
51
 
 
52
/*
 
53
 * Per-touchscreen data.
 
54
 */
 
55
 
 
56
struct elo {
 
57
        struct input_dev *dev;
 
58
        struct serio *serio;
 
59
        struct mutex cmd_mutex;
 
60
        struct completion cmd_done;
 
61
        int id;
 
62
        int idx;
 
63
        unsigned char expected_packet;
 
64
        unsigned char csum;
 
65
        unsigned char data[ELO_MAX_LENGTH];
 
66
        unsigned char response[ELO10_PACKET_LEN];
 
67
        char phys[32];
 
68
};
 
69
 
 
70
static void elo_process_data_10(struct elo *elo, unsigned char data)
 
71
{
 
72
        struct input_dev *dev = elo->dev;
 
73
 
 
74
        elo->data[elo->idx] = data;
 
75
        switch (elo->idx++) {
 
76
                case 0:
 
77
                        elo->csum = 0xaa;
 
78
                        if (data != ELO10_LEAD_BYTE) {
 
79
                                pr_debug("elo: unsynchronized data: 0x%02x\n", data);
 
80
                                elo->idx = 0;
 
81
                        }
 
82
                        break;
 
83
 
 
84
                case 9:
 
85
                        elo->idx = 0;
 
86
                        if (data != elo->csum) {
 
87
                                pr_debug("elo: bad checksum: 0x%02x, expected 0x%02x\n",
 
88
                                         data, elo->csum);
 
89
                                break;
 
90
                        }
 
91
                        if (elo->data[1] != elo->expected_packet) {
 
92
                                if (elo->data[1] != ELO10_TOUCH_PACKET)
 
93
                                        pr_debug("elo: unexpected packet: 0x%02x\n",
 
94
                                                 elo->data[1]);
 
95
                                break;
 
96
                        }
 
97
                        if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) {
 
98
                                input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
 
99
                                input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
 
100
                                if (elo->data[2] & ELO10_PRESSURE)
 
101
                                        input_report_abs(dev, ABS_PRESSURE,
 
102
                                                        (elo->data[8] << 8) | elo->data[7]);
 
103
                                input_report_key(dev, BTN_TOUCH, elo->data[2] & ELO10_TOUCH);
 
104
                                input_sync(dev);
 
105
                        } else if (elo->data[1] == ELO10_ACK_PACKET) {
 
106
                                if (elo->data[2] == '0')
 
107
                                        elo->expected_packet = ELO10_TOUCH_PACKET;
 
108
                                complete(&elo->cmd_done);
 
109
                        } else {
 
110
                                memcpy(elo->response, &elo->data[1], ELO10_PACKET_LEN);
 
111
                                elo->expected_packet = ELO10_ACK_PACKET;
 
112
                        }
 
113
                        break;
 
114
        }
 
115
        elo->csum += data;
 
116
}
 
117
 
 
118
static void elo_process_data_6(struct elo *elo, unsigned char data)
 
119
{
 
120
        struct input_dev *dev = elo->dev;
 
121
 
 
122
        elo->data[elo->idx] = data;
 
123
 
 
124
        switch (elo->idx++) {
 
125
 
 
126
                case 0: if ((data & 0xc0) != 0xc0) elo->idx = 0; break;
 
127
                case 1: if ((data & 0xc0) != 0x80) elo->idx = 0; break;
 
128
                case 2: if ((data & 0xc0) != 0x40) elo->idx = 0; break;
 
129
 
 
130
                case 3:
 
131
                        if (data & 0xc0) {
 
132
                                elo->idx = 0;
 
133
                                break;
 
134
                        }
 
135
 
 
136
                        input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f));
 
137
                        input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f));
 
138
 
 
139
                        if (elo->id == 2) {
 
140
                                input_report_key(dev, BTN_TOUCH, 1);
 
141
                                input_sync(dev);
 
142
                                elo->idx = 0;
 
143
                        }
 
144
 
 
145
                        break;
 
146
 
 
147
                case 4:
 
148
                        if (data) {
 
149
                                input_sync(dev);
 
150
                                elo->idx = 0;
 
151
                        }
 
152
                        break;
 
153
 
 
154
                case 5:
 
155
                        if ((data & 0xf0) == 0) {
 
156
                                input_report_abs(dev, ABS_PRESSURE, elo->data[5]);
 
157
                                input_report_key(dev, BTN_TOUCH, !!elo->data[5]);
 
158
                        }
 
159
                        input_sync(dev);
 
160
                        elo->idx = 0;
 
161
                        break;
 
162
        }
 
163
}
 
164
 
 
165
static void elo_process_data_3(struct elo *elo, unsigned char data)
 
166
{
 
167
        struct input_dev *dev = elo->dev;
 
168
 
 
169
        elo->data[elo->idx] = data;
 
170
 
 
171
        switch (elo->idx++) {
 
172
 
 
173
                case 0:
 
174
                        if ((data & 0x7f) != 0x01)
 
175
                                elo->idx = 0;
 
176
                        break;
 
177
                case 2:
 
178
                        input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80));
 
179
                        input_report_abs(dev, ABS_X, elo->data[1]);
 
180
                        input_report_abs(dev, ABS_Y, elo->data[2]);
 
181
                        input_sync(dev);
 
182
                        elo->idx = 0;
 
183
                        break;
 
184
        }
 
185
}
 
186
 
 
187
static irqreturn_t elo_interrupt(struct serio *serio,
 
188
                unsigned char data, unsigned int flags)
 
189
{
 
190
        struct elo *elo = serio_get_drvdata(serio);
 
191
 
 
192
        switch(elo->id) {
 
193
                case 0:
 
194
                        elo_process_data_10(elo, data);
 
195
                        break;
 
196
 
 
197
                case 1:
 
198
                case 2:
 
199
                        elo_process_data_6(elo, data);
 
200
                        break;
 
201
 
 
202
                case 3:
 
203
                        elo_process_data_3(elo, data);
 
204
                        break;
 
205
        }
 
206
 
 
207
        return IRQ_HANDLED;
 
208
}
 
209
 
 
210
static int elo_command_10(struct elo *elo, unsigned char *packet)
 
211
{
 
212
        int rc = -1;
 
213
        int i;
 
214
        unsigned char csum = 0xaa + ELO10_LEAD_BYTE;
 
215
 
 
216
        mutex_lock(&elo->cmd_mutex);
 
217
 
 
218
        serio_pause_rx(elo->serio);
 
219
        elo->expected_packet = toupper(packet[0]);
 
220
        init_completion(&elo->cmd_done);
 
221
        serio_continue_rx(elo->serio);
 
222
 
 
223
        if (serio_write(elo->serio, ELO10_LEAD_BYTE))
 
224
                goto out;
 
225
 
 
226
        for (i = 0; i < ELO10_PACKET_LEN; i++) {
 
227
                csum += packet[i];
 
228
                if (serio_write(elo->serio, packet[i]))
 
229
                        goto out;
 
230
        }
 
231
 
 
232
        if (serio_write(elo->serio, csum))
 
233
                goto out;
 
234
 
 
235
        wait_for_completion_timeout(&elo->cmd_done, HZ);
 
236
 
 
237
        if (elo->expected_packet == ELO10_TOUCH_PACKET) {
 
238
                /* We are back in reporting mode, the command was ACKed */
 
239
                memcpy(packet, elo->response, ELO10_PACKET_LEN);
 
240
                rc = 0;
 
241
        }
 
242
 
 
243
 out:
 
244
        mutex_unlock(&elo->cmd_mutex);
 
245
        return rc;
 
246
}
 
247
 
 
248
static int elo_setup_10(struct elo *elo)
 
249
{
 
250
        static const char *elo_types[] = { "Accu", "Dura", "Intelli", "Carroll" };
 
251
        struct input_dev *dev = elo->dev;
 
252
        unsigned char packet[ELO10_PACKET_LEN] = { ELO10_ID_CMD };
 
253
 
 
254
        if (elo_command_10(elo, packet))
 
255
                return -1;
 
256
 
 
257
        dev->id.version = (packet[5] << 8) | packet[4];
 
258
 
 
259
        input_set_abs_params(dev, ABS_X, 96, 4000, 0, 0);
 
260
        input_set_abs_params(dev, ABS_Y, 96, 4000, 0, 0);
 
261
        if (packet[3] & ELO10_PRESSURE)
 
262
                input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
 
263
 
 
264
        printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, "
 
265
                "features: 0x%02x, controller: 0x%02x\n",
 
266
                elo_types[(packet[1] -'0') & 0x03],
 
267
                packet[5], packet[4], packet[3], packet[7]);
 
268
 
 
269
        return 0;
 
270
}
 
271
 
 
272
/*
 
273
 * elo_disconnect() is the opposite of elo_connect()
 
274
 */
 
275
 
 
276
static void elo_disconnect(struct serio *serio)
 
277
{
 
278
        struct elo *elo = serio_get_drvdata(serio);
 
279
 
 
280
        input_get_device(elo->dev);
 
281
        input_unregister_device(elo->dev);
 
282
        serio_close(serio);
 
283
        serio_set_drvdata(serio, NULL);
 
284
        input_put_device(elo->dev);
 
285
        kfree(elo);
 
286
}
 
287
 
 
288
/*
 
289
 * elo_connect() is the routine that is called when someone adds a
 
290
 * new serio device that supports Gunze protocol and registers it as
 
291
 * an input device.
 
292
 */
 
293
 
 
294
static int elo_connect(struct serio *serio, struct serio_driver *drv)
 
295
{
 
296
        struct elo *elo;
 
297
        struct input_dev *input_dev;
 
298
        int err;
 
299
 
 
300
        elo = kzalloc(sizeof(struct elo), GFP_KERNEL);
 
301
        input_dev = input_allocate_device();
 
302
        if (!elo || !input_dev) {
 
303
                err = -ENOMEM;
 
304
                goto fail1;
 
305
        }
 
306
 
 
307
        elo->serio = serio;
 
308
        elo->id = serio->id.id;
 
309
        elo->dev = input_dev;
 
310
        elo->expected_packet = ELO10_TOUCH_PACKET;
 
311
        mutex_init(&elo->cmd_mutex);
 
312
        init_completion(&elo->cmd_done);
 
313
        snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys);
 
314
 
 
315
        input_dev->name = "Elo Serial TouchScreen";
 
316
        input_dev->phys = elo->phys;
 
317
        input_dev->id.bustype = BUS_RS232;
 
318
        input_dev->id.vendor = SERIO_ELO;
 
319
        input_dev->id.product = elo->id;
 
320
        input_dev->id.version = 0x0100;
 
321
        input_dev->dev.parent = &serio->dev;
 
322
 
 
323
        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
324
        input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
325
 
 
326
        serio_set_drvdata(serio, elo);
 
327
        err = serio_open(serio, drv);
 
328
        if (err)
 
329
                goto fail2;
 
330
 
 
331
        switch (elo->id) {
 
332
 
 
333
                case 0: /* 10-byte protocol */
 
334
                        if (elo_setup_10(elo))
 
335
                                goto fail3;
 
336
 
 
337
                        break;
 
338
 
 
339
                case 1: /* 6-byte protocol */
 
340
                        input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0);
 
341
 
 
342
                case 2: /* 4-byte protocol */
 
343
                        input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
 
344
                        input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
 
345
                        break;
 
346
 
 
347
                case 3: /* 3-byte protocol */
 
348
                        input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
 
349
                        input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
 
350
                        break;
 
351
        }
 
352
 
 
353
        err = input_register_device(elo->dev);
 
354
        if (err)
 
355
                goto fail3;
 
356
 
 
357
        return 0;
 
358
 
 
359
 fail3: serio_close(serio);
 
360
 fail2: serio_set_drvdata(serio, NULL);
 
361
 fail1: input_free_device(input_dev);
 
362
        kfree(elo);
 
363
        return err;
 
364
}
 
365
 
 
366
/*
 
367
 * The serio driver structure.
 
368
 */
 
369
 
 
370
static struct serio_device_id elo_serio_ids[] = {
 
371
        {
 
372
                .type   = SERIO_RS232,
 
373
                .proto  = SERIO_ELO,
 
374
                .id     = SERIO_ANY,
 
375
                .extra  = SERIO_ANY,
 
376
        },
 
377
        { 0 }
 
378
};
 
379
 
 
380
MODULE_DEVICE_TABLE(serio, elo_serio_ids);
 
381
 
 
382
static struct serio_driver elo_drv = {
 
383
        .driver         = {
 
384
                .name   = "elo",
 
385
        },
 
386
        .description    = DRIVER_DESC,
 
387
        .id_table       = elo_serio_ids,
 
388
        .interrupt      = elo_interrupt,
 
389
        .connect        = elo_connect,
 
390
        .disconnect     = elo_disconnect,
 
391
};
 
392
 
 
393
/*
 
394
 * The functions for inserting/removing us as a module.
 
395
 */
 
396
 
 
397
static int __init elo_init(void)
 
398
{
 
399
        return serio_register_driver(&elo_drv);
 
400
}
 
401
 
 
402
static void __exit elo_exit(void)
 
403
{
 
404
        serio_unregister_driver(&elo_drv);
 
405
}
 
406
 
 
407
module_init(elo_init);
 
408
module_exit(elo_exit);