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