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