root/drivers/input/touchscreen/mtouch.c

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

DEFINITIONS

This source file includes following definitions.
  1. mtouch_process_format_tablet
  2. mtouch_process_response
  3. mtouch_interrupt
  4. mtouch_disconnect
  5. mtouch_connect

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * MicroTouch (3M) serial touchscreen driver
   4  *
   5  * Copyright (c) 2004 Vojtech Pavlik
   6  */
   7 
   8 
   9 /*
  10  * 2005/02/19 Dan Streetman <ddstreet@ieee.org>
  11  *   Copied elo.c and edited for MicroTouch protocol
  12  */
  13 
  14 #include <linux/errno.h>
  15 #include <linux/kernel.h>
  16 #include <linux/module.h>
  17 #include <linux/slab.h>
  18 #include <linux/input.h>
  19 #include <linux/serio.h>
  20 
  21 #define DRIVER_DESC     "MicroTouch serial touchscreen driver"
  22 
  23 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  24 MODULE_DESCRIPTION(DRIVER_DESC);
  25 MODULE_LICENSE("GPL");
  26 
  27 /*
  28  * Definitions & global arrays.
  29  */
  30 
  31 #define MTOUCH_FORMAT_TABLET_STATUS_BIT 0x80
  32 #define MTOUCH_FORMAT_TABLET_TOUCH_BIT 0x40
  33 #define MTOUCH_FORMAT_TABLET_LENGTH 5
  34 #define MTOUCH_RESPONSE_BEGIN_BYTE 0x01
  35 #define MTOUCH_RESPONSE_END_BYTE 0x0d
  36 
  37 /* todo: check specs for max length of all responses */
  38 #define MTOUCH_MAX_LENGTH 16
  39 
  40 #define MTOUCH_MIN_XC 0
  41 #define MTOUCH_MAX_XC 0x3fff
  42 #define MTOUCH_MIN_YC 0
  43 #define MTOUCH_MAX_YC 0x3fff
  44 
  45 #define MTOUCH_GET_XC(data) (((data[2])<<7) | data[1])
  46 #define MTOUCH_GET_YC(data) (((data[4])<<7) | data[3])
  47 #define MTOUCH_GET_TOUCHED(data) (MTOUCH_FORMAT_TABLET_TOUCH_BIT & data[0])
  48 
  49 /*
  50  * Per-touchscreen data.
  51  */
  52 
  53 struct mtouch {
  54         struct input_dev *dev;
  55         struct serio *serio;
  56         int idx;
  57         unsigned char data[MTOUCH_MAX_LENGTH];
  58         char phys[32];
  59 };
  60 
  61 static void mtouch_process_format_tablet(struct mtouch *mtouch)
  62 {
  63         struct input_dev *dev = mtouch->dev;
  64 
  65         if (MTOUCH_FORMAT_TABLET_LENGTH == ++mtouch->idx) {
  66                 input_report_abs(dev, ABS_X, MTOUCH_GET_XC(mtouch->data));
  67                 input_report_abs(dev, ABS_Y, MTOUCH_MAX_YC - MTOUCH_GET_YC(mtouch->data));
  68                 input_report_key(dev, BTN_TOUCH, MTOUCH_GET_TOUCHED(mtouch->data));
  69                 input_sync(dev);
  70 
  71                 mtouch->idx = 0;
  72         }
  73 }
  74 
  75 static void mtouch_process_response(struct mtouch *mtouch)
  76 {
  77         if (MTOUCH_RESPONSE_END_BYTE == mtouch->data[mtouch->idx++]) {
  78                 /* FIXME - process response */
  79                 mtouch->idx = 0;
  80         } else if (MTOUCH_MAX_LENGTH == mtouch->idx) {
  81                 printk(KERN_ERR "mtouch.c: too many response bytes\n");
  82                 mtouch->idx = 0;
  83         }
  84 }
  85 
  86 static irqreturn_t mtouch_interrupt(struct serio *serio,
  87                 unsigned char data, unsigned int flags)
  88 {
  89         struct mtouch *mtouch = serio_get_drvdata(serio);
  90 
  91         mtouch->data[mtouch->idx] = data;
  92 
  93         if (MTOUCH_FORMAT_TABLET_STATUS_BIT & mtouch->data[0])
  94                 mtouch_process_format_tablet(mtouch);
  95         else if (MTOUCH_RESPONSE_BEGIN_BYTE == mtouch->data[0])
  96                 mtouch_process_response(mtouch);
  97         else
  98                 printk(KERN_DEBUG "mtouch.c: unknown/unsynchronized data from device, byte %x\n",mtouch->data[0]);
  99 
 100         return IRQ_HANDLED;
 101 }
 102 
 103 /*
 104  * mtouch_disconnect() is the opposite of mtouch_connect()
 105  */
 106 
 107 static void mtouch_disconnect(struct serio *serio)
 108 {
 109         struct mtouch *mtouch = serio_get_drvdata(serio);
 110 
 111         input_get_device(mtouch->dev);
 112         input_unregister_device(mtouch->dev);
 113         serio_close(serio);
 114         serio_set_drvdata(serio, NULL);
 115         input_put_device(mtouch->dev);
 116         kfree(mtouch);
 117 }
 118 
 119 /*
 120  * mtouch_connect() is the routine that is called when someone adds a
 121  * new serio device that supports MicroTouch (Format Tablet) protocol and registers it as
 122  * an input device.
 123  */
 124 
 125 static int mtouch_connect(struct serio *serio, struct serio_driver *drv)
 126 {
 127         struct mtouch *mtouch;
 128         struct input_dev *input_dev;
 129         int err;
 130 
 131         mtouch = kzalloc(sizeof(struct mtouch), GFP_KERNEL);
 132         input_dev = input_allocate_device();
 133         if (!mtouch || !input_dev) {
 134                 err = -ENOMEM;
 135                 goto fail1;
 136         }
 137 
 138         mtouch->serio = serio;
 139         mtouch->dev = input_dev;
 140         snprintf(mtouch->phys, sizeof(mtouch->phys), "%s/input0", serio->phys);
 141 
 142         input_dev->name = "MicroTouch Serial TouchScreen";
 143         input_dev->phys = mtouch->phys;
 144         input_dev->id.bustype = BUS_RS232;
 145         input_dev->id.vendor = SERIO_MICROTOUCH;
 146         input_dev->id.product = 0;
 147         input_dev->id.version = 0x0100;
 148         input_dev->dev.parent = &serio->dev;
 149         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 150         input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 151         input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0);
 152         input_set_abs_params(mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0);
 153 
 154         serio_set_drvdata(serio, mtouch);
 155 
 156         err = serio_open(serio, drv);
 157         if (err)
 158                 goto fail2;
 159 
 160         err = input_register_device(mtouch->dev);
 161         if (err)
 162                 goto fail3;
 163 
 164         return 0;
 165 
 166  fail3: serio_close(serio);
 167  fail2: serio_set_drvdata(serio, NULL);
 168  fail1: input_free_device(input_dev);
 169         kfree(mtouch);
 170         return err;
 171 }
 172 
 173 /*
 174  * The serio driver structure.
 175  */
 176 
 177 static const struct serio_device_id mtouch_serio_ids[] = {
 178         {
 179                 .type   = SERIO_RS232,
 180                 .proto  = SERIO_MICROTOUCH,
 181                 .id     = SERIO_ANY,
 182                 .extra  = SERIO_ANY,
 183         },
 184         { 0 }
 185 };
 186 
 187 MODULE_DEVICE_TABLE(serio, mtouch_serio_ids);
 188 
 189 static struct serio_driver mtouch_drv = {
 190         .driver         = {
 191                 .name   = "mtouch",
 192         },
 193         .description    = DRIVER_DESC,
 194         .id_table       = mtouch_serio_ids,
 195         .interrupt      = mtouch_interrupt,
 196         .connect        = mtouch_connect,
 197         .disconnect     = mtouch_disconnect,
 198 };
 199 
 200 module_serio_driver(mtouch_drv);

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