Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/drivers/input/touchscreen/inexio.c

  1 /*
  2  * iNexio serial touchscreen driver
  3  *
  4  * Copyright (c) 2008 Richard Lemon
  5  * Based on the mtouch driver (c) Vojtech Pavlik and Dan Streetman
  6  *
  7  */
  8 
  9 /*
 10  * This program is free software; you can redistribute it and/or modify it
 11  * under the terms of the GNU General Public License version 2 as published by
 12  * the Free Software Foundation.
 13  */
 14 
 15 /*
 16  * 2008/06/19 Richard Lemon <richard@codelemon.com>
 17  *   Copied mtouch.c and edited for iNexio protocol
 18  */
 19 
 20 #include <linux/errno.h>
 21 #include <linux/kernel.h>
 22 #include <linux/module.h>
 23 #include <linux/slab.h>
 24 #include <linux/input.h>
 25 #include <linux/serio.h>
 26 
 27 #define DRIVER_DESC     "iNexio serial touchscreen driver"
 28 
 29 MODULE_AUTHOR("Richard Lemon <richard@codelemon.com>");
 30 MODULE_DESCRIPTION(DRIVER_DESC);
 31 MODULE_LICENSE("GPL");
 32 
 33 /*
 34  * Definitions & global arrays.
 35  */
 36 
 37 #define INEXIO_FORMAT_TOUCH_BIT 0x01
 38 #define INEXIO_FORMAT_LENGTH 5
 39 #define INEXIO_RESPONSE_BEGIN_BYTE 0x80
 40 
 41 /* todo: check specs for max length of all responses */
 42 #define INEXIO_MAX_LENGTH 16
 43 
 44 #define INEXIO_MIN_XC 0
 45 #define INEXIO_MAX_XC 0x3fff
 46 #define INEXIO_MIN_YC 0
 47 #define INEXIO_MAX_YC 0x3fff
 48 
 49 #define INEXIO_GET_XC(data) (((data[1])<<7) | data[2])
 50 #define INEXIO_GET_YC(data) (((data[3])<<7) | data[4])
 51 #define INEXIO_GET_TOUCHED(data) (INEXIO_FORMAT_TOUCH_BIT & data[0])
 52 
 53 /*
 54  * Per-touchscreen data.
 55  */
 56 
 57 struct inexio {
 58         struct input_dev *dev;
 59         struct serio *serio;
 60         int idx;
 61         unsigned char data[INEXIO_MAX_LENGTH];
 62         char phys[32];
 63 };
 64 
 65 static void inexio_process_data(struct inexio *pinexio)
 66 {
 67         struct input_dev *dev = pinexio->dev;
 68 
 69         if (INEXIO_FORMAT_LENGTH == ++pinexio->idx) {
 70                 input_report_abs(dev, ABS_X, INEXIO_GET_XC(pinexio->data));
 71                 input_report_abs(dev, ABS_Y, INEXIO_GET_YC(pinexio->data));
 72                 input_report_key(dev, BTN_TOUCH, INEXIO_GET_TOUCHED(pinexio->data));
 73                 input_sync(dev);
 74 
 75                 pinexio->idx = 0;
 76         }
 77 }
 78 
 79 static irqreturn_t inexio_interrupt(struct serio *serio,
 80                 unsigned char data, unsigned int flags)
 81 {
 82         struct inexio* pinexio = serio_get_drvdata(serio);
 83 
 84         pinexio->data[pinexio->idx] = data;
 85 
 86         if (INEXIO_RESPONSE_BEGIN_BYTE&pinexio->data[0])
 87                 inexio_process_data(pinexio);
 88         else
 89                 printk(KERN_DEBUG "inexio.c: unknown/unsynchronized data from device, byte %x\n",pinexio->data[0]);
 90 
 91         return IRQ_HANDLED;
 92 }
 93 
 94 /*
 95  * inexio_disconnect() is the opposite of inexio_connect()
 96  */
 97 
 98 static void inexio_disconnect(struct serio *serio)
 99 {
100         struct inexio* pinexio = serio_get_drvdata(serio);
101 
102         input_get_device(pinexio->dev);
103         input_unregister_device(pinexio->dev);
104         serio_close(serio);
105         serio_set_drvdata(serio, NULL);
106         input_put_device(pinexio->dev);
107         kfree(pinexio);
108 }
109 
110 /*
111  * inexio_connect() is the routine that is called when someone adds a
112  * new serio device that supports iNexio protocol and registers it as
113  * an input device. This is usually accomplished using inputattach.
114  */
115 
116 static int inexio_connect(struct serio *serio, struct serio_driver *drv)
117 {
118         struct inexio *pinexio;
119         struct input_dev *input_dev;
120         int err;
121 
122         pinexio = kzalloc(sizeof(struct inexio), GFP_KERNEL);
123         input_dev = input_allocate_device();
124         if (!pinexio || !input_dev) {
125                 err = -ENOMEM;
126                 goto fail1;
127         }
128 
129         pinexio->serio = serio;
130         pinexio->dev = input_dev;
131         snprintf(pinexio->phys, sizeof(pinexio->phys), "%s/input0", serio->phys);
132 
133         input_dev->name = "iNexio Serial TouchScreen";
134         input_dev->phys = pinexio->phys;
135         input_dev->id.bustype = BUS_RS232;
136         input_dev->id.vendor = SERIO_INEXIO;
137         input_dev->id.product = 0;
138         input_dev->id.version = 0x0001;
139         input_dev->dev.parent = &serio->dev;
140         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
141         input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
142         input_set_abs_params(pinexio->dev, ABS_X, INEXIO_MIN_XC, INEXIO_MAX_XC, 0, 0);
143         input_set_abs_params(pinexio->dev, ABS_Y, INEXIO_MIN_YC, INEXIO_MAX_YC, 0, 0);
144 
145         serio_set_drvdata(serio, pinexio);
146 
147         err = serio_open(serio, drv);
148         if (err)
149                 goto fail2;
150 
151         err = input_register_device(pinexio->dev);
152         if (err)
153                 goto fail3;
154 
155         return 0;
156 
157  fail3: serio_close(serio);
158  fail2: serio_set_drvdata(serio, NULL);
159  fail1: input_free_device(input_dev);
160         kfree(pinexio);
161         return err;
162 }
163 
164 /*
165  * The serio driver structure.
166  */
167 
168 static struct serio_device_id inexio_serio_ids[] = {
169         {
170                 .type   = SERIO_RS232,
171                 .proto  = SERIO_INEXIO,
172                 .id     = SERIO_ANY,
173                 .extra  = SERIO_ANY,
174         },
175         { 0 }
176 };
177 
178 MODULE_DEVICE_TABLE(serio, inexio_serio_ids);
179 
180 static struct serio_driver inexio_drv = {
181         .driver         = {
182                 .name   = "inexio",
183         },
184         .description    = DRIVER_DESC,
185         .id_table       = inexio_serio_ids,
186         .interrupt      = inexio_interrupt,
187         .connect        = inexio_connect,
188         .disconnect     = inexio_disconnect,
189 };
190 
191 module_serio_driver(inexio_drv);
192 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us