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