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