root/drivers/input/touchscreen/hampshire.c

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

DEFINITIONS

This source file includes following definitions.
  1. hampshire_process_data
  2. hampshire_interrupt
  3. hampshire_disconnect
  4. hampshire_connect

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Hampshire serial touchscreen driver
   4  *
   5  * Copyright (c) 2010 Adam Bennett
   6  * Based on the dynapro driver (c) Tias Guns
   7  */
   8 
   9 
  10 /*
  11  * 2010/04/08 Adam Bennett <abennett72@gmail.com>
  12  *   Copied dynapro.c and edited for Hampshire 4-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 
  22 #define DRIVER_DESC     "Hampshire serial touchscreen driver"
  23 
  24 MODULE_AUTHOR("Adam Bennett <abennett72@gmail.com>");
  25 MODULE_DESCRIPTION(DRIVER_DESC);
  26 MODULE_LICENSE("GPL");
  27 
  28 /*
  29  * Definitions & global arrays.
  30  */
  31 
  32 #define HAMPSHIRE_FORMAT_TOUCH_BIT 0x40
  33 #define HAMPSHIRE_FORMAT_LENGTH 4
  34 #define HAMPSHIRE_RESPONSE_BEGIN_BYTE 0x80
  35 
  36 #define HAMPSHIRE_MIN_XC 0
  37 #define HAMPSHIRE_MAX_XC 0x1000
  38 #define HAMPSHIRE_MIN_YC 0
  39 #define HAMPSHIRE_MAX_YC 0x1000
  40 
  41 #define HAMPSHIRE_GET_XC(data) (((data[3] & 0x0c) >> 2) | (data[1] << 2) | ((data[0] & 0x38) << 6))
  42 #define HAMPSHIRE_GET_YC(data) ((data[3] & 0x03) | (data[2] << 2) | ((data[0] & 0x07) << 9))
  43 #define HAMPSHIRE_GET_TOUCHED(data) (HAMPSHIRE_FORMAT_TOUCH_BIT & data[0])
  44 
  45 /*
  46  * Per-touchscreen data.
  47  */
  48 
  49 struct hampshire {
  50         struct input_dev *dev;
  51         struct serio *serio;
  52         int idx;
  53         unsigned char data[HAMPSHIRE_FORMAT_LENGTH];
  54         char phys[32];
  55 };
  56 
  57 static void hampshire_process_data(struct hampshire *phampshire)
  58 {
  59         struct input_dev *dev = phampshire->dev;
  60 
  61         if (HAMPSHIRE_FORMAT_LENGTH == ++phampshire->idx) {
  62                 input_report_abs(dev, ABS_X, HAMPSHIRE_GET_XC(phampshire->data));
  63                 input_report_abs(dev, ABS_Y, HAMPSHIRE_GET_YC(phampshire->data));
  64                 input_report_key(dev, BTN_TOUCH,
  65                                  HAMPSHIRE_GET_TOUCHED(phampshire->data));
  66                 input_sync(dev);
  67 
  68                 phampshire->idx = 0;
  69         }
  70 }
  71 
  72 static irqreturn_t hampshire_interrupt(struct serio *serio,
  73                 unsigned char data, unsigned int flags)
  74 {
  75         struct hampshire *phampshire = serio_get_drvdata(serio);
  76 
  77         phampshire->data[phampshire->idx] = data;
  78 
  79         if (HAMPSHIRE_RESPONSE_BEGIN_BYTE & phampshire->data[0])
  80                 hampshire_process_data(phampshire);
  81         else
  82                 dev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n",
  83                         phampshire->data[0]);
  84 
  85         return IRQ_HANDLED;
  86 }
  87 
  88 static void hampshire_disconnect(struct serio *serio)
  89 {
  90         struct hampshire *phampshire = serio_get_drvdata(serio);
  91 
  92         input_get_device(phampshire->dev);
  93         input_unregister_device(phampshire->dev);
  94         serio_close(serio);
  95         serio_set_drvdata(serio, NULL);
  96         input_put_device(phampshire->dev);
  97         kfree(phampshire);
  98 }
  99 
 100 /*
 101  * hampshire_connect() is the routine that is called when someone adds a
 102  * new serio device that supports hampshire protocol and registers it as
 103  * an input device. This is usually accomplished using inputattach.
 104  */
 105 
 106 static int hampshire_connect(struct serio *serio, struct serio_driver *drv)
 107 {
 108         struct hampshire *phampshire;
 109         struct input_dev *input_dev;
 110         int err;
 111 
 112         phampshire = kzalloc(sizeof(struct hampshire), GFP_KERNEL);
 113         input_dev = input_allocate_device();
 114         if (!phampshire || !input_dev) {
 115                 err = -ENOMEM;
 116                 goto fail1;
 117         }
 118 
 119         phampshire->serio = serio;
 120         phampshire->dev = input_dev;
 121         snprintf(phampshire->phys, sizeof(phampshire->phys),
 122                  "%s/input0", serio->phys);
 123 
 124         input_dev->name = "Hampshire Serial TouchScreen";
 125         input_dev->phys = phampshire->phys;
 126         input_dev->id.bustype = BUS_RS232;
 127         input_dev->id.vendor = SERIO_HAMPSHIRE;
 128         input_dev->id.product = 0;
 129         input_dev->id.version = 0x0001;
 130         input_dev->dev.parent = &serio->dev;
 131         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 132         input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 133         input_set_abs_params(phampshire->dev, ABS_X,
 134                              HAMPSHIRE_MIN_XC, HAMPSHIRE_MAX_XC, 0, 0);
 135         input_set_abs_params(phampshire->dev, ABS_Y,
 136                              HAMPSHIRE_MIN_YC, HAMPSHIRE_MAX_YC, 0, 0);
 137 
 138         serio_set_drvdata(serio, phampshire);
 139 
 140         err = serio_open(serio, drv);
 141         if (err)
 142                 goto fail2;
 143 
 144         err = input_register_device(phampshire->dev);
 145         if (err)
 146                 goto fail3;
 147 
 148         return 0;
 149 
 150  fail3: serio_close(serio);
 151  fail2: serio_set_drvdata(serio, NULL);
 152  fail1: input_free_device(input_dev);
 153         kfree(phampshire);
 154         return err;
 155 }
 156 
 157 /*
 158  * The serio driver structure.
 159  */
 160 
 161 static const struct serio_device_id hampshire_serio_ids[] = {
 162         {
 163                 .type   = SERIO_RS232,
 164                 .proto  = SERIO_HAMPSHIRE,
 165                 .id     = SERIO_ANY,
 166                 .extra  = SERIO_ANY,
 167         },
 168         { 0 }
 169 };
 170 
 171 MODULE_DEVICE_TABLE(serio, hampshire_serio_ids);
 172 
 173 static struct serio_driver hampshire_drv = {
 174         .driver         = {
 175                 .name   = "hampshire",
 176         },
 177         .description    = DRIVER_DESC,
 178         .id_table       = hampshire_serio_ids,
 179         .interrupt      = hampshire_interrupt,
 180         .connect        = hampshire_connect,
 181         .disconnect     = hampshire_disconnect,
 182 };
 183 
 184 module_serio_driver(hampshire_drv);

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