1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/types.h>
31#include <linux/list.h>
32#include <linux/mutex.h>
33#include <linux/input.h>
34#include <linux/backlight.h>
35#include <linux/thermal.h>
36#include <linux/sort.h>
37#include <linux/pci.h>
38#include <linux/pci_ids.h>
39#include <linux/slab.h>
40#include <asm/uaccess.h>
41#include <linux/dmi.h>
42#include <acpi/acpi_bus.h>
43#include <acpi/acpi_drivers.h>
44#include <linux/suspend.h>
45#include <acpi/video.h>
46
47#include "internal.h"
48
49#define PREFIX "ACPI: "
50
51#define ACPI_VIDEO_BUS_NAME "Video Bus"
52#define ACPI_VIDEO_DEVICE_NAME "Video Device"
53#define ACPI_VIDEO_NOTIFY_SWITCH 0x80
54#define ACPI_VIDEO_NOTIFY_PROBE 0x81
55#define ACPI_VIDEO_NOTIFY_CYCLE 0x82
56#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
57#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
58
59#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85
60#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
61#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
62#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
63#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
64
65#define MAX_NAME_LEN 20
66
67#define _COMPONENT ACPI_VIDEO_COMPONENT
68ACPI_MODULE_NAME("video");
69
70MODULE_AUTHOR("Bruno Ducrot");
71MODULE_DESCRIPTION("ACPI Video Driver");
72MODULE_LICENSE("GPL");
73
74static bool brightness_switch_enabled = 1;
75module_param(brightness_switch_enabled, bool, 0644);
76
77
78
79
80
81static bool allow_duplicates;
82module_param(allow_duplicates, bool, 0644);
83
84
85
86
87
88static bool use_bios_initial_backlight = 1;
89module_param(use_bios_initial_backlight, bool, 0644);
90
91static int register_count = 0;
92static int acpi_video_bus_add(struct acpi_device *device);
93static int acpi_video_bus_remove(struct acpi_device *device);
94static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
95
96static const struct acpi_device_id video_device_ids[] = {
97 {ACPI_VIDEO_HID, 0},
98 {"", 0},
99};
100MODULE_DEVICE_TABLE(acpi, video_device_ids);
101
102static struct acpi_driver acpi_video_bus = {
103 .name = "video",
104 .class = ACPI_VIDEO_CLASS,
105 .ids = video_device_ids,
106 .ops = {
107 .add = acpi_video_bus_add,
108 .remove = acpi_video_bus_remove,
109 .notify = acpi_video_bus_notify,
110 },
111};
112
113struct acpi_video_bus_flags {
114 u8 multihead:1;
115 u8 rom:1;
116 u8 post:1;
117 u8 reserved:5;
118};
119
120struct acpi_video_bus_cap {
121 u8 _DOS:1;
122 u8 _DOD:1;
123 u8 _ROM:1;
124 u8 _GPD:1;
125 u8 _SPD:1;
126 u8 _VPO:1;
127 u8 reserved:2;
128};
129
130struct acpi_video_device_attrib {
131 u32 display_index:4;
132 u32 display_port_attachment:4;
133 u32 display_type:4;
134 u32 vendor_specific:4;
135 u32 bios_can_detect:1;
136 u32 depend_on_vga:1;
137
138 u32 pipe_id:3;
139 u32 reserved:10;
140 u32 device_id_scheme:1;
141};
142
143struct acpi_video_enumerated_device {
144 union {
145 u32 int_val;
146 struct acpi_video_device_attrib attrib;
147 } value;
148 struct acpi_video_device *bind_info;
149};
150
151struct acpi_video_bus {
152 struct acpi_device *device;
153 u8 dos_setting;
154 struct acpi_video_enumerated_device *attached_array;
155 u8 attached_count;
156 struct acpi_video_bus_cap cap;
157 struct acpi_video_bus_flags flags;
158 struct list_head video_device_list;
159 struct mutex device_list_lock;
160 struct input_dev *input;
161 char phys[32];
162 struct notifier_block pm_nb;
163};
164
165struct acpi_video_device_flags {
166 u8 crt:1;
167 u8 lcd:1;
168 u8 tvout:1;
169 u8 dvi:1;
170 u8 bios:1;
171 u8 unknown:1;
172 u8 notify:1;
173 u8 reserved:1;
174};
175
176struct acpi_video_device_cap {
177 u8 _ADR:1;
178 u8 _BCL:1;
179 u8 _BCM:1;
180 u8 _BQC:1;
181 u8 _BCQ:1;
182 u8 _DDC:1;
183};
184
185struct acpi_video_brightness_flags {
186 u8 _BCL_no_ac_battery_levels:1;
187 u8 _BCL_reversed:1;
188 u8 _BCL_use_index:1;
189 u8 _BCM_use_index:1;
190 u8 _BQC_use_index:1;
191};
192
193struct acpi_video_device_brightness {
194 int curr;
195 int count;
196 int *levels;
197 struct acpi_video_brightness_flags flags;
198};
199
200struct acpi_video_device {
201 unsigned long device_id;
202 struct acpi_video_device_flags flags;
203 struct acpi_video_device_cap cap;
204 struct list_head entry;
205 struct acpi_video_bus *video;
206 struct acpi_device *dev;
207 struct acpi_video_device_brightness *brightness;
208 struct backlight_device *backlight;
209 struct thermal_cooling_device *cooling_dev;
210};
211
212static const char device_decode[][30] = {
213 "motherboard VGA device",
214 "PCI VGA device",
215 "AGP VGA device",
216 "UNKNOWN",
217};
218
219static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data);
220static void acpi_video_device_rebind(struct acpi_video_bus *video);
221static void acpi_video_device_bind(struct acpi_video_bus *video,
222 struct acpi_video_device *device);
223static int acpi_video_device_enumerate(struct acpi_video_bus *video);
224static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
225 int level);
226static int acpi_video_device_lcd_get_level_current(
227 struct acpi_video_device *device,
228 unsigned long long *level, bool raw);
229static int acpi_video_get_next_level(struct acpi_video_device *device,
230 u32 level_current, u32 event);
231static int acpi_video_switch_brightness(struct acpi_video_device *device,
232 int event);
233
234
235static int acpi_video_get_brightness(struct backlight_device *bd)
236{
237 unsigned long long cur_level;
238 int i;
239 struct acpi_video_device *vd =
240 (struct acpi_video_device *)bl_get_data(bd);
241
242 if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false))
243 return -EINVAL;
244 for (i = 2; i < vd->brightness->count; i++) {
245 if (vd->brightness->levels[i] == cur_level)
246
247
248 return i-2;
249 }
250 return 0;
251}
252
253static int acpi_video_set_brightness(struct backlight_device *bd)
254{
255 int request_level = bd->props.brightness + 2;
256 struct acpi_video_device *vd =
257 (struct acpi_video_device *)bl_get_data(bd);
258
259 return acpi_video_device_lcd_set_level(vd,
260 vd->brightness->levels[request_level]);
261}
262
263static const struct backlight_ops acpi_backlight_ops = {
264 .get_brightness = acpi_video_get_brightness,
265 .update_status = acpi_video_set_brightness,
266};
267
268
269static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned
270 long *state)
271{
272 struct acpi_device *device = cooling_dev->devdata;
273 struct acpi_video_device *video = acpi_driver_data(device);
274
275 *state = video->brightness->count - 3;
276 return 0;
277}
278
279static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned
280 long *state)
281{
282 struct acpi_device *device = cooling_dev->devdata;
283 struct acpi_video_device *video = acpi_driver_data(device);
284 unsigned long long level;
285 int offset;
286
287 if (acpi_video_device_lcd_get_level_current(video, &level, false))
288 return -EINVAL;
289 for (offset = 2; offset < video->brightness->count; offset++)
290 if (level == video->brightness->levels[offset]) {
291 *state = video->brightness->count - offset - 1;
292 return 0;
293 }
294
295 return -EINVAL;
296}
297
298static int
299video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state)
300{
301 struct acpi_device *device = cooling_dev->devdata;
302 struct acpi_video_device *video = acpi_driver_data(device);
303 int level;
304
305 if ( state >= video->brightness->count - 2)
306 return -EINVAL;
307
308 state = video->brightness->count - state;
309 level = video->brightness->levels[state -1];
310 return acpi_video_device_lcd_set_level(video, level);
311}
312
313static const struct thermal_cooling_device_ops video_cooling_ops = {
314 .get_max_state = video_get_max_state,
315 .get_cur_state = video_get_cur_state,
316 .set_cur_state = video_set_cur_state,
317};
318
319
320
321
322
323static int
324acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
325 union acpi_object **levels)
326{
327 int status;
328 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
329 union acpi_object *obj;
330
331
332 *levels = NULL;
333
334 status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer);
335 if (!ACPI_SUCCESS(status))
336 return status;
337 obj = (union acpi_object *)buffer.pointer;
338 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
339 printk(KERN_ERR PREFIX "Invalid _BCL data\n");
340 status = -EFAULT;
341 goto err;
342 }
343
344 *levels = obj;
345
346 return 0;
347
348 err:
349 kfree(buffer.pointer);
350
351 return status;
352}
353
354static int
355acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
356{
357 int status;
358 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
359 struct acpi_object_list args = { 1, &arg0 };
360 int state;
361
362 arg0.integer.value = level;
363
364 status = acpi_evaluate_object(device->dev->handle, "_BCM",
365 &args, NULL);
366 if (ACPI_FAILURE(status)) {
367 ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
368 return -EIO;
369 }
370
371 device->brightness->curr = level;
372 for (state = 2; state < device->brightness->count; state++)
373 if (level == device->brightness->levels[state]) {
374 if (device->backlight)
375 device->backlight->props.brightness = state - 2;
376 return 0;
377 }
378
379 ACPI_ERROR((AE_INFO, "Current brightness invalid"));
380 return -EINVAL;
381}
382
383
384
385
386
387
388static int bqc_offset_aml_bug_workaround;
389static int __init video_set_bqc_offset(const struct dmi_system_id *d)
390{
391 bqc_offset_aml_bug_workaround = 9;
392 return 0;
393}
394
395static int video_ignore_initial_backlight(const struct dmi_system_id *d)
396{
397 use_bios_initial_backlight = 0;
398 return 0;
399}
400
401static struct dmi_system_id video_dmi_table[] __initdata = {
402
403
404
405 {
406 .callback = video_set_bqc_offset,
407 .ident = "Acer Aspire 5720",
408 .matches = {
409 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
410 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
411 },
412 },
413 {
414 .callback = video_set_bqc_offset,
415 .ident = "Acer Aspire 5710Z",
416 .matches = {
417 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
418 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"),
419 },
420 },
421 {
422 .callback = video_set_bqc_offset,
423 .ident = "eMachines E510",
424 .matches = {
425 DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"),
426 DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"),
427 },
428 },
429 {
430 .callback = video_set_bqc_offset,
431 .ident = "Acer Aspire 5315",
432 .matches = {
433 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
434 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
435 },
436 },
437 {
438 .callback = video_set_bqc_offset,
439 .ident = "Acer Aspire 7720",
440 .matches = {
441 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
442 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"),
443 },
444 },
445 {
446 .callback = video_ignore_initial_backlight,
447 .ident = "HP Folio 13-2000",
448 .matches = {
449 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
450 DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13 - 2000 Notebook PC"),
451 },
452 },
453 {
454 .callback = video_ignore_initial_backlight,
455 .ident = "Fujitsu E753",
456 .matches = {
457 DMI_MATCH(DMI_BOARD_VENDOR, "FUJITSU"),
458 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E753"),
459 },
460 },
461 {
462 .callback = video_ignore_initial_backlight,
463 .ident = "HP Pavilion dm4",
464 .matches = {
465 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
466 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dm4 Notebook PC"),
467 },
468 },
469 {
470 .callback = video_ignore_initial_backlight,
471 .ident = "HP Pavilion g6 Notebook PC",
472 .matches = {
473 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
474 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion g6 Notebook PC"),
475 },
476 },
477 {
478 .callback = video_ignore_initial_backlight,
479 .ident = "HP 1000 Notebook PC",
480 .matches = {
481 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
482 DMI_MATCH(DMI_PRODUCT_NAME, "HP 1000 Notebook PC"),
483 },
484 },
485 {
486 .callback = video_ignore_initial_backlight,
487 .ident = "HP Pavilion m4",
488 .matches = {
489 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
490 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion m4 Notebook PC"),
491 },
492 },
493 {}
494};
495
496static unsigned long long
497acpi_video_bqc_value_to_level(struct acpi_video_device *device,
498 unsigned long long bqc_value)
499{
500 unsigned long long level;
501
502 if (device->brightness->flags._BQC_use_index) {
503
504
505
506
507
508 if (device->brightness->flags._BCL_reversed)
509 bqc_value = device->brightness->count - 3 - bqc_value;
510
511 level = device->brightness->levels[bqc_value + 2];
512 } else {
513 level = bqc_value;
514 }
515
516 level += bqc_offset_aml_bug_workaround;
517
518 return level;
519}
520
521static int
522acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
523 unsigned long long *level, bool raw)
524{
525 acpi_status status = AE_OK;
526 int i;
527
528 if (device->cap._BQC || device->cap._BCQ) {
529 char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
530
531 status = acpi_evaluate_integer(device->dev->handle, buf,
532 NULL, level);
533 if (ACPI_SUCCESS(status)) {
534 if (raw) {
535
536
537
538
539
540 return 0;
541 }
542
543 *level = acpi_video_bqc_value_to_level(device, *level);
544
545 for (i = 2; i < device->brightness->count; i++)
546 if (device->brightness->levels[i] == *level) {
547 device->brightness->curr = *level;
548 return 0;
549 }
550
551
552
553
554 ACPI_WARNING((AE_INFO,
555 "%s returned an invalid level",
556 buf));
557 device->cap._BQC = device->cap._BCQ = 0;
558 } else {
559
560
561
562
563
564
565
566 ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
567 device->cap._BQC = device->cap._BCQ = 0;
568 }
569 }
570
571 *level = device->brightness->curr;
572 return 0;
573}
574
575static int
576acpi_video_device_EDID(struct acpi_video_device *device,
577 union acpi_object **edid, ssize_t length)
578{
579 int status;
580 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
581 union acpi_object *obj;
582 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
583 struct acpi_object_list args = { 1, &arg0 };
584
585
586 *edid = NULL;
587
588 if (!device)
589 return -ENODEV;
590 if (length == 128)
591 arg0.integer.value = 1;
592 else if (length == 256)
593 arg0.integer.value = 2;
594 else
595 return -EINVAL;
596
597 status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer);
598 if (ACPI_FAILURE(status))
599 return -ENODEV;
600
601 obj = buffer.pointer;
602
603 if (obj && obj->type == ACPI_TYPE_BUFFER)
604 *edid = obj;
605 else {
606 printk(KERN_ERR PREFIX "Invalid _DDC data\n");
607 status = -EFAULT;
608 kfree(obj);
609 }
610
611 return status;
612}
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637static int
638acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
639{
640 acpi_status status;
641 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
642 struct acpi_object_list args = { 1, &arg0 };
643
644 if (!video->cap._DOS)
645 return 0;
646
647 if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1)
648 return -EINVAL;
649 arg0.integer.value = (lcd_flag << 2) | bios_flag;
650 video->dos_setting = arg0.integer.value;
651 status = acpi_evaluate_object(video->device->handle, "_DOS",
652 &args, NULL);
653 if (ACPI_FAILURE(status))
654 return -EIO;
655
656 return 0;
657}
658
659
660
661
662
663static int
664acpi_video_cmp_level(const void *a, const void *b)
665{
666 return *(int *)a - *(int *)b;
667}
668
669
670
671
672
673
674
675
676static int acpi_video_bqc_quirk(struct acpi_video_device *device,
677 int max_level, int current_level)
678{
679 struct acpi_video_device_brightness *br = device->brightness;
680 int result;
681 unsigned long long level;
682 int test_level;
683
684
685 if (bqc_offset_aml_bug_workaround)
686 return 0;
687
688
689
690
691
692 test_level = current_level == max_level ? br->levels[3] : max_level;
693
694 result = acpi_video_device_lcd_set_level(device, test_level);
695 if (result)
696 return result;
697
698 result = acpi_video_device_lcd_get_level_current(device, &level, true);
699 if (result)
700 return result;
701
702 if (level != test_level) {
703
704 if (level < br->count) {
705 if (br->flags._BCL_reversed)
706 level = br->count - 3 - level;
707 if (br->levels[level + 2] == test_level)
708 br->flags._BQC_use_index = 1;
709 }
710
711 if (!br->flags._BQC_use_index)
712 device->cap._BQC = device->cap._BCQ = 0;
713 }
714
715 return 0;
716}
717
718
719
720
721
722
723
724
725
726
727
728
729static int
730acpi_video_init_brightness(struct acpi_video_device *device)
731{
732 union acpi_object *obj = NULL;
733 int i, max_level = 0, count = 0, level_ac_battery = 0;
734 unsigned long long level, level_old;
735 union acpi_object *o;
736 struct acpi_video_device_brightness *br = NULL;
737 int result = -EINVAL;
738
739 if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
740 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
741 "LCD brightness level\n"));
742 goto out;
743 }
744
745 if (obj->package.count < 2)
746 goto out;
747
748 br = kzalloc(sizeof(*br), GFP_KERNEL);
749 if (!br) {
750 printk(KERN_ERR "can't allocate memory\n");
751 result = -ENOMEM;
752 goto out;
753 }
754
755 br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
756 GFP_KERNEL);
757 if (!br->levels) {
758 result = -ENOMEM;
759 goto out_free;
760 }
761
762 for (i = 0; i < obj->package.count; i++) {
763 o = (union acpi_object *)&obj->package.elements[i];
764 if (o->type != ACPI_TYPE_INTEGER) {
765 printk(KERN_ERR PREFIX "Invalid data\n");
766 continue;
767 }
768 br->levels[count] = (u32) o->integer.value;
769
770 if (br->levels[count] > max_level)
771 max_level = br->levels[count];
772 count++;
773 }
774
775
776
777
778
779
780
781 for (i = 2; i < count; i++) {
782 if (br->levels[i] == br->levels[0])
783 level_ac_battery++;
784 if (br->levels[i] == br->levels[1])
785 level_ac_battery++;
786 }
787
788 if (level_ac_battery < 2) {
789 level_ac_battery = 2 - level_ac_battery;
790 br->flags._BCL_no_ac_battery_levels = 1;
791 for (i = (count - 1 + level_ac_battery); i >= 2; i--)
792 br->levels[i] = br->levels[i - level_ac_battery];
793 count += level_ac_battery;
794 } else if (level_ac_battery > 2)
795 ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package"));
796
797
798 if (max_level == br->levels[2]) {
799 br->flags._BCL_reversed = 1;
800 sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
801 acpi_video_cmp_level, NULL);
802 } else if (max_level != br->levels[count - 1])
803 ACPI_ERROR((AE_INFO,
804 "Found unordered _BCL package"));
805
806 br->count = count;
807 device->brightness = br;
808
809
810 if ((max_level < 100) && (max_level <= (count - 2)))
811 br->flags._BCL_use_index = 1;
812
813
814
815
816
817 br->flags._BCM_use_index = br->flags._BCL_use_index;
818
819
820 br->curr = level = max_level;
821
822 if (!device->cap._BQC)
823 goto set_level;
824
825 result = acpi_video_device_lcd_get_level_current(device,
826 &level_old, true);
827 if (result)
828 goto out_free_levels;
829
830 result = acpi_video_bqc_quirk(device, max_level, level_old);
831 if (result)
832 goto out_free_levels;
833
834
835
836
837 if (!device->cap._BQC)
838 goto set_level;
839
840 if (use_bios_initial_backlight) {
841 level = acpi_video_bqc_value_to_level(device, level_old);
842
843
844
845
846
847
848 for (i = 2; i < br->count; i++)
849 if (level_old == br->levels[i])
850 break;
851 if (i == br->count)
852 level = max_level;
853 }
854
855set_level:
856 result = acpi_video_device_lcd_set_level(device, level);
857 if (result)
858 goto out_free_levels;
859
860 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
861 "found %d brightness levels\n", count - 2));
862 kfree(obj);
863 return result;
864
865out_free_levels:
866 kfree(br->levels);
867out_free:
868 kfree(br);
869out:
870 device->brightness = NULL;
871 kfree(obj);
872 return result;
873}
874
875
876
877
878
879
880
881
882
883
884
885
886static void acpi_video_device_find_cap(struct acpi_video_device *device)
887{
888 acpi_handle h_dummy1;
889
890 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) {
891 device->cap._ADR = 1;
892 }
893 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) {
894 device->cap._BCL = 1;
895 }
896 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
897 device->cap._BCM = 1;
898 }
899 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
900 device->cap._BQC = 1;
901 else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
902 &h_dummy1))) {
903 printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
904 device->cap._BCQ = 1;
905 }
906
907 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
908 device->cap._DDC = 1;
909 }
910
911 if (acpi_video_backlight_support()) {
912 struct backlight_properties props;
913 struct pci_dev *pdev;
914 acpi_handle acpi_parent;
915 struct device *parent = NULL;
916 int result;
917 static int count = 0;
918 char *name;
919
920 result = acpi_video_init_brightness(device);
921 if (result)
922 return;
923 name = kasprintf(GFP_KERNEL, "acpi_video%d", count);
924 if (!name)
925 return;
926 count++;
927
928 acpi_get_parent(device->dev->handle, &acpi_parent);
929
930 pdev = acpi_get_pci_dev(acpi_parent);
931 if (pdev) {
932 parent = &pdev->dev;
933 pci_dev_put(pdev);
934 }
935
936 memset(&props, 0, sizeof(struct backlight_properties));
937 props.type = BACKLIGHT_FIRMWARE;
938 props.max_brightness = device->brightness->count - 3;
939 device->backlight = backlight_device_register(name,
940 parent,
941 device,
942 &acpi_backlight_ops,
943 &props);
944 kfree(name);
945 if (IS_ERR(device->backlight))
946 return;
947
948
949
950
951
952 device->backlight->props.brightness =
953 acpi_video_get_brightness(device->backlight);
954
955 device->cooling_dev = thermal_cooling_device_register("LCD",
956 device->dev, &video_cooling_ops);
957 if (IS_ERR(device->cooling_dev)) {
958
959
960
961
962
963
964
965
966 device->cooling_dev = NULL;
967 return;
968 }
969
970 dev_info(&device->dev->dev, "registered as cooling_device%d\n",
971 device->cooling_dev->id);
972 result = sysfs_create_link(&device->dev->dev.kobj,
973 &device->cooling_dev->device.kobj,
974 "thermal_cooling");
975 if (result)
976 printk(KERN_ERR PREFIX "Create sysfs link\n");
977 result = sysfs_create_link(&device->cooling_dev->device.kobj,
978 &device->dev->dev.kobj, "device");
979 if (result)
980 printk(KERN_ERR PREFIX "Create sysfs link\n");
981
982 }
983}
984
985
986
987
988
989
990
991
992
993
994
995static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
996{
997 acpi_handle h_dummy1;
998
999 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) {
1000 video->cap._DOS = 1;
1001 }
1002 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) {
1003 video->cap._DOD = 1;
1004 }
1005 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) {
1006 video->cap._ROM = 1;
1007 }
1008 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) {
1009 video->cap._GPD = 1;
1010 }
1011 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) {
1012 video->cap._SPD = 1;
1013 }
1014 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) {
1015 video->cap._VPO = 1;
1016 }
1017}
1018
1019
1020
1021
1022
1023
1024static int acpi_video_bus_check(struct acpi_video_bus *video)
1025{
1026 acpi_status status = -ENOENT;
1027 struct pci_dev *dev;
1028
1029 if (!video)
1030 return -EINVAL;
1031
1032 dev = acpi_get_pci_dev(video->device->handle);
1033 if (!dev)
1034 return -ENODEV;
1035 pci_dev_put(dev);
1036
1037
1038
1039
1040
1041
1042 if (video->cap._DOS || video->cap._DOD) {
1043 if (!video->cap._DOS) {
1044 printk(KERN_WARNING FW_BUG
1045 "ACPI(%s) defines _DOD but not _DOS\n",
1046 acpi_device_bid(video->device));
1047 }
1048 video->flags.multihead = 1;
1049 status = 0;
1050 }
1051
1052
1053 if (video->cap._ROM) {
1054 video->flags.rom = 1;
1055 status = 0;
1056 }
1057
1058
1059 if (video->cap._GPD && video->cap._SPD && video->cap._VPO) {
1060 video->flags.post = 1;
1061 status = 0;
1062 }
1063
1064 return status;
1065}
1066
1067
1068
1069
1070
1071
1072static struct acpi_video_device_attrib*
1073acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1074{
1075 struct acpi_video_enumerated_device *ids;
1076 int i;
1077
1078 for (i = 0; i < video->attached_count; i++) {
1079 ids = &video->attached_array[i];
1080 if ((ids->value.int_val & 0xffff) == device_id)
1081 return &ids->value.attrib;
1082 }
1083
1084 return NULL;
1085}
1086
1087static int
1088acpi_video_get_device_type(struct acpi_video_bus *video,
1089 unsigned long device_id)
1090{
1091 struct acpi_video_enumerated_device *ids;
1092 int i;
1093
1094 for (i = 0; i < video->attached_count; i++) {
1095 ids = &video->attached_array[i];
1096 if ((ids->value.int_val & 0xffff) == device_id)
1097 return ids->value.int_val;
1098 }
1099
1100 return 0;
1101}
1102
1103static int
1104acpi_video_bus_get_one_device(struct acpi_device *device,
1105 struct acpi_video_bus *video)
1106{
1107 unsigned long long device_id;
1108 int status, device_type;
1109 struct acpi_video_device *data;
1110 struct acpi_video_device_attrib* attribute;
1111
1112 status =
1113 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
1114
1115 if (ACPI_FAILURE(status))
1116 return 0;
1117
1118 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
1119 if (!data)
1120 return -ENOMEM;
1121
1122 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
1123 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1124 device->driver_data = data;
1125
1126 data->device_id = device_id;
1127 data->video = video;
1128 data->dev = device;
1129
1130 attribute = acpi_video_get_device_attr(video, device_id);
1131
1132 if((attribute != NULL) && attribute->device_id_scheme) {
1133 switch (attribute->display_type) {
1134 case ACPI_VIDEO_DISPLAY_CRT:
1135 data->flags.crt = 1;
1136 break;
1137 case ACPI_VIDEO_DISPLAY_TV:
1138 data->flags.tvout = 1;
1139 break;
1140 case ACPI_VIDEO_DISPLAY_DVI:
1141 data->flags.dvi = 1;
1142 break;
1143 case ACPI_VIDEO_DISPLAY_LCD:
1144 data->flags.lcd = 1;
1145 break;
1146 default:
1147 data->flags.unknown = 1;
1148 break;
1149 }
1150 if(attribute->bios_can_detect)
1151 data->flags.bios = 1;
1152 } else {
1153
1154 device_type = acpi_video_get_device_type(video, device_id);
1155
1156 switch (device_type & 0xffe2ffff) {
1157 case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR:
1158 data->flags.crt = 1;
1159 break;
1160 case ACPI_VIDEO_DISPLAY_LEGACY_PANEL:
1161 data->flags.lcd = 1;
1162 break;
1163 case ACPI_VIDEO_DISPLAY_LEGACY_TV:
1164 data->flags.tvout = 1;
1165 break;
1166 default:
1167 data->flags.unknown = 1;
1168 }
1169 }
1170
1171 acpi_video_device_bind(video, data);
1172 acpi_video_device_find_cap(data);
1173
1174 status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
1175 acpi_video_device_notify, data);
1176 if (ACPI_FAILURE(status))
1177 dev_err(&device->dev, "Error installing notify handler\n");
1178 else
1179 data->flags.notify = 1;
1180
1181 mutex_lock(&video->device_list_lock);
1182 list_add_tail(&data->entry, &video->video_device_list);
1183 mutex_unlock(&video->device_list_lock);
1184
1185 return status;
1186}
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200static void acpi_video_device_rebind(struct acpi_video_bus *video)
1201{
1202 struct acpi_video_device *dev;
1203
1204 mutex_lock(&video->device_list_lock);
1205
1206 list_for_each_entry(dev, &video->video_device_list, entry)
1207 acpi_video_device_bind(video, dev);
1208
1209 mutex_unlock(&video->device_list_lock);
1210}
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225static void
1226acpi_video_device_bind(struct acpi_video_bus *video,
1227 struct acpi_video_device *device)
1228{
1229 struct acpi_video_enumerated_device *ids;
1230 int i;
1231
1232 for (i = 0; i < video->attached_count; i++) {
1233 ids = &video->attached_array[i];
1234 if (device->device_id == (ids->value.int_val & 0xffff)) {
1235 ids->bind_info = device;
1236 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
1237 }
1238 }
1239}
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1253{
1254 int status;
1255 int count;
1256 int i;
1257 struct acpi_video_enumerated_device *active_list;
1258 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1259 union acpi_object *dod = NULL;
1260 union acpi_object *obj;
1261
1262 status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer);
1263 if (!ACPI_SUCCESS(status)) {
1264 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD"));
1265 return status;
1266 }
1267
1268 dod = buffer.pointer;
1269 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
1270 ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
1271 status = -EFAULT;
1272 goto out;
1273 }
1274
1275 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
1276 dod->package.count));
1277
1278 active_list = kcalloc(1 + dod->package.count,
1279 sizeof(struct acpi_video_enumerated_device),
1280 GFP_KERNEL);
1281 if (!active_list) {
1282 status = -ENOMEM;
1283 goto out;
1284 }
1285
1286 count = 0;
1287 for (i = 0; i < dod->package.count; i++) {
1288 obj = &dod->package.elements[i];
1289
1290 if (obj->type != ACPI_TYPE_INTEGER) {
1291 printk(KERN_ERR PREFIX
1292 "Invalid _DOD data in element %d\n", i);
1293 continue;
1294 }
1295
1296 active_list[count].value.int_val = obj->integer.value;
1297 active_list[count].bind_info = NULL;
1298 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
1299 (int)obj->integer.value));
1300 count++;
1301 }
1302
1303 kfree(video->attached_array);
1304
1305 video->attached_array = active_list;
1306 video->attached_count = count;
1307
1308 out:
1309 kfree(buffer.pointer);
1310 return status;
1311}
1312
1313static int
1314acpi_video_get_next_level(struct acpi_video_device *device,
1315 u32 level_current, u32 event)
1316{
1317 int min, max, min_above, max_below, i, l, delta = 255;
1318 max = max_below = 0;
1319 min = min_above = 255;
1320
1321 for (i = 2; i < device->brightness->count; i++) {
1322 l = device->brightness->levels[i];
1323 if (abs(l - level_current) < abs(delta)) {
1324 delta = l - level_current;
1325 if (!delta)
1326 break;
1327 }
1328 }
1329
1330 level_current += delta;
1331 for (i = 2; i < device->brightness->count; i++) {
1332 l = device->brightness->levels[i];
1333 if (l < min)
1334 min = l;
1335 if (l > max)
1336 max = l;
1337 if (l < min_above && l > level_current)
1338 min_above = l;
1339 if (l > max_below && l < level_current)
1340 max_below = l;
1341 }
1342
1343 switch (event) {
1344 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
1345 return (level_current < max) ? min_above : min;
1346 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
1347 return (level_current < max) ? min_above : max;
1348 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
1349 return (level_current > min) ? max_below : min;
1350 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
1351 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
1352 return 0;
1353 default:
1354 return level_current;
1355 }
1356}
1357
1358static int
1359acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1360{
1361 unsigned long long level_current, level_next;
1362 int result = -EINVAL;
1363
1364
1365 if (!acpi_video_backlight_support())
1366 return 0;
1367
1368 if (!device->brightness)
1369 goto out;
1370
1371 result = acpi_video_device_lcd_get_level_current(device,
1372 &level_current,
1373 false);
1374 if (result)
1375 goto out;
1376
1377 level_next = acpi_video_get_next_level(device, level_current, event);
1378
1379 result = acpi_video_device_lcd_set_level(device, level_next);
1380
1381 if (!result)
1382 backlight_force_update(device->backlight,
1383 BACKLIGHT_UPDATE_HOTKEY);
1384
1385out:
1386 if (result)
1387 printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
1388
1389 return result;
1390}
1391
1392int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
1393 void **edid)
1394{
1395 struct acpi_video_bus *video;
1396 struct acpi_video_device *video_device;
1397 union acpi_object *buffer = NULL;
1398 acpi_status status;
1399 int i, length;
1400
1401 if (!device || !acpi_driver_data(device))
1402 return -EINVAL;
1403
1404 video = acpi_driver_data(device);
1405
1406 for (i = 0; i < video->attached_count; i++) {
1407 video_device = video->attached_array[i].bind_info;
1408 length = 256;
1409
1410 if (!video_device)
1411 continue;
1412
1413 if (!video_device->cap._DDC)
1414 continue;
1415
1416 if (type) {
1417 switch (type) {
1418 case ACPI_VIDEO_DISPLAY_CRT:
1419 if (!video_device->flags.crt)
1420 continue;
1421 break;
1422 case ACPI_VIDEO_DISPLAY_TV:
1423 if (!video_device->flags.tvout)
1424 continue;
1425 break;
1426 case ACPI_VIDEO_DISPLAY_DVI:
1427 if (!video_device->flags.dvi)
1428 continue;
1429 break;
1430 case ACPI_VIDEO_DISPLAY_LCD:
1431 if (!video_device->flags.lcd)
1432 continue;
1433 break;
1434 }
1435 } else if (video_device->device_id != device_id) {
1436 continue;
1437 }
1438
1439 status = acpi_video_device_EDID(video_device, &buffer, length);
1440
1441 if (ACPI_FAILURE(status) || !buffer ||
1442 buffer->type != ACPI_TYPE_BUFFER) {
1443 length = 128;
1444 status = acpi_video_device_EDID(video_device, &buffer,
1445 length);
1446 if (ACPI_FAILURE(status) || !buffer ||
1447 buffer->type != ACPI_TYPE_BUFFER) {
1448 continue;
1449 }
1450 }
1451
1452 *edid = buffer->buffer.pointer;
1453 return length;
1454 }
1455
1456 return -ENODEV;
1457}
1458EXPORT_SYMBOL(acpi_video_get_edid);
1459
1460static int
1461acpi_video_bus_get_devices(struct acpi_video_bus *video,
1462 struct acpi_device *device)
1463{
1464 int status = 0;
1465 struct acpi_device *dev;
1466
1467
1468
1469
1470
1471
1472 acpi_video_device_enumerate(video);
1473
1474 list_for_each_entry(dev, &device->children, node) {
1475
1476 status = acpi_video_bus_get_one_device(dev, video);
1477 if (status) {
1478 dev_err(&dev->dev, "Can't attach device\n");
1479 break;
1480 }
1481 }
1482 return status;
1483}
1484
1485static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1486{
1487 acpi_status status;
1488
1489 if (!device || !device->video)
1490 return -ENOENT;
1491
1492 if (device->flags.notify) {
1493 status = acpi_remove_notify_handler(device->dev->handle,
1494 ACPI_DEVICE_NOTIFY, acpi_video_device_notify);
1495 if (ACPI_FAILURE(status))
1496 dev_err(&device->dev->dev,
1497 "Can't remove video notify handler\n");
1498 }
1499
1500 if (device->backlight) {
1501 backlight_device_unregister(device->backlight);
1502 device->backlight = NULL;
1503 }
1504 if (device->cooling_dev) {
1505 sysfs_remove_link(&device->dev->dev.kobj,
1506 "thermal_cooling");
1507 sysfs_remove_link(&device->cooling_dev->device.kobj,
1508 "device");
1509 thermal_cooling_device_unregister(device->cooling_dev);
1510 device->cooling_dev = NULL;
1511 }
1512
1513 return 0;
1514}
1515
1516static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1517{
1518 int status;
1519 struct acpi_video_device *dev, *next;
1520
1521 mutex_lock(&video->device_list_lock);
1522
1523 list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
1524
1525 status = acpi_video_bus_put_one_device(dev);
1526 if (ACPI_FAILURE(status))
1527 printk(KERN_WARNING PREFIX
1528 "hhuuhhuu bug in acpi video driver.\n");
1529
1530 if (dev->brightness) {
1531 kfree(dev->brightness->levels);
1532 kfree(dev->brightness);
1533 }
1534 list_del(&dev->entry);
1535 kfree(dev);
1536 }
1537
1538 mutex_unlock(&video->device_list_lock);
1539
1540 return 0;
1541}
1542
1543
1544
1545
1546
1547
1548
1549static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
1550{
1551 return acpi_video_bus_DOS(video, 0,
1552 acpi_video_backlight_quirks() ? 1 : 0);
1553}
1554
1555static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
1556{
1557 return acpi_video_bus_DOS(video, 0,
1558 acpi_video_backlight_quirks() ? 0 : 1);
1559}
1560
1561static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
1562{
1563 struct acpi_video_bus *video = acpi_driver_data(device);
1564 struct input_dev *input;
1565 int keycode = 0;
1566
1567 if (!video)
1568 return;
1569
1570 input = video->input;
1571
1572 switch (event) {
1573 case ACPI_VIDEO_NOTIFY_SWITCH:
1574
1575 acpi_bus_generate_proc_event(device, event, 0);
1576 keycode = KEY_SWITCHVIDEOMODE;
1577 break;
1578
1579 case ACPI_VIDEO_NOTIFY_PROBE:
1580
1581 acpi_video_device_enumerate(video);
1582 acpi_video_device_rebind(video);
1583 acpi_bus_generate_proc_event(device, event, 0);
1584 keycode = KEY_SWITCHVIDEOMODE;
1585 break;
1586
1587 case ACPI_VIDEO_NOTIFY_CYCLE:
1588 acpi_bus_generate_proc_event(device, event, 0);
1589 keycode = KEY_SWITCHVIDEOMODE;
1590 break;
1591 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:
1592 acpi_bus_generate_proc_event(device, event, 0);
1593 keycode = KEY_VIDEO_NEXT;
1594 break;
1595 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT:
1596 acpi_bus_generate_proc_event(device, event, 0);
1597 keycode = KEY_VIDEO_PREV;
1598 break;
1599
1600 default:
1601 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1602 "Unsupported event [0x%x]\n", event));
1603 break;
1604 }
1605
1606 if (acpi_notifier_call_chain(device, event, 0))
1607
1608 keycode = 0;
1609
1610 if (keycode) {
1611 input_report_key(input, keycode, 1);
1612 input_sync(input);
1613 input_report_key(input, keycode, 0);
1614 input_sync(input);
1615 }
1616
1617 return;
1618}
1619
1620static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1621{
1622 struct acpi_video_device *video_device = data;
1623 struct acpi_device *device = NULL;
1624 struct acpi_video_bus *bus;
1625 struct input_dev *input;
1626 int keycode = 0;
1627
1628 if (!video_device)
1629 return;
1630
1631 device = video_device->dev;
1632 bus = video_device->video;
1633 input = bus->input;
1634
1635 switch (event) {
1636 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
1637 if (brightness_switch_enabled)
1638 acpi_video_switch_brightness(video_device, event);
1639 acpi_bus_generate_proc_event(device, event, 0);
1640 keycode = KEY_BRIGHTNESS_CYCLE;
1641 break;
1642 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
1643 if (brightness_switch_enabled)
1644 acpi_video_switch_brightness(video_device, event);
1645 acpi_bus_generate_proc_event(device, event, 0);
1646 keycode = KEY_BRIGHTNESSUP;
1647 break;
1648 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
1649 if (brightness_switch_enabled)
1650 acpi_video_switch_brightness(video_device, event);
1651 acpi_bus_generate_proc_event(device, event, 0);
1652 keycode = KEY_BRIGHTNESSDOWN;
1653 break;
1654 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
1655 if (brightness_switch_enabled)
1656 acpi_video_switch_brightness(video_device, event);
1657 acpi_bus_generate_proc_event(device, event, 0);
1658 keycode = KEY_BRIGHTNESS_ZERO;
1659 break;
1660 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
1661 if (brightness_switch_enabled)
1662 acpi_video_switch_brightness(video_device, event);
1663 acpi_bus_generate_proc_event(device, event, 0);
1664 keycode = KEY_DISPLAY_OFF;
1665 break;
1666 default:
1667 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1668 "Unsupported event [0x%x]\n", event));
1669 break;
1670 }
1671
1672 acpi_notifier_call_chain(device, event, 0);
1673
1674 if (keycode) {
1675 input_report_key(input, keycode, 1);
1676 input_sync(input);
1677 input_report_key(input, keycode, 0);
1678 input_sync(input);
1679 }
1680
1681 return;
1682}
1683
1684static int acpi_video_resume(struct notifier_block *nb,
1685 unsigned long val, void *ign)
1686{
1687 struct acpi_video_bus *video;
1688 struct acpi_video_device *video_device;
1689 int i;
1690
1691 switch (val) {
1692 case PM_HIBERNATION_PREPARE:
1693 case PM_SUSPEND_PREPARE:
1694 case PM_RESTORE_PREPARE:
1695 return NOTIFY_DONE;
1696 }
1697
1698 video = container_of(nb, struct acpi_video_bus, pm_nb);
1699
1700 dev_info(&video->device->dev, "Restoring backlight state\n");
1701
1702 for (i = 0; i < video->attached_count; i++) {
1703 video_device = video->attached_array[i].bind_info;
1704 if (video_device && video_device->backlight)
1705 acpi_video_set_brightness(video_device->backlight);
1706 }
1707
1708 return NOTIFY_OK;
1709}
1710
1711static acpi_status
1712acpi_video_bus_match(acpi_handle handle, u32 level, void *context,
1713 void **return_value)
1714{
1715 struct acpi_device *device = context;
1716 struct acpi_device *sibling;
1717 int result;
1718
1719 if (handle == device->handle)
1720 return AE_CTRL_TERMINATE;
1721
1722 result = acpi_bus_get_device(handle, &sibling);
1723 if (result)
1724 return AE_OK;
1725
1726 if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME))
1727 return AE_ALREADY_EXISTS;
1728
1729 return AE_OK;
1730}
1731
1732static int instance;
1733
1734static int acpi_video_bus_add(struct acpi_device *device)
1735{
1736 struct acpi_video_bus *video;
1737 struct input_dev *input;
1738 int error;
1739 acpi_status status;
1740
1741 status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
1742 device->parent->handle, 1,
1743 acpi_video_bus_match, NULL,
1744 device, NULL);
1745 if (status == AE_ALREADY_EXISTS) {
1746 printk(KERN_WARNING FW_BUG
1747 "Duplicate ACPI video bus devices for the"
1748 " same VGA controller, please try module "
1749 "parameter \"video.allow_duplicates=1\""
1750 "if the current driver doesn't work.\n");
1751 if (!allow_duplicates)
1752 return -ENODEV;
1753 }
1754
1755 video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
1756 if (!video)
1757 return -ENOMEM;
1758
1759
1760 if (!strcmp(device->pnp.bus_id, "VID")) {
1761 if (instance)
1762 device->pnp.bus_id[3] = '0' + instance;
1763 instance ++;
1764 }
1765
1766 if (!strcmp(device->pnp.bus_id, "VGA")) {
1767 if (instance)
1768 device->pnp.bus_id[3] = '0' + instance;
1769 instance++;
1770 }
1771
1772 video->device = device;
1773 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
1774 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1775 device->driver_data = video;
1776
1777 acpi_video_bus_find_cap(video);
1778 error = acpi_video_bus_check(video);
1779 if (error)
1780 goto err_free_video;
1781
1782 mutex_init(&video->device_list_lock);
1783 INIT_LIST_HEAD(&video->video_device_list);
1784
1785 error = acpi_video_bus_get_devices(video, device);
1786 if (error)
1787 goto err_put_video;
1788
1789 video->input = input = input_allocate_device();
1790 if (!input) {
1791 error = -ENOMEM;
1792 goto err_put_video;
1793 }
1794
1795 error = acpi_video_bus_start_devices(video);
1796 if (error)
1797 goto err_free_input_dev;
1798
1799 snprintf(video->phys, sizeof(video->phys),
1800 "%s/video/input0", acpi_device_hid(video->device));
1801
1802 input->name = acpi_device_name(video->device);
1803 input->phys = video->phys;
1804 input->id.bustype = BUS_HOST;
1805 input->id.product = 0x06;
1806 input->dev.parent = &device->dev;
1807 input->evbit[0] = BIT(EV_KEY);
1808 set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
1809 set_bit(KEY_VIDEO_NEXT, input->keybit);
1810 set_bit(KEY_VIDEO_PREV, input->keybit);
1811 set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);
1812 set_bit(KEY_BRIGHTNESSUP, input->keybit);
1813 set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
1814 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
1815 set_bit(KEY_DISPLAY_OFF, input->keybit);
1816
1817 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
1818 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
1819 video->flags.multihead ? "yes" : "no",
1820 video->flags.rom ? "yes" : "no",
1821 video->flags.post ? "yes" : "no");
1822
1823 video->pm_nb.notifier_call = acpi_video_resume;
1824 video->pm_nb.priority = 0;
1825 error = register_pm_notifier(&video->pm_nb);
1826 if (error)
1827 goto err_stop_video;
1828
1829 error = input_register_device(input);
1830 if (error)
1831 goto err_unregister_pm_notifier;
1832
1833 return 0;
1834
1835 err_unregister_pm_notifier:
1836 unregister_pm_notifier(&video->pm_nb);
1837 err_stop_video:
1838 acpi_video_bus_stop_devices(video);
1839 err_free_input_dev:
1840 input_free_device(input);
1841 err_put_video:
1842 acpi_video_bus_put_devices(video);
1843 kfree(video->attached_array);
1844 err_free_video:
1845 kfree(video);
1846 device->driver_data = NULL;
1847
1848 return error;
1849}
1850
1851static int acpi_video_bus_remove(struct acpi_device *device)
1852{
1853 struct acpi_video_bus *video = NULL;
1854
1855
1856 if (!device || !acpi_driver_data(device))
1857 return -EINVAL;
1858
1859 video = acpi_driver_data(device);
1860
1861 unregister_pm_notifier(&video->pm_nb);
1862
1863 acpi_video_bus_stop_devices(video);
1864 acpi_video_bus_put_devices(video);
1865
1866 input_unregister_device(video->input);
1867 kfree(video->attached_array);
1868 kfree(video);
1869
1870 return 0;
1871}
1872
1873static int __init is_i740(struct pci_dev *dev)
1874{
1875 if (dev->device == 0x00D1)
1876 return 1;
1877 if (dev->device == 0x7000)
1878 return 1;
1879 return 0;
1880}
1881
1882static int __init intel_opregion_present(void)
1883{
1884 int opregion = 0;
1885 struct pci_dev *dev = NULL;
1886 u32 address;
1887
1888 for_each_pci_dev(dev) {
1889 if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
1890 continue;
1891 if (dev->vendor != PCI_VENDOR_ID_INTEL)
1892 continue;
1893
1894 if (is_i740(dev))
1895 continue;
1896 pci_read_config_dword(dev, 0xfc, &address);
1897 if (!address)
1898 continue;
1899 opregion = 1;
1900 }
1901 return opregion;
1902}
1903
1904int acpi_video_register(void)
1905{
1906 int result = 0;
1907 if (register_count) {
1908
1909
1910
1911
1912 return 0;
1913 }
1914
1915 result = acpi_bus_register_driver(&acpi_video_bus);
1916 if (result < 0)
1917 return -ENODEV;
1918
1919
1920
1921
1922
1923 register_count = 1;
1924
1925 return 0;
1926}
1927EXPORT_SYMBOL(acpi_video_register);
1928
1929void acpi_video_unregister(void)
1930{
1931 if (!register_count) {
1932
1933
1934
1935
1936 return;
1937 }
1938 acpi_bus_unregister_driver(&acpi_video_bus);
1939
1940 register_count = 0;
1941
1942 return;
1943}
1944EXPORT_SYMBOL(acpi_video_unregister);
1945
1946
1947
1948
1949
1950
1951
1952
1953static int __init acpi_video_init(void)
1954{
1955 dmi_check_system(video_dmi_table);
1956
1957 if (intel_opregion_present())
1958 return 0;
1959
1960 return acpi_video_register();
1961}
1962
1963static void __exit acpi_video_exit(void)
1964{
1965 acpi_video_unregister();
1966
1967 return;
1968}
1969
1970module_init(acpi_video_init);
1971module_exit(acpi_video_exit);
1972