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