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