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.c241
1 files changed, 176 insertions, 65 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 6e99eea689c8..e0b97add8c63 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 *
@@ -31,6 +32,7 @@
31#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
32#include <linux/seq_file.h> 33#include <linux/seq_file.h>
33 34
35#include <linux/backlight.h>
34#include <asm/uaccess.h> 36#include <asm/uaccess.h>
35 37
36#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
@@ -47,14 +49,20 @@
47#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 49#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
48#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 50#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
49 51
50#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82 52#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85
51#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83 53#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
52#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84 54#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
53#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85 55#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
54#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86 56#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
55 57
56#define ACPI_VIDEO_HEAD_INVALID (~0u - 1) 58#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
57#define ACPI_VIDEO_HEAD_END (~0u) 59#define ACPI_VIDEO_HEAD_END (~0u)
60#define MAX_NAME_LEN 20
61
62#define ACPI_VIDEO_DISPLAY_CRT 1
63#define ACPI_VIDEO_DISPLAY_TV 2
64#define ACPI_VIDEO_DISPLAY_DVI 3
65#define ACPI_VIDEO_DISPLAY_LCD 4
58 66
59#define _COMPONENT ACPI_VIDEO_COMPONENT 67#define _COMPONENT ACPI_VIDEO_COMPONENT
60ACPI_MODULE_NAME("acpi_video") 68ACPI_MODULE_NAME("acpi_video")
@@ -130,20 +138,21 @@ struct acpi_video_device_flags {
130 u8 crt:1; 138 u8 crt:1;
131 u8 lcd:1; 139 u8 lcd:1;
132 u8 tvout:1; 140 u8 tvout:1;
141 u8 dvi:1;
133 u8 bios:1; 142 u8 bios:1;
134 u8 unknown:1; 143 u8 unknown:1;
135 u8 reserved:3; 144 u8 reserved:2;
136}; 145};
137 146
138struct acpi_video_device_cap { 147struct acpi_video_device_cap {
139 u8 _ADR:1; /*Return the unique ID */ 148 u8 _ADR:1; /*Return the unique ID */
140 u8 _BCL:1; /*Query list of brightness control levels supported */ 149 u8 _BCL:1; /*Query list of brightness control levels supported */
141 u8 _BCM:1; /*Set the brightness level */ 150 u8 _BCM:1; /*Set the brightness level */
151 u8 _BQC:1; /* Get current brightness level */
142 u8 _DDC:1; /*Return the EDID for this device */ 152 u8 _DDC:1; /*Return the EDID for this device */
143 u8 _DCS:1; /*Return status of output device */ 153 u8 _DCS:1; /*Return status of output device */
144 u8 _DGS:1; /*Query graphics state */ 154 u8 _DGS:1; /*Query graphics state */
145 u8 _DSS:1; /*Device state set */ 155 u8 _DSS:1; /*Device state set */
146 u8 _reserved:1;
147}; 156};
148 157
149struct acpi_video_device_brightness { 158struct acpi_video_device_brightness {
@@ -160,6 +169,8 @@ struct acpi_video_device {
160 struct acpi_video_bus *video; 169 struct acpi_video_bus *video;
161 struct acpi_device *dev; 170 struct acpi_device *dev;
162 struct acpi_video_device_brightness *brightness; 171 struct acpi_video_device_brightness *brightness;
172 struct backlight_device *backlight;
173 struct backlight_properties *data;
163}; 174};
164 175
165/* bus */ 176/* bus */
@@ -254,11 +265,35 @@ static void acpi_video_device_bind(struct acpi_video_bus *video,
254 struct acpi_video_device *device); 265 struct acpi_video_device *device);
255static int acpi_video_device_enumerate(struct acpi_video_bus *video); 266static int acpi_video_device_enumerate(struct acpi_video_bus *video);
256static int acpi_video_switch_output(struct acpi_video_bus *video, int event); 267static int acpi_video_switch_output(struct acpi_video_bus *video, int event);
268static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
269 int level);
270static int acpi_video_device_lcd_get_level_current(
271 struct acpi_video_device *device,
272 unsigned long *level);
257static int acpi_video_get_next_level(struct acpi_video_device *device, 273static int acpi_video_get_next_level(struct acpi_video_device *device,
258 u32 level_current, u32 event); 274 u32 level_current, u32 event);
259static void acpi_video_switch_brightness(struct acpi_video_device *device, 275static void acpi_video_switch_brightness(struct acpi_video_device *device,
260 int event); 276 int event);
261 277
278/*backlight device sysfs support*/
279static int acpi_video_get_brightness(struct backlight_device *bd)
280{
281 unsigned long cur_level;
282 struct acpi_video_device *vd =
283 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
284 acpi_video_device_lcd_get_level_current(vd, &cur_level);
285 return (int) cur_level;
286}
287
288static int acpi_video_set_brightness(struct backlight_device *bd)
289{
290 int request_level = bd->props->brightness;
291 struct acpi_video_device *vd =
292 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
293 acpi_video_device_lcd_set_level(vd, request_level);
294 return 0;
295}
296
262/* -------------------------------------------------------------------------- 297/* --------------------------------------------------------------------------
263 Video Management 298 Video Management
264 -------------------------------------------------------------------------- */ 299 -------------------------------------------------------------------------- */
@@ -384,7 +419,7 @@ acpi_video_device_EDID(struct acpi_video_device *device,
384 if (ACPI_FAILURE(status)) 419 if (ACPI_FAILURE(status))
385 return -ENODEV; 420 return -ENODEV;
386 421
387 obj = (union acpi_object *)buffer.pointer; 422 obj = buffer.pointer;
388 423
389 if (obj && obj->type == ACPI_TYPE_BUFFER) 424 if (obj && obj->type == ACPI_TYPE_BUFFER)
390 *edid = obj; 425 *edid = obj;
@@ -496,6 +531,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
496 acpi_integer status; 531 acpi_integer status;
497 acpi_handle h_dummy1; 532 acpi_handle h_dummy1;
498 int i; 533 int i;
534 u32 max_level = 0;
499 union acpi_object *obj = NULL; 535 union acpi_object *obj = NULL;
500 struct acpi_video_device_brightness *br = NULL; 536 struct acpi_video_device_brightness *br = NULL;
501 537
@@ -511,6 +547,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
511 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { 547 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
512 device->cap._BCM = 1; 548 device->cap._BCM = 1;
513 } 549 }
550 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
551 device->cap._BQC = 1;
514 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { 552 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
515 device->cap._DDC = 1; 553 device->cap._DDC = 1;
516 } 554 }
@@ -530,11 +568,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
530 int count = 0; 568 int count = 0;
531 union acpi_object *o; 569 union acpi_object *o;
532 570
533 br = kmalloc(sizeof(*br), GFP_KERNEL); 571 br = kzalloc(sizeof(*br), GFP_KERNEL);
534 if (!br) { 572 if (!br) {
535 printk(KERN_ERR "can't allocate memory\n"); 573 printk(KERN_ERR "can't allocate memory\n");
536 } else { 574 } else {
537 memset(br, 0, sizeof(*br));
538 br->levels = kmalloc(obj->package.count * 575 br->levels = kmalloc(obj->package.count *
539 sizeof *(br->levels), GFP_KERNEL); 576 sizeof *(br->levels), GFP_KERNEL);
540 if (!br->levels) 577 if (!br->levels)
@@ -548,6 +585,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
548 continue; 585 continue;
549 } 586 }
550 br->levels[count] = (u32) o->integer.value; 587 br->levels[count] = (u32) o->integer.value;
588 if (br->levels[count] > max_level)
589 max_level = br->levels[count];
551 count++; 590 count++;
552 } 591 }
553 out: 592 out:
@@ -566,6 +605,37 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
566 605
567 kfree(obj); 606 kfree(obj);
568 607
608 if (device->cap._BCL && device->cap._BCM && device->cap._BQC){
609 unsigned long tmp;
610 static int count = 0;
611 char *name;
612 struct backlight_properties *acpi_video_data;
613
614 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
615 if (!name)
616 return;
617
618 acpi_video_data = kzalloc(
619 sizeof(struct backlight_properties),
620 GFP_KERNEL);
621 if (!acpi_video_data){
622 kfree(name);
623 return;
624 }
625 acpi_video_data->owner = THIS_MODULE;
626 acpi_video_data->get_brightness =
627 acpi_video_get_brightness;
628 acpi_video_data->update_status =
629 acpi_video_set_brightness;
630 sprintf(name, "acpi_video%d", count++);
631 device->data = acpi_video_data;
632 acpi_video_data->max_brightness = max_level;
633 acpi_video_device_lcd_get_level_current(device, &tmp);
634 acpi_video_data->brightness = (int)tmp;
635 device->backlight = backlight_device_register(name,
636 NULL, device, acpi_video_data);
637 kfree(name);
638 }
569 return; 639 return;
570} 640}
571 641
@@ -652,8 +722,7 @@ static struct proc_dir_entry *acpi_video_dir;
652 722
653static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) 723static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
654{ 724{
655 struct acpi_video_device *dev = 725 struct acpi_video_device *dev = seq->private;
656 (struct acpi_video_device *)seq->private;
657 726
658 727
659 if (!dev) 728 if (!dev)
@@ -667,6 +736,8 @@ static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
667 seq_printf(seq, "LCD\n"); 736 seq_printf(seq, "LCD\n");
668 else if (dev->flags.tvout) 737 else if (dev->flags.tvout)
669 seq_printf(seq, "TVOUT\n"); 738 seq_printf(seq, "TVOUT\n");
739 else if (dev->flags.dvi)
740 seq_printf(seq, "DVI\n");
670 else 741 else
671 seq_printf(seq, "UNKNOWN\n"); 742 seq_printf(seq, "UNKNOWN\n");
672 743
@@ -686,8 +757,7 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
686static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) 757static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
687{ 758{
688 int status; 759 int status;
689 struct acpi_video_device *dev = 760 struct acpi_video_device *dev = seq->private;
690 (struct acpi_video_device *)seq->private;
691 unsigned long state; 761 unsigned long state;
692 762
693 763
@@ -725,8 +795,8 @@ acpi_video_device_write_state(struct file *file,
725 size_t count, loff_t * data) 795 size_t count, loff_t * data)
726{ 796{
727 int status; 797 int status;
728 struct seq_file *m = (struct seq_file *)file->private_data; 798 struct seq_file *m = file->private_data;
729 struct acpi_video_device *dev = (struct acpi_video_device *)m->private; 799 struct acpi_video_device *dev = m->private;
730 char str[12] = { 0 }; 800 char str[12] = { 0 };
731 u32 state = 0; 801 u32 state = 0;
732 802
@@ -752,8 +822,7 @@ acpi_video_device_write_state(struct file *file,
752static int 822static int
753acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) 823acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
754{ 824{
755 struct acpi_video_device *dev = 825 struct acpi_video_device *dev = seq->private;
756 (struct acpi_video_device *)seq->private;
757 int i; 826 int i;
758 827
759 828
@@ -782,8 +851,8 @@ acpi_video_device_write_brightness(struct file *file,
782 const char __user * buffer, 851 const char __user * buffer,
783 size_t count, loff_t * data) 852 size_t count, loff_t * data)
784{ 853{
785 struct seq_file *m = (struct seq_file *)file->private_data; 854 struct seq_file *m = file->private_data;
786 struct acpi_video_device *dev = (struct acpi_video_device *)m->private; 855 struct acpi_video_device *dev = m->private;
787 char str[4] = { 0 }; 856 char str[4] = { 0 };
788 unsigned int level = 0; 857 unsigned int level = 0;
789 int i; 858 int i;
@@ -815,8 +884,7 @@ acpi_video_device_write_brightness(struct file *file,
815 884
816static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) 885static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
817{ 886{
818 struct acpi_video_device *dev = 887 struct acpi_video_device *dev = seq->private;
819 (struct acpi_video_device *)seq->private;
820 int status; 888 int status;
821 int i; 889 int i;
822 union acpi_object *edid = NULL; 890 union acpi_object *edid = NULL;
@@ -864,7 +932,7 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
864 if (!device) 932 if (!device)
865 return -ENODEV; 933 return -ENODEV;
866 934
867 vid_dev = (struct acpi_video_device *)acpi_driver_data(device); 935 vid_dev = acpi_driver_data(device);
868 if (!vid_dev) 936 if (!vid_dev)
869 return -ENODEV; 937 return -ENODEV;
870 938
@@ -929,7 +997,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device)
929{ 997{
930 struct acpi_video_device *vid_dev; 998 struct acpi_video_device *vid_dev;
931 999
932 vid_dev = (struct acpi_video_device *)acpi_driver_data(device); 1000 vid_dev = acpi_driver_data(device);
933 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) 1001 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
934 return -ENODEV; 1002 return -ENODEV;
935 1003
@@ -948,7 +1016,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device)
948/* video bus */ 1016/* video bus */
949static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) 1017static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
950{ 1018{
951 struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; 1019 struct acpi_video_bus *video = seq->private;
952 1020
953 1021
954 if (!video) 1022 if (!video)
@@ -973,7 +1041,7 @@ static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
973 1041
974static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) 1042static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
975{ 1043{
976 struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; 1044 struct acpi_video_bus *video = seq->private;
977 1045
978 1046
979 if (!video) 1047 if (!video)
@@ -993,7 +1061,7 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
993 1061
994static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) 1062static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
995{ 1063{
996 struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; 1064 struct acpi_video_bus *video = seq->private;
997 unsigned long options; 1065 unsigned long options;
998 int status; 1066 int status;
999 1067
@@ -1031,7 +1099,7 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
1031 1099
1032static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) 1100static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
1033{ 1101{
1034 struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; 1102 struct acpi_video_bus *video = seq->private;
1035 int status; 1103 int status;
1036 unsigned long id; 1104 unsigned long id;
1037 1105
@@ -1052,7 +1120,7 @@ static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
1052 1120
1053static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) 1121static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
1054{ 1122{
1055 struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; 1123 struct acpi_video_bus *video = seq->private;
1056 1124
1057 1125
1058 seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); 1126 seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
@@ -1077,8 +1145,8 @@ acpi_video_bus_write_POST(struct file *file,
1077 size_t count, loff_t * data) 1145 size_t count, loff_t * data)
1078{ 1146{
1079 int status; 1147 int status;
1080 struct seq_file *m = (struct seq_file *)file->private_data; 1148 struct seq_file *m = file->private_data;
1081 struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; 1149 struct acpi_video_bus *video = m->private;
1082 char str[12] = { 0 }; 1150 char str[12] = { 0 };
1083 unsigned long opt, options; 1151 unsigned long opt, options;
1084 1152
@@ -1117,8 +1185,8 @@ acpi_video_bus_write_DOS(struct file *file,
1117 size_t count, loff_t * data) 1185 size_t count, loff_t * data)
1118{ 1186{
1119 int status; 1187 int status;
1120 struct seq_file *m = (struct seq_file *)file->private_data; 1188 struct seq_file *m = file->private_data;
1121 struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; 1189 struct acpi_video_bus *video = m->private;
1122 char str[12] = { 0 }; 1190 char str[12] = { 0 };
1123 unsigned long opt; 1191 unsigned long opt;
1124 1192
@@ -1148,7 +1216,7 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
1148 struct acpi_video_bus *video; 1216 struct acpi_video_bus *video;
1149 1217
1150 1218
1151 video = (struct acpi_video_bus *)acpi_driver_data(device); 1219 video = acpi_driver_data(device);
1152 1220
1153 if (!acpi_device_dir(device)) { 1221 if (!acpi_device_dir(device)) {
1154 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1222 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
@@ -1224,7 +1292,7 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
1224 struct acpi_video_bus *video; 1292 struct acpi_video_bus *video;
1225 1293
1226 1294
1227 video = (struct acpi_video_bus *)acpi_driver_data(device); 1295 video = acpi_driver_data(device);
1228 1296
1229 if (acpi_device_dir(device)) { 1297 if (acpi_device_dir(device)) {
1230 remove_proc_entry("info", acpi_device_dir(device)); 1298 remove_proc_entry("info", acpi_device_dir(device));
@@ -1244,6 +1312,16 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
1244 -------------------------------------------------------------------------- */ 1312 -------------------------------------------------------------------------- */
1245 1313
1246/* device interface */ 1314/* device interface */
1315static struct acpi_video_device_attrib*
1316acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1317{
1318 int count;
1319
1320 for(count = 0; count < video->attached_count; count++)
1321 if((video->attached_array[count].value.int_val & 0xffff) == device_id)
1322 return &(video->attached_array[count].value.attrib);
1323 return NULL;
1324}
1247 1325
1248static int 1326static int
1249acpi_video_bus_get_one_device(struct acpi_device *device, 1327acpi_video_bus_get_one_device(struct acpi_device *device,
@@ -1252,7 +1330,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1252 unsigned long device_id; 1330 unsigned long device_id;
1253 int status; 1331 int status;
1254 struct acpi_video_device *data; 1332 struct acpi_video_device *data;
1255 1333 struct acpi_video_device_attrib* attribute;
1256 1334
1257 if (!device || !video) 1335 if (!device || !video)
1258 return -EINVAL; 1336 return -EINVAL;
@@ -1261,12 +1339,10 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1261 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); 1339 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
1262 if (ACPI_SUCCESS(status)) { 1340 if (ACPI_SUCCESS(status)) {
1263 1341
1264 data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL); 1342 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
1265 if (!data) 1343 if (!data)
1266 return -ENOMEM; 1344 return -ENOMEM;
1267 1345
1268 memset(data, 0, sizeof(struct acpi_video_device));
1269
1270 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); 1346 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
1271 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); 1347 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1272 acpi_driver_data(device) = data; 1348 acpi_driver_data(device) = data;
@@ -1275,20 +1351,30 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1275 data->video = video; 1351 data->video = video;
1276 data->dev = device; 1352 data->dev = device;
1277 1353
1278 switch (device_id & 0xffff) { 1354 attribute = acpi_video_get_device_attr(video, device_id);
1279 case 0x0100: 1355
1280 data->flags.crt = 1; 1356 if((attribute != NULL) && attribute->device_id_scheme) {
1281 break; 1357 switch (attribute->display_type) {
1282 case 0x0400: 1358 case ACPI_VIDEO_DISPLAY_CRT:
1283 data->flags.lcd = 1; 1359 data->flags.crt = 1;
1284 break; 1360 break;
1285 case 0x0200: 1361 case ACPI_VIDEO_DISPLAY_TV:
1286 data->flags.tvout = 1; 1362 data->flags.tvout = 1;
1287 break; 1363 break;
1288 default: 1364 case ACPI_VIDEO_DISPLAY_DVI:
1365 data->flags.dvi = 1;
1366 break;
1367 case ACPI_VIDEO_DISPLAY_LCD:
1368 data->flags.lcd = 1;
1369 break;
1370 default:
1371 data->flags.unknown = 1;
1372 break;
1373 }
1374 if(attribute->bios_can_detect)
1375 data->flags.bios = 1;
1376 } else
1289 data->flags.unknown = 1; 1377 data->flags.unknown = 1;
1290 break;
1291 }
1292 1378
1293 acpi_video_device_bind(video, data); 1379 acpi_video_device_bind(video, data);
1294 acpi_video_device_find_cap(data); 1380 acpi_video_device_find_cap(data);
@@ -1401,7 +1487,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1401 return status; 1487 return status;
1402 } 1488 }
1403 1489
1404 dod = (union acpi_object *)buffer.pointer; 1490 dod = buffer.pointer;
1405 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { 1491 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
1406 ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); 1492 ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
1407 status = -EFAULT; 1493 status = -EFAULT;
@@ -1424,7 +1510,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1424 1510
1425 count = 0; 1511 count = 0;
1426 for (i = 0; i < dod->package.count; i++) { 1512 for (i = 0; i < dod->package.count; i++) {
1427 obj = (union acpi_object *)&dod->package.elements[i]; 1513 obj = &dod->package.elements[i];
1428 1514
1429 if (obj->type != ACPI_TYPE_INTEGER) { 1515 if (obj->type != ACPI_TYPE_INTEGER) {
1430 printk(KERN_ERR PREFIX "Invalid _DOD data\n"); 1516 printk(KERN_ERR PREFIX "Invalid _DOD data\n");
@@ -1507,8 +1593,34 @@ static int
1507acpi_video_get_next_level(struct acpi_video_device *device, 1593acpi_video_get_next_level(struct acpi_video_device *device,
1508 u32 level_current, u32 event) 1594 u32 level_current, u32 event)
1509{ 1595{
1510 /*Fix me */ 1596 int min, max, min_above, max_below, i, l;
1511 return level_current; 1597 max = max_below = 0;
1598 min = min_above = 255;
1599 for (i = 0; i < device->brightness->count; i++) {
1600 l = device->brightness->levels[i];
1601 if (l < min)
1602 min = l;
1603 if (l > max)
1604 max = l;
1605 if (l < min_above && l > level_current)
1606 min_above = l;
1607 if (l > max_below && l < level_current)
1608 max_below = l;
1609 }
1610
1611 switch (event) {
1612 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
1613 return (level_current < max) ? min_above : min;
1614 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
1615 return (level_current < max) ? min_above : max;
1616 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
1617 return (level_current > min) ? max_below : min;
1618 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
1619 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
1620 return 0;
1621 default:
1622 return level_current;
1623 }
1512} 1624}
1513 1625
1514static void 1626static void
@@ -1566,7 +1678,10 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1566 status = acpi_remove_notify_handler(device->dev->handle, 1678 status = acpi_remove_notify_handler(device->dev->handle,
1567 ACPI_DEVICE_NOTIFY, 1679 ACPI_DEVICE_NOTIFY,
1568 acpi_video_device_notify); 1680 acpi_video_device_notify);
1569 1681 if (device->backlight){
1682 backlight_device_unregister(device->backlight);
1683 kfree(device->data);
1684 }
1570 return 0; 1685 return 0;
1571} 1686}
1572 1687
@@ -1610,7 +1725,7 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
1610 1725
1611static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) 1726static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1612{ 1727{
1613 struct acpi_video_bus *video = (struct acpi_video_bus *)data; 1728 struct acpi_video_bus *video = data;
1614 struct acpi_device *device = NULL; 1729 struct acpi_device *device = NULL;
1615 1730
1616 printk("video bus notify\n"); 1731 printk("video bus notify\n");
@@ -1652,12 +1767,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1652 1767
1653static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) 1768static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1654{ 1769{
1655 struct acpi_video_device *video_device = 1770 struct acpi_video_device *video_device = data;
1656 (struct acpi_video_device *)data;
1657 struct acpi_device *device = NULL; 1771 struct acpi_device *device = NULL;
1658 1772
1659
1660 printk("video device notify\n");
1661 if (!video_device) 1773 if (!video_device)
1662 return; 1774 return;
1663 1775
@@ -1694,10 +1806,9 @@ static int acpi_video_bus_add(struct acpi_device *device)
1694 if (!device) 1806 if (!device)
1695 return -EINVAL; 1807 return -EINVAL;
1696 1808
1697 video = kmalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); 1809 video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
1698 if (!video) 1810 if (!video)
1699 return -ENOMEM; 1811 return -ENOMEM;
1700 memset(video, 0, sizeof(struct acpi_video_bus));
1701 1812
1702 video->device = device; 1813 video->device = device;
1703 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); 1814 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
@@ -1755,7 +1866,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
1755 if (!device || !acpi_driver_data(device)) 1866 if (!device || !acpi_driver_data(device))
1756 return -EINVAL; 1867 return -EINVAL;
1757 1868
1758 video = (struct acpi_video_bus *)acpi_driver_data(device); 1869 video = acpi_driver_data(device);
1759 1870
1760 acpi_video_bus_stop_devices(video); 1871 acpi_video_bus_stop_devices(video);
1761 1872