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.c118
1 files changed, 106 insertions, 12 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index a0c93b321482..9865d46f49a8 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -45,6 +45,7 @@
45#include <acpi/acpi_bus.h> 45#include <acpi/acpi_bus.h>
46#include <acpi/acpi_drivers.h> 46#include <acpi/acpi_drivers.h>
47#include <linux/suspend.h> 47#include <linux/suspend.h>
48#include <acpi/video.h>
48 49
49#define PREFIX "ACPI: " 50#define PREFIX "ACPI: "
50 51
@@ -65,11 +66,6 @@
65 66
66#define MAX_NAME_LEN 20 67#define MAX_NAME_LEN 20
67 68
68#define ACPI_VIDEO_DISPLAY_CRT 1
69#define ACPI_VIDEO_DISPLAY_TV 2
70#define ACPI_VIDEO_DISPLAY_DVI 3
71#define ACPI_VIDEO_DISPLAY_LCD 4
72
73#define _COMPONENT ACPI_VIDEO_COMPONENT 69#define _COMPONENT ACPI_VIDEO_COMPONENT
74ACPI_MODULE_NAME("video"); 70ACPI_MODULE_NAME("video");
75 71
@@ -1007,11 +1003,11 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
1007 result = acpi_video_init_brightness(device); 1003 result = acpi_video_init_brightness(device);
1008 if (result) 1004 if (result)
1009 return; 1005 return;
1010 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); 1006 name = kasprintf(GFP_KERNEL, "acpi_video%d", count);
1011 if (!name) 1007 if (!name)
1012 return; 1008 return;
1009 count++;
1013 1010
1014 sprintf(name, "acpi_video%d", count++);
1015 memset(&props, 0, sizeof(struct backlight_properties)); 1011 memset(&props, 0, sizeof(struct backlight_properties));
1016 props.max_brightness = device->brightness->count - 3; 1012 props.max_brightness = device->brightness->count - 3;
1017 device->backlight = backlight_device_register(name, NULL, device, 1013 device->backlight = backlight_device_register(name, NULL, device,
@@ -1067,10 +1063,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
1067 if (device->cap._DCS && device->cap._DSS) { 1063 if (device->cap._DCS && device->cap._DSS) {
1068 static int count; 1064 static int count;
1069 char *name; 1065 char *name;
1070 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); 1066 name = kasprintf(GFP_KERNEL, "acpi_video%d", count);
1071 if (!name) 1067 if (!name)
1072 return; 1068 return;
1073 sprintf(name, "acpi_video%d", count++); 1069 count++;
1074 device->output_dev = video_output_register(name, 1070 device->output_dev = video_output_register(name,
1075 NULL, device, &acpi_output_properties); 1071 NULL, device, &acpi_output_properties);
1076 kfree(name); 1072 kfree(name);
@@ -1748,11 +1744,27 @@ acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id
1748} 1744}
1749 1745
1750static int 1746static int
1747acpi_video_get_device_type(struct acpi_video_bus *video,
1748 unsigned long device_id)
1749{
1750 struct acpi_video_enumerated_device *ids;
1751 int i;
1752
1753 for (i = 0; i < video->attached_count; i++) {
1754 ids = &video->attached_array[i];
1755 if ((ids->value.int_val & 0xffff) == device_id)
1756 return ids->value.int_val;
1757 }
1758
1759 return 0;
1760}
1761
1762static int
1751acpi_video_bus_get_one_device(struct acpi_device *device, 1763acpi_video_bus_get_one_device(struct acpi_device *device,
1752 struct acpi_video_bus *video) 1764 struct acpi_video_bus *video)
1753{ 1765{
1754 unsigned long long device_id; 1766 unsigned long long device_id;
1755 int status; 1767 int status, device_type;
1756 struct acpi_video_device *data; 1768 struct acpi_video_device *data;
1757 struct acpi_video_device_attrib* attribute; 1769 struct acpi_video_device_attrib* attribute;
1758 1770
@@ -1797,8 +1809,25 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1797 } 1809 }
1798 if(attribute->bios_can_detect) 1810 if(attribute->bios_can_detect)
1799 data->flags.bios = 1; 1811 data->flags.bios = 1;
1800 } else 1812 } else {
1801 data->flags.unknown = 1; 1813 /* Check for legacy IDs */
1814 device_type = acpi_video_get_device_type(video,
1815 device_id);
1816 /* Ignore bits 16 and 18-20 */
1817 switch (device_type & 0xffe2ffff) {
1818 case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR:
1819 data->flags.crt = 1;
1820 break;
1821 case ACPI_VIDEO_DISPLAY_LEGACY_PANEL:
1822 data->flags.lcd = 1;
1823 break;
1824 case ACPI_VIDEO_DISPLAY_LEGACY_TV:
1825 data->flags.tvout = 1;
1826 break;
1827 default:
1828 data->flags.unknown = 1;
1829 }
1830 }
1802 1831
1803 acpi_video_device_bind(video, data); 1832 acpi_video_device_bind(video, data);
1804 acpi_video_device_find_cap(data); 1833 acpi_video_device_find_cap(data);
@@ -2032,6 +2061,71 @@ out:
2032 return result; 2061 return result;
2033} 2062}
2034 2063
2064int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
2065 void **edid)
2066{
2067 struct acpi_video_bus *video;
2068 struct acpi_video_device *video_device;
2069 union acpi_object *buffer = NULL;
2070 acpi_status status;
2071 int i, length;
2072
2073 if (!device || !acpi_driver_data(device))
2074 return -EINVAL;
2075
2076 video = acpi_driver_data(device);
2077
2078 for (i = 0; i < video->attached_count; i++) {
2079 video_device = video->attached_array[i].bind_info;
2080 length = 256;
2081
2082 if (!video_device)
2083 continue;
2084
2085 if (type) {
2086 switch (type) {
2087 case ACPI_VIDEO_DISPLAY_CRT:
2088 if (!video_device->flags.crt)
2089 continue;
2090 break;
2091 case ACPI_VIDEO_DISPLAY_TV:
2092 if (!video_device->flags.tvout)
2093 continue;
2094 break;
2095 case ACPI_VIDEO_DISPLAY_DVI:
2096 if (!video_device->flags.dvi)
2097 continue;
2098 break;
2099 case ACPI_VIDEO_DISPLAY_LCD:
2100 if (!video_device->flags.lcd)
2101 continue;
2102 break;
2103 }
2104 } else if (video_device->device_id != device_id) {
2105 continue;
2106 }
2107
2108 status = acpi_video_device_EDID(video_device, &buffer, length);
2109
2110 if (ACPI_FAILURE(status) || !buffer ||
2111 buffer->type != ACPI_TYPE_BUFFER) {
2112 length = 128;
2113 status = acpi_video_device_EDID(video_device, &buffer,
2114 length);
2115 if (ACPI_FAILURE(status) || !buffer ||
2116 buffer->type != ACPI_TYPE_BUFFER) {
2117 continue;
2118 }
2119 }
2120
2121 *edid = buffer->buffer.pointer;
2122 return length;
2123 }
2124
2125 return -ENODEV;
2126}
2127EXPORT_SYMBOL(acpi_video_get_edid);
2128
2035static int 2129static int
2036acpi_video_bus_get_devices(struct acpi_video_bus *video, 2130acpi_video_bus_get_devices(struct acpi_video_bus *video,
2037 struct acpi_device *device) 2131 struct acpi_device *device)