0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/delay.h>
0014 #include <linux/module.h>
0015 #include <linux/slab.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/input.h>
0018 #include <linux/serio.h>
0019
0020 #define DRIVER_DESC "Serial mouse driver"
0021
0022 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
0023 MODULE_DESCRIPTION(DRIVER_DESC);
0024 MODULE_LICENSE("GPL");
0025
0026 static const char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse", "Microsoft Mouse",
0027 "Logitech M+ Mouse", "Microsoft MZ Mouse", "Logitech MZ+ Mouse",
0028 "Logitech MZ++ Mouse"};
0029
0030 struct sermouse {
0031 struct input_dev *dev;
0032 signed char buf[8];
0033 unsigned char count;
0034 unsigned char type;
0035 unsigned long last;
0036 char phys[32];
0037 };
0038
0039
0040
0041
0042
0043
0044
0045 static void sermouse_process_msc(struct sermouse *sermouse, signed char data)
0046 {
0047 struct input_dev *dev = sermouse->dev;
0048 signed char *buf = sermouse->buf;
0049
0050 switch (sermouse->count) {
0051
0052 case 0:
0053 if ((data & 0xf8) != 0x80)
0054 return;
0055 input_report_key(dev, BTN_LEFT, !(data & 4));
0056 input_report_key(dev, BTN_RIGHT, !(data & 1));
0057 input_report_key(dev, BTN_MIDDLE, !(data & 2));
0058 break;
0059
0060 case 1:
0061 case 3:
0062 input_report_rel(dev, REL_X, data / 2);
0063 input_report_rel(dev, REL_Y, -buf[1]);
0064 buf[0] = data - data / 2;
0065 break;
0066
0067 case 2:
0068 case 4:
0069 input_report_rel(dev, REL_X, buf[0]);
0070 input_report_rel(dev, REL_Y, buf[1] - data);
0071 buf[1] = data / 2;
0072 break;
0073 }
0074
0075 input_sync(dev);
0076
0077 if (++sermouse->count == 5)
0078 sermouse->count = 0;
0079 }
0080
0081
0082
0083
0084
0085
0086
0087 static void sermouse_process_ms(struct sermouse *sermouse, signed char data)
0088 {
0089 struct input_dev *dev = sermouse->dev;
0090 signed char *buf = sermouse->buf;
0091
0092 if (data & 0x40)
0093 sermouse->count = 0;
0094 else if (sermouse->count == 0)
0095 return;
0096
0097 switch (sermouse->count) {
0098
0099 case 0:
0100 buf[1] = data;
0101 input_report_key(dev, BTN_LEFT, (data >> 5) & 1);
0102 input_report_key(dev, BTN_RIGHT, (data >> 4) & 1);
0103 break;
0104
0105 case 1:
0106 buf[2] = data;
0107 data = (signed char) (((buf[1] << 6) & 0xc0) | (data & 0x3f));
0108 input_report_rel(dev, REL_X, data / 2);
0109 input_report_rel(dev, REL_Y, buf[4]);
0110 buf[3] = data - data / 2;
0111 break;
0112
0113 case 2:
0114
0115 if ((sermouse->type == SERIO_MS) && !data && !buf[2] && !((buf[0] & 0xf0) ^ buf[1]))
0116 input_report_key(dev, BTN_MIDDLE, !test_bit(BTN_MIDDLE, dev->key));
0117 buf[0] = buf[1];
0118
0119 data = (signed char) (((buf[1] << 4) & 0xc0) | (data & 0x3f));
0120 input_report_rel(dev, REL_X, buf[3]);
0121 input_report_rel(dev, REL_Y, data - buf[4]);
0122 buf[4] = data / 2;
0123 break;
0124
0125 case 3:
0126
0127 switch (sermouse->type) {
0128
0129 case SERIO_MS:
0130 sermouse->type = SERIO_MP;
0131 fallthrough;
0132
0133 case SERIO_MP:
0134 if ((data >> 2) & 3) break;
0135 input_report_key(dev, BTN_MIDDLE, (data >> 5) & 1);
0136 input_report_key(dev, BTN_SIDE, (data >> 4) & 1);
0137 break;
0138
0139 case SERIO_MZP:
0140 case SERIO_MZPP:
0141 input_report_key(dev, BTN_SIDE, (data >> 5) & 1);
0142 fallthrough;
0143
0144 case SERIO_MZ:
0145 input_report_key(dev, BTN_MIDDLE, (data >> 4) & 1);
0146 input_report_rel(dev, REL_WHEEL, (data & 8) - (data & 7));
0147 break;
0148 }
0149
0150 break;
0151
0152 case 4:
0153 case 6:
0154 buf[1] = (data >> 2) & 0x0f;
0155 break;
0156
0157 case 5:
0158 case 7:
0159 if (sermouse->type != SERIO_MZPP)
0160 break;
0161
0162 switch (buf[1]) {
0163
0164 case 1:
0165
0166 input_report_key(dev, BTN_SIDE, (data >> 4) & 1);
0167 input_report_key(dev, BTN_EXTRA, (data >> 5) & 1);
0168 input_report_rel(dev, data & 0x80 ? REL_HWHEEL : REL_WHEEL, (data & 7) - (data & 8));
0169
0170 break;
0171
0172 default:
0173
0174 printk(KERN_WARNING
0175 "sermouse.c: Received MZ++ packet %x, don't know how to handle.\n", buf[1]);
0176 break;
0177 }
0178
0179 break;
0180 }
0181
0182 input_sync(dev);
0183
0184 sermouse->count++;
0185 }
0186
0187
0188
0189
0190
0191
0192 static irqreturn_t sermouse_interrupt(struct serio *serio,
0193 unsigned char data, unsigned int flags)
0194 {
0195 struct sermouse *sermouse = serio_get_drvdata(serio);
0196
0197 if (time_after(jiffies, sermouse->last + HZ/10))
0198 sermouse->count = 0;
0199
0200 sermouse->last = jiffies;
0201
0202 if (sermouse->type > SERIO_SUN)
0203 sermouse_process_ms(sermouse, data);
0204 else
0205 sermouse_process_msc(sermouse, data);
0206
0207 return IRQ_HANDLED;
0208 }
0209
0210
0211
0212
0213
0214
0215 static void sermouse_disconnect(struct serio *serio)
0216 {
0217 struct sermouse *sermouse = serio_get_drvdata(serio);
0218
0219 serio_close(serio);
0220 serio_set_drvdata(serio, NULL);
0221 input_unregister_device(sermouse->dev);
0222 kfree(sermouse);
0223 }
0224
0225
0226
0227
0228
0229
0230 static int sermouse_connect(struct serio *serio, struct serio_driver *drv)
0231 {
0232 struct sermouse *sermouse;
0233 struct input_dev *input_dev;
0234 unsigned char c = serio->id.extra;
0235 int err = -ENOMEM;
0236
0237 sermouse = kzalloc(sizeof(struct sermouse), GFP_KERNEL);
0238 input_dev = input_allocate_device();
0239 if (!sermouse || !input_dev)
0240 goto fail1;
0241
0242 sermouse->dev = input_dev;
0243 snprintf(sermouse->phys, sizeof(sermouse->phys), "%s/input0", serio->phys);
0244 sermouse->type = serio->id.proto;
0245
0246 input_dev->name = sermouse_protocols[sermouse->type];
0247 input_dev->phys = sermouse->phys;
0248 input_dev->id.bustype = BUS_RS232;
0249 input_dev->id.vendor = sermouse->type;
0250 input_dev->id.product = c;
0251 input_dev->id.version = 0x0100;
0252 input_dev->dev.parent = &serio->dev;
0253
0254 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
0255 input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
0256 BIT_MASK(BTN_RIGHT);
0257 input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
0258
0259 if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit);
0260 if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit);
0261 if (c & 0x04) set_bit(BTN_EXTRA, input_dev->keybit);
0262 if (c & 0x10) set_bit(REL_WHEEL, input_dev->relbit);
0263 if (c & 0x20) set_bit(REL_HWHEEL, input_dev->relbit);
0264
0265 serio_set_drvdata(serio, sermouse);
0266
0267 err = serio_open(serio, drv);
0268 if (err)
0269 goto fail2;
0270
0271 err = input_register_device(sermouse->dev);
0272 if (err)
0273 goto fail3;
0274
0275 return 0;
0276
0277 fail3: serio_close(serio);
0278 fail2: serio_set_drvdata(serio, NULL);
0279 fail1: input_free_device(input_dev);
0280 kfree(sermouse);
0281 return err;
0282 }
0283
0284 static struct serio_device_id sermouse_serio_ids[] = {
0285 {
0286 .type = SERIO_RS232,
0287 .proto = SERIO_MSC,
0288 .id = SERIO_ANY,
0289 .extra = SERIO_ANY,
0290 },
0291 {
0292 .type = SERIO_RS232,
0293 .proto = SERIO_SUN,
0294 .id = SERIO_ANY,
0295 .extra = SERIO_ANY,
0296 },
0297 {
0298 .type = SERIO_RS232,
0299 .proto = SERIO_MS,
0300 .id = SERIO_ANY,
0301 .extra = SERIO_ANY,
0302 },
0303 {
0304 .type = SERIO_RS232,
0305 .proto = SERIO_MP,
0306 .id = SERIO_ANY,
0307 .extra = SERIO_ANY,
0308 },
0309 {
0310 .type = SERIO_RS232,
0311 .proto = SERIO_MZ,
0312 .id = SERIO_ANY,
0313 .extra = SERIO_ANY,
0314 },
0315 {
0316 .type = SERIO_RS232,
0317 .proto = SERIO_MZP,
0318 .id = SERIO_ANY,
0319 .extra = SERIO_ANY,
0320 },
0321 {
0322 .type = SERIO_RS232,
0323 .proto = SERIO_MZPP,
0324 .id = SERIO_ANY,
0325 .extra = SERIO_ANY,
0326 },
0327 { 0 }
0328 };
0329
0330 MODULE_DEVICE_TABLE(serio, sermouse_serio_ids);
0331
0332 static struct serio_driver sermouse_drv = {
0333 .driver = {
0334 .name = "sermouse",
0335 },
0336 .description = DRIVER_DESC,
0337 .id_table = sermouse_serio_ids,
0338 .interrupt = sermouse_interrupt,
0339 .connect = sermouse_connect,
0340 .disconnect = sermouse_disconnect,
0341 };
0342
0343 module_serio_driver(sermouse_drv);