View | Details | Raw Unified | Return to bug 9614 | Differences between
and this patch

Collapse All | Expand All

(-)a/drivers/acpi/video_detect.c (-1 / +223 lines)
Line 0 Link Here
0
- 
1
/*
2
 * video_detect.c:
3
 * Provides acpi_is_video_device() for early scanning of ACPI devices in scan.c
4
 * There a Linux specific (Spec does not provide a HID for video devices) is
5
 * assinged
6
 *
7
 * After PCI devices are glued with ACPI devices
8
 * acpi_get_physical_pci_device() can be called to identify ACPI graphics
9
 * devices for which a real graphics card is plugged in
10
 *
11
 * Now acpi_video_get_capabilities() can be called to check which
12
 * capabilities the graphics cards plugged in support.
13
 *
14
 * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B)
15
 * are available, video.ko should be used to handle the device.
16
 *
17
 * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi,
18
 * sony_acpi,... can take care about backlight brightness and display output
19
 * switching.
20
 *
21
 * Copyright 2008   Thomas Renninger <trenn@suse.de>
22
 */
23
24
/* If video.ko is not selected, we do not need to protect vendor acpi drivers */
25
#if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE)
26
27
#include <linux/acpi.h>
28
29
ACPI_MODULE_NAME("video");
30
#define ACPI_VIDEO_COMPONENT		0x08000000
31
#define _COMPONENT		ACPI_VIDEO_COMPONENT
32
33
/* video/backlight support */
34
#define ACPI_VIDEO_OUTPUT_SWITCHING			1
35
#define ACPI_VIDEO_DEVICE_POSTING			2
36
#define ACPI_VIDEO_ROM_AVAILABLE			4
37
#define ACPI_VIDEO_BACKLIGHT				8
38
#define ACPI_VIDEO_IGD					16
39
#define ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR		32
40
#define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR	64
41
42
long acpi_video_support;
43
EXPORT_SYMBOL(acpi_video_support);
44
45
static __devinit acpi_status
46
acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
47
			  void **retyurn_value)
48
{
49
	long *cap = context;
50
	acpi_handle h_dummy;
51
52
	if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) &&
53
	    ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) {
54
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
55
				  "support\n"));
56
		*cap |= ACPI_VIDEO_BACKLIGHT;
57
		return 0;
58
	}
59
	return -ENODEV;
60
}
61
62
/* Returns true if the device is a video device which can be handled by
63
 * video.ko.
64
 * The device will get a Linux specific CID added in scan.c to
65
 * identify the device as an ACPI graphics device
66
 * Be aware that the graphics device may not be physically present
67
 * Use acpi_video_get_capabilities() to detect general ACPI video
68
 * capabilities of present cards
69
 */
70
long acpi_is_video_device(struct acpi_device *device)
71
{
72
	acpi_handle h_dummy;
73
	long video_caps = 0;
74
75
	if (!device)
76
		return 0;
77
78
	/* Since there is no HID, CID for ACPI Video drivers, we have
79
	 * to check well known required nodes for each feature we support.
80
	 */
81
82
	/* Does this device able to support video switching ? */
83
	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
84
	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
85
		video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
86
87
	/* Does this device able to retrieve a video ROM ? */
88
	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
89
		video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
90
91
	/* Does this device able to configure which video head to be POSTed ? */
92
	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
93
	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
94
	    ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
95
		video_caps |= ACPI_VIDEO_DEVICE_POSTING;
96
97
	if (ACPI_SUCCESS(acpi_get_handle(device->handle, "DRDY", &h_dummy))) {
98
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IGD device\n"));
99
		video_caps |= ACPI_VIDEO_IGD;
100
	}
101
102
	acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle, ACPI_UINT32_MAX,
103
			    acpi_backlight_cap_match, &video_caps, NULL);
104
105
	return video_caps;
106
}
107
EXPORT_SYMBOL(acpi_is_video_device);
108
109
static __devinit acpi_status
110
find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
111
{
112
	long *cap = context;
113
	struct device *dev;
114
	struct acpi_device *acpi_dev;
115
116
	const struct acpi_device_id video_ids[] = {
117
		{ACPI_VIDEO_HID, 0},
118
		{"", 0},
119
	};
120
	acpi_bus_get_device(handle, &acpi_dev);
121
122
	if (!acpi_match_device_ids(acpi_dev, video_ids)) {
123
		dev = acpi_get_physical_pci_device(handle);
124
		if (!dev)
125
			return AE_OK;
126
		put_device(dev);
127
		*cap |= acpi_is_video_device(acpi_dev);
128
		printk("We have 0x%lX vid support\n", *cap);
129
	}
130
	return AE_OK;
131
}
132
133
long __devinit acpi_video_get_capabilities(void)
134
{
135
	long video_caps = 0;
136
137
	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
138
			    ACPI_UINT32_MAX, find_video, &video_caps, NULL);
139
	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support\n",
140
			  video_caps));
141
	return video_caps;
142
}
143
144
/* Returns true if video.ko can do backlight switching
145
 *
146
 * ToDo: Remove the IGD check as soon as there is a working driver
147
 * for it available
148
 */
149
int acpi_video_backlight_support(void)
150
{
151
152
	if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR)
153
		return 0;
154
155
	return (acpi_video_support & ACPI_VIDEO_BACKLIGHT) &&
156
		!(acpi_video_support & ACPI_VIDEO_IGD);
157
}
158
EXPORT_SYMBOL(acpi_video_backlight_support);
159
160
/* Returns true if video.ko can do display output switching.
161
 * This does not work well/at all with binary graphics drivers
162
 * which disable system io ranges and do it on their own.
163
 *
164
 * It should work well when we have an IGD driver for Intel
165
 * graphics cards.
166
 */
167
int acpi_video_display_switch_support(void)
168
{
169
170
	if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR)
171
		return 0;
172
	return (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING) &&
173
		!(acpi_video_support & ACPI_VIDEO_IGD);
174
}
175
EXPORT_SYMBOL(acpi_video_display_switch_support);
176
177
/* Use acpi_video_vendor=backlight,display_output
178
 * To force that backlight or display output switching is processed by vendor
179
 * specific acpi drivers instead of the ACPI video.ko driver
180
 */
181
int __init acpi_vendor(char *str)
182
{
183
	if (str == NULL || *str == '\0')
184
		return 1;
185
	else {
186
		if (!strcmp("backlight", str))
187
			acpi_video_support &=
188
				ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR;
189
		if (!strcmp("display_output", str))
190
			acpi_video_support &=
191
				ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR;
192
	}
193
	return 1;
194
}
195
__setup("acpi_vendor=", acpi_vendor);
196
197
#else
198
199
long acpi_video_get_capabilities(void)
200
{
201
	return 0;
202
}
203
EXPORT_SYMBOL(acpi_video_get_capabilities);
204
205
long acpi_is_video_device(struct acpi_device *device)
206
{
207
	return 0;
208
}
209
EXPORT_SYMBOL(acpi_is_video_device);
210
211
int acpi_video_backlight_support(void)
212
{
213
	return 0;
214
}
215
EXPORT_SYMBOL(acpi_video_backlight_support);
216
217
int acpi_video_display_switch_support()
218
{
219
	return 0;
220
}
221
EXPORT_SYMBOL(acpi_video_display_switch_support);
222
223
#endif /* defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) */

Return to bug 9614