aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/hil_kbd.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-08-08 02:17:47 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-08-09 16:27:27 -0400
commitfa71c605c2bb4d816514c2611ad53f48007f1fd3 (patch)
tree9f57765287a2c2a7623ba6b5031e2897c01e5216 /drivers/input/keyboard/hil_kbd.c
parent1437dc3089911d42180be11c50a0b960250a1d87 (diff)
Input: combine hil_kbd and hil_ptr drivers
hil_kbd and hil_ptr look like twins so it makes sense to combine them into a single driver. [deller@gmx.de: add MODULE_ALIAS() entry for mouse] Tested-by: Helge Deller <deller@gmx.de> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/keyboard/hil_kbd.c')
-rw-r--r--drivers/input/keyboard/hil_kbd.c251
1 files changed, 216 insertions, 35 deletions
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
index 235a669a0ac..c83f4b2ec7d 100644
--- a/drivers/input/keyboard/hil_kbd.c
+++ b/drivers/input/keyboard/hil_kbd.c
@@ -41,13 +41,13 @@
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <linux/pci_ids.h> 42#include <linux/pci_ids.h>
43 43
44#define PREFIX "HIL KEYB: " 44#define PREFIX "HIL: "
45#define HIL_GENERIC_NAME "HIL keyboard"
46 45
47MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); 46MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
48MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver"); 47MODULE_DESCRIPTION("HIL keyboard/mouse driver");
49MODULE_LICENSE("Dual BSD/GPL"); 48MODULE_LICENSE("Dual BSD/GPL");
50MODULE_ALIAS("serio:ty03pr25id00ex*"); 49MODULE_ALIAS("serio:ty03pr25id00ex*"); /* HIL keyboard */
50MODULE_ALIAS("serio:ty03pr25id0Fex*"); /* HIL mouse */
51 51
52#define HIL_PACKET_MAX_LENGTH 16 52#define HIL_PACKET_MAX_LENGTH 16
53 53
@@ -82,6 +82,11 @@ struct hil_dev {
82 char rnm[HIL_PACKET_MAX_LENGTH + 1]; /* RNM record + NULL term. */ 82 char rnm[HIL_PACKET_MAX_LENGTH + 1]; /* RNM record + NULL term. */
83 83
84 struct completion cmd_done; 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];
85}; 90};
86 91
87static bool hil_dev_is_command_response(hil_packet p) 92static bool hil_dev_is_command_response(hil_packet p)
@@ -139,7 +144,7 @@ static void hil_dev_handle_command_response(struct hil_dev *dev)
139 complete(&dev->cmd_done); 144 complete(&dev->cmd_done);
140} 145}
141 146
142static void hil_dev_handle_key_events(struct hil_dev *kbd) 147static void hil_dev_handle_kbd_events(struct hil_dev *kbd)
143{ 148{
144 struct input_dev *dev = kbd->dev; 149 struct input_dev *dev = kbd->dev;
145 int idx = kbd->idx4 / 4; 150 int idx = kbd->idx4 / 4;
@@ -198,6 +203,67 @@ static void hil_dev_handle_key_events(struct hil_dev *kbd)
198 input_sync(dev); 203 input_sync(dev);
199} 204}
200 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 < dev->absmin[ABS_X + i])
236 dev->absmin[ABS_X + i] = val;
237 if (val > dev->absmax[ABS_X + i])
238 dev->absmax[ABS_X + i] = val;
239#endif
240 if (i%3) val = dev->absmax[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
201static void hil_dev_process_err(struct hil_dev *dev) 267static void hil_dev_process_err(struct hil_dev *dev)
202{ 268{
203 printk(KERN_WARNING PREFIX "errored HIL packet\n"); 269 printk(KERN_WARNING PREFIX "errored HIL packet\n");
@@ -234,8 +300,10 @@ static irqreturn_t hil_dev_interrupt(struct serio *serio,
234 } else if (packet & HIL_PKT_CMD) { 300 } else if (packet & HIL_PKT_CMD) {
235 if (hil_dev_is_command_response(packet)) 301 if (hil_dev_is_command_response(packet))
236 hil_dev_handle_command_response(dev); 302 hil_dev_handle_command_response(dev);
303 else if (dev->is_pointer)
304 hil_dev_handle_ptr_events(dev);
237 else 305 else
238 hil_dev_handle_key_events(dev); 306 hil_dev_handle_kbd_events(dev);
239 dev->idx4 = 0; 307 dev->idx4 = 0;
240 } 308 }
241 } 309 }
@@ -251,15 +319,130 @@ static void hil_dev_disconnect(struct serio *serio)
251 319
252 serio_close(serio); 320 serio_close(serio);
253 input_unregister_device(dev->dev); 321 input_unregister_device(dev->dev);
322 serio_set_drvdata(serio, NULL);
254 kfree(dev); 323 kfree(dev);
255} 324}
256 325
326static 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
353static 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_dev->absmax[ABS_X + i] / 10;
391 input_dev->absmin[ABS_X + i] += diff;
392 input_dev->absmax[ABS_X + i] -= diff;
393 }
394#endif
395
396 txt = "absolute";
397 break;
398
399 default:
400 BUG();
401 }
402
403 ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
404 if (ptr->nbtn)
405 input_dev->evbit[0] |= BIT_MASK(EV_KEY);
406
407 btntype = BTN_MISC;
408 if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET)
409#ifdef TABLET_SIMULATES_MOUSE
410 btntype = BTN_TOUCH;
411#else
412 btntype = BTN_DIGI;
413#endif
414 if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN)
415 btntype = BTN_TOUCH;
416
417 if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE)
418 btntype = BTN_MOUSE;
419
420 for (i = 0; i < ptr->nbtn; i++) {
421 __set_bit(btntype | i, input_dev->keybit);
422 ptr->btnmap[i] = btntype | i;
423 }
424
425 if (btntype == BTN_MOUSE) {
426 /* Swap buttons 2 and 3 */
427 ptr->btnmap[1] = BTN_MIDDLE;
428 ptr->btnmap[2] = BTN_RIGHT;
429 }
430
431 input_dev->name = strlen(ptr->rnm) ? ptr->rnm : "HIL pointer device";
432
433 printk(KERN_INFO PREFIX
434 "HIL pointer device found (did: 0x%02x, axis: %s)\n",
435 did, txt);
436 printk(KERN_INFO PREFIX
437 "HIL pointer has %i buttons and %i sets of %i axes\n",
438 ptr->nbtn, naxsets, ptr->naxes);
439}
440
257static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) 441static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
258{ 442{
259 struct hil_dev *dev; 443 struct hil_dev *dev;
260 struct input_dev *input_dev; 444 struct input_dev *input_dev;
261 uint8_t did, *idd; 445 uint8_t did, *idd;
262 int i;
263 int error; 446 int error;
264 447
265 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 448 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -317,49 +500,47 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
317 500
318 did = dev->idd[0]; 501 did = dev->idd[0];
319 idd = dev->idd + 1; 502 idd = dev->idd + 1;
503
320 switch (did & HIL_IDD_DID_TYPE_MASK) { 504 switch (did & HIL_IDD_DID_TYPE_MASK) {
321 case HIL_IDD_DID_TYPE_KB_INTEGRAL: 505 case HIL_IDD_DID_TYPE_KB_INTEGRAL:
322 case HIL_IDD_DID_TYPE_KB_ITF: 506 case HIL_IDD_DID_TYPE_KB_ITF:
323 case HIL_IDD_DID_TYPE_KB_RSVD: 507 case HIL_IDD_DID_TYPE_KB_RSVD:
324 case HIL_IDD_DID_TYPE_CHAR: 508 case HIL_IDD_DID_TYPE_CHAR:
325 printk(KERN_INFO PREFIX "HIL keyboard found (did = 0x%02x, lang = %s)\n", 509 if (HIL_IDD_NUM_BUTTONS(idd) ||
326 did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]); 510 HIL_IDD_NUM_AXES_PER_SET(*idd)) {
511 printk(KERN_INFO PREFIX
512 "combo devices are not supported.\n");
513 goto bail1;
514 }
515
516 dev->is_pointer = false;
517 hil_dev_keyboard_setup(dev);
327 break; 518 break;
328 default:
329 goto bail1;
330 }
331 519
332 if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { 520 case HIL_IDD_DID_TYPE_REL:
333 printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); 521 case HIL_IDD_DID_TYPE_ABS:
522 dev->is_pointer = true;
523 hil_dev_pointer_setup(dev);
524 break;
525
526 default:
334 goto bail1; 527 goto bail1;
335 } 528 }
336 529
337 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
338 input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
339 BIT_MASK(LED_SCROLLL);
340 input_dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
341 input_dev->keycodesize = sizeof(hil_kbd_set1[0]);
342 input_dev->keycode = hil_kbd_set1;
343 input_dev->name = strlen(dev->rnm) ? dev->rnm : HIL_GENERIC_NAME;
344 input_dev->phys = "hpkbd/input0"; /* XXX */
345
346 input_dev->id.bustype = BUS_HIL; 530 input_dev->id.bustype = BUS_HIL;
347 input_dev->id.vendor = PCI_VENDOR_ID_HP; 531 input_dev->id.vendor = PCI_VENDOR_ID_HP;
348 input_dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ 532 input_dev->id.product = 0x0001; /* TODO: get from kbd->rsc */
349 input_dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ 533 input_dev->id.version = 0x0100; /* TODO: get from kbd->rsc */
350 input_dev->dev.parent = &serio->dev; 534 input_dev->dev.parent = &serio->dev;
351 535
352 for (i = 0; i < 128; i++) { 536 if (!dev->is_pointer) {
353 __set_bit(hil_kbd_set1[i], input_dev->keybit); 537 serio_write(serio, 0);
354 __set_bit(hil_kbd_set3[i], input_dev->keybit); 538 serio_write(serio, 0);
539 serio_write(serio, HIL_PKT_CMD >> 8);
540 /* Enable Keyswitch Autorepeat 1 */
541 serio_write(serio, HIL_CMD_EK1);
542 /* No need to wait for completion */
355 } 543 }
356 __clear_bit(KEY_RESERVED, input_dev->keybit);
357
358 serio_write(serio, 0);
359 serio_write(serio, 0);
360 serio_write(serio, HIL_PKT_CMD >> 8);
361 serio_write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */
362 /* No need to wait for completion */
363 544
364 error = input_register_device(input_dev); 545 error = input_register_device(input_dev);
365 if (error) 546 if (error)
@@ -388,9 +569,9 @@ static struct serio_device_id hil_dev_ids[] = {
388 569
389static struct serio_driver hil_serio_drv = { 570static struct serio_driver hil_serio_drv = {
390 .driver = { 571 .driver = {
391 .name = "hil_kbd", 572 .name = "hil_dev",
392 }, 573 },
393 .description = "HP HIL keyboard driver", 574 .description = "HP HIL keyboard/mouse/tablet driver",
394 .id_table = hil_dev_ids, 575 .id_table = hil_dev_ids,
395 .connect = hil_dev_connect, 576 .connect = hil_dev_connect,
396 .disconnect = hil_dev_disconnect, 577 .disconnect = hil_dev_disconnect,