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 const 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