]> err.no Git - linux-2.6/blobdiff - drivers/acpi/video.c
Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
[linux-2.6] / drivers / acpi / video.c
index 4b09a021b434046232563d5e0573ad7bbbd5d7eb..bf525cca3b637160a3c1b28f95269ea108c1dfd3 100644 (file)
@@ -40,7 +40,6 @@
 
 #define ACPI_VIDEO_COMPONENT           0x08000000
 #define ACPI_VIDEO_CLASS               "video"
-#define ACPI_VIDEO_DRIVER_NAME         "ACPI Video Driver"
 #define ACPI_VIDEO_BUS_NAME            "Video Bus"
 #define ACPI_VIDEO_DEVICE_NAME         "Video Device"
 #define ACPI_VIDEO_NOTIFY_SWITCH       0x80
 #define ACPI_VIDEO_HEAD_END            (~0u)
 #define MAX_NAME_LEN   20
 
+#define ACPI_VIDEO_DISPLAY_CRT 1
+#define ACPI_VIDEO_DISPLAY_TV  2
+#define ACPI_VIDEO_DISPLAY_DVI 3
+#define ACPI_VIDEO_DISPLAY_LCD 4
+
 #define _COMPONENT             ACPI_VIDEO_COMPONENT
-ACPI_MODULE_NAME("acpi_video")
+ACPI_MODULE_NAME("video");
 
