diff options
| -rw-r--r-- | drivers/acpi/video.c | 110 | ||||
| -rw-r--r-- | drivers/acpi/video_detect.c | 2 | ||||
| -rw-r--r-- | include/acpi/video.h | 16 |
3 files changed, 119 insertions, 9 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a0c93b321482..4b8bda1154db 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 |
| 74 | ACPI_MODULE_NAME("video"); | 70 | ACPI_MODULE_NAME("video"); |
| 75 | 71 | ||
| @@ -1748,11 +1744,27 @@ acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id | |||
| 1748 | } | 1744 | } |
| 1749 | 1745 | ||
| 1750 | static int | 1746 | static int |
| 1747 | acpi_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 | |||
| 1762 | static int | ||
| 1751 | acpi_video_bus_get_one_device(struct acpi_device *device, | 1763 | acpi_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 | ||
| 2064 | int 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 | } | ||
| 2127 | EXPORT_SYMBOL(acpi_video_get_edid); | ||
| 2128 | |||
| 2035 | static int | 2129 | static int |
| 2036 | acpi_video_bus_get_devices(struct acpi_video_bus *video, | 2130 | acpi_video_bus_get_devices(struct acpi_video_bus *video, |
| 2037 | struct acpi_device *device) | 2131 | struct acpi_device *device) |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index fc2f26b9b407..c5fef01b3c95 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
| @@ -250,7 +250,7 @@ static int __init acpi_backlight(char *str) | |||
| 250 | ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; | 250 | ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; |
| 251 | if (!strcmp("video", str)) | 251 | if (!strcmp("video", str)) |
| 252 | acpi_video_support |= | 252 | acpi_video_support |= |
| 253 | ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; | 253 | ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO; |
| 254 | } | 254 | } |
| 255 | return 1; | 255 | return 1; |
| 256 | } | 256 | } |
diff --git a/include/acpi/video.h b/include/acpi/video.h index cf7be3dd157b..551793c9b6e8 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h | |||
| @@ -1,12 +1,28 @@ | |||
| 1 | #ifndef __ACPI_VIDEO_H | 1 | #ifndef __ACPI_VIDEO_H |
| 2 | #define __ACPI_VIDEO_H | 2 | #define __ACPI_VIDEO_H |
| 3 | 3 | ||
| 4 | #define ACPI_VIDEO_DISPLAY_CRT 1 | ||
| 5 | #define ACPI_VIDEO_DISPLAY_TV 2 | ||
| 6 | #define ACPI_VIDEO_DISPLAY_DVI 3 | ||
| 7 | #define ACPI_VIDEO_DISPLAY_LCD 4 | ||
| 8 | |||
| 9 | #define ACPI_VIDEO_DISPLAY_LEGACY_MONITOR 0x0100 | ||
| 10 | #define ACPI_VIDEO_DISPLAY_LEGACY_PANEL 0x0110 | ||
| 11 | #define ACPI_VIDEO_DISPLAY_LEGACY_TV 0x0200 | ||
| 12 | |||
| 4 | #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) | 13 | #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) |
| 5 | extern int acpi_video_register(void); | 14 | extern int acpi_video_register(void); |
| 6 | extern void acpi_video_unregister(void); | 15 | extern void acpi_video_unregister(void); |
| 16 | extern int acpi_video_get_edid(struct acpi_device *device, int type, | ||
| 17 | int device_id, void **edid); | ||
| 7 | #else | 18 | #else |
| 8 | static inline int acpi_video_register(void) { return 0; } | 19 | static inline int acpi_video_register(void) { return 0; } |
| 9 | static inline void acpi_video_unregister(void) { return; } | 20 | static inline void acpi_video_unregister(void) { return; } |
| 21 | static inline int acpi_video_get_edid(struct acpi_device *device, int type, | ||
| 22 | int device_id, void **edid) | ||
| 23 | { | ||
| 24 | return -ENODEV; | ||
| 25 | } | ||
| 10 | #endif | 26 | #endif |
| 11 | 27 | ||
| 12 | #endif | 28 | #endif |
