]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/acpi/video.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[mv-sheeva.git] / drivers / acpi / video.c
index 79409c9d2ad6f5e3499ac3ccfc533731ccd73444..f261737636da7a5550c6ac26ab3d178c6220ab9a 100644 (file)
 #include <linux/backlight.h>
 #include <linux/thermal.h>
 #include <linux/video_output.h>
+#include <linux/sort.h>
 #include <asm/uaccess.h>
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define ACPI_VIDEO_COMPONENT           0x08000000
 #define ACPI_VIDEO_CLASS               "video"
 #define ACPI_VIDEO_BUS_NAME            "Video Bus"
 #define ACPI_VIDEO_DEVICE_NAME         "Video Device"
@@ -482,6 +482,7 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
        int status = AE_OK;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
+       int state;
 
 
        arg0.integer.value = level;
@@ -490,6 +491,10 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
                status = acpi_evaluate_object(device->dev->handle, "_BCM",
                                              &args, NULL);
        device->brightness->curr = level;
+       for (state = 2; state < device->brightness->count; state++)
+               if (level == device->brightness->levels[state])
+                       device->backlight->props.brightness = state - 2;
+
        return status;
 }
 
@@ -626,6 +631,16 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
        return status;
 }
 
+/*
+ * Simple comparison function used to sort backlight levels.
+ */
+
+static int
+acpi_video_cmp_level(const void *a, const void *b)
+{
+       return *(int *)a - *(int *)b;
+}
+
 /*
  *  Arg:       
  *     device  : video output device (LCD, CRT, ..)
@@ -677,6 +692,10 @@ acpi_video_init_brightness(struct acpi_video_device *device)
                count++;
        }
 
+       /* don't sort the first two brightness levels */
+       sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
+               acpi_video_cmp_level, NULL);
+
        if (count < 2)
                goto out_free_levels;
 
@@ -739,7 +758,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
                device->cap._DSS = 1;
        }
 
-       max_level = acpi_video_init_brightness(device);
+       if (acpi_video_backlight_support())
+               max_level = acpi_video_init_brightness(device);
 
        if (device->cap._BCL && device->cap._BCM && max_level > 0) {
                int result;
@@ -785,18 +805,21 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
                        printk(KERN_ERR PREFIX "Create sysfs link\n");
 
        }
-       if (device->cap._DCS && device->cap._DSS){
-               static int count = 0;
-               char *name;
-               name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
-               if (!name)
-                       return;
-               sprintf(name, "acpi_video%d", count++);
-               device->output_dev = video_output_register(name,
-                               NULL, device, &acpi_output_properties);
-               kfree(name);
+
+       if (acpi_video_display_switch_support()) {
+
+               if (device->cap._DCS && device->cap._DSS) {
+                       static int count;
+                       char *name;
+                       name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
+                       if (!name)
+                               return;
+                       sprintf(name, "acpi_video%d", count++);
+                       device->output_dev = video_output_register(name,
+                                       NULL, device, &acpi_output_properties);
+                       kfree(name);
+               }
        }
-       return;
 }
 
 /*
@@ -842,11 +865,16 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
 static int acpi_video_bus_check(struct acpi_video_bus *video)
 {
        acpi_status status = -ENOENT;
-
+       struct device *dev;
 
        if (!video)
                return -EINVAL;
 
+       dev = acpi_get_physical_pci_device(video->device->handle);
+       if (!dev)
+               return -ENODEV;
+       put_device(dev);
+
        /* Since there is no HID, CID and so on for VGA driver, we have
         * to check well known required nodes.
         */
@@ -1491,7 +1519,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
 
                strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
                strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
-               acpi_driver_data(device) = data;
+               device->driver_data = data;
 
                data->device_id = device_id;
                data->video = video;
@@ -1530,8 +1558,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
                                                     acpi_video_device_notify,
                                                     data);
                if (ACPI_FAILURE(status)) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                         "Error installing notify handler\n"));
+                       printk(KERN_ERR PREFIX
+                                         "Error installing notify handler\n");
                        if(data->brightness)
                                kfree(data->brightness->levels);
                        kfree(data->brightness);
@@ -1745,8 +1773,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
 
                status = acpi_video_bus_get_one_device(dev, video);
                if (ACPI_FAILURE(status)) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-                                       "Cant attach device"));
+                       printk(KERN_WARNING PREFIX
+                                       "Cant attach device");
                        continue;
                }
        }
@@ -1982,7 +2010,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
        video->device = device;
        strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
        strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
-       acpi_driver_data(device) = video;
+       device->driver_data = video;
 
        acpi_video_bus_find_cap(video);
        error = acpi_video_bus_check(video);
@@ -2003,8 +2031,8 @@ static int acpi_video_bus_add(struct acpi_device *device)
                                             ACPI_DEVICE_NOTIFY,
                                             acpi_video_bus_notify, video);
        if (ACPI_FAILURE(status)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                 "Error installing notify handler\n"));
+               printk(KERN_ERR PREFIX
+                                 "Error installing notify handler\n");
                error = -ENODEV;
                goto err_stop_video;
        }
@@ -2058,7 +2086,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
        acpi_video_bus_remove_fs(device);
  err_free_video:
        kfree(video);
-       acpi_driver_data(device) = NULL;
+       device->driver_data = NULL;
 
        return error;
 }
@@ -2094,12 +2122,6 @@ static int __init acpi_video_init(void)
 {
        int result = 0;
 
-
-       /*
-          acpi_dbg_level = 0xFFFFFFFF;
-          acpi_dbg_layer = 0x08000000;
-        */
-
        acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
        if (!acpi_video_dir)
                return -ENODEV;