📄 vsxxxaa.c
字号:
*/ left = (buf[0] & 0x02)? 1: 0; middle = (buf[0] & 0x04)? 1: 0; right = (buf[0] & 0x08)? 1: 0; touch = (buf[0] & 0x10)? 1: 0; vsxxxaa_drop_bytes (mouse, 5); DBG (KERN_INFO "%s on %s: x=%d, y=%d, buttons=%s%s%s%s\n", mouse->name, mouse->phys, x, y, left? "L": "l", middle? "M": "m", right? "R": "r", touch? "T": "t"); /* * Report what we've found so far... */ input_regs (dev, regs); input_report_key (dev, BTN_LEFT, left); input_report_key (dev, BTN_MIDDLE, middle); input_report_key (dev, BTN_RIGHT, right); input_report_key (dev, BTN_TOUCH, touch); input_report_abs (dev, ABS_X, x); input_report_abs (dev, ABS_Y, y); input_sync (dev);}static voidvsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs){ struct input_dev *dev = &mouse->dev; unsigned char *buf = mouse->buf; int left, middle, right; unsigned char error; /* * Check for Power-On-Reset packets. These are sent out * after plugging the mouse in, or when explicitely * requested by sending 'T'. * * [0]: 1 0 1 0 R3 R2 R1 R0 * [1]: 0 M2 M1 M0 D3 D2 D1 D0 * [2]: 0 E6 E5 E4 E3 E2 E1 E0 * [3]: 0 0 0 0 0 Left Middle Right * * M: manufacturer location code * R: revision code * E: Error code. If it's in the range of 0x00..0x1f, only some * minor problem occured. Errors >= 0x20 are considered bad * and the device may not work properly... * D: <0010> == mouse, <0100> == tablet */ mouse->version = buf[0] & 0x0f; mouse->country = (buf[1] >> 4) & 0x07; mouse->type = buf[1] & 0x0f; error = buf[2] & 0x7f; /* * Get button state. It's the low three bits * (for three buttons) of byte 0. Maybe even the bit <3> * has some meaning if a tablet is attached. */ left = (buf[0] & 0x04)? 1: 0; middle = (buf[0] & 0x02)? 1: 0; right = (buf[0] & 0x01)? 1: 0; vsxxxaa_drop_bytes (mouse, 4); vsxxxaa_detection_done (mouse); if (error <= 0x1f) { /* No (serious) error. Report buttons */ input_regs (dev, regs); input_report_key (dev, BTN_LEFT, left); input_report_key (dev, BTN_MIDDLE, middle); input_report_key (dev, BTN_RIGHT, right); input_report_key (dev, BTN_TOUCH, 0); input_sync (dev); if (error != 0) printk (KERN_INFO "Your %s on %s reports error=0x%02x\n", mouse->name, mouse->phys, error); } /* * If the mouse was hot-plugged, we need to force differential mode * now... However, give it a second to recover from it's reset. */ printk (KERN_NOTICE "%s on %s: Forceing standard packet format, " "incremental streaming mode and 72 samples/sec\n", mouse->name, mouse->phys); mouse->serio->write (mouse->serio, 'S'); /* Standard format */ mdelay (50); mouse->serio->write (mouse->serio, 'R'); /* Incremental */ mdelay (50); mouse->serio->write (mouse->serio, 'L'); /* 72 samples/sec */}static voidvsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs){ unsigned char *buf = mouse->buf; int stray_bytes; /* * Parse buffer to death... */ do { /* * Out of sync? Throw away what we don't understand. Each * packet starts with a byte whose bit 7 is set. Unhandled * packets (ie. which we don't know about or simply b0rk3d * data...) will get shifted out of the buffer after some * activity on the mouse. */ while (mouse->count > 0 && !IS_HDR_BYTE(buf[0])) { printk (KERN_ERR "%s on %s: Dropping a byte to regain " "sync with mouse data stream...\n", mouse->name, mouse->phys); vsxxxaa_drop_bytes (mouse, 1); } /* * Check for packets we know about. */ if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_REL, 3)) { /* Check for broken packet */ stray_bytes = vsxxxaa_check_packet (mouse, 3); if (stray_bytes > 0) { printk (KERN_ERR "Dropping %d bytes now...\n", stray_bytes); vsxxxaa_drop_bytes (mouse, stray_bytes); continue; } vsxxxaa_handle_REL_packet (mouse, regs); continue; /* More to parse? */ } if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_ABS, 5)) { /* Check for broken packet */ stray_bytes = vsxxxaa_check_packet (mouse, 5); if (stray_bytes > 0) { printk (KERN_ERR "Dropping %d bytes now...\n", stray_bytes); vsxxxaa_drop_bytes (mouse, stray_bytes); continue; } vsxxxaa_handle_ABS_packet (mouse, regs); continue; /* More to parse? */ } if (vsxxxaa_smells_like_packet (mouse, VSXXXAA_PACKET_POR, 4)) { /* Check for broken packet */ stray_bytes = vsxxxaa_check_packet (mouse, 4); if (stray_bytes > 0) { printk (KERN_ERR "Dropping %d bytes now...\n", stray_bytes); vsxxxaa_drop_bytes (mouse, stray_bytes); continue; } vsxxxaa_handle_POR_packet (mouse, regs); continue; /* More to parse? */ } break; /* No REL, ABS or POR packet found */ } while (1);}static irqreturn_tvsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs){ struct vsxxxaa *mouse = serio_get_drvdata (serio); vsxxxaa_queue_byte (mouse, data); vsxxxaa_parse_buffer (mouse, regs); return IRQ_HANDLED;}static voidvsxxxaa_disconnect (struct serio *serio){ struct vsxxxaa *mouse = serio_get_drvdata (serio); input_unregister_device (&mouse->dev); serio_close (serio); serio_set_drvdata (serio, NULL); kfree (mouse);}static intvsxxxaa_connect (struct serio *serio, struct serio_driver *drv){ struct vsxxxaa *mouse; int err; if (!(mouse = kmalloc (sizeof (struct vsxxxaa), GFP_KERNEL))) return -ENOMEM; memset (mouse, 0, sizeof (struct vsxxxaa)); init_input_dev (&mouse->dev); set_bit (EV_KEY, mouse->dev.evbit); /* We have buttons */ set_bit (EV_REL, mouse->dev.evbit); set_bit (EV_ABS, mouse->dev.evbit); set_bit (BTN_LEFT, mouse->dev.keybit); /* We have 3 buttons */ set_bit (BTN_MIDDLE, mouse->dev.keybit); set_bit (BTN_RIGHT, mouse->dev.keybit); set_bit (BTN_TOUCH, mouse->dev.keybit); /* ...and Tablet */ set_bit (REL_X, mouse->dev.relbit); set_bit (REL_Y, mouse->dev.relbit); set_bit (ABS_X, mouse->dev.absbit); set_bit (ABS_Y, mouse->dev.absbit); mouse->dev.absmin[ABS_X] = 0; mouse->dev.absmax[ABS_X] = 1023; mouse->dev.absmin[ABS_Y] = 0; mouse->dev.absmax[ABS_Y] = 1023; mouse->dev.private = mouse; sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer"); sprintf (mouse->phys, "%s/input0", serio->phys); mouse->dev.name = mouse->name; mouse->dev.phys = mouse->phys; mouse->dev.id.bustype = BUS_RS232; mouse->dev.dev = &serio->dev; mouse->serio = serio; serio_set_drvdata (serio, mouse); err = serio_open (serio, drv); if (err) { serio_set_drvdata (serio, NULL); kfree (mouse); return err; } /* * Request selftest. Standard packet format and differential * mode will be requested after the device ID'ed successfully. */ mouse->serio->write (mouse->serio, 'T'); /* Test */ input_register_device (&mouse->dev); printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys); return 0;}static struct serio_device_id vsxxaa_serio_ids[] = { { .type = SERIO_RS232, .proto = SERIO_VSXXXAA, .id = SERIO_ANY, .extra = SERIO_ANY, }, { 0 }};MODULE_DEVICE_TABLE(serio, vsxxaa_serio_ids);static struct serio_driver vsxxxaa_drv = { .driver = { .name = "vsxxxaa", }, .description = DRIVER_DESC, .id_table = vsxxaa_serio_ids, .connect = vsxxxaa_connect, .interrupt = vsxxxaa_interrupt, .disconnect = vsxxxaa_disconnect,};static int __initvsxxxaa_init (void){ serio_register_driver(&vsxxxaa_drv); return 0;}static void __exitvsxxxaa_exit (void){ serio_unregister_driver(&vsxxxaa_drv);}module_init (vsxxxaa_init);module_exit (vsxxxaa_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -