linux/drivers/input/touchscreen/elo.c
<<
>>
Prefs
   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
  30MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  31MODULE_DESCRIPTION(DRIVER_DESC);
  32MODULE_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
  56struct 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
  70static 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
 118static 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
 165static 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
 187static 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
 210static 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
 248static 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
 276static 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
 294static 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
 370static 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
 380MODULE_DEVICE_TABLE(serio, elo_serio_ids);
 381
 382static 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
 397static int __init elo_init(void)
 398{
 399        return serio_register_driver(&elo_drv);
 400}
 401
 402static void __exit elo_exit(void)
 403{
 404        serio_unregister_driver(&elo_drv);
 405}
 406
 407module_init(elo_init);
 408module_exit(elo_exit);
 409