-    MODULE_AUTHOR("Bruno Ducrot");
-MODULE_DESCRIPTION(ACPI_VIDEO_DRIVER_NAME);
+MODULE_AUTHOR("Bruno Ducrot");
+MODULE_DESCRIPTION("ACPI Video Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
-static int acpi_video_bus_match(struct acpi_device *device,
-                               struct acpi_driver *driver);
 
 static struct acpi_driver acpi_video_bus = {
-       .name = ACPI_VIDEO_DRIVER_NAME,
+       .name = "video",
        .class = ACPI_VIDEO_CLASS,
+       .ids = ACPI_VIDEO_HID,
        .ops = {
                .add = acpi_video_bus_add,
                .remove = acpi_video_bus_remove,
-               .match = acpi_video_bus_match,
                },
 };
 
@@ -135,9 +137,10 @@ struct acpi_video_device_flags {
        u8 crt:1;
        u8 lcd:1;
        u8 tvout:1;
+       u8 dvi:1;
        u8 bios:1;
        u8 unknown:1;
-       u8 reserved:3;
+       u8 reserved:2;
 };
 
 struct acpi_video_device_cap {
@@ -415,7 +418,7 @@ acpi_video_device_EDID(struct acpi_video_device *device,
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       obj = (union acpi_object *)buffer.pointer;
+       obj = buffer.pointer;
 
        if (obj && obj->type == ACPI_TYPE_BUFFER)
                *edid = obj;
@@ -564,11 +567,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
                int count = 0;
                union acpi_object *o;
 
-               br = kmalloc(sizeof(*br), GFP_KERNEL);
+               br = kzalloc(sizeof(*br), GFP_KERNEL);
                if (!br) {
                        printk(KERN_ERR "can't allocate memory\n");
                } else {
-                       memset(br, 0, sizeof(*br));
                        br->levels = kmalloc(obj->package.count *
                                             sizeof *(br->levels), GFP_KERNEL);
                        if (!br->levels)
@@ -719,8 +721,7 @@ static struct proc_dir_entry *acpi_video_dir;
 
 static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
 {
-       struct acpi_video_device *dev =
-           (struct acpi_video_device *)seq->private;
+       struct acpi_video_device *dev = seq->private;
 
 
        if (!dev)
@@ -734,6 +735,8 @@ static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
                seq_printf(seq, "LCD\n");
        else if (dev->flags.tvout)
                seq_printf(seq, "TVOUT\n");
+       else if (dev->flags.dvi)
+               seq_printf(seq, "DVI\n");
        else
                seq_printf(seq, "UNKNOWN\n");
 
@@ -753,8 +756,7 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
 static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
 {
        int status;
-       struct acpi_video_device *dev =
-           (struct acpi_video_device *)seq->private;
+       struct acpi_video_device *dev = seq->private;
        unsigned long state;
 
 
@@ -792,8 +794,8 @@ acpi_video_device_write_state(struct file *file,
                              size_t count, loff_t * data)
 {
        int status;
-       struct seq_file *m = (struct seq_file *)file->private_data;
-       struct acpi_video_device *dev = (struct acpi_video_device *)m->private;
+       struct seq_file *m = file->private_data;
+       struct acpi_video_device *dev = m->private;
        char str[12] = { 0 };
        u32 state = 0;
 
@@ -819,8 +821,7 @@ acpi_video_device_write_state(struct file *file,
 static int
 acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
 {
-       struct acpi_video_device *dev =
-           (struct acpi_video_device *)seq->private;
+       struct acpi_video_device *dev = seq->private;
        int i;
 
 
@@ -849,8 +850,8 @@ acpi_video_device_write_brightness(struct file *file,
                                   const char __user * buffer,
                                   size_t count, loff_t * data)
 {
-       struct seq_file *m = (struct seq_file *)file->private_data;
-       struct acpi_video_device *dev = (struct acpi_video_device *)m->private;
+       struct seq_file *m = file->private_data;
+       struct acpi_video_device *dev = m->private;
        char str[4] = { 0 };
        unsigned int level = 0;
        int i;
@@ -882,8 +883,7 @@ acpi_video_device_write_brightness(struct file *file,
 
 static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
 {
-       struct acpi_video_device *dev =
-           (struct acpi_video_device *)seq->private;
+       struct acpi_video_device *dev = seq->private;
        int status;
        int i;
        union acpi_object *edid = NULL;
@@ -931,7 +931,7 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
        if (!device)
                return -ENODEV;
 
-       vid_dev = (struct acpi_video_device *)acpi_driver_data(device);
+       vid_dev = acpi_driver_data(device);
        if (!vid_dev)
                return -ENODEV;
 
@@ -996,7 +996,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device)
 {
        struct acpi_video_device *vid_dev;
 
-       vid_dev = (struct acpi_video_device *)acpi_driver_data(device);
+       vid_dev = acpi_driver_data(device);
        if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
                return -ENODEV;
 
@@ -1015,7 +1015,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device)
 /* video bus */
 static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
 {
-       struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+       struct acpi_video_bus *video = seq->private;
 
 
        if (!video)
@@ -1040,7 +1040,7 @@ static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
 
 static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
 {
-       struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+       struct acpi_video_bus *video = seq->private;
 
 
        if (!video)
@@ -1060,7 +1060,7 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
 
 static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
 {
-       struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+       struct acpi_video_bus *video = seq->private;
        unsigned long options;
        int status;
 
@@ -1098,7 +1098,7 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
 
 static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
 {
-       struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+       struct acpi_video_bus *video = seq->private;
        int status;
        unsigned long id;
 
@@ -1119,7 +1119,7 @@ static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
 
 static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
 {
-       struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private;
+       struct acpi_video_bus *video = seq->private;
 
 
        seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
@@ -1144,8 +1144,8 @@ acpi_video_bus_write_POST(struct file *file,
                          size_t count, loff_t * data)
 {
        int status;
-       struct seq_file *m = (struct seq_file *)file->private_data;
-       struct acpi_video_bus *video = (struct acpi_video_bus *)m->private;
+       struct seq_file *m = file->private_data;
+       struct acpi_video_bus *video = m->private;
        char str[12] = { 0 };
        unsigned long opt, options;
 
@@ -1184,8 +1184,8 @@ acpi_video_bus_write_DOS(struct file *file,
                         size_t count, loff_t * data)
 {
        int status;
-       struct seq_file *m = (struct seq_file *)file->private_data;
-       struct acpi_video_bus *video = (struct acpi_video_bus *)m->private;
+       struct seq_file *m = file->private_data;
+       struct acpi_video_bus *video = m->private;
        char str[12] = { 0 };
        unsigned long opt;
 
@@ -1215,7 +1215,7 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
        struct acpi_video_bus *video;
 
 
-       video = (struct acpi_video_bus *)acpi_driver_data(device);
+       video = acpi_driver_data(device);
 
        if (!acpi_device_dir(device)) {
                acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
@@ -1291,7 +1291,7 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
        struct acpi_video_bus *video;
 
 
-       video = (struct acpi_video_bus *)acpi_driver_data(device);
+       video = acpi_driver_data(device);
 
        if (acpi_device_dir(device)) {
                remove_proc_entry("info", acpi_device_dir(device));
@@ -1311,6 +1311,16 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
    -------------------------------------------------------------------------- */
 
 /* device interface */
+static struct acpi_video_device_attrib*
+acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
+{
+       int count;
+
+       for(count = 0; count < video->attached_count; count++)
+               if((video->attached_array[count].value.int_val & 0xffff) == device_id)
+                       return &(video->attached_array[count].value.attrib);
+       return NULL;
+}
 
 static int
 acpi_video_bus_get_one_device(struct acpi_device *device,
@@ -1319,7 +1329,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
        unsigned long device_id;
        int status;
        struct acpi_video_device *data;
-
+       struct acpi_video_device_attrib* attribute;
 
        if (!device || !video)
                return -EINVAL;
@@ -1328,12 +1338,10 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
            acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
        if (ACPI_SUCCESS(status)) {
 
-               data = kmalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
+               data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
                if (!data)
                        return -ENOMEM;
 
-               memset(data, 0, sizeof(struct acpi_video_device));
-
                strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
                strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
                acpi_driver_data(device) = data;
@@ -1342,20 +1350,30 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
                data->video = video;
                data->dev = device;
 
-               switch (device_id & 0xffff) {
-               case 0x0100:
-                       data->flags.crt = 1;
-                       break;
-               case 0x0400:
-                       data->flags.lcd = 1;
-                       break;
-               case 0x0200:
-                       data->flags.tvout = 1;
-                       break;
-               default:
+               attribute = acpi_video_get_device_attr(video, device_id);
+
+               if((attribute != NULL) && attribute->device_id_scheme) {
+                       switch (attribute->display_type) {
+                       case ACPI_VIDEO_DISPLAY_CRT:
+                               data->flags.crt = 1;
+                               break;
+                       case ACPI_VIDEO_DISPLAY_TV:
+                               data->flags.tvout = 1;
+                               break;
+                       case ACPI_VIDEO_DISPLAY_DVI:
+                               data->flags.dvi = 1;
+                               break;
+                       case ACPI_VIDEO_DISPLAY_LCD:
+                               data->flags.lcd = 1;
+                               break;
+                       default:
+                               data->flags.unknown = 1;
+                               break;
+                       }
+                       if(attribute->bios_can_detect)
+                               data->flags.bios = 1;
+               } else
                        data->flags.unknown = 1;
-                       break;
-               }
 
                acpi_video_device_bind(video, data);
                acpi_video_device_find_cap(data);
@@ -1468,7 +1486,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
                return status;
        }
 
-       dod = (union acpi_object *)buffer.pointer;
+       dod = buffer.pointer;
        if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
                ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
                status = -EFAULT;
@@ -1491,7 +1509,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
 
        count = 0;
        for (i = 0; i < dod->package.count; i++) {
-               obj = (union acpi_object *)&dod->package.elements[i];
+               obj = &dod->package.elements[i];
 
                if (obj->type != ACPI_TYPE_INTEGER) {
                        printk(KERN_ERR PREFIX "Invalid _DOD data\n");
@@ -1706,7 +1724,7 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
 
 static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
 {
-       struct acpi_video_bus *video = (struct acpi_video_bus *)data;
+       struct acpi_video_bus *video = data;
        struct acpi_device *device = NULL;
 
        printk("video bus notify\n");
@@ -1748,12 +1766,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
 
 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
 {
-       struct acpi_video_device *video_device =
-           (struct acpi_video_device *)data;
+       struct acpi_video_device *video_device = data;
        struct acpi_device *device = NULL;
 
-
-       printk("video device notify\n");
        if (!video_device)
                return;
 
@@ -1790,10 +1805,9 @@ static int acpi_video_bus_add(struct acpi_device *device)
        if (!device)
                return -EINVAL;
 
-       video = kmalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
+       video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
        if (!video)
                return -ENOMEM;
-       memset(video, 0, sizeof(struct acpi_video_bus));
 
        video->device = device;
        strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
@@ -1851,7 +1865,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
 
-       video = (struct acpi_video_bus *)acpi_driver_data(device);
+       video = acpi_driver_data(device);
 
        acpi_video_bus_stop_devices(video);
 
@@ -1868,39 +1882,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
        return 0;
 }
 
-static int
-acpi_video_bus_match(struct acpi_device *device, struct acpi_driver *driver)
-{
-       acpi_handle h_dummy1;
-       acpi_handle h_dummy2;
-       acpi_handle h_dummy3;
-
-
-       if (!device || !driver)
-               return -EINVAL;
-
-       /* Since there is no HID, CID for ACPI Video drivers, we have
-        * to check well known required nodes for each feature we support.
-        */
-
-       /* Does this device able to support video switching ? */
-       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) &&
-           ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2)))
-               return 0;
-
-       /* Does this device able to retrieve a video ROM ? */
-       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1)))
-               return 0;
-
-       /* Does this device able to configure which video head to be POSTed ? */
-       if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) &&
-           ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) &&
-           ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3)))
-               return 0;
-
-       return -ENODEV;
-}
-
 static int __init acpi_video_init(void)
 {
        int result = 0;