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