aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/panasonic-laptop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/panasonic-laptop.c')
-rw-r--r--drivers/platform/x86/panasonic-laptop.c194
1 files changed, 73 insertions, 121 deletions
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index ec01c3d8fc5a..cc1e0ba104d7 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -128,6 +128,7 @@
128#include <acpi/acpi_bus.h> 128#include <acpi/acpi_bus.h>
129#include <acpi/acpi_drivers.h> 129#include <acpi/acpi_drivers.h>
130#include <linux/input.h> 130#include <linux/input.h>
131#include <linux/input/sparse-keymap.h>
131 132
132 133
133#ifndef ACPI_HOTKEY_COMPONENT 134#ifndef ACPI_HOTKEY_COMPONENT
@@ -200,30 +201,29 @@ static struct acpi_driver acpi_pcc_driver = {
200 }, 201 },
201}; 202};
202 203
203#define KEYMAP_SIZE 11 204static const struct key_entry panasonic_keymap[] = {
204static const unsigned int initial_keymap[KEYMAP_SIZE] = { 205 { KE_KEY, 0, { KEY_RESERVED } },
205 /* 0 */ KEY_RESERVED, 206 { KE_KEY, 1, { KEY_BRIGHTNESSDOWN } },
206 /* 1 */ KEY_BRIGHTNESSDOWN, 207 { KE_KEY, 2, { KEY_BRIGHTNESSUP } },
207 /* 2 */ KEY_BRIGHTNESSUP, 208 { KE_KEY, 3, { KEY_DISPLAYTOGGLE } },
208 /* 3 */ KEY_DISPLAYTOGGLE, 209 { KE_KEY, 4, { KEY_MUTE } },
209 /* 4 */ KEY_MUTE, 210 { KE_KEY, 5, { KEY_VOLUMEDOWN } },
210 /* 5 */ KEY_VOLUMEDOWN, 211 { KE_KEY, 6, { KEY_VOLUMEUP } },
211 /* 6 */ KEY_VOLUMEUP, 212 { KE_KEY, 7, { KEY_SLEEP } },
212 /* 7 */ KEY_SLEEP, 213 { KE_KEY, 8, { KEY_PROG1 } }, /* Change CPU boost */
213 /* 8 */ KEY_PROG1, /* Change CPU boost */ 214 { KE_KEY, 9, { KEY_BATTERY } },
214 /* 9 */ KEY_BATTERY, 215 { KE_KEY, 10, { KEY_SUSPEND } },
215 /* 10 */ KEY_SUSPEND, 216 { KE_END, 0 }
216}; 217};
217 218
218struct pcc_acpi { 219struct pcc_acpi {
219 acpi_handle handle; 220 acpi_handle handle;
220 unsigned long num_sifr; 221 unsigned long num_sifr;
221 int sticky_mode; 222 int sticky_mode;
222 u32 *sinf; 223 u32 *sinf;
223 struct acpi_device *device; 224 struct acpi_device *device;
224 struct input_dev *input_dev; 225 struct input_dev *input_dev;
225 struct backlight_device *backlight; 226 struct backlight_device *backlight;
226 unsigned int keymap[KEYMAP_SIZE];
227}; 227};
228 228
229struct pcc_keyinput { 229struct pcc_keyinput {
@@ -267,7 +267,7 @@ static inline int acpi_pcc_get_sqty(struct acpi_device *device)
267 } 267 }
268} 268}
269 269
270static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf) 270static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc)
271{ 271{
272 acpi_status status; 272 acpi_status status;
273 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; 273 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
@@ -285,6 +285,7 @@ static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf)
285 hkey = buffer.pointer; 285 hkey = buffer.pointer;
286 if (!hkey || (hkey->type != ACPI_TYPE_PACKAGE)) { 286 if (!hkey || (hkey->type != ACPI_TYPE_PACKAGE)) {
287 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid HKEY.SINF\n")); 287 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid HKEY.SINF\n"));
288 status = AE_ERROR;
288 goto end; 289 goto end;
289 } 290 }
290 291
@@ -298,12 +299,12 @@ static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf)
298 for (i = 0; i < hkey->package.count; i++) { 299 for (i = 0; i < hkey->package.count; i++) {
299 union acpi_object *element = &(hkey->package.elements[i]); 300 union acpi_object *element = &(hkey->package.elements[i]);
300 if (likely(element->type == ACPI_TYPE_INTEGER)) { 301 if (likely(element->type == ACPI_TYPE_INTEGER)) {
301 sinf[i] = element->integer.value; 302 pcc->sinf[i] = element->integer.value;
302 } else 303 } else
303 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 304 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
304 "Invalid HKEY.SINF data\n")); 305 "Invalid HKEY.SINF data\n"));
305 } 306 }
306 sinf[hkey->package.count] = -1; 307 pcc->sinf[hkey->package.count] = -1;
307 308
308end: 309end:
309 kfree(buffer.pointer); 310 kfree(buffer.pointer);
@@ -321,7 +322,7 @@ static int bl_get(struct backlight_device *bd)
321{ 322{
322 struct pcc_acpi *pcc = bl_get_data(bd); 323 struct pcc_acpi *pcc = bl_get_data(bd);
323 324
324 if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) 325 if (!acpi_pcc_retrieve_biosdata(pcc))
325 return -EIO; 326 return -EIO;
326 327
327 return pcc->sinf[SINF_AC_CUR_BRIGHT]; 328 return pcc->sinf[SINF_AC_CUR_BRIGHT];
@@ -333,7 +334,7 @@ static int bl_set_status(struct backlight_device *bd)
333 int bright = bd->props.brightness; 334 int bright = bd->props.brightness;
334 int rc; 335 int rc;
335 336
336 if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) 337 if (!acpi_pcc_retrieve_biosdata(pcc))
337 return -EIO; 338 return -EIO;
338 339
339 if (bright < pcc->sinf[SINF_AC_MIN_BRIGHT]) 340 if (bright < pcc->sinf[SINF_AC_MIN_BRIGHT])
@@ -367,7 +368,7 @@ static ssize_t show_numbatt(struct device *dev, struct device_attribute *attr,
367 struct acpi_device *acpi = to_acpi_device(dev); 368 struct acpi_device *acpi = to_acpi_device(dev);
368 struct pcc_acpi *pcc = acpi_driver_data(acpi); 369 struct pcc_acpi *pcc = acpi_driver_data(acpi);
369 370
370 if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) 371 if (!acpi_pcc_retrieve_biosdata(pcc))
371 return -EIO; 372 return -EIO;
372 373
373 return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]); 374 return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
@@ -379,7 +380,7 @@ static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
379 struct acpi_device *acpi = to_acpi_device(dev); 380 struct acpi_device *acpi = to_acpi_device(dev);
380 struct pcc_acpi *pcc = acpi_driver_data(acpi); 381 struct pcc_acpi *pcc = acpi_driver_data(acpi);
381 382
382 if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) 383 if (!acpi_pcc_retrieve_biosdata(pcc))
383 return -EIO; 384 return -EIO;
384 385
385 return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_LCD_TYPE]); 386 return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
@@ -391,7 +392,7 @@ static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
391 struct acpi_device *acpi = to_acpi_device(dev); 392 struct acpi_device *acpi = to_acpi_device(dev);
392 struct pcc_acpi *pcc = acpi_driver_data(acpi); 393 struct pcc_acpi *pcc = acpi_driver_data(acpi);
393 394
394 if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) 395 if (!acpi_pcc_retrieve_biosdata(pcc))
395 return -EIO; 396 return -EIO;
396 397
397 return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_MUTE]); 398 return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_MUTE]);
@@ -403,7 +404,7 @@ static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
403 struct acpi_device *acpi = to_acpi_device(dev); 404 struct acpi_device *acpi = to_acpi_device(dev);
404 struct pcc_acpi *pcc = acpi_driver_data(acpi); 405 struct pcc_acpi *pcc = acpi_driver_data(acpi);
405 406
406 if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) 407 if (!acpi_pcc_retrieve_biosdata(pcc))
407 return -EIO; 408 return -EIO;
408 409
409 return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_STICKY_KEY]); 410 return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
@@ -446,56 +447,10 @@ static struct attribute_group pcc_attr_group = {
446 447
447/* hotkey input device driver */ 448/* hotkey input device driver */
448 449
449static int pcc_getkeycode(struct input_dev *dev,
450 unsigned int scancode, unsigned int *keycode)
451{
452 struct pcc_acpi *pcc = input_get_drvdata(dev);
453
454 if (scancode >= ARRAY_SIZE(pcc->keymap))
455 return -EINVAL;
456
457 *keycode = pcc->keymap[scancode];
458
459 return 0;
460}
461
462static int keymap_get_by_keycode(struct pcc_acpi *pcc, unsigned int keycode)
463{
464 int i;
465
466 for (i = 0; i < ARRAY_SIZE(pcc->keymap); i++) {
467 if (pcc->keymap[i] == keycode)
468 return i+1;
469 }
470
471 return 0;
472}
473
474static int pcc_setkeycode(struct input_dev *dev,
475 unsigned int scancode, unsigned int keycode)
476{
477 struct pcc_acpi *pcc = input_get_drvdata(dev);
478 int oldkeycode;
479
480 if (scancode >= ARRAY_SIZE(pcc->keymap))
481 return -EINVAL;
482
483 oldkeycode = pcc->keymap[scancode];
484 pcc->keymap[scancode] = keycode;
485
486 set_bit(keycode, dev->keybit);
487
488 if (!keymap_get_by_keycode(pcc, oldkeycode))
489 clear_bit(oldkeycode, dev->keybit);
490
491 return 0;
492}
493
494static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) 450static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
495{ 451{
496 struct input_dev *hotk_input_dev = pcc->input_dev; 452 struct input_dev *hotk_input_dev = pcc->input_dev;
497 int rc; 453 int rc;
498 int key_code, hkey_num;
499 unsigned long long result; 454 unsigned long long result;
500 455
501 rc = acpi_evaluate_integer(pcc->handle, METHOD_HKEY_QUERY, 456 rc = acpi_evaluate_integer(pcc->handle, METHOD_HKEY_QUERY,
@@ -508,25 +463,10 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
508 463
509 acpi_bus_generate_proc_event(pcc->device, HKEY_NOTIFY, result); 464 acpi_bus_generate_proc_event(pcc->device, HKEY_NOTIFY, result);
510 465
511 hkey_num = result & 0xf; 466 if (!sparse_keymap_report_event(hotk_input_dev,
512 467 result & 0xf, result & 0x80, false))
513 if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) {
514 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 468 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
515 "hotkey number out of range: %d\n", 469 "Unknown hotkey event: %d\n", result));
516 hkey_num));
517 return;
518 }
519
520 key_code = pcc->keymap[hkey_num];
521
522 if (key_code != KEY_RESERVED) {
523 int pushed = (result & 0x80) ? TRUE : FALSE;
524
525 input_report_key(hotk_input_dev, key_code, pushed);
526 input_sync(hotk_input_dev);
527 }
528
529 return;
530} 470}
531 471
532static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event) 472static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
@@ -545,40 +485,55 @@ static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
545 485
546static int acpi_pcc_init_input(struct pcc_acpi *pcc) 486static int acpi_pcc_init_input(struct pcc_acpi *pcc)
547{ 487{
548 int i, rc; 488 struct input_dev *input_dev;
489 int error;
549 490
550 pcc->input_dev = input_allocate_device(); 491 input_dev = input_allocate_device();
551 if (!pcc->input_dev) { 492 if (!input_dev) {
552 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 493 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
553 "Couldn't allocate input device for hotkey")); 494 "Couldn't allocate input device for hotkey"));
554 return -ENOMEM; 495 return -ENOMEM;
555 } 496 }
556 497
557 pcc->input_dev->evbit[0] = BIT(EV_KEY); 498 input_dev->name = ACPI_PCC_DRIVER_NAME;
558 499 input_dev->phys = ACPI_PCC_INPUT_PHYS;
559 pcc->input_dev->name = ACPI_PCC_DRIVER_NAME; 500 input_dev->id.bustype = BUS_HOST;
560 pcc->input_dev->phys = ACPI_PCC_INPUT_PHYS; 501 input_dev->id.vendor = 0x0001;
561 pcc->input_dev->id.bustype = BUS_HOST; 502 input_dev->id.product = 0x0001;
562 pcc->input_dev->id.vendor = 0x0001; 503 input_dev->id.version = 0x0100;
563 pcc->input_dev->id.product = 0x0001;
564 pcc->input_dev->id.version = 0x0100;
565 pcc->input_dev->getkeycode = pcc_getkeycode;
566 pcc->input_dev->setkeycode = pcc_setkeycode;
567 504
568 /* load initial keymap */ 505 error = sparse_keymap_setup(input_dev, panasonic_keymap, NULL);
569 memcpy(pcc->keymap, initial_keymap, sizeof(pcc->keymap)); 506 if (error) {
507 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
508 "Unable to setup input device keymap\n"));
509 goto err_free_dev;
510 }
570 511
571 for (i = 0; i < ARRAY_SIZE(pcc->keymap); i++) 512 error = input_register_device(input_dev);
572 __set_bit(pcc->keymap[i], pcc->input_dev->keybit); 513 if (error) {
573 __clear_bit(KEY_RESERVED, pcc->input_dev->keybit); 514 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
515 "Unable to register input device\n"));
516 goto err_free_keymap;
517 }
574 518
575 input_set_drvdata(pcc->input_dev, pcc); 519 pcc->input_dev = input_dev;
520 return 0;
576 521
577 rc = input_register_device(pcc->input_dev); 522 err_free_keymap:
578 if (rc < 0) 523 sparse_keymap_free(input_dev);
579 input_free_device(pcc->input_dev); 524 err_free_dev:
525 input_free_device(input_dev);
526 return error;
527}
580 528
581 return rc; 529static void acpi_pcc_destroy_input(struct pcc_acpi *pcc)
530{
531 sparse_keymap_free(pcc->input_dev);
532 input_unregister_device(pcc->input_dev);
533 /*
534 * No need to input_free_device() since core input API refcounts
535 * and free()s the device.
536 */
582} 537}
583 538
584/* kernel module interface */ 539/* kernel module interface */
@@ -636,12 +591,13 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
636 if (result) { 591 if (result) {
637 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 592 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
638 "Error installing keyinput handler\n")); 593 "Error installing keyinput handler\n"));
639 goto out_hotkey; 594 goto out_sinf;
640 } 595 }
641 596
642 if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) { 597 if (!acpi_pcc_retrieve_biosdata(pcc)) {
643 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 598 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
644 "Couldn't retrieve BIOS data\n")); 599 "Couldn't retrieve BIOS data\n"));
600 result = -EIO;
645 goto out_input; 601 goto out_input;
646 } 602 }
647 /* initialize backlight */ 603 /* initialize backlight */
@@ -651,7 +607,7 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
651 &pcc_backlight_ops, &props); 607 &pcc_backlight_ops, &props);
652 if (IS_ERR(pcc->backlight)) { 608 if (IS_ERR(pcc->backlight)) {
653 result = PTR_ERR(pcc->backlight); 609 result = PTR_ERR(pcc->backlight);
654 goto out_sinf; 610 goto out_input;
655 } 611 }
656 612
657 /* read the initial brightness setting from the hardware */ 613 /* read the initial brightness setting from the hardware */
@@ -669,12 +625,10 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
669 625
670out_backlight: 626out_backlight:
671 backlight_device_unregister(pcc->backlight); 627 backlight_device_unregister(pcc->backlight);
628out_input:
629 acpi_pcc_destroy_input(pcc);
672out_sinf: 630out_sinf:
673 kfree(pcc->sinf); 631 kfree(pcc->sinf);
674out_input:
675 input_unregister_device(pcc->input_dev);
676 /* no need to input_free_device() since core input API refcount and
677 * free()s the device */
678out_hotkey: 632out_hotkey:
679 kfree(pcc); 633 kfree(pcc);
680 634
@@ -709,9 +663,7 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type)
709 663
710 backlight_device_unregister(pcc->backlight); 664 backlight_device_unregister(pcc->backlight);
711 665
712 input_unregister_device(pcc->input_dev); 666 acpi_pcc_destroy_input(pcc);
713 /* no need to input_free_device() since core input API refcount and
714 * free()s the device */
715 667
716 kfree(pcc->sinf); 668 kfree(pcc->sinf);
717 kfree(pcc); 669 kfree(pcc);