aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r--drivers/acpi/video.c301
1 files changed, 235 insertions, 66 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index bb5ed059114a..100c8eeaa5dd 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -37,6 +37,8 @@
37#include <linux/thermal.h> 37#include <linux/thermal.h>
38#include <linux/video_output.h> 38#include <linux/video_output.h>
39#include <linux/sort.h> 39#include <linux/sort.h>
40#include <linux/pci.h>
41#include <linux/pci_ids.h>
40#include <asm/uaccess.h> 42#include <asm/uaccess.h>
41 43
42#include <acpi/acpi_bus.h> 44#include <acpi/acpi_bus.h>
@@ -162,16 +164,26 @@ struct acpi_video_device_cap {
162 u8 _BCL:1; /*Query list of brightness control levels supported */ 164 u8 _BCL:1; /*Query list of brightness control levels supported */
163 u8 _BCM:1; /*Set the brightness level */ 165 u8 _BCM:1; /*Set the brightness level */
164 u8 _BQC:1; /* Get current brightness level */ 166 u8 _BQC:1; /* Get current brightness level */
167 u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */
165 u8 _DDC:1; /*Return the EDID for this device */ 168 u8 _DDC:1; /*Return the EDID for this device */
166 u8 _DCS:1; /*Return status of output device */ 169 u8 _DCS:1; /*Return status of output device */
167 u8 _DGS:1; /*Query graphics state */ 170 u8 _DGS:1; /*Query graphics state */
168 u8 _DSS:1; /*Device state set */ 171 u8 _DSS:1; /*Device state set */
169}; 172};
170 173
174struct acpi_video_brightness_flags {
175 u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
176 u8 _BCL_reversed:1; /* _BCL package is in a reversed order*/
177 u8 _BCL_use_index:1; /* levels in _BCL are index values */
178 u8 _BCM_use_index:1; /* input of _BCM is an index value */
179 u8 _BQC_use_index:1; /* _BQC returns an index value */
180};
181
171struct acpi_video_device_brightness { 182struct acpi_video_device_brightness {
172 int curr; 183 int curr;
173 int count; 184 int count;
174 int *levels; 185 int *levels;
186 struct acpi_video_brightness_flags flags;
175}; 187};
176 188
177struct acpi_video_device { 189struct acpi_video_device {
@@ -294,7 +306,7 @@ static int acpi_video_device_lcd_get_level_current(
294 unsigned long long *level); 306 unsigned long long *level);
295static int acpi_video_get_next_level(struct acpi_video_device *device, 307static int acpi_video_get_next_level(struct acpi_video_device *device,
296 u32 level_current, u32 event); 308 u32 level_current, u32 event);
297static void acpi_video_switch_brightness(struct acpi_video_device *device, 309static int acpi_video_switch_brightness(struct acpi_video_device *device,
298 int event); 310 int event);
299static int acpi_video_device_get_state(struct acpi_video_device *device, 311static int acpi_video_device_get_state(struct acpi_video_device *device,
300 unsigned long long *state); 312 unsigned long long *state);
@@ -308,7 +320,9 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
308 int i; 320 int i;
309 struct acpi_video_device *vd = 321 struct acpi_video_device *vd =
310 (struct acpi_video_device *)bl_get_data(bd); 322 (struct acpi_video_device *)bl_get_data(bd);
311 acpi_video_device_lcd_get_level_current(vd, &cur_level); 323
324 if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
325 return -EINVAL;
312 for (i = 2; i < vd->brightness->count; i++) { 326 for (i = 2; i < vd->brightness->count; i++) {
313 if (vd->brightness->levels[i] == cur_level) 327 if (vd->brightness->levels[i] == cur_level)
314 /* The first two entries are special - see page 575 328 /* The first two entries are special - see page 575
@@ -320,12 +334,12 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
320 334
321static int acpi_video_set_brightness(struct backlight_device *bd) 335static int acpi_video_set_brightness(struct backlight_device *bd)
322{ 336{
323 int request_level = bd->props.brightness+2; 337 int request_level = bd->props.brightness + 2;
324 struct acpi_video_device *vd = 338 struct acpi_video_device *vd =
325 (struct acpi_video_device *)bl_get_data(bd); 339 (struct acpi_video_device *)bl_get_data(bd);
326 acpi_video_device_lcd_set_level(vd, 340
327 vd->brightness->levels[request_level]); 341 return acpi_video_device_lcd_set_level(vd,
328 return 0; 342 vd->brightness->levels[request_level]);
329} 343}
330 344
331static struct backlight_ops acpi_backlight_ops = { 345static struct backlight_ops acpi_backlight_ops = {
@@ -358,32 +372,37 @@ static struct output_properties acpi_output_properties = {
358 372
359 373
360/* thermal cooling device callbacks */ 374/* thermal cooling device callbacks */
361static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf) 375static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
376 long *state)
362{ 377{
363 struct acpi_device *device = cdev->devdata; 378 struct acpi_device *device = cdev->devdata;
364 struct acpi_video_device *video = acpi_driver_data(device); 379 struct acpi_video_device *video = acpi_driver_data(device);
365 380
366 return sprintf(buf, "%d\n", video->brightness->count - 3); 381 *state = video->brightness->count - 3;
382 return 0;
367} 383}
368 384
369static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf) 385static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
386 long *state)
370{ 387{
371 struct acpi_device *device = cdev->devdata; 388 struct acpi_device *device = cdev->devdata;
372 struct acpi_video_device *video = acpi_driver_data(device); 389 struct acpi_video_device *video = acpi_driver_data(device);
373 unsigned long long level; 390 unsigned long long level;
374 int state; 391 int offset;
375 392
376 acpi_video_device_lcd_get_level_current(video, &level); 393 if (acpi_video_device_lcd_get_level_current(video, &level))
377 for (state = 2; state < video->brightness->count; state++) 394 return -EINVAL;
378 if (level == video->brightness->levels[state]) 395 for (offset = 2; offset < video->brightness->count; offset++)
379 return sprintf(buf, "%d\n", 396 if (level == video->brightness->levels[offset]) {
380 video->brightness->count - state - 1); 397 *state = video->brightness->count - offset - 1;
398 return 0;
399 }
381 400
382 return -EINVAL; 401 return -EINVAL;
383} 402}
384 403
385static int 404static int
386video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) 405video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
387{ 406{
388 struct acpi_device *device = cdev->devdata; 407 struct acpi_device *device = cdev->devdata;
389 struct acpi_video_device *video = acpi_driver_data(device); 408 struct acpi_video_device *video = acpi_driver_data(device);
@@ -479,34 +498,68 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
479static int 498static int
480acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) 499acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
481{ 500{
482 int status = AE_OK; 501 int status;
483 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 502 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
484 struct acpi_object_list args = { 1, &arg0 }; 503 struct acpi_object_list args = { 1, &arg0 };
485 int state; 504 int state;
486 505
487
488 arg0.integer.value = level; 506 arg0.integer.value = level;
489 507
490 if (device->cap._BCM) 508 status = acpi_evaluate_object(device->dev->handle, "_BCM",
491 status = acpi_evaluate_object(device->dev->handle, "_BCM", 509 &args, NULL);
492 &args, NULL); 510 if (ACPI_FAILURE(status)) {
511 ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
512 return -EIO;
513 }
514
493 device->brightness->curr = level; 515 device->brightness->curr = level;
494 for (state = 2; state < device->brightness->count; state++) 516 for (state = 2; state < device->brightness->count; state++)
495 if (level == device->brightness->levels[state]) 517 if (level == device->brightness->levels[state]) {
496 device->backlight->props.brightness = state - 2; 518 if (device->backlight)
519 device->backlight->props.brightness = state - 2;
520 return 0;
521 }
497 522
498 return status; 523 ACPI_ERROR((AE_INFO, "Current brightness invalid"));
524 return -EINVAL;
499} 525}
500 526
501static int 527static int
502acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, 528acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
503 unsigned long long *level) 529 unsigned long long *level)
504{ 530{
505 if (device->cap._BQC) 531 acpi_status status = AE_OK;
506 return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, 532
507 level); 533 if (device->cap._BQC || device->cap._BCQ) {
534 char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
535
536 status = acpi_evaluate_integer(device->dev->handle, buf,
537 NULL, level);
538 if (ACPI_SUCCESS(status)) {
539 if (device->brightness->flags._BQC_use_index) {
540 if (device->brightness->flags._BCL_reversed)
541 *level = device->brightness->count
542 - 3 - (*level);
543 *level = device->brightness->levels[*level + 2];
544
545 }
546 device->brightness->curr = *level;
547 return 0;
548 } else {
549 /* Fixme:
550 * should we return an error or ignore this failure?
551 * dev->brightness->curr is a cached value which stores
552 * the correct current backlight level in most cases.
553 * ACPI video backlight still works w/ buggy _BQC.
554 * http://bugzilla.kernel.org/show_bug.cgi?id=12233
555 */
556 ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
557 device->cap._BQC = device->cap._BCQ = 0;
558 }
559 }
560
508 *level = device->brightness->curr; 561 *level = device->brightness->curr;
509 return AE_OK; 562 return 0;
510} 563}
511 564
512static int 565static int
@@ -655,9 +708,11 @@ static int
655acpi_video_init_brightness(struct acpi_video_device *device) 708acpi_video_init_brightness(struct acpi_video_device *device)
656{ 709{
657 union acpi_object *obj = NULL; 710 union acpi_object *obj = NULL;
658 int i, max_level = 0, count = 0; 711 int i, max_level = 0, count = 0, level_ac_battery = 0;
712 unsigned long long level, level_old;
659 union acpi_object *o; 713 union acpi_object *o;
660 struct acpi_video_device_brightness *br = NULL; 714 struct acpi_video_device_brightness *br = NULL;
715 int result = -EINVAL;
661 716
662 if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { 717 if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
663 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " 718 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
@@ -671,13 +726,16 @@ acpi_video_init_brightness(struct acpi_video_device *device)
671 br = kzalloc(sizeof(*br), GFP_KERNEL); 726 br = kzalloc(sizeof(*br), GFP_KERNEL);
672 if (!br) { 727 if (!br) {
673 printk(KERN_ERR "can't allocate memory\n"); 728 printk(KERN_ERR "can't allocate memory\n");
729 result = -ENOMEM;
674 goto out; 730 goto out;
675 } 731 }
676 732
677 br->levels = kmalloc(obj->package.count * sizeof *(br->levels), 733 br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
678 GFP_KERNEL); 734 GFP_KERNEL);
679 if (!br->levels) 735 if (!br->levels) {
736 result = -ENOMEM;
680 goto out_free; 737 goto out_free;
738 }
681 739
682 for (i = 0; i < obj->package.count; i++) { 740 for (i = 0; i < obj->package.count; i++) {
683 o = (union acpi_object *)&obj->package.elements[i]; 741 o = (union acpi_object *)&obj->package.elements[i];
@@ -692,18 +750,86 @@ acpi_video_init_brightness(struct acpi_video_device *device)
692 count++; 750 count++;
693 } 751 }
694 752
695 /* don't sort the first two brightness levels */ 753 /*
696 sort(&br->levels[2], count - 2, sizeof(br->levels[2]), 754 * some buggy BIOS don't export the levels
697 acpi_video_cmp_level, NULL); 755 * when machine is on AC/Battery in _BCL package.
698 756 * In this case, the first two elements in _BCL packages
699 if (count < 2) 757 * are also supported brightness levels that OS should take care of.
700 goto out_free_levels; 758 */
759 for (i = 2; i < count; i++)
760 if (br->levels[i] == br->levels[0] ||
761 br->levels[i] == br->levels[1])
762 level_ac_battery++;
763
764 if (level_ac_battery < 2) {
765 level_ac_battery = 2 - level_ac_battery;
766 br->flags._BCL_no_ac_battery_levels = 1;
767 for (i = (count - 1 + level_ac_battery); i >= 2; i--)
768 br->levels[i] = br->levels[i - level_ac_battery];
769 count += level_ac_battery;
770 } else if (level_ac_battery > 2)
771 ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
772
773 /* Check if the _BCL package is in a reversed order */
774 if (max_level == br->levels[2]) {
775 br->flags._BCL_reversed = 1;
776 sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
777 acpi_video_cmp_level, NULL);
778 } else if (max_level != br->levels[count - 1])
779 ACPI_ERROR((AE_INFO,
780 "Found unordered _BCL package\n"));
701 781
702 br->count = count; 782 br->count = count;
703 device->brightness = br; 783 device->brightness = br;
704 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count)); 784
785 /* Check the input/output of _BQC/_BCL/_BCM */
786 if ((max_level < 100) && (max_level <= (count - 2)))
787 br->flags._BCL_use_index = 1;
788
789 /*
790 * _BCM is always consistent with _BCL,
791 * at least for all the laptops we have ever seen.
792 */
793 br->flags._BCM_use_index = br->flags._BCL_use_index;
794
795 /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
796 br->curr = max_level;
797 result = acpi_video_device_lcd_get_level_current(device, &level_old);
798 if (result)
799 goto out_free_levels;
800
801 result = acpi_video_device_lcd_set_level(device, br->curr);
802 if (result)
803 goto out_free_levels;
804
805 result = acpi_video_device_lcd_get_level_current(device, &level);
806 if (result)
807 goto out_free_levels;
808
809 if ((level != level_old) && !br->flags._BCM_use_index) {
810 /* Note:
811 * This piece of code does not work correctly if the current
812 * brightness levels is 0.
813 * But I guess boxes that boot with such a dark screen are rare
814 * and no more code is needed to cover this specifial case.
815 */
816
817 if (level_ac_battery != 2) {
818 /*
819 * For now, we don't support the _BCL like this:
820 * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16
821 * because we may mess up the index returned by _BQC.
822 * Plus: we have not got a box like this.
823 */
824 ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
825 }
826 br->flags._BQC_use_index = 1;
827 }
828
829 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
830 "found %d brightness levels\n", count - 2));
705 kfree(obj); 831 kfree(obj);
706 return max_level; 832 return result;
707 833
708out_free_levels: 834out_free_levels:
709 kfree(br->levels); 835 kfree(br->levels);
@@ -712,7 +838,7 @@ out_free:
712out: 838out:
713 device->brightness = NULL; 839 device->brightness = NULL;
714 kfree(obj); 840 kfree(obj);
715 return 0; 841 return result;
716} 842}
717 843
718/* 844/*
@@ -729,7 +855,6 @@ out:
729static void acpi_video_device_find_cap(struct acpi_video_device *device) 855static void acpi_video_device_find_cap(struct acpi_video_device *device)
730{ 856{
731 acpi_handle h_dummy1; 857 acpi_handle h_dummy1;
732 u32 max_level = 0;
733 858
734 859
735 memset(&device->cap, 0, sizeof(device->cap)); 860 memset(&device->cap, 0, sizeof(device->cap));
@@ -745,6 +870,12 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
745 } 870 }
746 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) 871 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
747 device->cap._BQC = 1; 872 device->cap._BQC = 1;
873 else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
874 &h_dummy1))) {
875 printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
876 device->cap._BCQ = 1;
877 }
878
748 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { 879 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
749 device->cap._DDC = 1; 880 device->cap._DDC = 1;
750 } 881 }
@@ -758,13 +889,14 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
758 device->cap._DSS = 1; 889 device->cap._DSS = 1;
759 } 890 }
760 891
761 if (acpi_video_backlight_support()) 892 if (acpi_video_backlight_support()) {
762 max_level = acpi_video_init_brightness(device);
763
764 if (device->cap._BCL && device->cap._BCM && max_level > 0) {
765 int result; 893 int result;
766 static int count = 0; 894 static int count = 0;
767 char *name; 895 char *name;
896
897 result = acpi_video_init_brightness(device);
898 if (result)
899 return;
768 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); 900 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
769 if (!name) 901 if (!name)
770 return; 902 return;
@@ -773,18 +905,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
773 device->backlight = backlight_device_register(name, 905 device->backlight = backlight_device_register(name,
774 NULL, device, &acpi_backlight_ops); 906 NULL, device, &acpi_backlight_ops);
775 device->backlight->props.max_brightness = device->brightness->count-3; 907 device->backlight->props.max_brightness = device->brightness->count-3;
776 /*
777 * If there exists the _BQC object, the _BQC object will be
778 * called to get the current backlight brightness. Otherwise
779 * the brightness will be set to the maximum.
780 */
781 if (device->cap._BQC)
782 device->backlight->props.brightness =
783 acpi_video_get_brightness(device->backlight);
784 else
785 device->backlight->props.brightness =
786 device->backlight->props.max_brightness;
787 backlight_update_status(device->backlight);
788 kfree(name); 908 kfree(name);
789 909
790 device->cdev = thermal_cooling_device_register("LCD", 910 device->cdev = thermal_cooling_device_register("LCD",
@@ -1061,13 +1181,12 @@ acpi_video_device_write_brightness(struct file *file,
1061 /* validate through the list of available levels */ 1181 /* validate through the list of available levels */
1062 for (i = 2; i < dev->brightness->count; i++) 1182 for (i = 2; i < dev->brightness->count; i++)
1063 if (level == dev->brightness->levels[i]) { 1183 if (level == dev->brightness->levels[i]) {
1064 if (ACPI_SUCCESS 1184 if (!acpi_video_device_lcd_set_level(dev, level))
1065 (acpi_video_device_lcd_set_level(dev, level))) 1185 return count;
1066 dev->brightness->curr = level;
1067 break; 1186 break;
1068 } 1187 }
1069 1188
1070 return count; 1189 return -EINVAL;
1071} 1190}
1072 1191
1073static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) 1192static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
@@ -1749,15 +1868,29 @@ acpi_video_get_next_level(struct acpi_video_device *device,
1749 } 1868 }
1750} 1869}
1751 1870
1752static void 1871static int
1753acpi_video_switch_brightness(struct acpi_video_device *device, int event) 1872acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1754{ 1873{
1755 unsigned long long level_current, level_next; 1874 unsigned long long level_current, level_next;
1875 int result = -EINVAL;
1876
1756 if (!device->brightness) 1877 if (!device->brightness)
1757 return; 1878 goto out;
1758 acpi_video_device_lcd_get_level_current(device, &level_current); 1879
1880 result = acpi_video_device_lcd_get_level_current(device,
1881 &level_current);
1882 if (result)
1883 goto out;
1884
1759 level_next = acpi_video_get_next_level(device, level_current, event); 1885 level_next = acpi_video_get_next_level(device, level_current, event);
1760 acpi_video_device_lcd_set_level(device, level_next); 1886
1887 result = acpi_video_device_lcd_set_level(device, level_next);
1888
1889out:
1890 if (result)
1891 printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
1892
1893 return result;
1761} 1894}
1762 1895
1763static int 1896static int
@@ -2124,7 +2257,27 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
2124 return 0; 2257 return 0;
2125} 2258}
2126 2259
2127static int __init acpi_video_init(void) 2260static int __init intel_opregion_present(void)
2261{
2262#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
2263 struct pci_dev *dev = NULL;
2264 u32 address;
2265
2266 for_each_pci_dev(dev) {
2267 if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
2268 continue;
2269 if (dev->vendor != PCI_VENDOR_ID_INTEL)
2270 continue;
2271 pci_read_config_dword(dev, 0xfc, &address);
2272 if (!address)
2273 continue;
2274 return 1;
2275 }
2276#endif
2277 return 0;
2278}
2279
2280int acpi_video_register(void)
2128{ 2281{
2129 int result = 0; 2282 int result = 0;
2130 2283
@@ -2141,6 +2294,22 @@ static int __init acpi_video_init(void)
2141 2294
2142 return 0; 2295 return 0;
2143} 2296}
2297EXPORT_SYMBOL(acpi_video_register);
2298
2299/*
2300 * This is kind of nasty. Hardware using Intel chipsets may require
2301 * the video opregion code to be run first in order to initialise
2302 * state before any ACPI video calls are made. To handle this we defer
2303 * registration of the video class until the opregion code has run.
2304 */
2305
2306static int __init acpi_video_init(void)
2307{
2308 if (intel_opregion_present())
2309 return 0;
2310
2311 return acpi_video_register();
2312}
2144 2313
2145static void __exit acpi_video_exit(void) 2314static void __exit acpi_video_exit(void)
2146{ 2315{