wacom_w8001.c (17170B)
1/* 2 * Wacom W8001 penabled serial touchscreen driver 3 * 4 * Copyright (c) 2008 Jaya Kumar 5 * Copyright (c) 2010 Red Hat, Inc. 6 * Copyright (c) 2010 - 2011 Ping Cheng, Wacom. <pingc@wacom.com> 7 * 8 * This file is subject to the terms and conditions of the GNU General Public 9 * License. See the file COPYING in the main directory of this archive for 10 * more details. 11 * 12 * Layout based on Elo serial touchscreen driver by Vojtech Pavlik 13 */ 14 15#include <linux/errno.h> 16#include <linux/kernel.h> 17#include <linux/module.h> 18#include <linux/slab.h> 19#include <linux/input/mt.h> 20#include <linux/serio.h> 21#include <linux/ctype.h> 22#include <linux/delay.h> 23 24#define DRIVER_DESC "Wacom W8001 serial touchscreen driver" 25 26MODULE_AUTHOR("Jaya Kumar <jayakumar.lkml@gmail.com>"); 27MODULE_DESCRIPTION(DRIVER_DESC); 28MODULE_LICENSE("GPL"); 29 30#define W8001_MAX_PHYS 42 31 32#define W8001_MAX_LENGTH 13 33#define W8001_LEAD_MASK 0x80 34#define W8001_LEAD_BYTE 0x80 35#define W8001_TAB_MASK 0x40 36#define W8001_TAB_BYTE 0x40 37/* set in first byte of touch data packets */ 38#define W8001_TOUCH_MASK (0x10 | W8001_LEAD_MASK) 39#define W8001_TOUCH_BYTE (0x10 | W8001_LEAD_BYTE) 40 41#define W8001_QUERY_PACKET 0x20 42 43#define W8001_CMD_STOP '0' 44#define W8001_CMD_START '1' 45#define W8001_CMD_QUERY '*' 46#define W8001_CMD_TOUCHQUERY '%' 47 48/* length of data packets in bytes, depends on device. */ 49#define W8001_PKTLEN_TOUCH93 5 50#define W8001_PKTLEN_TOUCH9A 7 51#define W8001_PKTLEN_TPCPEN 9 52#define W8001_PKTLEN_TPCCTL 11 /* control packet */ 53#define W8001_PKTLEN_TOUCH2FG 13 54 55/* resolution in points/mm */ 56#define W8001_PEN_RESOLUTION 100 57#define W8001_TOUCH_RESOLUTION 10 58 59struct w8001_coord { 60 u8 rdy; 61 u8 tsw; 62 u8 f1; 63 u8 f2; 64 u16 x; 65 u16 y; 66 u16 pen_pressure; 67 u8 tilt_x; 68 u8 tilt_y; 69}; 70 71/* touch query reply packet */ 72struct w8001_touch_query { 73 u16 x; 74 u16 y; 75 u8 panel_res; 76 u8 capacity_res; 77 u8 sensor_id; 78}; 79 80/* 81 * Per-touchscreen data. 82 */ 83 84struct w8001 { 85 struct input_dev *pen_dev; 86 struct input_dev *touch_dev; 87 struct serio *serio; 88 struct completion cmd_done; 89 int id; 90 int idx; 91 unsigned char response_type; 92 unsigned char response[W8001_MAX_LENGTH]; 93 unsigned char data[W8001_MAX_LENGTH]; 94 char phys[W8001_MAX_PHYS]; 95 int type; 96 unsigned int pktlen; 97 u16 max_touch_x; 98 u16 max_touch_y; 99 u16 max_pen_x; 100 u16 max_pen_y; 101 char pen_name[64]; 102 char touch_name[64]; 103 int open_count; 104 struct mutex mutex; 105}; 106 107static void parse_pen_data(u8 *data, struct w8001_coord *coord) 108{ 109 memset(coord, 0, sizeof(*coord)); 110 111 coord->rdy = data[0] & 0x20; 112 coord->tsw = data[0] & 0x01; 113 coord->f1 = data[0] & 0x02; 114 coord->f2 = data[0] & 0x04; 115 116 coord->x = (data[1] & 0x7F) << 9; 117 coord->x |= (data[2] & 0x7F) << 2; 118 coord->x |= (data[6] & 0x60) >> 5; 119 120 coord->y = (data[3] & 0x7F) << 9; 121 coord->y |= (data[4] & 0x7F) << 2; 122 coord->y |= (data[6] & 0x18) >> 3; 123 124 coord->pen_pressure = data[5] & 0x7F; 125 coord->pen_pressure |= (data[6] & 0x07) << 7 ; 126 127 coord->tilt_x = data[7] & 0x7F; 128 coord->tilt_y = data[8] & 0x7F; 129} 130 131static void parse_single_touch(u8 *data, struct w8001_coord *coord) 132{ 133 coord->x = (data[1] << 7) | data[2]; 134 coord->y = (data[3] << 7) | data[4]; 135 coord->tsw = data[0] & 0x01; 136} 137 138static void scale_touch_coordinates(struct w8001 *w8001, 139 unsigned int *x, unsigned int *y) 140{ 141 if (w8001->max_pen_x && w8001->max_touch_x) 142 *x = *x * w8001->max_pen_x / w8001->max_touch_x; 143 144 if (w8001->max_pen_y && w8001->max_touch_y) 145 *y = *y * w8001->max_pen_y / w8001->max_touch_y; 146} 147 148static void parse_multi_touch(struct w8001 *w8001) 149{ 150 struct input_dev *dev = w8001->touch_dev; 151 unsigned char *data = w8001->data; 152 unsigned int x, y; 153 int i; 154 int count = 0; 155 156 for (i = 0; i < 2; i++) { 157 bool touch = data[0] & (1 << i); 158 159 input_mt_slot(dev, i); 160 input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch); 161 if (touch) { 162 x = (data[6 * i + 1] << 7) | data[6 * i + 2]; 163 y = (data[6 * i + 3] << 7) | data[6 * i + 4]; 164 /* data[5,6] and [11,12] is finger capacity */ 165 166 /* scale to pen maximum */ 167 scale_touch_coordinates(w8001, &x, &y); 168 169 input_report_abs(dev, ABS_MT_POSITION_X, x); 170 input_report_abs(dev, ABS_MT_POSITION_Y, y); 171 count++; 172 } 173 } 174 175 /* emulate single touch events when stylus is out of proximity. 176 * This is to make single touch backward support consistent 177 * across all Wacom single touch devices. 178 */ 179 if (w8001->type != BTN_TOOL_PEN && 180 w8001->type != BTN_TOOL_RUBBER) { 181 w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED; 182 input_mt_report_pointer_emulation(dev, true); 183 } 184 185 input_sync(dev); 186} 187 188static void parse_touchquery(u8 *data, struct w8001_touch_query *query) 189{ 190 memset(query, 0, sizeof(*query)); 191 192 query->panel_res = data[1]; 193 query->sensor_id = data[2] & 0x7; 194 query->capacity_res = data[7]; 195 196 query->x = data[3] << 9; 197 query->x |= data[4] << 2; 198 query->x |= (data[2] >> 5) & 0x3; 199 200 query->y = data[5] << 9; 201 query->y |= data[6] << 2; 202 query->y |= (data[2] >> 3) & 0x3; 203 204 /* Early days' single-finger touch models need the following defaults */ 205 if (!query->x && !query->y) { 206 query->x = 1024; 207 query->y = 1024; 208 if (query->panel_res) 209 query->x = query->y = (1 << query->panel_res); 210 query->panel_res = W8001_TOUCH_RESOLUTION; 211 } 212} 213 214static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) 215{ 216 struct input_dev *dev = w8001->pen_dev; 217 218 /* 219 * We have 1 bit for proximity (rdy) and 3 bits for tip, side, 220 * side2/eraser. If rdy && f2 are set, this can be either pen + side2, 221 * or eraser. Assume: 222 * - if dev is already in proximity and f2 is toggled → pen + side2 223 * - if dev comes into proximity with f2 set → eraser 224 * If f2 disappears after assuming eraser, fake proximity out for 225 * eraser and in for pen. 226 */ 227 228 switch (w8001->type) { 229 case BTN_TOOL_RUBBER: 230 if (!coord->f2) { 231 input_report_abs(dev, ABS_PRESSURE, 0); 232 input_report_key(dev, BTN_TOUCH, 0); 233 input_report_key(dev, BTN_STYLUS, 0); 234 input_report_key(dev, BTN_STYLUS2, 0); 235 input_report_key(dev, BTN_TOOL_RUBBER, 0); 236 input_sync(dev); 237 w8001->type = BTN_TOOL_PEN; 238 } 239 break; 240 241 case BTN_TOOL_FINGER: 242 case KEY_RESERVED: 243 w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; 244 break; 245 246 default: 247 input_report_key(dev, BTN_STYLUS2, coord->f2); 248 break; 249 } 250 251 input_report_abs(dev, ABS_X, coord->x); 252 input_report_abs(dev, ABS_Y, coord->y); 253 input_report_abs(dev, ABS_PRESSURE, coord->pen_pressure); 254 input_report_key(dev, BTN_TOUCH, coord->tsw); 255 input_report_key(dev, BTN_STYLUS, coord->f1); 256 input_report_key(dev, w8001->type, coord->rdy); 257 input_sync(dev); 258 259 if (!coord->rdy) 260 w8001->type = KEY_RESERVED; 261} 262 263static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord) 264{ 265 struct input_dev *dev = w8001->touch_dev; 266 unsigned int x = coord->x; 267 unsigned int y = coord->y; 268 269 /* scale to pen maximum */ 270 scale_touch_coordinates(w8001, &x, &y); 271 272 input_report_abs(dev, ABS_X, x); 273 input_report_abs(dev, ABS_Y, y); 274 input_report_key(dev, BTN_TOUCH, coord->tsw); 275 276 input_sync(dev); 277 278 w8001->type = coord->tsw ? BTN_TOOL_FINGER : KEY_RESERVED; 279} 280 281static irqreturn_t w8001_interrupt(struct serio *serio, 282 unsigned char data, unsigned int flags) 283{ 284 struct w8001 *w8001 = serio_get_drvdata(serio); 285 struct w8001_coord coord; 286 unsigned char tmp; 287 288 w8001->data[w8001->idx] = data; 289 switch (w8001->idx++) { 290 case 0: 291 if ((data & W8001_LEAD_MASK) != W8001_LEAD_BYTE) { 292 pr_debug("w8001: unsynchronized data: 0x%02x\n", data); 293 w8001->idx = 0; 294 } 295 break; 296 297 case W8001_PKTLEN_TOUCH93 - 1: 298 case W8001_PKTLEN_TOUCH9A - 1: 299 tmp = w8001->data[0] & W8001_TOUCH_BYTE; 300 if (tmp != W8001_TOUCH_BYTE) 301 break; 302 303 if (w8001->pktlen == w8001->idx) { 304 w8001->idx = 0; 305 if (w8001->type != BTN_TOOL_PEN && 306 w8001->type != BTN_TOOL_RUBBER) { 307 parse_single_touch(w8001->data, &coord); 308 report_single_touch(w8001, &coord); 309 } 310 } 311 break; 312 313 /* Pen coordinates packet */ 314 case W8001_PKTLEN_TPCPEN - 1: 315 tmp = w8001->data[0] & W8001_TAB_MASK; 316 if (unlikely(tmp == W8001_TAB_BYTE)) 317 break; 318 319 tmp = w8001->data[0] & W8001_TOUCH_BYTE; 320 if (tmp == W8001_TOUCH_BYTE) 321 break; 322 323 w8001->idx = 0; 324 parse_pen_data(w8001->data, &coord); 325 report_pen_events(w8001, &coord); 326 break; 327 328 /* control packet */ 329 case W8001_PKTLEN_TPCCTL - 1: 330 tmp = w8001->data[0] & W8001_TOUCH_MASK; 331 if (tmp == W8001_TOUCH_BYTE) 332 break; 333 334 w8001->idx = 0; 335 memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH); 336 w8001->response_type = W8001_QUERY_PACKET; 337 complete(&w8001->cmd_done); 338 break; 339 340 /* 2 finger touch packet */ 341 case W8001_PKTLEN_TOUCH2FG - 1: 342 w8001->idx = 0; 343 parse_multi_touch(w8001); 344 break; 345 346 default: 347 /* 348 * ThinkPad X60 Tablet PC (pen only device) sometimes 349 * sends invalid data packets that are larger than 350 * W8001_PKTLEN_TPCPEN. Let's start over again. 351 */ 352 if (!w8001->touch_dev && w8001->idx > W8001_PKTLEN_TPCPEN - 1) 353 w8001->idx = 0; 354 } 355 356 return IRQ_HANDLED; 357} 358 359static int w8001_command(struct w8001 *w8001, unsigned char command, 360 bool wait_response) 361{ 362 int rc; 363 364 w8001->response_type = 0; 365 init_completion(&w8001->cmd_done); 366 367 rc = serio_write(w8001->serio, command); 368 if (rc == 0 && wait_response) { 369 370 wait_for_completion_timeout(&w8001->cmd_done, HZ); 371 if (w8001->response_type != W8001_QUERY_PACKET) 372 rc = -EIO; 373 } 374 375 return rc; 376} 377 378static int w8001_open(struct input_dev *dev) 379{ 380 struct w8001 *w8001 = input_get_drvdata(dev); 381 int err; 382 383 err = mutex_lock_interruptible(&w8001->mutex); 384 if (err) 385 return err; 386 387 if (w8001->open_count++ == 0) { 388 err = w8001_command(w8001, W8001_CMD_START, false); 389 if (err) 390 w8001->open_count--; 391 } 392 393 mutex_unlock(&w8001->mutex); 394 return err; 395} 396 397static void w8001_close(struct input_dev *dev) 398{ 399 struct w8001 *w8001 = input_get_drvdata(dev); 400 401 mutex_lock(&w8001->mutex); 402 403 if (--w8001->open_count == 0) 404 w8001_command(w8001, W8001_CMD_STOP, false); 405 406 mutex_unlock(&w8001->mutex); 407} 408 409static int w8001_detect(struct w8001 *w8001) 410{ 411 int error; 412 413 error = w8001_command(w8001, W8001_CMD_STOP, false); 414 if (error) 415 return error; 416 417 msleep(250); /* wait 250ms before querying the device */ 418 419 return 0; 420} 421 422static int w8001_setup_pen(struct w8001 *w8001, char *basename, 423 size_t basename_sz) 424{ 425 struct input_dev *dev = w8001->pen_dev; 426 struct w8001_coord coord; 427 int error; 428 429 /* penabled? */ 430 error = w8001_command(w8001, W8001_CMD_QUERY, true); 431 if (error) 432 return error; 433 434 __set_bit(EV_KEY, dev->evbit); 435 __set_bit(EV_ABS, dev->evbit); 436 __set_bit(BTN_TOUCH, dev->keybit); 437 __set_bit(BTN_TOOL_PEN, dev->keybit); 438 __set_bit(BTN_TOOL_RUBBER, dev->keybit); 439 __set_bit(BTN_STYLUS, dev->keybit); 440 __set_bit(BTN_STYLUS2, dev->keybit); 441 __set_bit(INPUT_PROP_DIRECT, dev->propbit); 442 443 parse_pen_data(w8001->response, &coord); 444 w8001->max_pen_x = coord.x; 445 w8001->max_pen_y = coord.y; 446 447 input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); 448 input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); 449 input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION); 450 input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION); 451 input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); 452 if (coord.tilt_x && coord.tilt_y) { 453 input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); 454 input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); 455 } 456 457 w8001->id = 0x90; 458 strlcat(basename, " Penabled", basename_sz); 459 460 return 0; 461} 462 463static int w8001_setup_touch(struct w8001 *w8001, char *basename, 464 size_t basename_sz) 465{ 466 struct input_dev *dev = w8001->touch_dev; 467 struct w8001_touch_query touch; 468 int error; 469 470 471 /* Touch enabled? */ 472 error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); 473 if (error) 474 return error; 475 /* 476 * Some non-touch devices may reply to the touch query. But their 477 * second byte is empty, which indicates touch is not supported. 478 */ 479 if (!w8001->response[1]) 480 return -ENXIO; 481 482 __set_bit(EV_KEY, dev->evbit); 483 __set_bit(EV_ABS, dev->evbit); 484 __set_bit(BTN_TOUCH, dev->keybit); 485 __set_bit(INPUT_PROP_DIRECT, dev->propbit); 486 487 parse_touchquery(w8001->response, &touch); 488 w8001->max_touch_x = touch.x; 489 w8001->max_touch_y = touch.y; 490 491 if (w8001->max_pen_x && w8001->max_pen_y) { 492 /* if pen is supported scale to pen maximum */ 493 touch.x = w8001->max_pen_x; 494 touch.y = w8001->max_pen_y; 495 touch.panel_res = W8001_PEN_RESOLUTION; 496 } 497 498 input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); 499 input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); 500 input_abs_set_res(dev, ABS_X, touch.panel_res); 501 input_abs_set_res(dev, ABS_Y, touch.panel_res); 502 503 switch (touch.sensor_id) { 504 case 0: 505 case 2: 506 w8001->pktlen = W8001_PKTLEN_TOUCH93; 507 w8001->id = 0x93; 508 strlcat(basename, " 1FG", basename_sz); 509 break; 510 511 case 1: 512 case 3: 513 case 4: 514 w8001->pktlen = W8001_PKTLEN_TOUCH9A; 515 strlcat(basename, " 1FG", basename_sz); 516 w8001->id = 0x9a; 517 break; 518 519 case 5: 520 w8001->pktlen = W8001_PKTLEN_TOUCH2FG; 521 522 __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); 523 error = input_mt_init_slots(dev, 2, 0); 524 if (error) { 525 dev_err(&w8001->serio->dev, 526 "failed to initialize MT slots: %d\n", error); 527 return error; 528 } 529 530 input_set_abs_params(dev, ABS_MT_POSITION_X, 531 0, touch.x, 0, 0); 532 input_set_abs_params(dev, ABS_MT_POSITION_Y, 533 0, touch.y, 0, 0); 534 input_set_abs_params(dev, ABS_MT_TOOL_TYPE, 535 0, MT_TOOL_MAX, 0, 0); 536 input_abs_set_res(dev, ABS_MT_POSITION_X, touch.panel_res); 537 input_abs_set_res(dev, ABS_MT_POSITION_Y, touch.panel_res); 538 539 strlcat(basename, " 2FG", basename_sz); 540 if (w8001->max_pen_x && w8001->max_pen_y) 541 w8001->id = 0xE3; 542 else 543 w8001->id = 0xE2; 544 break; 545 } 546 547 strlcat(basename, " Touchscreen", basename_sz); 548 549 return 0; 550} 551 552static void w8001_set_devdata(struct input_dev *dev, struct w8001 *w8001, 553 struct serio *serio) 554{ 555 dev->phys = w8001->phys; 556 dev->id.bustype = BUS_RS232; 557 dev->id.product = w8001->id; 558 dev->id.vendor = 0x056a; 559 dev->id.version = 0x0100; 560 dev->open = w8001_open; 561 dev->close = w8001_close; 562 563 dev->dev.parent = &serio->dev; 564 565 input_set_drvdata(dev, w8001); 566} 567 568/* 569 * w8001_disconnect() is the opposite of w8001_connect() 570 */ 571 572static void w8001_disconnect(struct serio *serio) 573{ 574 struct w8001 *w8001 = serio_get_drvdata(serio); 575 576 serio_close(serio); 577 578 if (w8001->pen_dev) 579 input_unregister_device(w8001->pen_dev); 580 if (w8001->touch_dev) 581 input_unregister_device(w8001->touch_dev); 582 kfree(w8001); 583 584 serio_set_drvdata(serio, NULL); 585} 586 587/* 588 * w8001_connect() is the routine that is called when someone adds a 589 * new serio device that supports the w8001 protocol and registers it as 590 * an input device. 591 */ 592 593static int w8001_connect(struct serio *serio, struct serio_driver *drv) 594{ 595 struct w8001 *w8001; 596 struct input_dev *input_dev_pen; 597 struct input_dev *input_dev_touch; 598 char basename[64]; 599 int err, err_pen, err_touch; 600 601 w8001 = kzalloc(sizeof(struct w8001), GFP_KERNEL); 602 input_dev_pen = input_allocate_device(); 603 input_dev_touch = input_allocate_device(); 604 if (!w8001 || !input_dev_pen || !input_dev_touch) { 605 err = -ENOMEM; 606 goto fail1; 607 } 608 609 w8001->serio = serio; 610 w8001->pen_dev = input_dev_pen; 611 w8001->touch_dev = input_dev_touch; 612 mutex_init(&w8001->mutex); 613 init_completion(&w8001->cmd_done); 614 snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); 615 616 serio_set_drvdata(serio, w8001); 617 err = serio_open(serio, drv); 618 if (err) 619 goto fail2; 620 621 err = w8001_detect(w8001); 622 if (err) 623 goto fail3; 624 625 /* For backwards-compatibility we compose the basename based on 626 * capabilities and then just append the tool type 627 */ 628 strlcpy(basename, "Wacom Serial", sizeof(basename)); 629 630 err_pen = w8001_setup_pen(w8001, basename, sizeof(basename)); 631 err_touch = w8001_setup_touch(w8001, basename, sizeof(basename)); 632 if (err_pen && err_touch) { 633 err = -ENXIO; 634 goto fail3; 635 } 636 637 if (!err_pen) { 638 strlcpy(w8001->pen_name, basename, sizeof(w8001->pen_name)); 639 strlcat(w8001->pen_name, " Pen", sizeof(w8001->pen_name)); 640 input_dev_pen->name = w8001->pen_name; 641 642 w8001_set_devdata(input_dev_pen, w8001, serio); 643 644 err = input_register_device(w8001->pen_dev); 645 if (err) 646 goto fail3; 647 } else { 648 input_free_device(input_dev_pen); 649 input_dev_pen = NULL; 650 w8001->pen_dev = NULL; 651 } 652 653 if (!err_touch) { 654 strlcpy(w8001->touch_name, basename, sizeof(w8001->touch_name)); 655 strlcat(w8001->touch_name, " Finger", 656 sizeof(w8001->touch_name)); 657 input_dev_touch->name = w8001->touch_name; 658 659 w8001_set_devdata(input_dev_touch, w8001, serio); 660 661 err = input_register_device(w8001->touch_dev); 662 if (err) 663 goto fail4; 664 } else { 665 input_free_device(input_dev_touch); 666 input_dev_touch = NULL; 667 w8001->touch_dev = NULL; 668 } 669 670 return 0; 671 672fail4: 673 if (w8001->pen_dev) 674 input_unregister_device(w8001->pen_dev); 675fail3: 676 serio_close(serio); 677fail2: 678 serio_set_drvdata(serio, NULL); 679fail1: 680 input_free_device(input_dev_pen); 681 input_free_device(input_dev_touch); 682 kfree(w8001); 683 return err; 684} 685 686static const struct serio_device_id w8001_serio_ids[] = { 687 { 688 .type = SERIO_RS232, 689 .proto = SERIO_W8001, 690 .id = SERIO_ANY, 691 .extra = SERIO_ANY, 692 }, 693 { 0 } 694}; 695 696MODULE_DEVICE_TABLE(serio, w8001_serio_ids); 697 698static struct serio_driver w8001_drv = { 699 .driver = { 700 .name = "w8001", 701 }, 702 .description = DRIVER_DESC, 703 .id_table = w8001_serio_ids, 704 .interrupt = w8001_interrupt, 705 .connect = w8001_connect, 706 .disconnect = w8001_disconnect, 707}; 708 709module_serio_driver(w8001_drv);