diff options
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r-- | drivers/acpi/video.c | 110 |
1 files changed, 64 insertions, 46 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 56666a982476..36b37d755dbc 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> | 4 | * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> |
5 | * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> | 5 | * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> |
6 | * Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net> | ||
6 | * | 7 | * |
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 8 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
8 | * | 9 | * |
@@ -47,11 +48,11 @@ | |||
47 | #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 | 48 | #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 |
48 | #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 | 49 | #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 |
49 | 50 | ||
50 | #define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82 | 51 | #define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85 |
51 | #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83 | 52 | #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 |
52 | #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84 | 53 | #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 |
53 | #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85 | 54 | #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 |
54 | #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86 | 55 | #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 |
55 | 56 | ||
56 | #define ACPI_VIDEO_HEAD_INVALID (~0u - 1) | 57 | #define ACPI_VIDEO_HEAD_INVALID (~0u - 1) |
57 | #define ACPI_VIDEO_HEAD_END (~0u) | 58 | #define ACPI_VIDEO_HEAD_END (~0u) |
@@ -386,7 +387,7 @@ acpi_video_device_EDID(struct acpi_video_device *device, | |||
386 | if (ACPI_FAILURE(status)) | 387 | if (ACPI_FAILURE(status)) |
387 | return -ENODEV; | 388 | return -ENODEV; |
388 | 389 | ||
389 | obj = (union acpi_object *)buffer.pointer; | 390 | obj = buffer.pointer; |
390 | 391 | ||
391 | if (obj && obj->type == ACPI_TYPE_BUFFER) | 392 | if (obj && obj->type == ACPI_TYPE_BUFFER) |
392 | *edid = obj; | 393 | *edid = obj; |
@@ -532,11 +533,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
532 | int count = 0; | 533 | int count = 0; |
533 | union acpi_object *o; | 534 | union acpi_object *o; |
534 | 535 | ||
535 | br = kmalloc(sizeof(*br), GFP_KERNEL); | 536 | br = kzalloc(sizeof(*br), GFP_KERNEL); |
536 | if (!br) { | 537 | if (!br) { |
537 | printk(KERN_ERR "can't allocate memory\n"); | 538 | printk(KERN_ERR "can't allocate memory\n"); |
538 | } else { | 539 | } else { |
539 | memset(br, 0, sizeof(*br)); | ||
540 | br->levels = kmalloc(obj->package.count * | 540 | br->levels = kmalloc(obj->package.count * |
541 | sizeof *(br->levels), GFP_KERNEL); | 541 | sizeof *(br->levels), GFP_KERNEL); |
542 | if (!br->levels) | 542 | if (!br->levels) |
@@ -654,8 +654,7 @@ static struct proc_dir_entry *acpi_video_dir; | |||
654 | 654 | ||
655 | static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) | 655 | static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) |
656 | { | 656 | { |
657 | struct acpi_video_device *dev = | 657 | struct acpi_video_device *dev = seq->private; |
658 | (struct acpi_video_device *)seq->private; | ||
659 | 658 | ||
660 | 659 | ||
661 | if (!dev) | 660 | if (!dev) |
@@ -688,8 +687,7 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file) | |||
688 | static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) | 687 | static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) |
689 | { | 688 | { |
690 | int status; | 689 | int status; |
691 | struct acpi_video_device *dev = | 690 | struct acpi_video_device *dev = seq->private; |
692 | (struct acpi_video_device *)seq->private; | ||
693 | unsigned long state; | 691 | unsigned long state; |
694 | 692 | ||
695 | 693 | ||
@@ -727,8 +725,8 @@ acpi_video_device_write_state(struct file *file, | |||
727 | size_t count, loff_t * data) | 725 | size_t count, loff_t * data) |
728 | { | 726 | { |
729 | int status; | 727 | int status; |
730 | struct seq_file *m = (struct seq_file *)file->private_data; | 728 | struct seq_file *m = file->private_data; |
731 | struct acpi_video_device *dev = (struct acpi_video_device *)m->private; | 729 | struct acpi_video_device *dev = m->private; |
732 | char str[12] = { 0 }; | 730 | char str[12] = { 0 }; |
733 | u32 state = 0; | 731 | u32 state = 0; |
734 | 732 | ||
@@ -754,8 +752,7 @@ acpi_video_device_write_state(struct file *file, | |||
754 | static int | 752 | static int |
755 | acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) | 753 | acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) |
756 | { | 754 | { |
757 | struct acpi_video_device *dev = | 755 | struct acpi_video_device *dev = seq->private; |
758 | (struct acpi_video_device *)seq->private; | ||
759 | int i; | 756 | int i; |
760 | 757 | ||
761 | 758 | ||
@@ -784,8 +781,8 @@ acpi_video_device_write_brightness(struct file *file, | |||
784 | const char __user * buffer, | 781 | const char __user * buffer, |
785 | size_t count, loff_t * data) | 782 | size_t count, loff_t * data) |
786 | { | 783 | { |
787 | struct seq_file *m = (struct seq_file *)file->private_data; | 784 | struct seq_file *m = file->private_data; |
788 | struct acpi_video_device *dev = (struct acpi_video_device *)m->private; | 785 | struct acpi_video_device *dev = m->private; |
789 | char str[4] = { 0 }; | 786 | char str[4] = { 0 }; |
790 | unsigned int level = 0; | 787 | unsigned int level = 0; |
791 | int i; | 788 | int i; |
@@ -817,8 +814,7 @@ acpi_video_device_write_brightness(struct file *file, | |||
817 | 814 | ||
818 | static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) | 815 | static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) |
819 | { | 816 | { |
820 | struct acpi_video_device *dev = | 817 | struct acpi_video_device *dev = seq->private; |
821 | (struct acpi_video_device *)seq->private; | ||
822 | int status; | 818 | int status; |
823 | int i; | 819 | int i; |
824 | union acpi_object *edid = NULL; | 820 | union acpi_object *edid = NULL; |
@@ -866,7 +862,7 @@ static int acpi_video_device_add_fs(struct acpi_device *device) | |||
866 | if (!device) | 862 | if (!device) |
867 | return -ENODEV; | 863 | return -ENODEV; |
868 | 864 | ||
869 | vid_dev = (struct acpi_video_device *)acpi_driver_data(device); | 865 | vid_dev = acpi_driver_data(device); |
870 | if (!vid_dev) | 866 | if (!vid_dev) |
871 | return -ENODEV; | 867 | return -ENODEV; |
872 | 868 | ||
@@ -931,7 +927,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device) | |||
931 | { | 927 | { |
932 | struct acpi_video_device *vid_dev; | 928 | struct acpi_video_device *vid_dev; |
933 | 929 | ||
934 | vid_dev = (struct acpi_video_device *)acpi_driver_data(device); | 930 | vid_dev = acpi_driver_data(device); |
935 | if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) | 931 | if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) |
936 | return -ENODEV; | 932 | return -ENODEV; |
937 | 933 | ||
@@ -950,7 +946,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device) | |||
950 | /* video bus */ | 946 | /* video bus */ |
951 | static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) | 947 | static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) |
952 | { | 948 | { |
953 | struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; | 949 | struct acpi_video_bus *video = seq->private; |
954 | 950 | ||
955 | 951 | ||
956 | if (!video) | 952 | if (!video) |
@@ -975,7 +971,7 @@ static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file) | |||
975 | 971 | ||
976 | static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) | 972 | static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) |
977 | { | 973 | { |
978 | struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; | 974 | struct acpi_video_bus *video = seq->private; |
979 | 975 | ||
980 | 976 | ||
981 | if (!video) | 977 | if (!video) |
@@ -995,7 +991,7 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) | |||
995 | 991 | ||
996 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) | 992 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) |
997 | { | 993 | { |
998 | struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; | 994 | struct acpi_video_bus *video = seq->private; |
999 | unsigned long options; | 995 | unsigned long options; |
1000 | int status; | 996 | int status; |
1001 | 997 | ||
@@ -1033,7 +1029,7 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file) | |||
1033 | 1029 | ||
1034 | static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) | 1030 | static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) |
1035 | { | 1031 | { |
1036 | struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; | 1032 | struct acpi_video_bus *video = seq->private; |
1037 | int status; | 1033 | int status; |
1038 | unsigned long id; | 1034 | unsigned long id; |
1039 | 1035 | ||
@@ -1054,7 +1050,7 @@ static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) | |||
1054 | 1050 | ||
1055 | static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) | 1051 | static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) |
1056 | { | 1052 | { |
1057 | struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; | 1053 | struct acpi_video_bus *video = seq->private; |
1058 | 1054 | ||
1059 | 1055 | ||
1060 | seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); | 1056 | seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); |
@@ -1079,8 +1075,8 @@ acpi_video_bus_write_POST(struct file *file, | |||
1079 | size_t count, loff_t * data) | 1075 | size_t count, loff_t * data) |
1080 | { | 1076 | { |
1081 | int status; | 1077 | int status; |
1082 | struct seq_file *m = (struct seq_file *)file->private_data; | 1078 | struct seq_file *m = file->private_data; |
1083 | struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; | 1079 | struct acpi_video_bus *video = m->private; |
1084 | char str[12] = { 0 }; | 1080 | char str[12] = { 0 }; |
1085 | unsigned long opt, options; | 1081 | unsigned long opt, options; |
1086 | 1082 | ||
@@ -1119,8 +1115,8 @@ acpi_video_bus_write_DOS(struct file *file, | |||
1119 | size_t count, loff_t * data) | 1115 | size_t count, loff_t * data) |
1120 | { | 1116 | { |
1121 | int status; | 1117 | int status; |
1122 | struct seq_file *m = (struct seq_file *)file->private_data; | 1118 | struct seq_file *m = file->private_data; |
1123 | struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; | 1119 | struct acpi_video_bus *video = m->private; |
1124 | char str[12] = { 0 }; | 1120 | char str[12] = { 0 }; |
1125 | unsigned long opt; | 1121 | unsigned long opt; |
1126 | 1122 | ||
@@ -1150,7 +1146,7 @@ static int acpi_video_bus_add_fs(struct acpi_device *device) | |||
1150 | struct acpi_video_bus *video; | 1146 | struct acpi_video_bus *video; |
1151 | 1147 | ||
1152 | 1148 | ||
1153 | video = (struct acpi_video_bus *)acpi_driver_data(device); | 1149 | video = acpi_driver_data(device); |
1154 | 1150 | ||
1155 | if (!acpi_device_dir(device)) { | 1151 | if (!acpi_device_dir(device)) { |
1156 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | 1152 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), |
@@ -1226,7 +1222,7 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device) | |||
1226 | struct acpi_video_bus *video; | 1222 | struct acpi_video_bus *video; |
1227 | 1223 | ||
1228 | 1224 | ||
1229 | video = (struct acpi_video_bus *)acpi_driver_data(device); | 1225 | video = acpi_driver_data(device); |
1230 | 1226 | ||
1231 | if (acpi_device_dir(device)) { | 1227 | if (acpi_device_dir(device)) { |
1232 | remove_proc_entry("info", acpi_device_dir(device)); | 1228 | remove_proc_entry("info", acpi_device_dir(device)); |
@@ -1263,12 +1259,10 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1263 | acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); | 1259 | acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); |
1264 | if (ACPI_SUCCESS(status)) { | 1260 | if (ACPI_SUCCESS(status)) { |
1265 | 1261 | ||
1266 | data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL); | 1262 | data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); |
1267 | if (!data) | 1263 | if (!data) |
1268 | return -ENOMEM; | 1264 | return -ENOMEM; |
1269 | 1265 | ||
1270 | memset(data, 0, sizeof(struct acpi_video_device)); | ||
1271 | |||
1272 | strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); | 1266 | strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); |
1273 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); | 1267 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); |
1274 | acpi_driver_data(device) = data; | 1268 | acpi_driver_data(device) = data; |
@@ -1403,7 +1397,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1403 | return status; | 1397 | return status; |
1404 | } | 1398 | } |
1405 | 1399 | ||
1406 | dod = (union acpi_object *)buffer.pointer; | 1400 | dod = buffer.pointer; |
1407 | if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { | 1401 | if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { |
1408 | ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); | 1402 | ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); |
1409 | status = -EFAULT; | 1403 | status = -EFAULT; |
@@ -1426,7 +1420,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1426 | 1420 | ||
1427 | count = 0; | 1421 | count = 0; |
1428 | for (i = 0; i < dod->package.count; i++) { | 1422 | for (i = 0; i < dod->package.count; i++) { |
1429 | obj = (union acpi_object *)&dod->package.elements[i]; | 1423 | obj = &dod->package.elements[i]; |
1430 | 1424 | ||
1431 | if (obj->type != ACPI_TYPE_INTEGER) { | 1425 | if (obj->type != ACPI_TYPE_INTEGER) { |
1432 | printk(KERN_ERR PREFIX "Invalid _DOD data\n"); | 1426 | printk(KERN_ERR PREFIX "Invalid _DOD data\n"); |
@@ -1509,8 +1503,34 @@ static int | |||
1509 | acpi_video_get_next_level(struct acpi_video_device *device, | 1503 | acpi_video_get_next_level(struct acpi_video_device *device, |
1510 | u32 level_current, u32 event) | 1504 | u32 level_current, u32 event) |
1511 | { | 1505 | { |
1512 | /*Fix me */ | 1506 | int min, max, min_above, max_below, i, l; |
1513 | return level_current; | 1507 | max = max_below = 0; |
1508 | min = min_above = 255; | ||
1509 | for (i = 0; i < device->brightness->count; i++) { | ||
1510 | l = device->brightness->levels[i]; | ||
1511 | if (l < min) | ||
1512 | min = l; | ||
1513 | if (l > max) | ||
1514 | max = l; | ||
1515 | if (l < min_above && l > level_current) | ||
1516 | min_above = l; | ||
1517 | if (l > max_below && l < level_current) | ||
1518 | max_below = l; | ||
1519 | } | ||
1520 | |||
1521 | switch (event) { | ||
1522 | case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: | ||
1523 | return (level_current < max) ? min_above : min; | ||
1524 | case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: | ||
1525 | return (level_current < max) ? min_above : max; | ||
1526 | case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: | ||
1527 | return (level_current > min) ? max_below : min; | ||
1528 | case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: | ||
1529 | case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: | ||
1530 | return 0; | ||
1531 | default: | ||
1532 | return level_current; | ||
1533 | } | ||
1514 | } | 1534 | } |
1515 | 1535 | ||
1516 | static void | 1536 | static void |
@@ -1612,7 +1632,7 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) | |||
1612 | 1632 | ||
1613 | static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) | 1633 | static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) |
1614 | { | 1634 | { |
1615 | struct acpi_video_bus *video = (struct acpi_video_bus *)data; | 1635 | struct acpi_video_bus *video = data; |
1616 | struct acpi_device *device = NULL; | 1636 | struct acpi_device *device = NULL; |
1617 | 1637 | ||
1618 | printk("video bus notify\n"); | 1638 | printk("video bus notify\n"); |
@@ -1654,8 +1674,7 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) | |||
1654 | 1674 | ||
1655 | static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | 1675 | static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) |
1656 | { | 1676 | { |
1657 | struct acpi_video_device *video_device = | 1677 | struct acpi_video_device *video_device = data; |
1658 | (struct acpi_video_device *)data; | ||
1659 | struct acpi_device *device = NULL; | 1678 | struct acpi_device *device = NULL; |
1660 | 1679 | ||
1661 | 1680 | ||
@@ -1696,10 +1715,9 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1696 | if (!device) | 1715 | if (!device) |
1697 | return -EINVAL; | 1716 | return -EINVAL; |
1698 | 1717 | ||
1699 | video = kmalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); | 1718 | video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); |
1700 | if (!video) | 1719 | if (!video) |
1701 | return -ENOMEM; | 1720 | return -ENOMEM; |
1702 | memset(video, 0, sizeof(struct acpi_video_bus)); | ||
1703 | 1721 | ||
1704 | video->device = device; | 1722 | video->device = device; |
1705 | strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); | 1723 | strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); |
@@ -1757,7 +1775,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) | |||
1757 | if (!device || !acpi_driver_data(device)) | 1775 | if (!device || !acpi_driver_data(device)) |
1758 | return -EINVAL; | 1776 | return -EINVAL; |
1759 | 1777 | ||
1760 | video = (struct acpi_video_bus *)acpi_driver_data(device); | 1778 | video = acpi_driver_data(device); |
1761 | 1779 | ||
1762 | acpi_video_bus_stop_devices(video); | 1780 | acpi_video_bus_stop_devices(video); |
1763 | 1781 | ||