1 /* 2 * Copyright (c) 1999-2001 Vojtech Pavlik 3 */ 4 5 /* 6 * Serial mouse driver for Linux 7 */ 8 9 /* 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25 #include <linux/delay.h> 26 #include <linux/module.h> 27 #include <linux/slab.h> 28 #include <linux/interrupt.h> 29 #include <linux/input.h> 30 #include <linux/serio.h> 31 32 #define DRIVER_DESC "Serial mouse driver" 33 34 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 35 MODULE_DESCRIPTION(DRIVER_DESC); 36 MODULE_LICENSE("GPL"); 37 38 static const char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse", "Microsoft Mouse", 39 "Logitech M+ Mouse", "Microsoft MZ Mouse", "Logitech MZ+ Mouse", 40 "Logitech MZ++ Mouse"}; 41 42 struct sermouse { 43 struct input_dev *dev; 44 signed char buf[8]; 45 unsigned char count; 46 unsigned char type; 47 unsigned long last; 48 char phys[32]; 49 }; 50 51 /* 52 * sermouse_process_msc() analyzes the incoming MSC/Sun bytestream and 53 * applies some prediction to the data, resulting in 96 updates per 54 * second, which is as good as a PS/2 or USB mouse. 55 */ 56 57 static void sermouse_process_msc(struct sermouse *sermouse, signed char data) 58 { 59 struct input_dev *dev = sermouse->dev; 60 signed char *buf = sermouse->buf; 61 62 switch (sermouse->count) { 63 64 case 0: 65 if ((data & 0xf8) != 0x80) 66 return; 67 input_report_key(dev, BTN_LEFT, !(data & 4)); 68 input_report_key(dev, BTN_RIGHT, !(data & 1)); 69 input_report_key(dev, BTN_MIDDLE, !(data & 2)); 70 break; 71 72 case 1: 73 case 3: 74 input_report_rel(dev, REL_X, data / 2); 75 input_report_rel(dev, REL_Y, -buf[1]); 76 buf[0] = data - data / 2; 77 break; 78 79 case 2: 80 case 4: 81 input_report_rel(dev, REL_X, buf[0]); 82 input_report_rel(dev, REL_Y, buf[1] - data); 83 buf[1] = data / 2; 84 break; 85 } 86 87 input_sync(dev); 88 89 if (++sermouse->count == 5) 90 sermouse->count = 0; 91 } 92 93 /* 94 * sermouse_process_ms() anlyzes the incoming MS(Z/+/++) bytestream and 95 * generates events. With prediction it gets 80 updates/sec, assuming 96 * standard 3-byte packets and 1200 bps. 97 */ 98 99 static void sermouse_process_ms(struct sermouse *sermouse, signed char data) 100 { 101 struct input_dev *dev = sermouse->dev; 102 signed char *buf = sermouse->buf; 103 104 if (data & 0x40) 105 sermouse->count = 0; 106 else if (sermouse->count == 0) 107 return; 108 109 switch (sermouse->count) { 110 111 case 0: 112 buf[1] = data; 113 input_report_key(dev, BTN_LEFT, (data >> 5) & 1); 114 input_report_key(dev, BTN_RIGHT, (data >> 4) & 1); 115 break; 116 117 case 1: 118 buf[2] = data; 119 data = (signed char) (((buf[1] << 6) & 0xc0) | (data & 0x3f)); 120 input_report_rel(dev, REL_X, data / 2); 121 input_report_rel(dev, REL_Y, buf[4]); 122 buf[3] = data - data / 2; 123 break; 124 125 case 2: 126 /* Guessing the state of the middle button on 3-button MS-protocol mice - ugly. */ 127 if ((sermouse->type == SERIO_MS) && !data && !buf[2] && !((buf[0] & 0xf0) ^ buf[1])) 128 input_report_key(dev, BTN_MIDDLE, !test_bit(BTN_MIDDLE, dev->key)); 129 buf[0] = buf[1]; 130 131 data = (signed char) (((buf[1] << 4) & 0xc0) | (data & 0x3f)); 132 input_report_rel(dev, REL_X, buf[3]); 133 input_report_rel(dev, REL_Y, data - buf[4]); 134 buf[4] = data / 2; 135 break; 136 137 case 3: 138 139 switch (sermouse->type) { 140 141 case SERIO_MS: 142 sermouse->type = SERIO_MP; 143 /* fall through */ 144 145 case SERIO_MP: 146 if ((data >> 2) & 3) break; /* M++ Wireless Extension packet. */ 147 input_report_key(dev, BTN_MIDDLE, (data >> 5) & 1); 148 input_report_key(dev, BTN_SIDE, (data >> 4) & 1); 149 break; 150 151 case SERIO_MZP: 152 case SERIO_MZPP: 153 input_report_key(dev, BTN_SIDE, (data >> 5) & 1); 154 /* fall through */ 155 156 case SERIO_MZ: 157 input_report_key(dev, BTN_MIDDLE, (data >> 4) & 1); 158 input_report_rel(dev, REL_WHEEL, (data & 8) - (data & 7)); 159 break; 160 } 161 162 break; 163 164 case 4: 165 case 6: /* MZ++ packet type. We can get these bytes for M++ too but we ignore them later. */ 166 buf[1] = (data >> 2) & 0x0f; 167 break; 168 169 case 5: 170 case 7: /* Ignore anything besides MZ++ */ 171 if (sermouse->type != SERIO_MZPP) 172 break; 173 174 switch (buf[1]) { 175 176 case 1: /* Extra mouse info */ 177 178 input_report_key(dev, BTN_SIDE, (data >> 4) & 1); 179 input_report_key(dev, BTN_EXTRA, (data >> 5) & 1); 180 input_report_rel(dev, data & 0x80 ? REL_HWHEEL : REL_WHEEL, (data & 7) - (data & 8)); 181 182 break; 183 184 default: /* We don't decode anything else yet. */ 185 186 printk(KERN_WARNING 187 "sermouse.c: Received MZ++ packet %x, don't know how to handle.\n", buf[1]); 188 break; 189 } 190 191 break; 192 } 193 194 input_sync(dev); 195 196 sermouse->count++; 197 } 198 199 /* 200 * sermouse_interrupt() handles incoming characters, either gathering them into 201 * packets or passing them to the command routine as command output. 202 */ 203 204 static irqreturn_t sermouse_interrupt(struct serio *serio, 205 unsigned char data, unsigned int flags) 206 { 207 struct sermouse *sermouse = serio_get_drvdata(serio); 208 209 if (time_after(jiffies, sermouse->last + HZ/10)) 210 sermouse->count = 0; 211 212 sermouse->last = jiffies; 213 214 if (sermouse->type > SERIO_SUN) 215 sermouse_process_ms(sermouse, data); 216 else 217 sermouse_process_msc(sermouse, data); 218 219 return IRQ_HANDLED; 220 } 221 222 /* 223 * sermouse_disconnect() cleans up after we don't want talk 224 * to the mouse anymore. 225 */ 226 227 static void sermouse_disconnect(struct serio *serio) 228 { 229 struct sermouse *sermouse = serio_get_drvdata(serio); 230 231 serio_close(serio); 232 serio_set_drvdata(serio, NULL); 233 input_unregister_device(sermouse->dev); 234 kfree(sermouse); 235 } 236 237 /* 238 * sermouse_connect() is a callback form the serio module when 239 * an unhandled serio port is found. 240 */ 241 242 static int sermouse_connect(struct serio *serio, struct serio_driver *drv) 243 { 244 struct sermouse *sermouse; 245 struct input_dev *input_dev; 246 unsigned char c = serio->id.extra; 247 int err = -ENOMEM; 248 249 sermouse = kzalloc(sizeof(struct sermouse), GFP_KERNEL); 250 input_dev = input_allocate_device(); 251 if (!sermouse || !input_dev) 252 goto fail1; 253 254 sermouse->dev = input_dev; 255 snprintf(sermouse->phys, sizeof(sermouse->phys), "%s/input0", serio->phys); 256 sermouse->type = serio->id.proto; 257 258 input_dev->name = sermouse_protocols[sermouse->type]; 259 input_dev->phys = sermouse->phys; 260 input_dev->id.bustype = BUS_RS232; 261 input_dev->id.vendor = sermouse->type; 262 input_dev->id.product = c; 263 input_dev->id.version = 0x0100; 264 input_dev->dev.parent = &serio->dev; 265 266 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); 267 input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | 268 BIT_MASK(BTN_RIGHT); 269 input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); 270 271 if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit); 272 if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit); 273 if (c & 0x04) set_bit(BTN_EXTRA, input_dev->keybit); 274 if (c & 0x10) set_bit(REL_WHEEL, input_dev->relbit); 275 if (c & 0x20) set_bit(REL_HWHEEL, input_dev->relbit); 276 277 serio_set_drvdata(serio, sermouse); 278 279 err = serio_open(serio, drv); 280 if (err) 281 goto fail2; 282 283 err = input_register_device(sermouse->dev); 284 if (err) 285 goto fail3; 286 287 return 0; 288 289 fail3: serio_close(serio); 290 fail2: serio_set_drvdata(serio, NULL); 291 fail1: input_free_device(input_dev); 292 kfree(sermouse); 293 return err; 294 } 295 296 static struct serio_device_id sermouse_serio_ids[] = { 297 { 298 .type = SERIO_RS232, 299 .proto = SERIO_MSC, 300 .id = SERIO_ANY, 301 .extra = SERIO_ANY, 302 }, 303 { 304 .type = SERIO_RS232, 305 .proto = SERIO_SUN, 306 .id = SERIO_ANY, 307 .extra = SERIO_ANY, 308 }, 309 { 310 .type = SERIO_RS232, 311 .proto = SERIO_MS, 312 .id = SERIO_ANY, 313 .extra = SERIO_ANY, 314 }, 315 { 316 .type = SERIO_RS232, 317 .proto = SERIO_MP, 318 .id = SERIO_ANY, 319 .extra = SERIO_ANY, 320 }, 321 { 322 .type = SERIO_RS232, 323 .proto = SERIO_MZ, 324 .id = SERIO_ANY, 325 .extra = SERIO_ANY, 326 }, 327 { 328 .type = SERIO_RS232, 329 .proto = SERIO_MZP, 330 .id = SERIO_ANY, 331 .extra = SERIO_ANY, 332 }, 333 { 334 .type = SERIO_RS232, 335 .proto = SERIO_MZPP, 336 .id = SERIO_ANY, 337 .extra = SERIO_ANY, 338 }, 339 { 0 } 340 }; 341 342 MODULE_DEVICE_TABLE(serio, sermouse_serio_ids); 343 344 static struct serio_driver sermouse_drv = { 345 .driver = { 346 .name = "sermouse", 347 }, 348 .description = DRIVER_DESC, 349 .id_table = sermouse_serio_ids, 350 .interrupt = sermouse_interrupt, 351 .connect = sermouse_connect, 352 .disconnect = sermouse_disconnect, 353 }; 354 355 module_serio_driver(sermouse_drv); 356