root/drivers/input/keyboard/hil_kbd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hil_dev_is_command_response
  2. hil_dev_handle_command_response
  3. hil_dev_handle_kbd_events
  4. hil_dev_handle_ptr_events
  5. hil_dev_process_err
  6. hil_dev_interrupt
  7. hil_dev_disconnect
  8. hil_dev_keyboard_setup
  9. hil_dev_pointer_setup
  10. hil_dev_connect

   1 /*
   2  * Generic linux-input device driver for keyboard devices
   3  *
   4  * Copyright (c) 2001 Brian S. Julin
   5  * All rights reserved.
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  * 1. Redistributions of source code must retain the above copyright
  11  *    notice, this list of conditions, and the following disclaimer,
  12  *    without modification.
  13  * 2. The name of the author may not be used to endorse or promote products
  14  *    derived from this software without specific prior written permission.
  15  *
  16  * Alternatively, this software may be distributed under the terms of the
  17  * GNU General Public License ("GPL").
  18  *
  19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28  *
  29  * References:
  30  * HP-HIL Technical Reference Manual.  Hewlett Packard Product No. 45918A
  31  *
  32  */
  33 
  34 #include <linux/hil.h>
  35 #include <linux/input.h>
  36 #include <linux/serio.h>
  37 #include <linux/kernel.h>
  38 #include <linux/module.h>
  39 #include <linux/completion.h>
  40 #include <linux/slab.h>
  41 #include <linux/pci_ids.h>
  42 
  43 #define PREFIX "HIL: "
  44 
  45 MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
  46 MODULE_DESCRIPTION("HIL keyboard/mouse driver");
  47 MODULE_LICENSE("Dual BSD/GPL");
  48 MODULE_ALIAS("serio:ty03pr25id00ex*"); /* HIL keyboard */
  49 MODULE_ALIAS("serio:ty03pr25id0Fex*"); /* HIL mouse */
  50 
  51 #define HIL_PACKET_MAX_LENGTH 16
  52 
  53 #define HIL_KBD_SET1_UPBIT 0x01
  54 #define HIL_KBD_SET1_SHIFT 1
  55 static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly =
  56         { HIL_KEYCODES_SET1 };
  57 
  58 #define HIL_KBD_SET2_UPBIT 0x01
  59 #define HIL_KBD_SET2_SHIFT 1
  60 /* Set2 is user defined */
  61 
  62 #define HIL_KBD_SET3_UPBIT 0x80
  63 #define HIL_KBD_SET3_SHIFT 0
  64 static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] __read_mostly =
  65         { HIL_KEYCODES_SET3 };
  66 
  67 static const char hil_language[][16] = { HIL_LOCALE_MAP };
  68 
  69 struct hil_dev {
  70         struct input_dev *dev;
  71         struct serio *serio;
  72 
  73         /* Input buffer and index for packets from HIL bus. */
  74         hil_packet data[HIL_PACKET_MAX_LENGTH];
  75         int idx4; /* four counts per packet */
  76 
  77         /* Raw device info records from HIL bus, see hil.h for fields. */
  78         char    idd[HIL_PACKET_MAX_LENGTH];     /* DID byte and IDD record */
  79         char    rsc[HIL_PACKET_MAX_LENGTH];     /* RSC record */
  80         char    exd[HIL_PACKET_MAX_LENGTH];     /* EXD record */
  81         char    rnm[HIL_PACKET_MAX_LENGTH + 1]; /* RNM record + NULL term. */
  82 
  83         struct completion cmd_done;
  84 
  85         bool is_pointer;
  86         /* Extra device details needed for pointing devices. */
  87         unsigned int nbtn, naxes;
  88         unsigned int btnmap[7];
  89 };
  90 
  91 static bool hil_dev_is_command_response(hil_packet p)
  92 {
  93         if ((p & ~HIL_CMDCT_POL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
  94                 return false;
  95 
  96         if ((p & ~HIL_CMDCT_RPL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
  97                 return false;
  98 
  99         return true;
 100 }
 101 
 102 static void hil_dev_handle_command_response(struct hil_dev *dev)
 103 {
 104         hil_packet p;
 105         char *buf;
 106         int i, idx;
 107 
 108         idx = dev->idx4 / 4;
 109         p = dev->data[idx - 1];
 110 
 111         switch (p & HIL_PKT_DATA_MASK) {
 112         case HIL_CMD_IDD:
 113                 buf = dev->idd;
 114                 break;
 115 
 116         case HIL_CMD_RSC:
 117                 buf = dev->rsc;
 118                 break;
 119 
 120         case HIL_CMD_EXD:
 121                 buf = dev->exd;
 122                 break;
 123 
 124         case HIL_CMD_RNM:
 125                 dev->rnm[HIL_PACKET_MAX_LENGTH] = 0;
 126                 buf = dev->rnm;
 127                 break;
 128 
 129         default:
 130                 /* These occur when device isn't present */
 131                 if (p != (HIL_ERR_INT | HIL_PKT_CMD)) {
 132                         /* Anything else we'd like to know about. */
 133                         printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
 134                 }
 135                 goto out;
 136         }
 137 
 138         for (i = 0; i < idx; i++)
 139                 buf[i] = dev->data[i] & HIL_PKT_DATA_MASK;
 140         for (; i < HIL_PACKET_MAX_LENGTH; i++)
 141                 buf[i] = 0;
 142  out:
 143         complete(&dev->cmd_done);
 144 }
 145 
 146 static void hil_dev_handle_kbd_events(struct hil_dev *kbd)
 147 {
 148         struct input_dev *dev = kbd->dev;
 149         int idx = kbd->idx4 / 4;
 150         int i;
 151 
 152         switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) {
 153         case HIL_POL_CHARTYPE_NONE:
 154                 return;
 155 
 156         case HIL_POL_CHARTYPE_ASCII:
 157                 for (i = 1; i < idx - 1; i++)
 158                         input_report_key(dev, kbd->data[i] & 0x7f, 1);
 159                 break;
 160 
 161         case HIL_POL_CHARTYPE_RSVD1:
 162         case HIL_POL_CHARTYPE_RSVD2:
 163         case HIL_POL_CHARTYPE_BINARY:
 164                 for (i = 1; i < idx - 1; i++)
 165                         input_report_key(dev, kbd->data[i], 1);
 166                 break;
 167 
 168         case HIL_POL_CHARTYPE_SET1:
 169                 for (i = 1; i < idx - 1; i++) {
 170                         unsigned int key = kbd->data[i];
 171                         int up = key & HIL_KBD_SET1_UPBIT;
 172 
 173                         key &= (~HIL_KBD_SET1_UPBIT & 0xff);
 174                         key = hil_kbd_set1[key >> HIL_KBD_SET1_SHIFT];
 175                         input_report_key(dev, key, !up);
 176                 }
 177                 break;
 178 
 179         case HIL_POL_CHARTYPE_SET2:
 180                 for (i = 1; i < idx - 1; i++) {
 181                         unsigned int key = kbd->data[i];
 182                         int up = key & HIL_KBD_SET2_UPBIT;
 183 
 184                         key &= (~HIL_KBD_SET1_UPBIT & 0xff);
 185                         key = key >> HIL_KBD_SET2_SHIFT;
 186                         input_report_key(dev, key, !up);
 187                 }
 188                 break;
 189 
 190         case HIL_POL_CHARTYPE_SET3:
 191                 for (i = 1; i < idx - 1; i++) {
 192                         unsigned int key = kbd->data[i];
 193                         int up = key & HIL_KBD_SET3_UPBIT;
 194 
 195                         key &= (~HIL_KBD_SET1_UPBIT & 0xff);
 196                         key = hil_kbd_set3[key >> HIL_KBD_SET3_SHIFT];
 197                         input_report_key(dev, key, !up);
 198                 }
 199                 break;
 200         }
 201 
 202         input_sync(dev);
 203 }
 204 
 205 static void hil_dev_handle_ptr_events(struct hil_dev *ptr)
 206 {
 207         struct input_dev *dev = ptr->dev;
 208         int idx = ptr->idx4 / 4;
 209         hil_packet p = ptr->data[idx - 1];
 210         int i, cnt, laxis;
 211         bool absdev, ax16;
 212 
 213         if ((p & HIL_CMDCT_POL) != idx - 1) {
 214                 printk(KERN_WARNING PREFIX
 215                         "Malformed poll packet %x (idx = %i)\n", p, idx);
 216                 return;
 217         }
 218 
 219         i = (p & HIL_POL_AXIS_ALT) ? 3 : 0;
 220         laxis = (p & HIL_POL_NUM_AXES_MASK) + i;
 221 
 222         ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */
 223         absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS;
 224 
 225         for (cnt = 1; i < laxis; i++) {
 226                 unsigned int lo, hi, val;
 227 
 228                 lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK;
 229                 hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0;
 230 
 231                 if (absdev) {
 232                         val = lo + (hi << 8);
 233 #ifdef TABLET_AUTOADJUST
 234                         if (val < input_abs_get_min(dev, ABS_X + i))
 235                                 input_abs_set_min(dev, ABS_X + i, val);
 236                         if (val > input_abs_get_max(dev, ABS_X + i))
 237                                 input_abs_set_max(dev, ABS_X + i, val);
 238 #endif
 239                         if (i % 3)
 240                                 val = input_abs_get_max(dev, ABS_X + i) - val;
 241                         input_report_abs(dev, ABS_X + i, val);
 242                 } else {
 243                         val = (int) (((int8_t) lo) | ((int8_t) hi << 8));
 244                         if (i % 3)
 245                                 val *= -1;
 246                         input_report_rel(dev, REL_X + i, val);
 247                 }
 248         }
 249 
 250         while (cnt < idx - 1) {
 251                 unsigned int btn = ptr->data[cnt++];
 252                 int up = btn & 1;
 253 
 254                 btn &= 0xfe;
 255                 if (btn == 0x8e)
 256                         continue; /* TODO: proximity == touch? */
 257                 if (btn > 0x8c || btn < 0x80)
 258                         continue;
 259                 btn = (btn - 0x80) >> 1;
 260                 btn = ptr->btnmap[btn];
 261                 input_report_key(dev, btn, !up);
 262         }
 263 
 264         input_sync(dev);
 265 }
 266 
 267 static void hil_dev_process_err(struct hil_dev *dev)
 268 {
 269         printk(KERN_WARNING PREFIX "errored HIL packet\n");
 270         dev->idx4 = 0;
 271         complete(&dev->cmd_done); /* just in case somebody is waiting */
 272 }
 273 
 274 static irqreturn_t hil_dev_interrupt(struct serio *serio,
 275                                 unsigned char data, unsigned int flags)
 276 {
 277         struct hil_dev *dev;
 278         hil_packet packet;
 279         int idx;
 280 
 281         dev = serio_get_drvdata(serio);
 282         BUG_ON(dev == NULL);
 283 
 284         if (dev->idx4 >= HIL_PACKET_MAX_LENGTH * sizeof(hil_packet)) {
 285                 hil_dev_process_err(dev);
 286                 goto out;
 287         }
 288 
 289         idx = dev->idx4 / 4;
 290         if (!(dev->idx4 % 4))
 291                 dev->data[idx] = 0;
 292         packet = dev->data[idx];
 293         packet |= ((hil_packet)data) << ((3 - (dev->idx4 % 4)) * 8);
 294         dev->data[idx] = packet;
 295 
 296         /* Records of N 4-byte hil_packets must terminate with a command. */
 297         if ((++dev->idx4 % 4) == 0) {
 298                 if ((packet & 0xffff0000) != HIL_ERR_INT) {
 299                         hil_dev_process_err(dev);
 300                 } else if (packet & HIL_PKT_CMD) {
 301                         if (hil_dev_is_command_response(packet))
 302                                 hil_dev_handle_command_response(dev);
 303                         else if (dev->is_pointer)
 304                                 hil_dev_handle_ptr_events(dev);
 305                         else
 306                                 hil_dev_handle_kbd_events(dev);
 307                         dev->idx4 = 0;
 308                 }
 309         }
 310  out:
 311         return IRQ_HANDLED;
 312 }
 313 
 314 static void hil_dev_disconnect(struct serio *serio)
 315 {
 316         struct hil_dev *dev = serio_get_drvdata(serio);
 317 
 318         BUG_ON(dev == NULL);
 319 
 320         serio_close(serio);
 321         input_unregister_device(dev->dev);
 322         serio_set_drvdata(serio, NULL);
 323         kfree(dev);
 324 }
 325 
 326 static void hil_dev_keyboard_setup(struct hil_dev *kbd)
 327 {
 328         struct input_dev *input_dev = kbd->dev;
 329         uint8_t did = kbd->idd[0];
 330         int i;
 331 
 332         input_dev->evbit[0]     = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
 333         input_dev->ledbit[0]    = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
 334                                   BIT_MASK(LED_SCROLLL);
 335 
 336         for (i = 0; i < 128; i++) {
 337                 __set_bit(hil_kbd_set1[i], input_dev->keybit);
 338                 __set_bit(hil_kbd_set3[i], input_dev->keybit);
 339         }
 340         __clear_bit(KEY_RESERVED, input_dev->keybit);
 341 
 342         input_dev->keycodemax   = HIL_KEYCODES_SET1_TBLSIZE;
 343         input_dev->keycodesize  = sizeof(hil_kbd_set1[0]);
 344         input_dev->keycode      = hil_kbd_set1;
 345 
 346         input_dev->name = strlen(kbd->rnm) ? kbd->rnm : "HIL keyboard";
 347         input_dev->phys = "hpkbd/input0";
 348 
 349         printk(KERN_INFO PREFIX "HIL keyboard found (did = 0x%02x, lang = %s)\n",
 350                 did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]);
 351 }
 352 
 353 static void hil_dev_pointer_setup(struct hil_dev *ptr)
 354 {
 355         struct input_dev *input_dev = ptr->dev;
 356         uint8_t did = ptr->idd[0];
 357         uint8_t *idd = ptr->idd + 1;
 358         unsigned int naxsets = HIL_IDD_NUM_AXSETS(*idd);
 359         unsigned int i, btntype;
 360         const char *txt;
 361 
 362         ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
 363 
 364         switch (did & HIL_IDD_DID_TYPE_MASK) {
 365         case HIL_IDD_DID_TYPE_REL:
 366                 input_dev->evbit[0] = BIT_MASK(EV_REL);
 367 
 368                 for (i = 0; i < ptr->naxes; i++)
 369                         __set_bit(REL_X + i, input_dev->relbit);
 370 
 371                 for (i = 3; naxsets > 1 && i < ptr->naxes + 3; i++)
 372                         __set_bit(REL_X + i, input_dev->relbit);
 373 
 374                 txt = "relative";
 375                 break;
 376 
 377         case HIL_IDD_DID_TYPE_ABS:
 378                 input_dev->evbit[0] = BIT_MASK(EV_ABS);
 379 
 380                 for (i = 0; i < ptr->naxes; i++)
 381                         input_set_abs_params(input_dev, ABS_X + i,
 382                                         0, HIL_IDD_AXIS_MAX(idd, i), 0, 0);
 383 
 384                 for (i = 3; naxsets > 1 && i < ptr->naxes + 3; i++)
 385                         input_set_abs_params(input_dev, ABS_X + i,
 386                                         0, HIL_IDD_AXIS_MAX(idd, i - 3), 0, 0);
 387 
 388 #ifdef TABLET_AUTOADJUST
 389                 for (i = 0; i < ABS_MAX; i++) {
 390                         int diff = input_abs_get_max(input_dev, ABS_X + i) / 10;
 391                         input_abs_set_min(input_dev, ABS_X + i,
 392                                 input_abs_get_min(input_dev, ABS_X + i) + diff);
 393                         input_abs_set_max(input_dev, ABS_X + i,
 394                                 input_abs_get_max(input_dev, ABS_X + i) - diff);
 395                 }
 396 #endif
 397 
 398                 txt = "absolute";
 399                 break;
 400 
 401         default:
 402                 BUG();
 403         }
 404 
 405         ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
 406         if (ptr->nbtn)
 407                 input_dev->evbit[0] |= BIT_MASK(EV_KEY);
 408 
 409         btntype = BTN_MISC;
 410         if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET)
 411 #ifdef TABLET_SIMULATES_MOUSE
 412                 btntype = BTN_TOUCH;
 413 #else
 414                 btntype = BTN_DIGI;
 415 #endif
 416         if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN)
 417                 btntype = BTN_TOUCH;
 418 
 419         if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE)
 420                 btntype = BTN_MOUSE;
 421 
 422         for (i = 0; i < ptr->nbtn; i++) {
 423                 __set_bit(btntype | i, input_dev->keybit);
 424                 ptr->btnmap[i] = btntype | i;
 425         }
 426 
 427         if (btntype == BTN_MOUSE) {
 428                 /* Swap buttons 2 and 3 */
 429                 ptr->btnmap[1] = BTN_MIDDLE;
 430                 ptr->btnmap[2] = BTN_RIGHT;
 431         }
 432 
 433         input_dev->name = strlen(ptr->rnm) ? ptr->rnm : "HIL pointer device";
 434 
 435         printk(KERN_INFO PREFIX
 436                 "HIL pointer device found (did: 0x%02x, axis: %s)\n",
 437                 did, txt);
 438         printk(KERN_INFO PREFIX
 439                 "HIL pointer has %i buttons and %i sets of %i axes\n",
 440                 ptr->nbtn, naxsets, ptr->naxes);
 441 }
 442 
 443 static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
 444 {
 445         struct hil_dev *dev;
 446         struct input_dev *input_dev;
 447         uint8_t did, *idd;
 448         int error;
 449 
 450         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 451         input_dev = input_allocate_device();
 452         if (!dev || !input_dev) {
 453                 error = -ENOMEM;
 454                 goto bail0;
 455         }
 456 
 457         dev->serio = serio;
 458         dev->dev = input_dev;
 459 
 460         error = serio_open(serio, drv);
 461         if (error)
 462                 goto bail0;
 463 
 464         serio_set_drvdata(serio, dev);
 465 
 466         /* Get device info.  MLC driver supplies devid/status/etc. */
 467         init_completion(&dev->cmd_done);
 468         serio_write(serio, 0);
 469         serio_write(serio, 0);
 470         serio_write(serio, HIL_PKT_CMD >> 8);
 471         serio_write(serio, HIL_CMD_IDD);
 472         error = wait_for_completion_killable(&dev->cmd_done);
 473         if (error)
 474                 goto bail1;
 475 
 476         reinit_completion(&dev->cmd_done);
 477         serio_write(serio, 0);
 478         serio_write(serio, 0);
 479         serio_write(serio, HIL_PKT_CMD >> 8);
 480         serio_write(serio, HIL_CMD_RSC);
 481         error = wait_for_completion_killable(&dev->cmd_done);
 482         if (error)
 483                 goto bail1;
 484 
 485         reinit_completion(&dev->cmd_done);
 486         serio_write(serio, 0);
 487         serio_write(serio, 0);
 488         serio_write(serio, HIL_PKT_CMD >> 8);
 489         serio_write(serio, HIL_CMD_RNM);
 490         error = wait_for_completion_killable(&dev->cmd_done);
 491         if (error)
 492                 goto bail1;
 493 
 494         reinit_completion(&dev->cmd_done);
 495         serio_write(serio, 0);
 496         serio_write(serio, 0);
 497         serio_write(serio, HIL_PKT_CMD >> 8);
 498         serio_write(serio, HIL_CMD_EXD);
 499         error = wait_for_completion_killable(&dev->cmd_done);
 500         if (error)
 501                 goto bail1;
 502 
 503         did = dev->idd[0];
 504         idd = dev->idd + 1;
 505 
 506         switch (did & HIL_IDD_DID_TYPE_MASK) {
 507         case HIL_IDD_DID_TYPE_KB_INTEGRAL:
 508         case HIL_IDD_DID_TYPE_KB_ITF:
 509         case HIL_IDD_DID_TYPE_KB_RSVD:
 510         case HIL_IDD_DID_TYPE_CHAR:
 511                 if (HIL_IDD_NUM_BUTTONS(idd) ||
 512                     HIL_IDD_NUM_AXES_PER_SET(*idd)) {
 513                         printk(KERN_INFO PREFIX
 514                                 "combo devices are not supported.\n");
 515                         goto bail1;
 516                 }
 517 
 518                 dev->is_pointer = false;
 519                 hil_dev_keyboard_setup(dev);
 520                 break;
 521 
 522         case HIL_IDD_DID_TYPE_REL:
 523         case HIL_IDD_DID_TYPE_ABS:
 524                 dev->is_pointer = true;
 525                 hil_dev_pointer_setup(dev);
 526                 break;
 527 
 528         default:
 529                 goto bail1;
 530         }
 531 
 532         input_dev->id.bustype   = BUS_HIL;
 533         input_dev->id.vendor    = PCI_VENDOR_ID_HP;
 534         input_dev->id.product   = 0x0001; /* TODO: get from kbd->rsc */
 535         input_dev->id.version   = 0x0100; /* TODO: get from kbd->rsc */
 536         input_dev->dev.parent   = &serio->dev;
 537 
 538         if (!dev->is_pointer) {
 539                 serio_write(serio, 0);
 540                 serio_write(serio, 0);
 541                 serio_write(serio, HIL_PKT_CMD >> 8);
 542                 /* Enable Keyswitch Autorepeat 1 */
 543                 serio_write(serio, HIL_CMD_EK1);
 544                 /* No need to wait for completion */
 545         }
 546 
 547         error = input_register_device(input_dev);
 548         if (error)
 549                 goto bail1;
 550 
 551         return 0;
 552 
 553  bail1:
 554         serio_close(serio);
 555         serio_set_drvdata(serio, NULL);
 556  bail0:
 557         input_free_device(input_dev);
 558         kfree(dev);
 559         return error;
 560 }
 561 
 562 static const struct serio_device_id hil_dev_ids[] = {
 563         {
 564                 .type = SERIO_HIL_MLC,
 565                 .proto = SERIO_HIL,
 566                 .id = SERIO_ANY,
 567                 .extra = SERIO_ANY,
 568         },
 569         { 0 }
 570 };
 571 
 572 MODULE_DEVICE_TABLE(serio, hil_dev_ids);
 573 
 574 static struct serio_driver hil_serio_drv = {
 575         .driver         = {
 576                 .name   = "hil_dev",
 577         },
 578         .description    = "HP HIL keyboard/mouse/tablet driver",
 579         .id_table       = hil_dev_ids,
 580         .connect        = hil_dev_connect,
 581         .disconnect     = hil_dev_disconnect,
 582         .interrupt      = hil_dev_interrupt
 583 };
 584 
 585 module_serio_driver(hil_serio_drv);

/* [<][>][^][v][top][bottom][index][help] */