root/drivers/input/touchscreen/elo.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. elo_process_data_10
  2. elo_process_data_6
  3. elo_process_data_3
  4. elo_interrupt
  5. elo_command_10
  6. elo_setup_10
  7. elo_disconnect
  8. elo_connect

   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 
  25 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  26 MODULE_DESCRIPTION(DRIVER_DESC);
  27 MODULE_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 
  51 struct 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 
  65 static 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 
 117 static 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 
 175 static 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 
 197 static 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 
 220 static 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 
 258 static 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 
 286 static 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 
 304 static 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                         goto fail3;
 346 
 347                 break;
 348 
 349         case 1: /* 6-byte protocol */
 350                 input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0);
 351                 /* fall through */
 352 
 353         case 2: /* 4-byte protocol */
 354                 input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
 355                 input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
 356                 break;
 357 
 358         case 3: /* 3-byte protocol */
 359                 input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
 360                 input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
 361                 break;
 362         }
 363 
 364         err = input_register_device(elo->dev);
 365         if (err)
 366                 goto fail3;
 367 
 368         return 0;
 369 
 370  fail3: serio_close(serio);
 371  fail2: serio_set_drvdata(serio, NULL);
 372  fail1: input_free_device(input_dev);
 373         kfree(elo);
 374         return err;
 375 }
 376 
 377 /*
 378  * The serio driver structure.
 379  */
 380 
 381 static const struct serio_device_id elo_serio_ids[] = {
 382         {
 383                 .type   = SERIO_RS232,
 384                 .proto  = SERIO_ELO,
 385                 .id     = SERIO_ANY,
 386                 .extra  = SERIO_ANY,
 387         },
 388         { 0 }
 389 };
 390 
 391 MODULE_DEVICE_TABLE(serio, elo_serio_ids);
 392 
 393 static struct serio_driver elo_drv = {
 394         .driver         = {
 395                 .name   = "elo",
 396         },
 397         .description    = DRIVER_DESC,
 398         .id_table       = elo_serio_ids,
 399         .interrupt      = elo_interrupt,
 400         .connect        = elo_connect,
 401         .disconnect     = elo_disconnect,
 402 };
 403 
 404 module_serio_driver(elo_drv);

/* [<][>][^][v][top][bottom][index][help] */