diff options
author | Corentin Chary <corentincj@iksaif.net> | 2007-01-26 08:04:49 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-01-30 01:37:06 -0500 |
commit | 78127b4a90469d6973de2837d483f80f3709e6e0 (patch) | |
tree | 83d289005b65afa1a4f46db5af416d1c095774c3 /drivers/misc/asus-laptop.c | |
parent | 6b7091e74fe176da97917ca60524e2b3554305f0 (diff) |
asus-laptop: add display switching support
/sys/.../asus-laptop/display can now be used to switch displays
like the old /proc/acpi/asus/disp does
Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/misc/asus-laptop.c')
-rw-r--r-- | drivers/misc/asus-laptop.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index 58ab44dc52d8..979daa6755a7 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
@@ -125,6 +125,23 @@ ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */ | |||
125 | "\\_SB.PCI0.PX40.Q10", /* S1x */ | 125 | "\\_SB.PCI0.PX40.Q10", /* S1x */ |
126 | "\\Q10"); /* A2x, L2D, L3D, M2E */ | 126 | "\\Q10"); /* A2x, L2D, L3D, M2E */ |
127 | 127 | ||
128 | /* Display */ | ||
129 | ASUS_HANDLE(display_set, ASUS_HOTK_PREFIX "SDSP"); | ||
130 | ASUS_HANDLE(display_get, | ||
131 | "\\_SB.PCI0.P0P1.VGA.GETD", /* A6B, A6K A6R A7D F3JM L4R M6R A3G | ||
132 | M6A M6V VX-1 V6J V6V W3Z */ | ||
133 | "\\_SB.PCI0.P0P2.VGA.GETD", /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V | ||
134 | S5A M5A z33A W1Jc W2V */ | ||
135 | "\\_SB.PCI0.P0P3.VGA.GETD", /* A6V A6Q */ | ||
136 | "\\_SB.PCI0.P0PA.VGA.GETD", /* A6T, A6M */ | ||
137 | "\\_SB.PCI0.PCI1.VGAC.NMAP", /* L3C */ | ||
138 | "\\_SB.PCI0.VGA.GETD", /* Z96F */ | ||
139 | "\\ACTD", /* A2D */ | ||
140 | "\\ADVG", /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */ | ||
141 | "\\DNXT", /* P30 */ | ||
142 | "\\INFB", /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */ | ||
143 | "\\SSTE"); /* A3F A6F A3N A3L M6N W3N W6A */ | ||
144 | |||
128 | /* | 145 | /* |
129 | * This is the main structure, we can use it to store anything interesting | 146 | * This is the main structure, we can use it to store anything interesting |
130 | * about the hotk device | 147 | * about the hotk device |
@@ -491,6 +508,60 @@ static ssize_t store_bluetooth(struct device *dev, struct device_attribute *attr | |||
491 | return store_status(buf, count, bt_switch_handle, BT_ON, 0); | 508 | return store_status(buf, count, bt_switch_handle, BT_ON, 0); |
492 | } | 509 | } |
493 | 510 | ||
511 | /* | ||
512 | * Display | ||
513 | */ | ||
514 | static void set_display(int value) | ||
515 | { | ||
516 | /* no sanity check needed for now */ | ||
517 | if (!write_acpi_int(display_set_handle, NULL, value, NULL)) | ||
518 | printk(ASUS_WARNING "Error setting display\n"); | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | static int read_display(void) | ||
523 | { | ||
524 | int value = 0; | ||
525 | |||
526 | /* In most of the case, we know how to set the display, but sometime | ||
527 | we can't read it */ | ||
528 | if(display_get_handle) { | ||
529 | if (!read_acpi_int(display_get_handle, NULL, &value, NULL)) | ||
530 | printk(ASUS_WARNING "Error reading display status\n"); | ||
531 | } | ||
532 | |||
533 | value &= 0x0F; /* needed for some models, shouldn't hurt others */ | ||
534 | |||
535 | return value; | ||
536 | } | ||
537 | /* | ||
538 | * Now, *this* one could be more user-friendly, but so far, no-one has | ||
539 | * complained. The significance of bits is the same as in store_disp() | ||
540 | */ | ||
541 | static ssize_t show_disp(struct device *dev, | ||
542 | struct device_attribute *attr, char *buf) | ||
543 | { | ||
544 | return sprintf(buf, "%d\n", read_display()); | ||
545 | } | ||
546 | |||
547 | /* | ||
548 | * Experimental support for display switching. As of now: 1 should activate | ||
549 | * the LCD output, 2 should do for CRT, 4 for TV-Out and 8 for DVI. | ||
550 | * Any combination (bitwise) of these will suffice. I never actually tested 4 | ||
551 | * displays hooked up simultaneously, so be warned. See the acpi4asus README | ||
552 | * for more info. | ||
553 | */ | ||
554 | static ssize_t store_disp(struct device *dev, struct device_attribute *attr, | ||
555 | const char *buf, size_t count) | ||
556 | { | ||
557 | int rv, value; | ||
558 | |||
559 | rv = parse_arg(buf, count, &value); | ||
560 | if (rv > 0) | ||
561 | set_display(value); | ||
562 | return rv; | ||
563 | } | ||
564 | |||
494 | static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) | 565 | static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) |
495 | { | 566 | { |
496 | /* TODO Find a better way to handle events count. */ | 567 | /* TODO Find a better way to handle events count. */ |
@@ -535,11 +606,13 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) | |||
535 | static ASUS_CREATE_DEVICE_ATTR(infos); | 606 | static ASUS_CREATE_DEVICE_ATTR(infos); |
536 | static ASUS_CREATE_DEVICE_ATTR(wlan); | 607 | static ASUS_CREATE_DEVICE_ATTR(wlan); |
537 | static ASUS_CREATE_DEVICE_ATTR(bluetooth); | 608 | static ASUS_CREATE_DEVICE_ATTR(bluetooth); |
609 | static ASUS_CREATE_DEVICE_ATTR(display); | ||
538 | 610 | ||
539 | static struct attribute *asuspf_attributes[] = { | 611 | static struct attribute *asuspf_attributes[] = { |
540 | &dev_attr_infos.attr, | 612 | &dev_attr_infos.attr, |
541 | &dev_attr_wlan.attr, | 613 | &dev_attr_wlan.attr, |
542 | &dev_attr_bluetooth.attr, | 614 | &dev_attr_bluetooth.attr, |
615 | &dev_attr_display.attr, | ||
543 | NULL | 616 | NULL |
544 | }; | 617 | }; |
545 | 618 | ||
@@ -567,6 +640,12 @@ static void asus_hotk_add_fs(void) | |||
567 | if (bt_switch_handle) | 640 | if (bt_switch_handle) |
568 | ASUS_SET_DEVICE_ATTR(bluetooth, 0644, | 641 | ASUS_SET_DEVICE_ATTR(bluetooth, 0644, |
569 | show_bluetooth, store_bluetooth); | 642 | show_bluetooth, store_bluetooth); |
643 | |||
644 | if (display_set_handle && display_get_handle) | ||
645 | ASUS_SET_DEVICE_ATTR(display, 0644, show_disp, store_disp); | ||
646 | else if(display_set_handle) | ||
647 | ASUS_SET_DEVICE_ATTR(display, 0200, NULL, store_disp); | ||
648 | |||
570 | } | 649 | } |
571 | 650 | ||
572 | static int asus_handle_init(char *name, acpi_handle *handle, | 651 | static int asus_handle_init(char *name, acpi_handle *handle, |
@@ -683,6 +762,9 @@ static int asus_hotk_get_info(void) | |||
683 | 762 | ||
684 | ASUS_HANDLE_INIT(lcd_switch); | 763 | ASUS_HANDLE_INIT(lcd_switch); |
685 | 764 | ||
765 | ASUS_HANDLE_INIT(display_set); | ||
766 | ASUS_HANDLE_INIT(display_get); | ||
767 | |||
686 | kfree(model); | 768 | kfree(model); |
687 | 769 | ||
688 | return AE_OK; | 770 | return AE_OK; |