2 * Generic linux-input device driver for keyboard devices
4 * Copyright (c) 2001 Brian S. Julin
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL").
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
30 * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
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/semaphore.h>
41 #include <linux/slab.h>
42 #include <linux/pci_ids.h>
44 #define PREFIX "HIL KEYB: "
45 #define HIL_GENERIC_NAME "HIL keyboard"
47 MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
48 MODULE_DESCRIPTION(HIL_GENERIC_NAME
" driver");
49 MODULE_LICENSE("Dual BSD/GPL");
50 MODULE_ALIAS("serio:ty03pr25id00ex*");
52 #define HIL_KBD_MAX_LENGTH 16
54 #define HIL_KBD_SET1_UPBIT 0x01
55 #define HIL_KBD_SET1_SHIFT 1
56 static unsigned int hil_kbd_set1
[HIL_KEYCODES_SET1_TBLSIZE
] __read_mostly
=
57 { HIL_KEYCODES_SET1
};
59 #define HIL_KBD_SET2_UPBIT 0x01
60 #define HIL_KBD_SET2_SHIFT 1
61 /* Set2 is user defined */
63 #define HIL_KBD_SET3_UPBIT 0x80
64 #define HIL_KBD_SET3_SHIFT 0
65 static unsigned int hil_kbd_set3
[HIL_KEYCODES_SET3_TBLSIZE
] __read_mostly
=
66 { HIL_KEYCODES_SET3
};
68 static const char hil_language
[][16] = { HIL_LOCALE_MAP
};
71 struct input_dev
*dev
;
74 /* Input buffer and index for packets from HIL bus. */
75 hil_packet data
[HIL_KBD_MAX_LENGTH
];
76 int idx4
; /* four counts per packet */
78 /* Raw device info records from HIL bus, see hil.h for fields. */
79 char idd
[HIL_KBD_MAX_LENGTH
]; /* DID byte and IDD record */
80 char rsc
[HIL_KBD_MAX_LENGTH
]; /* RSC record */
81 char exd
[HIL_KBD_MAX_LENGTH
]; /* EXD record */
82 char rnm
[HIL_KBD_MAX_LENGTH
+ 1]; /* RNM record + NULL term. */
84 /* Something to sleep around with. */
88 /* Process a complete packet after transfer from the HIL */
89 static void hil_kbd_process_record(struct hil_kbd
*kbd
)
91 struct input_dev
*dev
= kbd
->dev
;
92 hil_packet
*data
= kbd
->data
;
99 if ((p
& ~HIL_CMDCT_POL
) ==
100 (HIL_ERR_INT
| HIL_PKT_CMD
| HIL_CMD_POL
))
102 if ((p
& ~HIL_CMDCT_RPL
) ==
103 (HIL_ERR_INT
| HIL_PKT_CMD
| HIL_CMD_RPL
))
106 /* Not a poll response. See if we are loading config records. */
107 switch (p
& HIL_PKT_DATA_MASK
) {
109 for (i
= 0; i
< idx
; i
++)
110 kbd
->idd
[i
] = kbd
->data
[i
] & HIL_PKT_DATA_MASK
;
111 for (; i
< HIL_KBD_MAX_LENGTH
; i
++)
116 for (i
= 0; i
< idx
; i
++)
117 kbd
->rsc
[i
] = kbd
->data
[i
] & HIL_PKT_DATA_MASK
;
118 for (; i
< HIL_KBD_MAX_LENGTH
; i
++)
123 for (i
= 0; i
< idx
; i
++)
124 kbd
->exd
[i
] = kbd
->data
[i
] & HIL_PKT_DATA_MASK
;
125 for (; i
< HIL_KBD_MAX_LENGTH
; i
++)
130 for (i
= 0; i
< idx
; i
++)
131 kbd
->rnm
[i
] = kbd
->data
[i
] & HIL_PKT_DATA_MASK
;
132 for (; i
< HIL_KBD_MAX_LENGTH
+ 1; i
++)
137 /* These occur when device isn't present */
138 if (p
== (HIL_ERR_INT
| HIL_PKT_CMD
))
140 /* Anything else we'd like to know about. */
141 printk(KERN_WARNING PREFIX
"Device sent unknown record %x\n", p
);
148 switch (kbd
->data
[0] & HIL_POL_CHARTYPE_MASK
) {
149 case HIL_POL_CHARTYPE_NONE
:
152 case HIL_POL_CHARTYPE_ASCII
:
153 while (cnt
< idx
- 1)
154 input_report_key(dev
, kbd
->data
[cnt
++] & 0x7f, 1);
157 case HIL_POL_CHARTYPE_RSVD1
:
158 case HIL_POL_CHARTYPE_RSVD2
:
159 case HIL_POL_CHARTYPE_BINARY
:
160 while (cnt
< idx
- 1)
161 input_report_key(dev
, kbd
->data
[cnt
++], 1);
164 case HIL_POL_CHARTYPE_SET1
:
165 while (cnt
< idx
- 1) {
168 key
= kbd
->data
[cnt
++];
169 up
= key
& HIL_KBD_SET1_UPBIT
;
170 key
&= (~HIL_KBD_SET1_UPBIT
& 0xff);
171 key
= hil_kbd_set1
[key
>> HIL_KBD_SET1_SHIFT
];
172 if (key
!= KEY_RESERVED
)
173 input_report_key(dev
, key
, !up
);
177 case HIL_POL_CHARTYPE_SET2
:
178 while (cnt
< idx
- 1) {
181 key
= kbd
->data
[cnt
++];
182 up
= key
& HIL_KBD_SET2_UPBIT
;
183 key
&= (~HIL_KBD_SET1_UPBIT
& 0xff);
184 key
= key
>> HIL_KBD_SET2_SHIFT
;
185 if (key
!= KEY_RESERVED
)
186 input_report_key(dev
, key
, !up
);
190 case HIL_POL_CHARTYPE_SET3
:
191 while (cnt
< idx
- 1) {
194 key
= kbd
->data
[cnt
++];
195 up
= key
& HIL_KBD_SET3_UPBIT
;
196 key
&= (~HIL_KBD_SET1_UPBIT
& 0xff);
197 key
= hil_kbd_set3
[key
>> HIL_KBD_SET3_SHIFT
];
198 if (key
!= KEY_RESERVED
)
199 input_report_key(dev
, key
, !up
);
208 static void hil_kbd_process_err(struct hil_kbd
*kbd
)
210 printk(KERN_WARNING PREFIX
"errored HIL packet\n");
215 static irqreturn_t
hil_kbd_interrupt(struct serio
*serio
,
216 unsigned char data
, unsigned int flags
)
222 kbd
= serio_get_drvdata(serio
);
225 if (kbd
->idx4
>= (HIL_KBD_MAX_LENGTH
* sizeof(hil_packet
))) {
226 hil_kbd_process_err(kbd
);
230 if (!(kbd
->idx4
% 4))
232 packet
= kbd
->data
[idx
];
233 packet
|= ((hil_packet
)data
) << ((3 - (kbd
->idx4
% 4)) * 8);
234 kbd
->data
[idx
] = packet
;
236 /* Records of N 4-byte hil_packets must terminate with a command. */
237 if ((++(kbd
->idx4
)) % 4)
239 if ((packet
& 0xffff0000) != HIL_ERR_INT
) {
240 hil_kbd_process_err(kbd
);
243 if (packet
& HIL_PKT_CMD
)
244 hil_kbd_process_record(kbd
);
248 static void hil_kbd_disconnect(struct serio
*serio
)
252 kbd
= serio_get_drvdata(serio
);
256 input_unregister_device(kbd
->dev
);
260 static int hil_kbd_connect(struct serio
*serio
, struct serio_driver
*drv
)
266 kbd
= kzalloc(sizeof(*kbd
), GFP_KERNEL
);
270 kbd
->dev
= input_allocate_device();
274 if (serio_open(serio
, drv
))
277 serio_set_drvdata(serio
, kbd
);
280 init_MUTEX_LOCKED(&kbd
->sem
);
282 /* Get device info. MLC driver supplies devid/status/etc. */
283 serio
->write(serio
, 0);
284 serio
->write(serio
, 0);
285 serio
->write(serio
, HIL_PKT_CMD
>> 8);
286 serio
->write(serio
, HIL_CMD_IDD
);
289 serio
->write(serio
, 0);
290 serio
->write(serio
, 0);
291 serio
->write(serio
, HIL_PKT_CMD
>> 8);
292 serio
->write(serio
, HIL_CMD_RSC
);
295 serio
->write(serio
, 0);
296 serio
->write(serio
, 0);
297 serio
->write(serio
, HIL_PKT_CMD
>> 8);
298 serio
->write(serio
, HIL_CMD_RNM
);
301 serio
->write(serio
, 0);
302 serio
->write(serio
, 0);
303 serio
->write(serio
, HIL_PKT_CMD
>> 8);
304 serio
->write(serio
, HIL_CMD_EXD
);
311 switch (did
& HIL_IDD_DID_TYPE_MASK
) {
312 case HIL_IDD_DID_TYPE_KB_INTEGRAL
:
313 case HIL_IDD_DID_TYPE_KB_ITF
:
314 case HIL_IDD_DID_TYPE_KB_RSVD
:
315 case HIL_IDD_DID_TYPE_CHAR
:
316 printk(KERN_INFO PREFIX
"HIL keyboard found (did = 0x%02x, lang = %s)\n",
317 did
, hil_language
[did
& HIL_IDD_DID_TYPE_KB_LANG_MASK
]);
323 if (HIL_IDD_NUM_BUTTONS(idd
) || HIL_IDD_NUM_AXES_PER_SET(*idd
)) {
324 printk(KERN_INFO PREFIX
"keyboards only, no combo devices supported.\n");
328 kbd
->dev
->evbit
[0] = BIT_MASK(EV_KEY
) | BIT_MASK(EV_REP
);
329 kbd
->dev
->ledbit
[0] = BIT_MASK(LED_NUML
) | BIT_MASK(LED_CAPSL
) |
330 BIT_MASK(LED_SCROLLL
);
331 kbd
->dev
->keycodemax
= HIL_KEYCODES_SET1_TBLSIZE
;
332 kbd
->dev
->keycodesize
= sizeof(hil_kbd_set1
[0]);
333 kbd
->dev
->keycode
= hil_kbd_set1
;
334 kbd
->dev
->name
= strlen(kbd
->rnm
) ? kbd
->rnm
: HIL_GENERIC_NAME
;
335 kbd
->dev
->phys
= "hpkbd/input0"; /* XXX */
337 kbd
->dev
->id
.bustype
= BUS_HIL
;
338 kbd
->dev
->id
.vendor
= PCI_VENDOR_ID_HP
;
339 kbd
->dev
->id
.product
= 0x0001; /* TODO: get from kbd->rsc */
340 kbd
->dev
->id
.version
= 0x0100; /* TODO: get from kbd->rsc */
341 kbd
->dev
->dev
.parent
= &serio
->dev
;
343 for (i
= 0; i
< 128; i
++) {
344 set_bit(hil_kbd_set1
[i
], kbd
->dev
->keybit
);
345 set_bit(hil_kbd_set3
[i
], kbd
->dev
->keybit
);
347 clear_bit(0, kbd
->dev
->keybit
);
349 input_register_device(kbd
->dev
);
350 printk(KERN_INFO
"input: %s, ID: %d\n",
351 kbd
->dev
->name
, did
);
353 serio
->write(serio
, 0);
354 serio
->write(serio
, 0);
355 serio
->write(serio
, HIL_PKT_CMD
>> 8);
356 serio
->write(serio
, HIL_CMD_EK1
); /* Enable Keyswitch Autorepeat 1 */
363 serio_set_drvdata(serio
, NULL
);
365 input_free_device(kbd
->dev
);
371 static struct serio_device_id hil_kbd_ids
[] = {
373 .type
= SERIO_HIL_MLC
,
381 static struct serio_driver hil_kbd_serio_drv
= {
385 .description
= "HP HIL keyboard driver",
386 .id_table
= hil_kbd_ids
,
387 .connect
= hil_kbd_connect
,
388 .disconnect
= hil_kbd_disconnect
,
389 .interrupt
= hil_kbd_interrupt
392 static int __init
hil_kbd_init(void)
394 return serio_register_driver(&hil_kbd_serio_drv
);
397 static void __exit
hil_kbd_exit(void)
399 serio_unregister_driver(&hil_kbd_serio_drv
);
402 module_init(hil_kbd_init
);
403 module_exit(hil_kbd_exit
);