2 * Generic linux-input device driver for axis-bearing 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/slab.h>
41 #include <linux/pci_ids.h>
43 #define PREFIX "HIL PTR: "
44 #define HIL_GENERIC_NAME "HIL pointer device"
46 MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
47 MODULE_DESCRIPTION(HIL_GENERIC_NAME
" driver");
48 MODULE_LICENSE("Dual BSD/GPL");
51 #define TABLET_SIMULATES_MOUSE /* allow tablet to be used as mouse */
52 #undef TABLET_AUTOADJUST /* auto-adjust valid tablet ranges */
55 #define HIL_PTR_MAX_LENGTH 16
58 struct input_dev
*dev
;
61 /* Input buffer and index for packets from HIL bus. */
62 hil_packet data
[HIL_PTR_MAX_LENGTH
];
63 int idx4
; /* four counts per packet */
65 /* Raw device info records from HIL bus, see hil.h for fields. */
66 char idd
[HIL_PTR_MAX_LENGTH
]; /* DID byte and IDD record */
67 char rsc
[HIL_PTR_MAX_LENGTH
]; /* RSC record */
68 char exd
[HIL_PTR_MAX_LENGTH
]; /* EXD record */
69 char rnm
[HIL_PTR_MAX_LENGTH
+ 1]; /* RNM record + NULL term. */
71 /* Extra device details not contained in struct input_dev. */
72 unsigned int nbtn
, naxes
;
73 unsigned int btnmap
[7];
75 /* Something to sleep around with. */
79 /* Process a complete packet after transfer from the HIL */
80 static void hil_ptr_process_record(struct hil_ptr
*ptr
)
82 struct input_dev
*dev
= ptr
->dev
;
83 hil_packet
*data
= ptr
->data
;
85 int idx
, i
, cnt
, laxis
;
91 if ((p
& ~HIL_CMDCT_POL
) ==
92 (HIL_ERR_INT
| HIL_PKT_CMD
| HIL_CMD_POL
)) goto report
;
93 if ((p
& ~HIL_CMDCT_RPL
) ==
94 (HIL_ERR_INT
| HIL_PKT_CMD
| HIL_CMD_RPL
)) goto report
;
96 /* Not a poll response. See if we are loading config records. */
97 switch (p
& HIL_PKT_DATA_MASK
) {
99 for (i
= 0; i
< idx
; i
++)
100 ptr
->idd
[i
] = ptr
->data
[i
] & HIL_PKT_DATA_MASK
;
101 for (; i
< HIL_PTR_MAX_LENGTH
; i
++)
105 for (i
= 0; i
< idx
; i
++)
106 ptr
->rsc
[i
] = ptr
->data
[i
] & HIL_PKT_DATA_MASK
;
107 for (; i
< HIL_PTR_MAX_LENGTH
; i
++)
111 for (i
= 0; i
< idx
; i
++)
112 ptr
->exd
[i
] = ptr
->data
[i
] & HIL_PKT_DATA_MASK
;
113 for (; i
< HIL_PTR_MAX_LENGTH
; i
++)
117 for (i
= 0; i
< idx
; i
++)
118 ptr
->rnm
[i
] = ptr
->data
[i
] & HIL_PKT_DATA_MASK
;
119 for (; i
< HIL_PTR_MAX_LENGTH
+ 1; i
++)
123 /* These occur when device isn't present */
124 if (p
== (HIL_ERR_INT
| HIL_PKT_CMD
)) break;
125 /* Anything else we'd like to know about. */
126 printk(KERN_WARNING PREFIX
"Device sent unknown record %x\n", p
);
132 if ((p
& HIL_CMDCT_POL
) != idx
- 1) {
133 printk(KERN_WARNING PREFIX
"Malformed poll packet %x (idx = %i)\n", p
, idx
);
137 i
= (ptr
->data
[0] & HIL_POL_AXIS_ALT
) ? 3 : 0;
138 laxis
= ptr
->data
[0] & HIL_POL_NUM_AXES_MASK
;
141 ax16
= ptr
->idd
[1] & HIL_IDD_HEADER_16BIT
; /* 8 or 16bit resolution */
142 absdev
= ptr
->idd
[1] & HIL_IDD_HEADER_ABS
;
144 for (cnt
= 1; i
< laxis
; i
++) {
145 unsigned int lo
,hi
,val
;
146 lo
= ptr
->data
[cnt
++] & HIL_PKT_DATA_MASK
;
147 hi
= ax16
? (ptr
->data
[cnt
++] & HIL_PKT_DATA_MASK
) : 0;
150 #ifdef TABLET_AUTOADJUST
151 if (val
< dev
->absmin
[ABS_X
+ i
])
152 dev
->absmin
[ABS_X
+ i
] = val
;
153 if (val
> dev
->absmax
[ABS_X
+ i
])
154 dev
->absmax
[ABS_X
+ i
] = val
;
156 if (i
%3) val
= dev
->absmax
[ABS_X
+ i
] - val
;
157 input_report_abs(dev
, ABS_X
+ i
, val
);
159 val
= (int) (((int8_t)lo
) | ((int8_t)hi
<<8));
161 input_report_rel(dev
, REL_X
+ i
, val
);
165 while (cnt
< idx
- 1) {
168 btn
= ptr
->data
[cnt
++];
172 continue; /* TODO: proximity == touch? */
174 else if ((btn
> 0x8c) || (btn
< 0x80)) continue;
175 btn
= (btn
- 0x80) >> 1;
176 btn
= ptr
->btnmap
[btn
];
177 input_report_key(dev
, btn
, !up
);
185 static void hil_ptr_process_err(struct hil_ptr
*ptr
) {
186 printk(KERN_WARNING PREFIX
"errored HIL packet\n");
192 static irqreturn_t
hil_ptr_interrupt(struct serio
*serio
,
193 unsigned char data
, unsigned int flags
, struct pt_regs
*regs
)
199 ptr
= serio_get_drvdata(serio
);
205 if (ptr
->idx4
>= (HIL_PTR_MAX_LENGTH
* sizeof(hil_packet
))) {
206 hil_ptr_process_err(ptr
);
210 if (!(ptr
->idx4
% 4)) ptr
->data
[idx
] = 0;
211 packet
= ptr
->data
[idx
];
212 packet
|= ((hil_packet
)data
) << ((3 - (ptr
->idx4
% 4)) * 8);
213 ptr
->data
[idx
] = packet
;
215 /* Records of N 4-byte hil_packets must terminate with a command. */
216 if ((++(ptr
->idx4
)) % 4) return IRQ_HANDLED
;
217 if ((packet
& 0xffff0000) != HIL_ERR_INT
) {
218 hil_ptr_process_err(ptr
);
221 if (packet
& HIL_PKT_CMD
)
222 hil_ptr_process_record(ptr
);
226 static void hil_ptr_disconnect(struct serio
*serio
)
230 ptr
= serio_get_drvdata(serio
);
236 input_unregister_device(ptr
->dev
);
238 input_free_device(ptr
->dev
);
242 static int hil_ptr_connect(struct serio
*serio
, struct serio_driver
*driver
)
246 unsigned int i
, naxsets
, btntype
;
249 if (!(ptr
= kzalloc(sizeof(struct hil_ptr
), GFP_KERNEL
)))
252 ptr
->dev
= input_allocate_device();
253 if (!ptr
->dev
) goto bail0
;
254 ptr
->dev
->private = ptr
;
256 if (serio_open(serio
, driver
)) goto bail1
;
258 serio_set_drvdata(serio
, ptr
);
261 init_MUTEX_LOCKED(&(ptr
->sem
));
263 /* Get device info. MLC driver supplies devid/status/etc. */
264 serio
->write(serio
, 0);
265 serio
->write(serio
, 0);
266 serio
->write(serio
, HIL_PKT_CMD
>> 8);
267 serio
->write(serio
, HIL_CMD_IDD
);
270 serio
->write(serio
, 0);
271 serio
->write(serio
, 0);
272 serio
->write(serio
, HIL_PKT_CMD
>> 8);
273 serio
->write(serio
, HIL_CMD_RSC
);
276 serio
->write(serio
, 0);
277 serio
->write(serio
, 0);
278 serio
->write(serio
, HIL_PKT_CMD
>> 8);
279 serio
->write(serio
, HIL_CMD_RNM
);
282 serio
->write(serio
, 0);
283 serio
->write(serio
, 0);
284 serio
->write(serio
, HIL_PKT_CMD
>> 8);
285 serio
->write(serio
, HIL_CMD_EXD
);
293 if ((did
& HIL_IDD_DID_TYPE_MASK
) == HIL_IDD_DID_TYPE_REL
) {
294 ptr
->dev
->evbit
[0] = BIT(EV_REL
);
298 if ((did
& HIL_IDD_DID_TYPE_MASK
) == HIL_IDD_DID_TYPE_ABS
) {
299 ptr
->dev
->evbit
[0] = BIT(EV_ABS
);
302 if (!ptr
->dev
->evbit
[0]) {
306 ptr
->nbtn
= HIL_IDD_NUM_BUTTONS(idd
);
307 if (ptr
->nbtn
) ptr
->dev
->evbit
[0] |= BIT(EV_KEY
);
309 naxsets
= HIL_IDD_NUM_AXSETS(*idd
);
310 ptr
->naxes
= HIL_IDD_NUM_AXES_PER_SET(*idd
);
312 printk(KERN_INFO PREFIX
"HIL pointer device found (did: 0x%02x, axis: %s)\n",
314 printk(KERN_INFO PREFIX
"HIL pointer has %i buttons and %i sets of %i axes\n",
315 ptr
->nbtn
, naxsets
, ptr
->naxes
);
318 if ((did
& HIL_IDD_DID_ABS_TABLET_MASK
) == HIL_IDD_DID_ABS_TABLET
)
319 #ifdef TABLET_SIMULATES_MOUSE
324 if ((did
& HIL_IDD_DID_ABS_TSCREEN_MASK
) == HIL_IDD_DID_ABS_TSCREEN
)
327 if ((did
& HIL_IDD_DID_REL_MOUSE_MASK
) == HIL_IDD_DID_REL_MOUSE
)
330 for (i
= 0; i
< ptr
->nbtn
; i
++) {
331 set_bit(btntype
| i
, ptr
->dev
->keybit
);
332 ptr
->btnmap
[i
] = btntype
| i
;
335 if (btntype
== BTN_MOUSE
) {
336 /* Swap buttons 2 and 3 */
337 ptr
->btnmap
[1] = BTN_MIDDLE
;
338 ptr
->btnmap
[2] = BTN_RIGHT
;
341 if ((did
& HIL_IDD_DID_TYPE_MASK
) == HIL_IDD_DID_TYPE_REL
) {
342 for (i
= 0; i
< ptr
->naxes
; i
++) {
343 set_bit(REL_X
+ i
, ptr
->dev
->relbit
);
345 for (i
= 3; (i
< ptr
->naxes
+ 3) && (naxsets
> 1); i
++) {
346 set_bit(REL_X
+ i
, ptr
->dev
->relbit
);
349 for (i
= 0; i
< ptr
->naxes
; i
++) {
350 set_bit(ABS_X
+ i
, ptr
->dev
->absbit
);
351 ptr
->dev
->absmin
[ABS_X
+ i
] = 0;
352 ptr
->dev
->absmax
[ABS_X
+ i
] =
353 HIL_IDD_AXIS_MAX((ptr
->idd
+ 1), i
);
355 for (i
= 3; (i
< ptr
->naxes
+ 3) && (naxsets
> 1); i
++) {
356 set_bit(ABS_X
+ i
, ptr
->dev
->absbit
);
357 ptr
->dev
->absmin
[ABS_X
+ i
] = 0;
358 ptr
->dev
->absmax
[ABS_X
+ i
] =
359 HIL_IDD_AXIS_MAX((ptr
->idd
+ 1), (i
- 3));
361 #ifdef TABLET_AUTOADJUST
362 for (i
= 0; i
< ABS_MAX
; i
++) {
363 int diff
= ptr
->dev
->absmax
[ABS_X
+ i
] / 10;
364 ptr
->dev
->absmin
[ABS_X
+ i
] += diff
;
365 ptr
->dev
->absmax
[ABS_X
+ i
] -= diff
;
370 ptr
->dev
->name
= strlen(ptr
->rnm
) ? ptr
->rnm
: HIL_GENERIC_NAME
;
372 ptr
->dev
->id
.bustype
= BUS_HIL
;
373 ptr
->dev
->id
.vendor
= PCI_VENDOR_ID_HP
;
374 ptr
->dev
->id
.product
= 0x0001; /* TODO: get from ptr->rsc */
375 ptr
->dev
->id
.version
= 0x0100; /* TODO: get from ptr->rsc */
376 ptr
->dev
->dev
= &serio
->dev
;
378 input_register_device(ptr
->dev
);
379 printk(KERN_INFO
"input: %s (%s), ID: %d\n",
381 (btntype
== BTN_MOUSE
) ? "HIL mouse":"HIL tablet or touchpad",
388 input_free_device(ptr
->dev
);
391 serio_set_drvdata(serio
, NULL
);
395 static struct serio_device_id hil_ptr_ids
[] = {
397 .type
= SERIO_HIL_MLC
,
405 static struct serio_driver hil_ptr_serio_driver
= {
409 .description
= "HP HIL mouse/tablet driver",
410 .id_table
= hil_ptr_ids
,
411 .connect
= hil_ptr_connect
,
412 .disconnect
= hil_ptr_disconnect
,
413 .interrupt
= hil_ptr_interrupt
416 static int __init
hil_ptr_init(void)
418 serio_register_driver(&hil_ptr_serio_driver
);
422 static void __exit
hil_ptr_exit(void)
424 serio_unregister_driver(&hil_ptr_serio_driver
);
427 module_init(hil_ptr_init
);
428 module_exit(hil_ptr_exit
);