Blame view
drivers/acpi/video.c
54 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
21fcb34e2 ACPI / video: tri... |
2 |
* video.c - ACPI Video Driver |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 |
* * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> |
f4715189d ACPI: Implement a... |
6 |
* Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net> |
1da177e4c Linux-2.6.12-rc2 |
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/types.h> #include <linux/list.h> |
bbac81f54 ACPI: video - con... |
32 |
#include <linux/mutex.h> |
e9dab1960 ACPI video hotkey... |
33 |
#include <linux/input.h> |
2f3d000a1 ACPI: Adds backli... |
34 |
#include <linux/backlight.h> |
702ed512d ACPI: register AC... |
35 |
#include <linux/thermal.h> |
935e5f290 ACPI: video: Fix ... |
36 |
#include <linux/sort.h> |
74a365b3f ACPI: Populate DI... |
37 38 |
#include <linux/pci.h> #include <linux/pci_ids.h> |
5a0e3ad6a include cleanup: ... |
39 |
#include <linux/slab.h> |
eb27cae8a ACPI: linux/acpi.... |
40 |
#include <linux/dmi.h> |
ac7729da8 ACPI / PM: Move A... |
41 |
#include <linux/suspend.h> |
8b48463f8 ACPI: Clean up in... |
42 |
#include <linux/acpi.h> |
e92a71624 ACPI: Export EDID... |
43 |
#include <acpi/video.h> |
8b48463f8 ACPI: Clean up in... |
44 |
#include <asm/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
45 |
|
8c5bd7adb ACPI / video / i9... |
46 |
#include "internal.h" |
1da177e4c Linux-2.6.12-rc2 |
47 48 49 50 51 52 53 |
#define ACPI_VIDEO_BUS_NAME "Video Bus" #define ACPI_VIDEO_DEVICE_NAME "Video Device" #define ACPI_VIDEO_NOTIFY_SWITCH 0x80 #define ACPI_VIDEO_NOTIFY_PROBE 0x81 #define ACPI_VIDEO_NOTIFY_CYCLE 0x82 #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 |
f4715189d ACPI: Implement a... |
54 55 56 57 58 |
#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85 #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 |
1da177e4c Linux-2.6.12-rc2 |
59 |
|
2f3d000a1 ACPI: Adds backli... |
60 |
#define MAX_NAME_LEN 20 |
1da177e4c Linux-2.6.12-rc2 |
61 |
|
1da177e4c Linux-2.6.12-rc2 |
62 |
#define _COMPONENT ACPI_VIDEO_COMPONENT |
f52fd66d2 ACPI: clean up AC... |
63 |
ACPI_MODULE_NAME("video"); |
1da177e4c Linux-2.6.12-rc2 |
64 |
|
f52fd66d2 ACPI: clean up AC... |
65 |
MODULE_AUTHOR("Bruno Ducrot"); |
7cda93e00 ACPI: delete extr... |
66 |
MODULE_DESCRIPTION("ACPI Video Driver"); |
1da177e4c Linux-2.6.12-rc2 |
67 |
MODULE_LICENSE("GPL"); |
2843768b7 Revert "ACPI / vi... |
68 |
static bool brightness_switch_enabled = 1; |
8a681a4de ACPI: video: crea... |
69 |
module_param(brightness_switch_enabled, bool, 0644); |
c504f8cb6 ACPI video: Prune... |
70 71 72 73 |
/* * By default, we don't allow duplicate ACPI video bus devices * under the same VGA controller */ |
90ab5ee94 module_param: mak... |
74 |
static bool allow_duplicates; |
c504f8cb6 ACPI video: Prune... |
75 |
module_param(allow_duplicates, bool, 0644); |
99fd1895e ACPI video: intro... |
76 |
/* |
0e9f81d3b ACPI / video: Add... |
77 78 |
* For Windows 8 systems: used to decide if video module * should skip registering backlight interface of its own. |
fbc9fe1b4 ACPI / video: Do ... |
79 |
*/ |
25294e9f0 ACPI / video: Fix... |
80 |
static int use_native_backlight_param = -1; |
0e9f81d3b ACPI / video: Add... |
81 |
module_param_named(use_native_backlight, use_native_backlight_param, int, 0444); |
25294e9f0 ACPI / video: Fix... |
82 |
static bool use_native_backlight_dmi = true; |
fbc9fe1b4 ACPI / video: Do ... |
83 |
|
915ea7e41 ACPI / video: tri... |
84 |
static int register_count; |
67b662e18 ACPI / video: sep... |
85 86 |
static struct mutex video_list_lock; static struct list_head video_bus_head; |
4be44fcd3 [ACPI] Lindent al... |
87 |
static int acpi_video_bus_add(struct acpi_device *device); |
51fac8388 ACPI: Remove usel... |
88 |
static int acpi_video_bus_remove(struct acpi_device *device); |
7015558fc ACPI: video: use ... |
89 |
static void acpi_video_bus_notify(struct acpi_device *device, u32 event); |
1da177e4c Linux-2.6.12-rc2 |
90 |
|
1ba90e3a8 ACPI: autoload mo... |
91 92 93 94 95 |
static const struct acpi_device_id video_device_ids[] = { {ACPI_VIDEO_HID, 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, video_device_ids); |
1da177e4c Linux-2.6.12-rc2 |
96 |
static struct acpi_driver acpi_video_bus = { |
c2b6705b7 ACPI: fix acpi_dr... |
97 |
.name = "video", |
1da177e4c Linux-2.6.12-rc2 |
98 |
.class = ACPI_VIDEO_CLASS, |
1ba90e3a8 ACPI: autoload mo... |
99 |
.ids = video_device_ids, |
1da177e4c Linux-2.6.12-rc2 |
100 101 102 |
.ops = { .add = acpi_video_bus_add, .remove = acpi_video_bus_remove, |
7015558fc ACPI: video: use ... |
103 |
.notify = acpi_video_bus_notify, |
4be44fcd3 [ACPI] Lindent al... |
104 |
}, |
1da177e4c Linux-2.6.12-rc2 |
105 106 107 |
}; struct acpi_video_bus_flags { |
4be44fcd3 [ACPI] Lindent al... |
108 109 110 111 |
u8 multihead:1; /* can switch video heads */ u8 rom:1; /* can retrieve a video rom */ u8 post:1; /* can configure the head to */ u8 reserved:5; |
1da177e4c Linux-2.6.12-rc2 |
112 113 114 |
}; struct acpi_video_bus_cap { |
21fcb34e2 ACPI / video: tri... |
115 116 117 118 119 120 |
u8 _DOS:1; /* Enable/Disable output switching */ u8 _DOD:1; /* Enumerate all devices attached to display adapter */ u8 _ROM:1; /* Get ROM Data */ u8 _GPD:1; /* Get POST Device */ u8 _SPD:1; /* Set POST Device */ u8 _VPO:1; /* Video POST Options */ |
4be44fcd3 [ACPI] Lindent al... |
121 |
u8 reserved:2; |
1da177e4c Linux-2.6.12-rc2 |
122 |
}; |
4be44fcd3 [ACPI] Lindent al... |
123 124 |
struct acpi_video_device_attrib { u32 display_index:4; /* A zero-based instance of the Display */ |
21fcb34e2 ACPI / video: tri... |
125 126 127 128 129 |
u32 display_port_attachment:4; /* This field differentiates the display type */ u32 display_type:4; /* Describe the specific type in use */ u32 vendor_specific:4; /* Chipset Vendor Specific */ u32 bios_can_detect:1; /* BIOS can detect the device */ u32 depend_on_vga:1; /* Non-VGA output device whose power is related to |
4be44fcd3 [ACPI] Lindent al... |
130 |
the VGA device. */ |
21fcb34e2 ACPI / video: tri... |
131 132 133 |
u32 pipe_id:3; /* For VGA multiple-head devices. */ u32 reserved:10; /* Must be 0 */ u32 device_id_scheme:1; /* Device ID Scheme */ |
1da177e4c Linux-2.6.12-rc2 |
134 135 136 137 138 |
}; struct acpi_video_enumerated_device { union { u32 int_val; |
4be44fcd3 [ACPI] Lindent al... |
139 |
struct acpi_video_device_attrib attrib; |
1da177e4c Linux-2.6.12-rc2 |
140 141 142 143 144 |
} value; struct acpi_video_device *bind_info; }; struct acpi_video_bus { |
e6afa0de1 ACPI: video: add ... |
145 |
struct acpi_device *device; |
99678ed73 ACPI / video: Don... |
146 |
bool backlight_registered; |
53a92ba7e ACPI / video: Unr... |
147 |
bool backlight_notifier_registered; |
4be44fcd3 [ACPI] Lindent al... |
148 |
u8 dos_setting; |
1da177e4c Linux-2.6.12-rc2 |
149 |
struct acpi_video_enumerated_device *attached_array; |
4be44fcd3 [ACPI] Lindent al... |
150 |
u8 attached_count; |
b4df46367 ACPI / video: upd... |
151 |
u8 child_count; |
4be44fcd3 [ACPI] Lindent al... |
152 |
struct acpi_video_bus_cap cap; |
1da177e4c Linux-2.6.12-rc2 |
153 |
struct acpi_video_bus_flags flags; |
4be44fcd3 [ACPI] Lindent al... |
154 |
struct list_head video_device_list; |
bbac81f54 ACPI: video - con... |
155 |
struct mutex device_list_lock; /* protects video_device_list */ |
67b662e18 ACPI / video: sep... |
156 |
struct list_head entry; |
e9dab1960 ACPI video hotkey... |
157 158 |
struct input_dev *input; char phys[32]; /* for input device */ |
ac7729da8 ACPI / PM: Move A... |
159 |
struct notifier_block pm_nb; |
53a92ba7e ACPI / video: Unr... |
160 |
struct notifier_block backlight_nb; |
1da177e4c Linux-2.6.12-rc2 |
161 162 163 |
}; struct acpi_video_device_flags { |
4be44fcd3 [ACPI] Lindent al... |
164 165 166 |
u8 crt:1; u8 lcd:1; u8 tvout:1; |
82cae9998 ACPI: video: fix ... |
167 |
u8 dvi:1; |
4be44fcd3 [ACPI] Lindent al... |
168 169 |
u8 bios:1; u8 unknown:1; |
91e13aa37 ACPI: video: corr... |
170 171 |
u8 notify:1; u8 reserved:1; |
1da177e4c Linux-2.6.12-rc2 |
172 173 174 |
}; struct acpi_video_device_cap { |
21fcb34e2 ACPI / video: tri... |
175 176 177 |
u8 _ADR:1; /* Return the unique ID */ u8 _BCL:1; /* Query list of brightness control levels supported */ u8 _BCM:1; /* Set the brightness level */ |
2f3d000a1 ACPI: Adds backli... |
178 |
u8 _BQC:1; /* Get current brightness level */ |
c60d638e2 ACPI video: suppo... |
179 |
u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ |
21fcb34e2 ACPI / video: tri... |
180 |
u8 _DDC:1; /* Return the EDID for this device */ |
1da177e4c Linux-2.6.12-rc2 |
181 |
}; |
d32f69470 ACPI video: suppo... |
182 183 |
struct acpi_video_brightness_flags { u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */ |
21fcb34e2 ACPI / video: tri... |
184 |
u8 _BCL_reversed:1; /* _BCL package is in a reversed order */ |
1a7c618a3 ACPI video: suppo... |
185 |
u8 _BQC_use_index:1; /* _BQC returns an index value */ |
d32f69470 ACPI video: suppo... |
186 |
}; |
1da177e4c Linux-2.6.12-rc2 |
187 |
struct acpi_video_device_brightness { |
4be44fcd3 [ACPI] Lindent al... |
188 189 190 |
int curr; int count; int *levels; |
d32f69470 ACPI video: suppo... |
191 |
struct acpi_video_brightness_flags flags; |
1da177e4c Linux-2.6.12-rc2 |
192 193 194 |
}; struct acpi_video_device { |
4be44fcd3 [ACPI] Lindent al... |
195 196 197 198 |
unsigned long device_id; struct acpi_video_device_flags flags; struct acpi_video_device_cap cap; struct list_head entry; |
8ab58e8e7 ACPI / video: Fix... |
199 200 |
struct delayed_work switch_brightness_work; int switch_brightness_event; |
4be44fcd3 [ACPI] Lindent al... |
201 202 |
struct acpi_video_bus *video; struct acpi_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
203 |
struct acpi_video_device_brightness *brightness; |
2f3d000a1 ACPI: Adds backli... |
204 |
struct backlight_device *backlight; |
4a703a8fe ACPI: video - ren... |
205 |
struct thermal_cooling_device *cooling_dev; |
1da177e4c Linux-2.6.12-rc2 |
206 |
}; |
b7171ae74 ACPI: constify VF... |
207 |
static const char device_decode[][30] = { |
1da177e4c Linux-2.6.12-rc2 |
208 209 210 211 212 |
"motherboard VGA device", "PCI VGA device", "AGP VGA device", "UNKNOWN", }; |
4be44fcd3 [ACPI] Lindent al... |
213 214 215 216 |
static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data); static void acpi_video_device_rebind(struct acpi_video_bus *video); static void acpi_video_device_bind(struct acpi_video_bus *video, struct acpi_video_device *device); |
1da177e4c Linux-2.6.12-rc2 |
217 |
static int acpi_video_device_enumerate(struct acpi_video_bus *video); |
2f3d000a1 ACPI: Adds backli... |
218 219 220 221 |
static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level); static int acpi_video_device_lcd_get_level_current( struct acpi_video_device *device, |
a89803df9 ACPI / video: Fix... |
222 |
unsigned long long *level, bool raw); |
4be44fcd3 [ACPI] Lindent al... |
223 224 |
static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event); |
8ab58e8e7 ACPI / video: Fix... |
225 |
static void acpi_video_switch_brightness(struct work_struct *work); |
1da177e4c Linux-2.6.12-rc2 |
226 |
|
0e9f81d3b ACPI / video: Add... |
227 228 229 230 231 232 233 |
static bool acpi_video_use_native_backlight(void) { if (use_native_backlight_param != -1) return use_native_backlight_param; else return use_native_backlight_dmi; } |
0b9f7d93c ACPI / i915: igno... |
234 |
bool acpi_video_verify_backlight_support(void) |
fbc9fe1b4 ACPI / video: Do ... |
235 |
{ |
0e9f81d3b ACPI / video: Add... |
236 |
if (acpi_osi_is_win8() && acpi_video_use_native_backlight() && |
fbc9fe1b4 ACPI / video: Do ... |
237 238 239 240 |
backlight_device_registered(BACKLIGHT_RAW)) return false; return acpi_video_backlight_support(); } |
0b9f7d93c ACPI / i915: igno... |
241 |
EXPORT_SYMBOL_GPL(acpi_video_verify_backlight_support); |
fbc9fe1b4 ACPI / video: Do ... |
242 |
|
21fcb34e2 ACPI / video: tri... |
243 |
/* backlight device sysfs support */ |
2f3d000a1 ACPI: Adds backli... |
244 245 |
static int acpi_video_get_brightness(struct backlight_device *bd) { |
27663c585 ACPI: Change acpi... |
246 |
unsigned long long cur_level; |
38531e6fe ACPI: video: Rati... |
247 |
int i; |
7c364e79a ACPI / video: rem... |
248 |
struct acpi_video_device *vd = bl_get_data(bd); |
c8890f903 ACPI video: check... |
249 |
|
a89803df9 ACPI / video: Fix... |
250 |
if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false)) |
c8890f903 ACPI video: check... |
251 |
return -EINVAL; |
38531e6fe ACPI: video: Rati... |
252 253 |
for (i = 2; i < vd->brightness->count; i++) { if (vd->brightness->levels[i] == cur_level) |
21fcb34e2 ACPI / video: tri... |
254 255 256 257 |
/* * The first two entries are special - see page 575 * of the ACPI spec 3.0 */ |
915ea7e41 ACPI / video: tri... |
258 |
return i - 2; |
38531e6fe ACPI: video: Rati... |
259 260 |
} return 0; |
2f3d000a1 ACPI: Adds backli... |
261 262 263 264 |
} static int acpi_video_set_brightness(struct backlight_device *bd) { |
24450c7ad ACPI video: check... |
265 |
int request_level = bd->props.brightness + 2; |
7c364e79a ACPI / video: rem... |
266 |
struct acpi_video_device *vd = bl_get_data(bd); |
24450c7ad ACPI video: check... |
267 |
|
8ab58e8e7 ACPI / video: Fix... |
268 |
cancel_delayed_work(&vd->switch_brightness_work); |
24450c7ad ACPI video: check... |
269 270 |
return acpi_video_device_lcd_set_level(vd, vd->brightness->levels[request_level]); |
2f3d000a1 ACPI: Adds backli... |
271 |
} |
acc2472ed backlight: consti... |
272 |
static const struct backlight_ops acpi_backlight_ops = { |
599a52d12 backlight: Separa... |
273 274 275 |
.get_brightness = acpi_video_get_brightness, .update_status = acpi_video_set_brightness, }; |
702ed512d ACPI: register AC... |
276 |
/* thermal cooling device callbacks */ |
4a703a8fe ACPI: video - ren... |
277 |
static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned |
6503e5df0 thermal: use inte... |
278 |
long *state) |
702ed512d ACPI: register AC... |
279 |
{ |
4a703a8fe ACPI: video - ren... |
280 |
struct acpi_device *device = cooling_dev->devdata; |
702ed512d ACPI: register AC... |
281 |
struct acpi_video_device *video = acpi_driver_data(device); |
6503e5df0 thermal: use inte... |
282 283 |
*state = video->brightness->count - 3; return 0; |
702ed512d ACPI: register AC... |
284 |
} |
4a703a8fe ACPI: video - ren... |
285 |
static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned |
6503e5df0 thermal: use inte... |
286 |
long *state) |
702ed512d ACPI: register AC... |
287 |
{ |
4a703a8fe ACPI: video - ren... |
288 |
struct acpi_device *device = cooling_dev->devdata; |
702ed512d ACPI: register AC... |
289 |
struct acpi_video_device *video = acpi_driver_data(device); |
27663c585 ACPI: Change acpi... |
290 |
unsigned long long level; |
6503e5df0 thermal: use inte... |
291 |
int offset; |
702ed512d ACPI: register AC... |
292 |
|
a89803df9 ACPI / video: Fix... |
293 |
if (acpi_video_device_lcd_get_level_current(video, &level, false)) |
c8890f903 ACPI video: check... |
294 |
return -EINVAL; |
6503e5df0 thermal: use inte... |
295 296 297 298 299 |
for (offset = 2; offset < video->brightness->count; offset++) if (level == video->brightness->levels[offset]) { *state = video->brightness->count - offset - 1; return 0; } |
702ed512d ACPI: register AC... |
300 301 302 303 304 |
return -EINVAL; } static int |
4a703a8fe ACPI: video - ren... |
305 |
video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state) |
702ed512d ACPI: register AC... |
306 |
{ |
4a703a8fe ACPI: video - ren... |
307 |
struct acpi_device *device = cooling_dev->devdata; |
702ed512d ACPI: register AC... |
308 309 |
struct acpi_video_device *video = acpi_driver_data(device); int level; |
915ea7e41 ACPI / video: tri... |
310 |
if (state >= video->brightness->count - 2) |
702ed512d ACPI: register AC... |
311 312 313 |
return -EINVAL; state = video->brightness->count - state; |
915ea7e41 ACPI / video: tri... |
314 |
level = video->brightness->levels[state - 1]; |
702ed512d ACPI: register AC... |
315 316 |
return acpi_video_device_lcd_set_level(video, level); } |
9c8b04be4 ACPI: constify op... |
317 |
static const struct thermal_cooling_device_ops video_cooling_ops = { |
702ed512d ACPI: register AC... |
318 319 320 321 |
.get_max_state = video_get_max_state, .get_cur_state = video_get_cur_state, .set_cur_state = video_set_cur_state, }; |
21fcb34e2 ACPI / video: tri... |
322 323 324 325 326 |
/* * -------------------------------------------------------------------------- * Video Management * -------------------------------------------------------------------------- */ |
1da177e4c Linux-2.6.12-rc2 |
327 |
|
1da177e4c Linux-2.6.12-rc2 |
328 |
static int |
4be44fcd3 [ACPI] Lindent al... |
329 330 |
acpi_video_device_lcd_query_levels(struct acpi_video_device *device, union acpi_object **levels) |
1da177e4c Linux-2.6.12-rc2 |
331 |
{ |
4be44fcd3 [ACPI] Lindent al... |
332 333 334 |
int status; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; |
1da177e4c Linux-2.6.12-rc2 |
335 |
|
1da177e4c Linux-2.6.12-rc2 |
336 337 |
*levels = NULL; |
901302688 ACPI: video: Use ... |
338 |
status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer); |
1da177e4c Linux-2.6.12-rc2 |
339 |
if (!ACPI_SUCCESS(status)) |
d550d98d3 ACPI: delete trac... |
340 |
return status; |
4be44fcd3 [ACPI] Lindent al... |
341 |
obj = (union acpi_object *)buffer.pointer; |
6665bda76 [ACPI] drivers/ac... |
342 |
if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { |
6468463ab ACPI: un-export A... |
343 344 |
printk(KERN_ERR PREFIX "Invalid _BCL data "); |
1da177e4c Linux-2.6.12-rc2 |
345 346 347 348 349 |
status = -EFAULT; goto err; } *levels = obj; |
d550d98d3 ACPI: delete trac... |
350 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
351 |
|
915ea7e41 ACPI / video: tri... |
352 |
err: |
6044ec888 [PATCH] kfree cle... |
353 |
kfree(buffer.pointer); |
1da177e4c Linux-2.6.12-rc2 |
354 |
|
d550d98d3 ACPI: delete trac... |
355 |
return status; |
1da177e4c Linux-2.6.12-rc2 |
356 357 358 |
} static int |
4be44fcd3 [ACPI] Lindent al... |
359 |
acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) |
1da177e4c Linux-2.6.12-rc2 |
360 |
{ |
24450c7ad ACPI video: check... |
361 |
int status; |
9e6dada9d video: always upd... |
362 |
int state; |
1da177e4c Linux-2.6.12-rc2 |
363 |
|
0db982026 ACPI: introduce h... |
364 365 |
status = acpi_execute_simple_method(device->dev->handle, "_BCM", level); |
24450c7ad ACPI video: check... |
366 367 368 369 |
if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Evaluating _BCM failed")); return -EIO; } |
4500ca8e2 ACPI: video: Don'... |
370 |
device->brightness->curr = level; |
9e6dada9d video: always upd... |
371 |
for (state = 2; state < device->brightness->count; state++) |
24450c7ad ACPI video: check... |
372 |
if (level == device->brightness->levels[state]) { |
1a7c618a3 ACPI video: suppo... |
373 374 |
if (device->backlight) device->backlight->props.brightness = state - 2; |
24450c7ad ACPI video: check... |
375 376 |
return 0; } |
9e6dada9d video: always upd... |
377 |
|
24450c7ad ACPI video: check... |
378 379 |
ACPI_ERROR((AE_INFO, "Current brightness invalid")); return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
380 |
} |
45cb50e64 ACPI video: dmi c... |
381 382 383 384 385 386 387 388 389 390 391 |
/* * For some buggy _BQC methods, we need to add a constant value to * the _BQC return value to get the actual current brightness level */ static int bqc_offset_aml_bug_workaround; static int __init video_set_bqc_offset(const struct dmi_system_id *d) { bqc_offset_aml_bug_workaround = 9; return 0; } |
5f24079b0 ACPI / video: Add... |
392 393 394 395 396 |
static int __init video_disable_native_backlight(const struct dmi_system_id *d) { use_native_backlight_dmi = false; return 0; } |
45cb50e64 ACPI video: dmi c... |
397 398 399 400 401 402 403 404 405 406 407 408 |
static struct dmi_system_id video_dmi_table[] __initdata = { /* * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 */ { .callback = video_set_bqc_offset, .ident = "Acer Aspire 5720", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), }, }, |
5afc4abe7 ACPI: video: DMI ... |
409 410 411 412 413 414 415 416 |
{ .callback = video_set_bqc_offset, .ident = "Acer Aspire 5710Z", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"), }, }, |
34ac272b3 ACPI: video: DMI ... |
417 418 419 420 421 422 423 424 |
{ .callback = video_set_bqc_offset, .ident = "eMachines E510", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"), DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"), }, }, |
93bcece20 ACPI: video: DMI ... |
425 426 427 428 429 430 431 432 |
{ .callback = video_set_bqc_offset, .ident = "Acer Aspire 5315", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), }, }, |
152a4e630 ACPI: video: DMI ... |
433 434 435 436 437 438 439 440 |
{ .callback = video_set_bqc_offset, .ident = "Acer Aspire 7720", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), }, }, |
5f24079b0 ACPI / video: Add... |
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
/* * These models have a working acpi_video backlight control, and using * native backlight causes a regression where backlight does not work * when userspace is not handling brightness key events. Disable * native_backlight on these to fix this: * https://bugzilla.kernel.org/show_bug.cgi?id=81691 */ { .callback = video_disable_native_backlight, .ident = "ThinkPad T420", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T420"), }, }, { .callback = video_disable_native_backlight, .ident = "ThinkPad T520", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T520"), }, }, |
789eeea12 ACPI / video: dis... |
465 466 467 468 469 470 471 472 |
{ .callback = video_disable_native_backlight, .ident = "ThinkPad X201s", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"), }, }, |
84c34858a ACPI / video: Dis... |
473 474 475 476 477 478 479 480 481 482 483 |
/* The native backlight controls do not work on some older machines */ { /* https://bugs.freedesktop.org/show_bug.cgi?id=81515 */ .callback = video_disable_native_backlight, .ident = "HP ENVY 15 Notebook", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"), }, }, |
7d0b93499 ACPI / video: Add... |
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 |
{ .callback = video_disable_native_backlight, .ident = "SAMSUNG 870Z5E/880Z5E/680Z5E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"), }, }, { .callback = video_disable_native_backlight, .ident = "SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "370R4E/370R4V/370R5E/3570RE/370R5V"), }, }, |
45cb50e64 ACPI video: dmi c... |
501 502 |
{} }; |
994fa63c5 ACPI / video: Fix... |
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
static unsigned long long acpi_video_bqc_value_to_level(struct acpi_video_device *device, unsigned long long bqc_value) { unsigned long long level; if (device->brightness->flags._BQC_use_index) { /* * _BQC returns an index that doesn't account for * the first 2 items with special meaning, so we need * to compensate for that by offsetting ourselves */ if (device->brightness->flags._BCL_reversed) bqc_value = device->brightness->count - 3 - bqc_value; level = device->brightness->levels[bqc_value + 2]; } else { level = bqc_value; } level += bqc_offset_aml_bug_workaround; return level; } |
1da177e4c Linux-2.6.12-rc2 |
527 |
static int |
4be44fcd3 [ACPI] Lindent al... |
528 |
acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, |
a89803df9 ACPI / video: Fix... |
529 |
unsigned long long *level, bool raw) |
1da177e4c Linux-2.6.12-rc2 |
530 |
{ |
c8890f903 ACPI video: check... |
531 |
acpi_status status = AE_OK; |
4e231fa4c ACPI video: ignor... |
532 |
int i; |
c8890f903 ACPI video: check... |
533 |
|
c60d638e2 ACPI video: suppo... |
534 535 536 537 |
if (device->cap._BQC || device->cap._BCQ) { char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; status = acpi_evaluate_integer(device->dev->handle, buf, |
c8890f903 ACPI video: check... |
538 539 |
NULL, level); if (ACPI_SUCCESS(status)) { |
a89803df9 ACPI / video: Fix... |
540 541 542 543 544 545 546 547 |
if (raw) { /* * Caller has indicated he wants the raw * value returned by _BQC, so don't furtherly * mess with the value. */ return 0; } |
994fa63c5 ACPI / video: Fix... |
548 |
*level = acpi_video_bqc_value_to_level(device, *level); |
1a7c618a3 ACPI video: suppo... |
549 |
|
4e231fa4c ACPI video: ignor... |
550 551 552 553 |
for (i = 2; i < device->brightness->count; i++) if (device->brightness->levels[i] == *level) { device->brightness->curr = *level; return 0; |
915ea7e41 ACPI / video: tri... |
554 |
} |
a89803df9 ACPI / video: Fix... |
555 556 557 558 559 560 561 562 |
/* * BQC returned an invalid level. * Stop using it. */ ACPI_WARNING((AE_INFO, "%s returned an invalid level", buf)); device->cap._BQC = device->cap._BCQ = 0; |
c8890f903 ACPI video: check... |
563 |
} else { |
21fcb34e2 ACPI / video: tri... |
564 565 |
/* * Fixme: |
c8890f903 ACPI video: check... |
566 567 568 569 570 571 |
* should we return an error or ignore this failure? * dev->brightness->curr is a cached value which stores * the correct current backlight level in most cases. * ACPI video backlight still works w/ buggy _BQC. * http://bugzilla.kernel.org/show_bug.cgi?id=12233 */ |
c60d638e2 ACPI video: suppo... |
572 573 |
ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf)); device->cap._BQC = device->cap._BCQ = 0; |
c8890f903 ACPI video: check... |
574 575 |
} } |
4500ca8e2 ACPI: video: Don'... |
576 |
*level = device->brightness->curr; |
c8890f903 ACPI video: check... |
577 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
578 579 580 |
} static int |
4be44fcd3 [ACPI] Lindent al... |
581 582 |
acpi_video_device_EDID(struct acpi_video_device *device, union acpi_object **edid, ssize_t length) |
1da177e4c Linux-2.6.12-rc2 |
583 |
{ |
4be44fcd3 [ACPI] Lindent al... |
584 585 586 587 588 |
int status; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; |
1da177e4c Linux-2.6.12-rc2 |
589 |
|
1da177e4c Linux-2.6.12-rc2 |
590 591 592 593 |
*edid = NULL; if (!device) |
d550d98d3 ACPI: delete trac... |
594 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
595 596 597 598 599 |
if (length == 128) arg0.integer.value = 1; else if (length == 256) arg0.integer.value = 2; else |
d550d98d3 ACPI: delete trac... |
600 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
601 |
|
901302688 ACPI: video: Use ... |
602 |
status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer); |
1da177e4c Linux-2.6.12-rc2 |
603 |
if (ACPI_FAILURE(status)) |
d550d98d3 ACPI: delete trac... |
604 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
605 |
|
50dd09697 ACPI: Remove unne... |
606 |
obj = buffer.pointer; |
1da177e4c Linux-2.6.12-rc2 |
607 608 609 610 |
if (obj && obj->type == ACPI_TYPE_BUFFER) *edid = obj; else { |
6468463ab ACPI: un-export A... |
611 612 |
printk(KERN_ERR PREFIX "Invalid _DDC data "); |
1da177e4c Linux-2.6.12-rc2 |
613 614 615 |
status = -EFAULT; kfree(obj); } |
d550d98d3 ACPI: delete trac... |
616 |
return status; |
1da177e4c Linux-2.6.12-rc2 |
617 |
} |
1da177e4c Linux-2.6.12-rc2 |
618 |
/* bus */ |
1da177e4c Linux-2.6.12-rc2 |
619 620 |
/* * Arg: |
21fcb34e2 ACPI / video: tri... |
621 622 |
* video : video bus device pointer * bios_flag : |
1da177e4c Linux-2.6.12-rc2 |
623 624 625 |
* 0. The system BIOS should NOT automatically switch(toggle) * the active display output. * 1. The system BIOS should automatically switch (toggle) the |
98fb8fe10 ACPI: video: Fix ... |
626 |
* active display output. No switch event. |
1da177e4c Linux-2.6.12-rc2 |
627 628 629 630 631 632 |
* 2. The _DGS value should be locked. * 3. The system BIOS should not automatically switch (toggle) the * active display output, but instead generate the display switch * event notify code. * lcd_flag : * 0. The system BIOS should automatically control the brightness level |
98fb8fe10 ACPI: video: Fix ... |
633 |
* of the LCD when the power changes from AC to DC |
21fcb34e2 ACPI / video: tri... |
634 |
* 1. The system BIOS should NOT automatically control the brightness |
98fb8fe10 ACPI: video: Fix ... |
635 |
* level of the LCD when the power changes from AC to DC. |
21fcb34e2 ACPI / video: tri... |
636 |
* Return Value: |
ea9f8856b ACPI video: Harde... |
637 |
* -EINVAL wrong arg. |
1da177e4c Linux-2.6.12-rc2 |
638 639 640 |
*/ static int |
4be44fcd3 [ACPI] Lindent al... |
641 |
acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) |
1da177e4c Linux-2.6.12-rc2 |
642 |
{ |
ea9f8856b ACPI video: Harde... |
643 |
acpi_status status; |
1da177e4c Linux-2.6.12-rc2 |
644 |
|
b03738430 ACPI video: Still... |
645 646 |
if (!video->cap._DOS) return 0; |
1da177e4c Linux-2.6.12-rc2 |
647 |
|
ea9f8856b ACPI video: Harde... |
648 649 |
if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) return -EINVAL; |
0db982026 ACPI: introduce h... |
650 651 652 |
video->dos_setting = (lcd_flag << 2) | bios_flag; status = acpi_execute_simple_method(video->device->handle, "_DOS", (lcd_flag << 2) | bios_flag); |
ea9f8856b ACPI video: Harde... |
653 654 |
if (ACPI_FAILURE(status)) return -EIO; |
1da177e4c Linux-2.6.12-rc2 |
655 |
|
ea9f8856b ACPI video: Harde... |
656 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
657 658 659 |
} /* |
935e5f290 ACPI: video: Fix ... |
660 661 662 663 664 665 666 667 668 669 |
* 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; } /* |
a50188dae acpi: video: enha... |
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 |
* Decides if _BQC/_BCQ for this system is usable * * We do this by changing the level first and then read out the current * brightness level, if the value does not match, find out if it is using * index. If not, clear the _BQC/_BCQ capability. */ static int acpi_video_bqc_quirk(struct acpi_video_device *device, int max_level, int current_level) { struct acpi_video_device_brightness *br = device->brightness; int result; unsigned long long level; int test_level; /* don't mess with existing known broken systems */ if (bqc_offset_aml_bug_workaround) return 0; /* * Some systems always report current brightness level as maximum * through _BQC, we need to test another value for them. */ |
b3b301c5f ACPI / video: imp... |
692 |
test_level = current_level == max_level ? br->levels[3] : max_level; |
a50188dae acpi: video: enha... |
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 |
result = acpi_video_device_lcd_set_level(device, test_level); if (result) return result; result = acpi_video_device_lcd_get_level_current(device, &level, true); if (result) return result; if (level != test_level) { /* buggy _BQC found, need to find out if it uses index */ if (level < br->count) { if (br->flags._BCL_reversed) level = br->count - 3 - level; if (br->levels[level + 2] == test_level) br->flags._BQC_use_index = 1; } if (!br->flags._BQC_use_index) device->cap._BQC = device->cap._BCQ = 0; } return 0; } /* |
21fcb34e2 ACPI / video: tri... |
720 721 |
* Arg: * device : video output device (LCD, CRT, ..) |
1da177e4c Linux-2.6.12-rc2 |
722 723 |
* * Return Value: |
469778c17 ACPI: video: fix ... |
724 725 726 727 728 729 730 731 732 |
* Maximum brightness level * * Allocate and initialize device->brightness. */ static int acpi_video_init_brightness(struct acpi_video_device *device) { union acpi_object *obj = NULL; |
d32f69470 ACPI video: suppo... |
733 |
int i, max_level = 0, count = 0, level_ac_battery = 0; |
1a7c618a3 ACPI video: suppo... |
734 |
unsigned long long level, level_old; |
469778c17 ACPI: video: fix ... |
735 736 |
union acpi_object *o; struct acpi_video_device_brightness *br = NULL; |
1a7c618a3 ACPI video: suppo... |
737 |
int result = -EINVAL; |
bd8ba2059 ACPI / video: Fil... |
738 |
u32 value; |
469778c17 ACPI: video: fix ... |
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 |
if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " "LCD brightness level ")); goto out; } if (obj->package.count < 2) goto out; br = kzalloc(sizeof(*br), GFP_KERNEL); if (!br) { printk(KERN_ERR "can't allocate memory "); |
1a7c618a3 ACPI video: suppo... |
754 |
result = -ENOMEM; |
469778c17 ACPI: video: fix ... |
755 756 |
goto out; } |
d32f69470 ACPI video: suppo... |
757 |
br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels), |
469778c17 ACPI: video: fix ... |
758 |
GFP_KERNEL); |
1a7c618a3 ACPI video: suppo... |
759 760 |
if (!br->levels) { result = -ENOMEM; |
469778c17 ACPI: video: fix ... |
761 |
goto out_free; |
1a7c618a3 ACPI video: suppo... |
762 |
} |
469778c17 ACPI: video: fix ... |
763 764 765 766 767 768 769 770 |
for (i = 0; i < obj->package.count; i++) { o = (union acpi_object *)&obj->package.elements[i]; if (o->type != ACPI_TYPE_INTEGER) { printk(KERN_ERR PREFIX "Invalid data "); continue; } |
bd8ba2059 ACPI / video: Fil... |
771 772 773 774 775 776 |
value = (u32) o->integer.value; /* Skip duplicate entries */ if (count > 2 && br->levels[count - 1] == value) continue; br->levels[count] = value; |
469778c17 ACPI: video: fix ... |
777 778 779 780 781 |
if (br->levels[count] > max_level) max_level = br->levels[count]; count++; } |
d32f69470 ACPI video: suppo... |
782 783 784 785 786 787 |
/* * some buggy BIOS don't export the levels * when machine is on AC/Battery in _BCL package. * In this case, the first two elements in _BCL packages * are also supported brightness levels that OS should take care of. */ |
90af2cf62 ACPI video: fix a... |
788 789 |
for (i = 2; i < count; i++) { if (br->levels[i] == br->levels[0]) |
d32f69470 ACPI video: suppo... |
790 |
level_ac_battery++; |
90af2cf62 ACPI video: fix a... |
791 792 793 |
if (br->levels[i] == br->levels[1]) level_ac_battery++; } |
d32f69470 ACPI video: suppo... |
794 795 796 797 798 799 800 801 |
if (level_ac_battery < 2) { level_ac_battery = 2 - level_ac_battery; br->flags._BCL_no_ac_battery_levels = 1; for (i = (count - 1 + level_ac_battery); i >= 2; i--) br->levels[i] = br->levels[i - level_ac_battery]; count += level_ac_battery; } else if (level_ac_battery > 2) |
bf6787ebb ACPI video: remov... |
802 |
ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package")); |
d32f69470 ACPI video: suppo... |
803 |
|
d80fb99fd ACPI video: suppo... |
804 805 806 807 808 809 810 |
/* Check if the _BCL package is in a reversed order */ if (max_level == br->levels[2]) { br->flags._BCL_reversed = 1; sort(&br->levels[2], count - 2, sizeof(br->levels[2]), acpi_video_cmp_level, NULL); } else if (max_level != br->levels[count - 1]) ACPI_ERROR((AE_INFO, |
bf6787ebb ACPI video: remov... |
811 |
"Found unordered _BCL package")); |
469778c17 ACPI: video: fix ... |
812 813 814 |
br->count = count; device->brightness = br; |
1a7c618a3 ACPI video: suppo... |
815 |
|
1a7c618a3 ACPI video: suppo... |
816 |
/* _BQC uses INDEX while _BCL uses VALUE in some laptops */ |
90c53ca42 ACPI video: work-... |
817 |
br->curr = level = max_level; |
e047cca66 ACPI video: handl... |
818 819 820 |
if (!device->cap._BQC) goto set_level; |
a89803df9 ACPI / video: Fix... |
821 822 |
result = acpi_video_device_lcd_get_level_current(device, &level_old, true); |
1a7c618a3 ACPI video: suppo... |
823 824 |
if (result) goto out_free_levels; |
a50188dae acpi: video: enha... |
825 |
result = acpi_video_bqc_quirk(device, max_level, level_old); |
1a7c618a3 ACPI video: suppo... |
826 827 |
if (result) goto out_free_levels; |
a50188dae acpi: video: enha... |
828 829 830 831 832 833 |
/* * cap._BQC may get cleared due to _BQC is found to be broken * in acpi_video_bqc_quirk, so check again here. */ if (!device->cap._BQC) goto set_level; |
e047cca66 ACPI video: handl... |
834 |
|
545ef368e ACPI / video: cle... |
835 836 837 838 839 840 841 842 843 844 845 846 |
level = acpi_video_bqc_value_to_level(device, level_old); /* * On some buggy laptops, _BQC returns an uninitialized * value when invoked for the first time, i.e. * level_old is invalid (no matter whether it's a level * or an index). Set the backlight to max_level in this case. */ for (i = 2; i < br->count; i++) if (level == br->levels[i]) break; if (i == br->count || !level) level = max_level; |
e047cca66 ACPI video: handl... |
847 |
|
e047cca66 ACPI video: handl... |
848 |
set_level: |
90c53ca42 ACPI video: work-... |
849 |
result = acpi_video_device_lcd_set_level(device, level); |
e047cca66 ACPI video: handl... |
850 851 |
if (result) goto out_free_levels; |
1a7c618a3 ACPI video: suppo... |
852 |
|
d32f69470 ACPI video: suppo... |
853 854 855 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels ", count - 2)); |
469778c17 ACPI: video: fix ... |
856 |
kfree(obj); |
1a7c618a3 ACPI video: suppo... |
857 |
return result; |
469778c17 ACPI: video: fix ... |
858 859 860 861 862 863 864 865 |
out_free_levels: kfree(br->levels); out_free: kfree(br); out: device->brightness = NULL; kfree(obj); |
1a7c618a3 ACPI video: suppo... |
866 |
return result; |
469778c17 ACPI: video: fix ... |
867 868 869 870 871 872 873 |
} /* * Arg: * device : video output device (LCD, CRT, ..) * * Return Value: |
21fcb34e2 ACPI / video: tri... |
874 |
* None |
1da177e4c Linux-2.6.12-rc2 |
875 |
* |
98fb8fe10 ACPI: video: Fix ... |
876 |
* Find out all required AML methods defined under the output |
1da177e4c Linux-2.6.12-rc2 |
877 878 |
* device. */ |
4be44fcd3 [ACPI] Lindent al... |
879 |
static void acpi_video_device_find_cap(struct acpi_video_device *device) |
1da177e4c Linux-2.6.12-rc2 |
880 |
{ |
952c63e95 ACPI: introduce h... |
881 |
if (acpi_has_method(device->dev->handle, "_ADR")) |
1da177e4c Linux-2.6.12-rc2 |
882 |
device->cap._ADR = 1; |
952c63e95 ACPI: introduce h... |
883 |
if (acpi_has_method(device->dev->handle, "_BCL")) |
4be44fcd3 [ACPI] Lindent al... |
884 |
device->cap._BCL = 1; |
952c63e95 ACPI: introduce h... |
885 |
if (acpi_has_method(device->dev->handle, "_BCM")) |
4be44fcd3 [ACPI] Lindent al... |
886 |
device->cap._BCM = 1; |
952c63e95 ACPI: introduce h... |
887 |
if (acpi_has_method(device->dev->handle, "_BQC")) { |
2f3d000a1 ACPI: Adds backli... |
888 |
device->cap._BQC = 1; |
952c63e95 ACPI: introduce h... |
889 |
} else if (acpi_has_method(device->dev->handle, "_BCQ")) { |
c60d638e2 ACPI video: suppo... |
890 891 892 893 |
printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC "); device->cap._BCQ = 1; } |
952c63e95 ACPI: introduce h... |
894 |
if (acpi_has_method(device->dev->handle, "_DDC")) |
4be44fcd3 [ACPI] Lindent al... |
895 |
device->cap._DDC = 1; |
1da177e4c Linux-2.6.12-rc2 |
896 897 898 |
} /* |
21fcb34e2 ACPI / video: tri... |
899 900 |
* Arg: * device : video output device (VGA) |
1da177e4c Linux-2.6.12-rc2 |
901 902 |
* * Return Value: |
21fcb34e2 ACPI / video: tri... |
903 |
* None |
1da177e4c Linux-2.6.12-rc2 |
904 |
* |
98fb8fe10 ACPI: video: Fix ... |
905 |
* Find out all required AML methods defined under the video bus device. |
1da177e4c Linux-2.6.12-rc2 |
906 |
*/ |
4be44fcd3 [ACPI] Lindent al... |
907 |
static void acpi_video_bus_find_cap(struct acpi_video_bus *video) |
1da177e4c Linux-2.6.12-rc2 |
908 |
{ |
952c63e95 ACPI: introduce h... |
909 |
if (acpi_has_method(video->device->handle, "_DOS")) |
1da177e4c Linux-2.6.12-rc2 |
910 |
video->cap._DOS = 1; |
952c63e95 ACPI: introduce h... |
911 |
if (acpi_has_method(video->device->handle, "_DOD")) |
1da177e4c Linux-2.6.12-rc2 |
912 |
video->cap._DOD = 1; |
952c63e95 ACPI: introduce h... |
913 |
if (acpi_has_method(video->device->handle, "_ROM")) |
1da177e4c Linux-2.6.12-rc2 |
914 |
video->cap._ROM = 1; |
952c63e95 ACPI: introduce h... |
915 |
if (acpi_has_method(video->device->handle, "_GPD")) |
1da177e4c Linux-2.6.12-rc2 |
916 |
video->cap._GPD = 1; |
952c63e95 ACPI: introduce h... |
917 |
if (acpi_has_method(video->device->handle, "_SPD")) |
1da177e4c Linux-2.6.12-rc2 |
918 |
video->cap._SPD = 1; |
952c63e95 ACPI: introduce h... |
919 |
if (acpi_has_method(video->device->handle, "_VPO")) |
1da177e4c Linux-2.6.12-rc2 |
920 |
video->cap._VPO = 1; |
1da177e4c Linux-2.6.12-rc2 |
921 922 923 924 925 926 |
} /* * Check whether the video bus device has required AML method to * support the desired features */ |
4be44fcd3 [ACPI] Lindent al... |
927 |
static int acpi_video_bus_check(struct acpi_video_bus *video) |
1da177e4c Linux-2.6.12-rc2 |
928 |
{ |
4be44fcd3 [ACPI] Lindent al... |
929 |
acpi_status status = -ENOENT; |
1e4cffe78 ACPI: video: conv... |
930 |
struct pci_dev *dev; |
1da177e4c Linux-2.6.12-rc2 |
931 932 |
if (!video) |
d550d98d3 ACPI: delete trac... |
933 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
934 |
|
1e4cffe78 ACPI: video: conv... |
935 |
dev = acpi_get_pci_dev(video->device->handle); |
22c13f9d8 ACPI: video: Igno... |
936 937 |
if (!dev) return -ENODEV; |
1e4cffe78 ACPI: video: conv... |
938 |
pci_dev_put(dev); |
22c13f9d8 ACPI: video: Igno... |
939 |
|
21fcb34e2 ACPI / video: tri... |
940 941 |
/* * Since there is no HID, CID and so on for VGA driver, we have |
1da177e4c Linux-2.6.12-rc2 |
942 943 |
* to check well known required nodes. */ |
98fb8fe10 ACPI: video: Fix ... |
944 |
/* Does this device support video switching? */ |
3a1151e3f ACPI: video: Loos... |
945 946 947 948 949 950 951 |
if (video->cap._DOS || video->cap._DOD) { if (!video->cap._DOS) { printk(KERN_WARNING FW_BUG "ACPI(%s) defines _DOD but not _DOS ", acpi_device_bid(video->device)); } |
1da177e4c Linux-2.6.12-rc2 |
952 953 954 |
video->flags.multihead = 1; status = 0; } |
98fb8fe10 ACPI: video: Fix ... |
955 |
/* Does this device support retrieving a video ROM? */ |
4be44fcd3 [ACPI] Lindent al... |
956 |
if (video->cap._ROM) { |
1da177e4c Linux-2.6.12-rc2 |
957 958 959 |
video->flags.rom = 1; status = 0; } |
98fb8fe10 ACPI: video: Fix ... |
960 |
/* Does this device support configuring which video device to POST? */ |
4be44fcd3 [ACPI] Lindent al... |
961 |
if (video->cap._GPD && video->cap._SPD && video->cap._VPO) { |
1da177e4c Linux-2.6.12-rc2 |
962 963 964 |
video->flags.post = 1; status = 0; } |
d550d98d3 ACPI: delete trac... |
965 |
return status; |
1da177e4c Linux-2.6.12-rc2 |
966 |
} |
21fcb34e2 ACPI / video: tri... |
967 968 969 970 971 |
/* * -------------------------------------------------------------------------- * Driver Interface * -------------------------------------------------------------------------- */ |
1da177e4c Linux-2.6.12-rc2 |
972 973 |
/* device interface */ |
915ea7e41 ACPI / video: tri... |
974 |
static struct acpi_video_device_attrib * |
82cae9998 ACPI: video: fix ... |
975 976 |
acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) { |
78eed028f ACPI: video - do ... |
977 978 979 980 981 982 983 984 |
struct acpi_video_enumerated_device *ids; int i; for (i = 0; i < video->attached_count; i++) { ids = &video->attached_array[i]; if ((ids->value.int_val & 0xffff) == device_id) return &ids->value.attrib; } |
82cae9998 ACPI: video: fix ... |
985 |
|
82cae9998 ACPI: video: fix ... |
986 987 |
return NULL; } |
1da177e4c Linux-2.6.12-rc2 |
988 989 |
static int |
e92a71624 ACPI: Export EDID... |
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 |
acpi_video_get_device_type(struct acpi_video_bus *video, unsigned long device_id) { struct acpi_video_enumerated_device *ids; int i; for (i = 0; i < video->attached_count; i++) { ids = &video->attached_array[i]; if ((ids->value.int_val & 0xffff) == device_id) return ids->value.int_val; } return 0; } static int |
4be44fcd3 [ACPI] Lindent al... |
1006 1007 |
acpi_video_bus_get_one_device(struct acpi_device *device, struct acpi_video_bus *video) |
1da177e4c Linux-2.6.12-rc2 |
1008 |
{ |
27663c585 ACPI: Change acpi... |
1009 |
unsigned long long device_id; |
e92a71624 ACPI: Export EDID... |
1010 |
int status, device_type; |
4be44fcd3 [ACPI] Lindent al... |
1011 |
struct acpi_video_device *data; |
915ea7e41 ACPI / video: tri... |
1012 |
struct acpi_video_device_attrib *attribute; |
1da177e4c Linux-2.6.12-rc2 |
1013 |
|
4be44fcd3 [ACPI] Lindent al... |
1014 1015 |
status = acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); |
91e13aa37 ACPI: video: corr... |
1016 1017 1018 |
/* Some device omits _ADR, we skip them instead of fail */ if (ACPI_FAILURE(status)) return 0; |
1da177e4c Linux-2.6.12-rc2 |
1019 |
|
91e13aa37 ACPI: video: corr... |
1020 1021 1022 |
data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); if (!data) return -ENOMEM; |
82cae9998 ACPI: video: fix ... |
1023 |
|
91e13aa37 ACPI: video: corr... |
1024 1025 1026 1027 1028 1029 1030 |
strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); device->driver_data = data; data->device_id = device_id; data->video = video; data->dev = device; |
8ab58e8e7 ACPI / video: Fix... |
1031 1032 |
INIT_DELAYED_WORK(&data->switch_brightness_work, acpi_video_switch_brightness); |
91e13aa37 ACPI: video: corr... |
1033 1034 |
attribute = acpi_video_get_device_attr(video, device_id); |
915ea7e41 ACPI / video: tri... |
1035 |
if (attribute && attribute->device_id_scheme) { |
91e13aa37 ACPI: video: corr... |
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 |
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; } |
915ea7e41 ACPI / video: tri... |
1053 |
if (attribute->bios_can_detect) |
91e13aa37 ACPI: video: corr... |
1054 1055 1056 1057 1058 1059 |
data->flags.bios = 1; } else { /* Check for legacy IDs */ device_type = acpi_video_get_device_type(video, device_id); /* Ignore bits 16 and 18-20 */ switch (device_type & 0xffe2ffff) { |
915ea7e41 ACPI / video: tri... |
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 |
case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: data->flags.crt = 1; break; case ACPI_VIDEO_DISPLAY_LEGACY_PANEL: data->flags.lcd = 1; break; case ACPI_VIDEO_DISPLAY_LEGACY_TV: data->flags.tvout = 1; break; default: data->flags.unknown = 1; |
e92a71624 ACPI: Export EDID... |
1071 |
} |
91e13aa37 ACPI: video: corr... |
1072 |
} |
4be44fcd3 [ACPI] Lindent al... |
1073 |
|
91e13aa37 ACPI: video: corr... |
1074 1075 |
acpi_video_device_bind(video, data); acpi_video_device_find_cap(data); |
1da177e4c Linux-2.6.12-rc2 |
1076 |
|
91e13aa37 ACPI: video: corr... |
1077 1078 1079 |
mutex_lock(&video->device_list_lock); list_add_tail(&data->entry, &video->video_device_list); mutex_unlock(&video->device_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
1080 |
|
91e13aa37 ACPI: video: corr... |
1081 |
return status; |
1da177e4c Linux-2.6.12-rc2 |
1082 1083 1084 1085 |
} /* * Arg: |
21fcb34e2 ACPI / video: tri... |
1086 |
* video : video bus device |
1da177e4c Linux-2.6.12-rc2 |
1087 1088 |
* * Return: |
21fcb34e2 ACPI / video: tri... |
1089 1090 1091 |
* none * * Enumerate the video device list of the video bus, |
1da177e4c Linux-2.6.12-rc2 |
1092 1093 |
* bind the ids with the corresponding video devices * under the video bus. |
4be44fcd3 [ACPI] Lindent al... |
1094 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
1095 |
|
4be44fcd3 [ACPI] Lindent al... |
1096 |
static void acpi_video_device_rebind(struct acpi_video_bus *video) |
1da177e4c Linux-2.6.12-rc2 |
1097 |
{ |
ff102ea99 ACPI: video - rem... |
1098 |
struct acpi_video_device *dev; |
bbac81f54 ACPI: video - con... |
1099 |
mutex_lock(&video->device_list_lock); |
ff102ea99 ACPI: video - rem... |
1100 1101 |
list_for_each_entry(dev, &video->video_device_list, entry) |
4be44fcd3 [ACPI] Lindent al... |
1102 |
acpi_video_device_bind(video, dev); |
ff102ea99 ACPI: video - rem... |
1103 |
|
bbac81f54 ACPI: video - con... |
1104 |
mutex_unlock(&video->device_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
1105 1106 1107 1108 |
} /* * Arg: |
21fcb34e2 ACPI / video: tri... |
1109 1110 1111 |
* video : video bus device * device : video output device under the video * bus |
1da177e4c Linux-2.6.12-rc2 |
1112 1113 |
* * Return: |
21fcb34e2 ACPI / video: tri... |
1114 1115 |
* none * |
1da177e4c Linux-2.6.12-rc2 |
1116 1117 |
* Bind the ids with the corresponding video devices * under the video bus. |
4be44fcd3 [ACPI] Lindent al... |
1118 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
1119 1120 |
static void |
4be44fcd3 [ACPI] Lindent al... |
1121 1122 |
acpi_video_device_bind(struct acpi_video_bus *video, struct acpi_video_device *device) |
1da177e4c Linux-2.6.12-rc2 |
1123 |
{ |
78eed028f ACPI: video - do ... |
1124 |
struct acpi_video_enumerated_device *ids; |
4be44fcd3 [ACPI] Lindent al... |
1125 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
1126 |
|
78eed028f ACPI: video - do ... |
1127 1128 1129 1130 |
for (i = 0; i < video->attached_count; i++) { ids = &video->attached_array[i]; if (device->device_id == (ids->value.int_val & 0xffff)) { ids->bind_info = device; |
1da177e4c Linux-2.6.12-rc2 |
1131 1132 1133 1134 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d ", i)); } } |
1da177e4c Linux-2.6.12-rc2 |
1135 |
} |
0b8db271f ACPI / video: che... |
1136 1137 1138 1139 |
static bool acpi_video_device_in_dod(struct acpi_video_device *device) { struct acpi_video_bus *video = device->video; int i; |
b4df46367 ACPI / video: upd... |
1140 1141 1142 1143 1144 1145 |
/* * If we have a broken _DOD or we have more than 8 output devices * under the graphics controller node that we can't proper deal with * in the operation region code currently, no need to test. */ if (!video->attached_count || video->child_count > 8) |
0b8db271f ACPI / video: che... |
1146 1147 1148 |
return true; for (i = 0; i < video->attached_count; i++) { |
35d0565b9 ACPI / video: upd... |
1149 1150 |
if ((video->attached_array[i].value.int_val & 0xfff) == (device->device_id & 0xfff)) |
0b8db271f ACPI / video: che... |
1151 1152 1153 1154 1155 |
return true; } return false; } |
1da177e4c Linux-2.6.12-rc2 |
1156 1157 |
/* * Arg: |
21fcb34e2 ACPI / video: tri... |
1158 |
* video : video bus device |
1da177e4c Linux-2.6.12-rc2 |
1159 1160 |
* * Return: |
21fcb34e2 ACPI / video: tri... |
1161 1162 |
* < 0 : error * |
1da177e4c Linux-2.6.12-rc2 |
1163 1164 |
* Call _DOD to enumerate all devices attached to display adapter * |
4be44fcd3 [ACPI] Lindent al... |
1165 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
1166 1167 1168 |
static int acpi_video_device_enumerate(struct acpi_video_bus *video) { |
4be44fcd3 [ACPI] Lindent al... |
1169 1170 1171 |
int status; int count; int i; |
78eed028f ACPI: video - do ... |
1172 |
struct acpi_video_enumerated_device *active_list; |
4be44fcd3 [ACPI] Lindent al... |
1173 1174 1175 |
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *dod = NULL; union acpi_object *obj; |
1da177e4c Linux-2.6.12-rc2 |
1176 |
|
901302688 ACPI: video: Use ... |
1177 |
status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer); |
1da177e4c Linux-2.6.12-rc2 |
1178 |
if (!ACPI_SUCCESS(status)) { |
a6fc67202 ACPI: Enable ACPI... |
1179 |
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD")); |
d550d98d3 ACPI: delete trac... |
1180 |
return status; |
1da177e4c Linux-2.6.12-rc2 |
1181 |
} |
50dd09697 ACPI: Remove unne... |
1182 |
dod = buffer.pointer; |
1da177e4c Linux-2.6.12-rc2 |
1183 |
if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { |
a6fc67202 ACPI: Enable ACPI... |
1184 |
ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); |
1da177e4c Linux-2.6.12-rc2 |
1185 1186 1187 1188 1189 1190 |
status = -EFAULT; goto out; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD ", |
4be44fcd3 [ACPI] Lindent al... |
1191 |
dod->package.count)); |
1da177e4c Linux-2.6.12-rc2 |
1192 |
|
78eed028f ACPI: video - do ... |
1193 1194 1195 1196 |
active_list = kcalloc(1 + dod->package.count, sizeof(struct acpi_video_enumerated_device), GFP_KERNEL); if (!active_list) { |
1da177e4c Linux-2.6.12-rc2 |
1197 1198 1199 1200 1201 1202 |
status = -ENOMEM; goto out; } count = 0; for (i = 0; i < dod->package.count; i++) { |
50dd09697 ACPI: Remove unne... |
1203 |
obj = &dod->package.elements[i]; |
1da177e4c Linux-2.6.12-rc2 |
1204 1205 |
if (obj->type != ACPI_TYPE_INTEGER) { |
78eed028f ACPI: video - do ... |
1206 1207 1208 1209 |
printk(KERN_ERR PREFIX "Invalid _DOD data in element %d ", i); continue; |
1da177e4c Linux-2.6.12-rc2 |
1210 |
} |
78eed028f ACPI: video - do ... |
1211 1212 1213 |
active_list[count].value.int_val = obj->integer.value; active_list[count].bind_info = NULL; |
4be44fcd3 [ACPI] Lindent al... |
1214 1215 1216 |
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d ", i, (int)obj->integer.value)); |
1da177e4c Linux-2.6.12-rc2 |
1217 1218 |
count++; } |
1da177e4c Linux-2.6.12-rc2 |
1219 |
|
6044ec888 [PATCH] kfree cle... |
1220 |
kfree(video->attached_array); |
4be44fcd3 [ACPI] Lindent al... |
1221 |
|
78eed028f ACPI: video - do ... |
1222 |
video->attached_array = active_list; |
1da177e4c Linux-2.6.12-rc2 |
1223 |
video->attached_count = count; |
78eed028f ACPI: video - do ... |
1224 |
|
915ea7e41 ACPI / video: tri... |
1225 |
out: |
02438d877 ACPI: delete acpi... |
1226 |
kfree(buffer.pointer); |
d550d98d3 ACPI: delete trac... |
1227 |
return status; |
1da177e4c Linux-2.6.12-rc2 |
1228 |
} |
4be44fcd3 [ACPI] Lindent al... |
1229 1230 1231 |
static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event) |
1da177e4c Linux-2.6.12-rc2 |
1232 |
{ |
63f0edfc0 ACPI: VIDEO: Adju... |
1233 |
int min, max, min_above, max_below, i, l, delta = 255; |
f4715189d ACPI: Implement a... |
1234 1235 |
max = max_below = 0; min = min_above = 255; |
63f0edfc0 ACPI: VIDEO: Adju... |
1236 |
/* Find closest level to level_current */ |
0a3db1cec ACPI: Skip the fi... |
1237 |
for (i = 2; i < device->brightness->count; i++) { |
63f0edfc0 ACPI: VIDEO: Adju... |
1238 1239 1240 1241 1242 1243 1244 1245 1246 |
l = device->brightness->levels[i]; if (abs(l - level_current) < abs(delta)) { delta = l - level_current; if (!delta) break; } } /* Ajust level_current to closest available level */ level_current += delta; |
0a3db1cec ACPI: Skip the fi... |
1247 |
for (i = 2; i < device->brightness->count; i++) { |
f4715189d ACPI: Implement a... |
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 |
l = device->brightness->levels[i]; if (l < min) min = l; if (l > max) max = l; if (l < min_above && l > level_current) min_above = l; if (l > max_below && l < level_current) max_below = l; } switch (event) { case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: return (level_current < max) ? min_above : min; case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: return (level_current < max) ? min_above : max; case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: return (level_current > min) ? max_below : min; case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: return 0; default: return level_current; } |
1da177e4c Linux-2.6.12-rc2 |
1272 |
} |
8ab58e8e7 ACPI / video: Fix... |
1273 1274 |
static void acpi_video_switch_brightness(struct work_struct *work) |
1da177e4c Linux-2.6.12-rc2 |
1275 |
{ |
8ab58e8e7 ACPI / video: Fix... |
1276 1277 |
struct acpi_video_device *device = container_of(to_delayed_work(work), struct acpi_video_device, switch_brightness_work); |
27663c585 ACPI: Change acpi... |
1278 |
unsigned long long level_current, level_next; |
8ab58e8e7 ACPI / video: Fix... |
1279 |
int event = device->switch_brightness_event; |
c8890f903 ACPI video: check... |
1280 |
int result = -EINVAL; |
fbc9fe1b4 ACPI / video: Do ... |
1281 1282 |
/* no warning message if acpi_backlight=vendor or a quirk is used */ if (!acpi_video_verify_backlight_support()) |
8ab58e8e7 ACPI / video: Fix... |
1283 |
return; |
28c32e99b ACPI video: no wa... |
1284 |
|
469778c17 ACPI: video: fix ... |
1285 |
if (!device->brightness) |
c8890f903 ACPI video: check... |
1286 1287 1288 |
goto out; result = acpi_video_device_lcd_get_level_current(device, |
a89803df9 ACPI / video: Fix... |
1289 1290 |
&level_current, false); |
c8890f903 ACPI video: check... |
1291 1292 |
if (result) goto out; |
1da177e4c Linux-2.6.12-rc2 |
1293 |
level_next = acpi_video_get_next_level(device, level_current, event); |
c8890f903 ACPI video: check... |
1294 |
|
24450c7ad ACPI video: check... |
1295 |
result = acpi_video_device_lcd_set_level(device, level_next); |
c8890f903 ACPI video: check... |
1296 |
|
36342742a backlight/acpi: U... |
1297 1298 1299 |
if (!result) backlight_force_update(device->backlight, BACKLIGHT_UPDATE_HOTKEY); |
c8890f903 ACPI video: check... |
1300 1301 1302 1303 |
out: if (result) printk(KERN_ERR PREFIX "Failed to switch the brightness "); |
1da177e4c Linux-2.6.12-rc2 |
1304 |
} |
e92a71624 ACPI: Export EDID... |
1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 |
int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, void **edid) { struct acpi_video_bus *video; struct acpi_video_device *video_device; union acpi_object *buffer = NULL; acpi_status status; int i, length; if (!device || !acpi_driver_data(device)) return -EINVAL; video = acpi_driver_data(device); for (i = 0; i < video->attached_count; i++) { video_device = video->attached_array[i].bind_info; length = 256; if (!video_device) continue; |
820695525 ACPI video: check... |
1325 1326 |
if (!video_device->cap._DDC) continue; |
e92a71624 ACPI: Export EDID... |
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 |
if (type) { switch (type) { case ACPI_VIDEO_DISPLAY_CRT: if (!video_device->flags.crt) continue; break; case ACPI_VIDEO_DISPLAY_TV: if (!video_device->flags.tvout) continue; break; case ACPI_VIDEO_DISPLAY_DVI: if (!video_device->flags.dvi) continue; break; case ACPI_VIDEO_DISPLAY_LCD: if (!video_device->flags.lcd) continue; break; } } else if (video_device->device_id != device_id) { continue; } status = acpi_video_device_EDID(video_device, &buffer, length); if (ACPI_FAILURE(status) || !buffer || buffer->type != ACPI_TYPE_BUFFER) { length = 128; status = acpi_video_device_EDID(video_device, &buffer, length); if (ACPI_FAILURE(status) || !buffer || buffer->type != ACPI_TYPE_BUFFER) { continue; } } *edid = buffer->buffer.pointer; return length; } return -ENODEV; } EXPORT_SYMBOL(acpi_video_get_edid); |
1da177e4c Linux-2.6.12-rc2 |
1370 |
static int |
4be44fcd3 [ACPI] Lindent al... |
1371 1372 |
acpi_video_bus_get_devices(struct acpi_video_bus *video, struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
1373 |
{ |
fba4e0873 ACPI video: Ignor... |
1374 |
int status = 0; |
ff102ea99 ACPI: video - rem... |
1375 |
struct acpi_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
1376 |
|
fba4e0873 ACPI video: Ignor... |
1377 1378 1379 1380 1381 1382 |
/* * There are systems where video module known to work fine regardless * of broken _DOD and ignoring returned value here doesn't cause * any issues later. */ acpi_video_device_enumerate(video); |
1da177e4c Linux-2.6.12-rc2 |
1383 |
|
ff102ea99 ACPI: video - rem... |
1384 |
list_for_each_entry(dev, &device->children, node) { |
1da177e4c Linux-2.6.12-rc2 |
1385 1386 |
status = acpi_video_bus_get_one_device(dev, video); |
ea9f8856b ACPI video: Harde... |
1387 |
if (status) { |
91e13aa37 ACPI: video: corr... |
1388 1389 1390 |
dev_err(&dev->dev, "Can't attach device "); break; |
1da177e4c Linux-2.6.12-rc2 |
1391 |
} |
b4df46367 ACPI / video: upd... |
1392 |
video->child_count++; |
1da177e4c Linux-2.6.12-rc2 |
1393 |
} |
d550d98d3 ACPI: delete trac... |
1394 |
return status; |
1da177e4c Linux-2.6.12-rc2 |
1395 |
} |
1da177e4c Linux-2.6.12-rc2 |
1396 |
/* acpi_video interface */ |
efaa14c7e ACPI / video: no ... |
1397 1398 1399 1400 |
/* * Win8 requires setting bit2 of _DOS to let firmware know it shouldn't * preform any automatic brightness change on receiving a notification. */ |
4be44fcd3 [ACPI] Lindent al... |
1401 |
static int acpi_video_bus_start_devices(struct acpi_video_bus *video) |
1da177e4c Linux-2.6.12-rc2 |
1402 |
{ |
efaa14c7e ACPI / video: no ... |
1403 |
return acpi_video_bus_DOS(video, 0, |
fbc9fe1b4 ACPI / video: Do ... |
1404 |
acpi_osi_is_win8() ? 1 : 0); |
1da177e4c Linux-2.6.12-rc2 |
1405 |
} |
4be44fcd3 [ACPI] Lindent al... |
1406 |
static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) |
1da177e4c Linux-2.6.12-rc2 |
1407 |
{ |
efaa14c7e ACPI / video: no ... |
1408 |
return acpi_video_bus_DOS(video, 0, |
fbc9fe1b4 ACPI / video: Do ... |
1409 |
acpi_osi_is_win8() ? 0 : 1); |
1da177e4c Linux-2.6.12-rc2 |
1410 |
} |
7015558fc ACPI: video: use ... |
1411 |
static void acpi_video_bus_notify(struct acpi_device *device, u32 event) |
1da177e4c Linux-2.6.12-rc2 |
1412 |
{ |
7015558fc ACPI: video: use ... |
1413 |
struct acpi_video_bus *video = acpi_driver_data(device); |
e9dab1960 ACPI video hotkey... |
1414 |
struct input_dev *input; |
17c452f99 ACPI: Don't send ... |
1415 |
int keycode = 0; |
e9dab1960 ACPI video hotkey... |
1416 |
|
67b662e18 ACPI / video: sep... |
1417 |
if (!video || !video->input) |
d550d98d3 ACPI: delete trac... |
1418 |
return; |
1da177e4c Linux-2.6.12-rc2 |
1419 |
|
e9dab1960 ACPI video hotkey... |
1420 |
input = video->input; |
1da177e4c Linux-2.6.12-rc2 |
1421 1422 |
switch (event) { |
98fb8fe10 ACPI: video: Fix ... |
1423 |
case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, |
1da177e4c Linux-2.6.12-rc2 |
1424 |
* most likely via hotkey. */ |
8a37c65df ACPI video: allow... |
1425 |
keycode = KEY_SWITCHVIDEOMODE; |
1da177e4c Linux-2.6.12-rc2 |
1426 |
break; |
98fb8fe10 ACPI: video: Fix ... |
1427 |
case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video |
1da177e4c Linux-2.6.12-rc2 |
1428 1429 1430 |
* connector. */ acpi_video_device_enumerate(video); acpi_video_device_rebind(video); |
e9dab1960 ACPI video hotkey... |
1431 |
keycode = KEY_SWITCHVIDEOMODE; |
1da177e4c Linux-2.6.12-rc2 |
1432 |
break; |
4be44fcd3 [ACPI] Lindent al... |
1433 |
case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ |
e9dab1960 ACPI video hotkey... |
1434 1435 |
keycode = KEY_SWITCHVIDEOMODE; break; |
4be44fcd3 [ACPI] Lindent al... |
1436 |
case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ |
e9dab1960 ACPI video hotkey... |
1437 1438 |
keycode = KEY_VIDEO_NEXT; break; |
4be44fcd3 [ACPI] Lindent al... |
1439 |
case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ |
e9dab1960 ACPI video hotkey... |
1440 |
keycode = KEY_VIDEO_PREV; |
1da177e4c Linux-2.6.12-rc2 |
1441 1442 1443 1444 |
break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
4be44fcd3 [ACPI] Lindent al... |
1445 1446 |
"Unsupported event [0x%x] ", event)); |
1da177e4c Linux-2.6.12-rc2 |
1447 1448 |
break; } |
8a37c65df ACPI video: allow... |
1449 1450 1451 |
if (acpi_notifier_call_chain(device, event, 0)) /* Something vetoed the keypress. */ keycode = 0; |
17c452f99 ACPI: Don't send ... |
1452 1453 1454 1455 1456 1457 1458 |
if (keycode) { input_report_key(input, keycode, 1); input_sync(input); input_report_key(input, keycode, 0); input_sync(input); } |
e9dab1960 ACPI video hotkey... |
1459 |
|
d550d98d3 ACPI: delete trac... |
1460 |
return; |
1da177e4c Linux-2.6.12-rc2 |
1461 |
} |
8ab58e8e7 ACPI / video: Fix... |
1462 1463 1464 1465 1466 1467 1468 1469 1470 |
static void brightness_switch_event(struct acpi_video_device *video_device, u32 event) { if (!brightness_switch_enabled) return; video_device->switch_brightness_event = event; schedule_delayed_work(&video_device->switch_brightness_work, HZ / 10); } |
4be44fcd3 [ACPI] Lindent al... |
1471 |
static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) |
1da177e4c Linux-2.6.12-rc2 |
1472 |
{ |
50dd09697 ACPI: Remove unne... |
1473 |
struct acpi_video_device *video_device = data; |
4be44fcd3 [ACPI] Lindent al... |
1474 |
struct acpi_device *device = NULL; |
e9dab1960 ACPI video hotkey... |
1475 1476 |
struct acpi_video_bus *bus; struct input_dev *input; |
17c452f99 ACPI: Don't send ... |
1477 |
int keycode = 0; |
1da177e4c Linux-2.6.12-rc2 |
1478 |
|
1da177e4c Linux-2.6.12-rc2 |
1479 |
if (!video_device) |
d550d98d3 ACPI: delete trac... |
1480 |
return; |
1da177e4c Linux-2.6.12-rc2 |
1481 |
|
e6afa0de1 ACPI: video: add ... |
1482 |
device = video_device->dev; |
e9dab1960 ACPI video hotkey... |
1483 1484 |
bus = video_device->video; input = bus->input; |
1da177e4c Linux-2.6.12-rc2 |
1485 1486 |
switch (event) { |
4be44fcd3 [ACPI] Lindent al... |
1487 |
case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ |
8ab58e8e7 ACPI / video: Fix... |
1488 |
brightness_switch_event(video_device, event); |
e9dab1960 ACPI video hotkey... |
1489 1490 |
keycode = KEY_BRIGHTNESS_CYCLE; break; |
4be44fcd3 [ACPI] Lindent al... |
1491 |
case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ |
8ab58e8e7 ACPI / video: Fix... |
1492 |
brightness_switch_event(video_device, event); |
e9dab1960 ACPI video hotkey... |
1493 1494 |
keycode = KEY_BRIGHTNESSUP; break; |
4be44fcd3 [ACPI] Lindent al... |
1495 |
case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ |
8ab58e8e7 ACPI / video: Fix... |
1496 |
brightness_switch_event(video_device, event); |
e9dab1960 ACPI video hotkey... |
1497 1498 |
keycode = KEY_BRIGHTNESSDOWN; break; |
70f23fd66 treewide: fix a f... |
1499 |
case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ |
8ab58e8e7 ACPI / video: Fix... |
1500 |
brightness_switch_event(video_device, event); |
e9dab1960 ACPI video hotkey... |
1501 1502 |
keycode = KEY_BRIGHTNESS_ZERO; break; |
4be44fcd3 [ACPI] Lindent al... |
1503 |
case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ |
8ab58e8e7 ACPI / video: Fix... |
1504 |
brightness_switch_event(video_device, event); |
e9dab1960 ACPI video hotkey... |
1505 |
keycode = KEY_DISPLAY_OFF; |
1da177e4c Linux-2.6.12-rc2 |
1506 1507 1508 |
break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
4be44fcd3 [ACPI] Lindent al... |
1509 1510 |
"Unsupported event [0x%x] ", event)); |
1da177e4c Linux-2.6.12-rc2 |
1511 1512 |
break; } |
e9dab1960 ACPI video hotkey... |
1513 |
|
7761f638f ACPI: video: call... |
1514 |
acpi_notifier_call_chain(device, event, 0); |
17c452f99 ACPI: Don't send ... |
1515 1516 1517 1518 1519 1520 1521 |
if (keycode) { input_report_key(input, keycode, 1); input_sync(input); input_report_key(input, keycode, 0); input_sync(input); } |
e9dab1960 ACPI video hotkey... |
1522 |
|
d550d98d3 ACPI: delete trac... |
1523 |
return; |
1da177e4c Linux-2.6.12-rc2 |
1524 |
} |
ac7729da8 ACPI / PM: Move A... |
1525 1526 |
static int acpi_video_resume(struct notifier_block *nb, unsigned long val, void *ign) |
863c1490e ACPI: video: rese... |
1527 1528 1529 1530 |
{ struct acpi_video_bus *video; struct acpi_video_device *video_device; int i; |
ac7729da8 ACPI / PM: Move A... |
1531 1532 1533 1534 1535 1536 |
switch (val) { case PM_HIBERNATION_PREPARE: case PM_SUSPEND_PREPARE: case PM_RESTORE_PREPARE: return NOTIFY_DONE; } |
863c1490e ACPI: video: rese... |
1537 |
|
ac7729da8 ACPI / PM: Move A... |
1538 1539 1540 1541 |
video = container_of(nb, struct acpi_video_bus, pm_nb); dev_info(&video->device->dev, "Restoring backlight state "); |
863c1490e ACPI: video: rese... |
1542 1543 1544 1545 1546 1547 |
for (i = 0; i < video->attached_count; i++) { video_device = video->attached_array[i].bind_info; if (video_device && video_device->backlight) acpi_video_set_brightness(video_device->backlight); } |
ac7729da8 ACPI / PM: Move A... |
1548 1549 |
return NOTIFY_OK; |
863c1490e ACPI: video: rese... |
1550 |
} |
c504f8cb6 ACPI video: Prune... |
1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 |
static acpi_status acpi_video_bus_match(acpi_handle handle, u32 level, void *context, void **return_value) { struct acpi_device *device = context; struct acpi_device *sibling; int result; if (handle == device->handle) return AE_CTRL_TERMINATE; result = acpi_bus_get_device(handle, &sibling); if (result) return AE_OK; if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME)) return AE_ALREADY_EXISTS; return AE_OK; } |
67b662e18 ACPI / video: sep... |
1571 1572 |
static void acpi_video_dev_register_backlight(struct acpi_video_device *device) { |
99678ed73 ACPI / video: Don... |
1573 1574 1575 1576 1577 1578 1579 |
struct backlight_properties props; struct pci_dev *pdev; acpi_handle acpi_parent; struct device *parent = NULL; int result; static int count; char *name; |
67b662e18 ACPI / video: sep... |
1580 |
|
0b8db271f ACPI / video: che... |
1581 1582 1583 1584 1585 1586 1587 1588 1589 |
/* * Do not create backlight device for video output * device that is not in the enumerated list. */ if (!acpi_video_device_in_dod(device)) { dev_dbg(&device->dev->dev, "not in _DOD list, ignore "); return; } |
99678ed73 ACPI / video: Don... |
1590 1591 1592 1593 1594 1595 1596 |
result = acpi_video_init_brightness(device); if (result) return; name = kasprintf(GFP_KERNEL, "acpi_video%d", count); if (!name) return; count++; |
67b662e18 ACPI / video: sep... |
1597 |
|
99678ed73 ACPI / video: Don... |
1598 |
acpi_get_parent(device->dev->handle, &acpi_parent); |
67b662e18 ACPI / video: sep... |
1599 |
|
99678ed73 ACPI / video: Don... |
1600 1601 1602 1603 1604 |
pdev = acpi_get_pci_dev(acpi_parent); if (pdev) { parent = &pdev->dev; pci_dev_put(pdev); } |
67b662e18 ACPI / video: sep... |
1605 |
|
99678ed73 ACPI / video: Don... |
1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 |
memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_FIRMWARE; props.max_brightness = device->brightness->count - 3; device->backlight = backlight_device_register(name, parent, device, &acpi_backlight_ops, &props); kfree(name); if (IS_ERR(device->backlight)) return; |
67b662e18 ACPI / video: sep... |
1617 |
|
99678ed73 ACPI / video: Don... |
1618 1619 1620 1621 1622 1623 |
/* * Save current brightness level in case we have to restore it * before acpi_video_device_lcd_set_level() is called next time. */ device->backlight->props.brightness = acpi_video_get_brightness(device->backlight); |
67b662e18 ACPI / video: sep... |
1624 |
|
99678ed73 ACPI / video: Don... |
1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 |
device->cooling_dev = thermal_cooling_device_register("LCD", device->dev, &video_cooling_ops); if (IS_ERR(device->cooling_dev)) { /* * Set cooling_dev to NULL so we don't crash trying to free it. * Also, why the hell we are returning early and not attempt to * register video output if cooling device registration failed? * -- dtor */ device->cooling_dev = NULL; return; |
67b662e18 ACPI / video: sep... |
1636 |
} |
99678ed73 ACPI / video: Don... |
1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 |
dev_info(&device->dev->dev, "registered as cooling_device%d ", device->cooling_dev->id); result = sysfs_create_link(&device->dev->dev.kobj, &device->cooling_dev->device.kobj, "thermal_cooling"); if (result) printk(KERN_ERR PREFIX "Create sysfs link "); result = sysfs_create_link(&device->cooling_dev->device.kobj, &device->dev->dev.kobj, "device"); if (result) printk(KERN_ERR PREFIX "Create sysfs link "); |
67b662e18 ACPI / video: sep... |
1652 |
} |
dce4ec2e4 ACPI / video: Run... |
1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 |
static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video) { struct acpi_video_device *dev; union acpi_object *levels; mutex_lock(&video->device_list_lock); list_for_each_entry(dev, &video->video_device_list, entry) { if (!acpi_video_device_lcd_query_levels(dev, &levels)) kfree(levels); } mutex_unlock(&video->device_list_lock); } |
67b662e18 ACPI / video: sep... |
1665 1666 1667 |
static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) { struct acpi_video_device *dev; |
53a92ba7e ACPI / video: Unr... |
1668 1669 |
if (video->backlight_registered) return 0; |
dce4ec2e4 ACPI / video: Run... |
1670 |
acpi_video_run_bcl_for_osi(video); |
99678ed73 ACPI / video: Don... |
1671 1672 |
if (!acpi_video_verify_backlight_support()) return 0; |
67b662e18 ACPI / video: sep... |
1673 1674 1675 1676 |
mutex_lock(&video->device_list_lock); list_for_each_entry(dev, &video->video_device_list, entry) acpi_video_dev_register_backlight(dev); mutex_unlock(&video->device_list_lock); |
99678ed73 ACPI / video: Don... |
1677 |
video->backlight_registered = true; |
67b662e18 ACPI / video: sep... |
1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 |
video->pm_nb.notifier_call = acpi_video_resume; video->pm_nb.priority = 0; return register_pm_notifier(&video->pm_nb); } static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device) { if (device->backlight) { backlight_device_unregister(device->backlight); device->backlight = NULL; } if (device->brightness) { kfree(device->brightness->levels); kfree(device->brightness); device->brightness = NULL; } if (device->cooling_dev) { sysfs_remove_link(&device->dev->dev.kobj, "thermal_cooling"); sysfs_remove_link(&device->cooling_dev->device.kobj, "device"); thermal_cooling_device_unregister(device->cooling_dev); device->cooling_dev = NULL; } } static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video) { struct acpi_video_device *dev; |
99678ed73 ACPI / video: Don... |
1705 1706 1707 1708 1709 1710 |
int error; if (!video->backlight_registered) return 0; error = unregister_pm_notifier(&video->pm_nb); |
67b662e18 ACPI / video: sep... |
1711 1712 1713 1714 1715 |
mutex_lock(&video->device_list_lock); list_for_each_entry(dev, &video->video_device_list, entry) acpi_video_dev_unregister_backlight(dev); mutex_unlock(&video->device_list_lock); |
99678ed73 ACPI / video: Don... |
1716 |
video->backlight_registered = false; |
67b662e18 ACPI / video: sep... |
1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 |
return error; } static void acpi_video_dev_add_notify_handler(struct acpi_video_device *device) { acpi_status status; struct acpi_device *adev = device->dev; status = acpi_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY, acpi_video_device_notify, device); if (ACPI_FAILURE(status)) dev_err(&adev->dev, "Error installing notify handler "); else device->flags.notify = 1; } static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video) { struct input_dev *input; struct acpi_video_device *dev; int error; video->input = input = input_allocate_device(); if (!input) { error = -ENOMEM; goto out; } error = acpi_video_bus_start_devices(video); if (error) goto err_free_input; snprintf(video->phys, sizeof(video->phys), "%s/video/input0", acpi_device_hid(video->device)); input->name = acpi_device_name(video->device); input->phys = video->phys; input->id.bustype = BUS_HOST; input->id.product = 0x06; input->dev.parent = &video->device->dev; input->evbit[0] = BIT(EV_KEY); set_bit(KEY_SWITCHVIDEOMODE, input->keybit); set_bit(KEY_VIDEO_NEXT, input->keybit); set_bit(KEY_VIDEO_PREV, input->keybit); set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit); set_bit(KEY_BRIGHTNESSUP, input->keybit); set_bit(KEY_BRIGHTNESSDOWN, input->keybit); set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); set_bit(KEY_DISPLAY_OFF, input->keybit); error = input_register_device(input); if (error) goto err_stop_dev; mutex_lock(&video->device_list_lock); list_for_each_entry(dev, &video->video_device_list, entry) acpi_video_dev_add_notify_handler(dev); mutex_unlock(&video->device_list_lock); return 0; err_stop_dev: acpi_video_bus_stop_devices(video); err_free_input: input_free_device(input); video->input = NULL; out: return error; } static void acpi_video_dev_remove_notify_handler(struct acpi_video_device *dev) { if (dev->flags.notify) { acpi_remove_notify_handler(dev->dev->handle, ACPI_DEVICE_NOTIFY, acpi_video_device_notify); dev->flags.notify = 0; } } static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video) { struct acpi_video_device *dev; mutex_lock(&video->device_list_lock); list_for_each_entry(dev, &video->video_device_list, entry) acpi_video_dev_remove_notify_handler(dev); mutex_unlock(&video->device_list_lock); acpi_video_bus_stop_devices(video); input_unregister_device(video->input); video->input = NULL; } |
53a92ba7e ACPI / video: Unr... |
1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 |
static int acpi_video_backlight_notify(struct notifier_block *nb, unsigned long val, void *bd) { struct backlight_device *backlight = bd; struct acpi_video_bus *video; /* acpi_video_verify_backlight_support only cares about raw devices */ if (backlight->props.type != BACKLIGHT_RAW) return NOTIFY_DONE; video = container_of(nb, struct acpi_video_bus, backlight_nb); switch (val) { case BACKLIGHT_REGISTERED: if (!acpi_video_verify_backlight_support()) acpi_video_bus_unregister_backlight(video); break; case BACKLIGHT_UNREGISTERED: acpi_video_bus_register_backlight(video); break; } return NOTIFY_OK; } static int acpi_video_bus_add_backlight_notify_handler( struct acpi_video_bus *video) { int error; video->backlight_nb.notifier_call = acpi_video_backlight_notify; video->backlight_nb.priority = 0; error = backlight_register_notifier(&video->backlight_nb); if (error == 0) video->backlight_notifier_registered = true; return error; } static int acpi_video_bus_remove_backlight_notify_handler( struct acpi_video_bus *video) { if (!video->backlight_notifier_registered) return 0; video->backlight_notifier_registered = false; return backlight_unregister_notifier(&video->backlight_nb); } |
67b662e18 ACPI / video: sep... |
1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 |
static int acpi_video_bus_put_devices(struct acpi_video_bus *video) { struct acpi_video_device *dev, *next; mutex_lock(&video->device_list_lock); list_for_each_entry_safe(dev, next, &video->video_device_list, entry) { list_del(&dev->entry); kfree(dev); } mutex_unlock(&video->device_list_lock); return 0; } |
ac7729da8 ACPI / PM: Move A... |
1872 |
static int instance; |
4be44fcd3 [ACPI] Lindent al... |
1873 |
static int acpi_video_bus_add(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
1874 |
{ |
f51e83916 ACPI: video - add... |
1875 |
struct acpi_video_bus *video; |
f51e83916 ACPI: video - add... |
1876 |
int error; |
c504f8cb6 ACPI video: Prune... |
1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 |
acpi_status status; status = acpi_walk_namespace(ACPI_TYPE_DEVICE, device->parent->handle, 1, acpi_video_bus_match, NULL, device, NULL); if (status == AE_ALREADY_EXISTS) { printk(KERN_WARNING FW_BUG "Duplicate ACPI video bus devices for the" " same VGA controller, please try module " "parameter \"video.allow_duplicates=1\"" "if the current driver doesn't work. "); if (!allow_duplicates) return -ENODEV; } |
1da177e4c Linux-2.6.12-rc2 |
1893 |
|
36bcbec7c ACPI: replace kma... |
1894 |
video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
1895 |
if (!video) |
d550d98d3 ACPI: delete trac... |
1896 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
1897 |
|
e6d9da1de ACPI: work around... |
1898 1899 1900 1901 |
/* a hack to fix the duplicate name "VID" problem on T61 */ if (!strcmp(device->pnp.bus_id, "VID")) { if (instance) device->pnp.bus_id[3] = '0' + instance; |
915ea7e41 ACPI / video: tri... |
1902 |
instance++; |
e6d9da1de ACPI: work around... |
1903 |
} |
f3b39f139 ACPI: proc_dir_en... |
1904 1905 1906 1907 1908 1909 |
/* a hack to fix the duplicate name "VGA" problem on Pa 3553 */ if (!strcmp(device->pnp.bus_id, "VGA")) { if (instance) device->pnp.bus_id[3] = '0' + instance; instance++; } |
e6d9da1de ACPI: work around... |
1910 |
|
e6afa0de1 ACPI: video: add ... |
1911 |
video->device = device; |
1da177e4c Linux-2.6.12-rc2 |
1912 1913 |
strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); |
db89b4f0d ACPI: catch calls... |
1914 |
device->driver_data = video; |
1da177e4c Linux-2.6.12-rc2 |
1915 1916 |
acpi_video_bus_find_cap(video); |
f51e83916 ACPI: video - add... |
1917 1918 1919 |
error = acpi_video_bus_check(video); if (error) goto err_free_video; |
1da177e4c Linux-2.6.12-rc2 |
1920 |
|
bbac81f54 ACPI: video - con... |
1921 |
mutex_init(&video->device_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
1922 |
INIT_LIST_HEAD(&video->video_device_list); |
ea9f8856b ACPI video: Harde... |
1923 1924 |
error = acpi_video_bus_get_devices(video, device); if (error) |
91e13aa37 ACPI: video: corr... |
1925 |
goto err_put_video; |
1da177e4c Linux-2.6.12-rc2 |
1926 |
|
1da177e4c Linux-2.6.12-rc2 |
1927 1928 |
printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s) ", |
4be44fcd3 [ACPI] Lindent al... |
1929 1930 1931 1932 |
ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), video->flags.multihead ? "yes" : "no", video->flags.rom ? "yes" : "no", video->flags.post ? "yes" : "no"); |
67b662e18 ACPI / video: sep... |
1933 1934 1935 |
mutex_lock(&video_list_lock); list_add_tail(&video->entry, &video_bus_head); mutex_unlock(&video_list_lock); |
1da177e4c Linux-2.6.12-rc2 |
1936 |
|
67b662e18 ACPI / video: sep... |
1937 1938 |
acpi_video_bus_register_backlight(video); acpi_video_bus_add_notify_handler(video); |
53a92ba7e ACPI / video: Unr... |
1939 |
acpi_video_bus_add_backlight_notify_handler(video); |
ac7729da8 ACPI / PM: Move A... |
1940 |
|
f51e83916 ACPI: video - add... |
1941 |
return 0; |
67b662e18 ACPI / video: sep... |
1942 |
err_put_video: |
f51e83916 ACPI: video - add... |
1943 1944 |
acpi_video_bus_put_devices(video); kfree(video->attached_array); |
67b662e18 ACPI / video: sep... |
1945 |
err_free_video: |
f51e83916 ACPI: video - add... |
1946 |
kfree(video); |
db89b4f0d ACPI: catch calls... |
1947 |
device->driver_data = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1948 |
|
f51e83916 ACPI: video - add... |
1949 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
1950 |
} |
51fac8388 ACPI: Remove usel... |
1951 |
static int acpi_video_bus_remove(struct acpi_device *device) |
1da177e4c Linux-2.6.12-rc2 |
1952 |
{ |
4be44fcd3 [ACPI] Lindent al... |
1953 |
struct acpi_video_bus *video = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1954 |
|
1da177e4c Linux-2.6.12-rc2 |
1955 1956 |
if (!device || !acpi_driver_data(device)) |
d550d98d3 ACPI: delete trac... |
1957 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
1958 |
|
50dd09697 ACPI: Remove unne... |
1959 |
video = acpi_driver_data(device); |
1da177e4c Linux-2.6.12-rc2 |
1960 |
|
53a92ba7e ACPI / video: Unr... |
1961 |
acpi_video_bus_remove_backlight_notify_handler(video); |
67b662e18 ACPI / video: sep... |
1962 1963 |
acpi_video_bus_remove_notify_handler(video); acpi_video_bus_unregister_backlight(video); |
1da177e4c Linux-2.6.12-rc2 |
1964 |
acpi_video_bus_put_devices(video); |
1da177e4c Linux-2.6.12-rc2 |
1965 |
|
67b662e18 ACPI / video: sep... |
1966 1967 1968 |
mutex_lock(&video_list_lock); list_del(&video->entry); mutex_unlock(&video_list_lock); |
6044ec888 [PATCH] kfree cle... |
1969 |
kfree(video->attached_array); |
1da177e4c Linux-2.6.12-rc2 |
1970 |
kfree(video); |
d550d98d3 ACPI: delete trac... |
1971 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1972 |
} |
c6996bdd8 acpi_video: Intel... |
1973 1974 1975 1976 1977 1978 1979 1980 |
static int __init is_i740(struct pci_dev *dev) { if (dev->device == 0x00D1) return 1; if (dev->device == 0x7000) return 1; return 0; } |
74a365b3f ACPI: Populate DI... |
1981 1982 |
static int __init intel_opregion_present(void) { |
c6996bdd8 acpi_video: Intel... |
1983 |
int opregion = 0; |
74a365b3f ACPI: Populate DI... |
1984 1985 1986 1987 1988 1989 1990 1991 |
struct pci_dev *dev = NULL; u32 address; for_each_pci_dev(dev) { if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) continue; if (dev->vendor != PCI_VENDOR_ID_INTEL) continue; |
c6996bdd8 acpi_video: Intel... |
1992 1993 1994 |
/* We don't want to poke around undefined i740 registers */ if (is_i740(dev)) continue; |
74a365b3f ACPI: Populate DI... |
1995 1996 1997 |
pci_read_config_dword(dev, 0xfc, &address); if (!address) continue; |
c6996bdd8 acpi_video: Intel... |
1998 |
opregion = 1; |
74a365b3f ACPI: Populate DI... |
1999 |
} |
c6996bdd8 acpi_video: Intel... |
2000 |
return opregion; |
74a365b3f ACPI: Populate DI... |
2001 |
} |
8e5c2b776 Revert "ACPI / vi... |
2002 |
int acpi_video_register(void) |
1da177e4c Linux-2.6.12-rc2 |
2003 |
{ |
8e5c2b776 Revert "ACPI / vi... |
2004 |
int result = 0; |
86e437f07 ACPI: Add the ref... |
2005 2006 |
if (register_count) { /* |
8e5c2b776 Revert "ACPI / vi... |
2007 2008 |
* if the function of acpi_video_register is already called, * don't register the acpi_vide_bus again and return no error. |
86e437f07 ACPI: Add the ref... |
2009 2010 2011 |
*/ return 0; } |
1da177e4c Linux-2.6.12-rc2 |
2012 |
|
67b662e18 ACPI / video: sep... |
2013 2014 |
mutex_init(&video_list_lock); INIT_LIST_HEAD(&video_bus_head); |
1da177e4c Linux-2.6.12-rc2 |
2015 |
result = acpi_bus_register_driver(&acpi_video_bus); |
39fe394d0 ACPI video: remov... |
2016 |
if (result < 0) |
d550d98d3 ACPI: delete trac... |
2017 |
return -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
2018 |
|
86e437f07 ACPI: Add the ref... |
2019 2020 2021 2022 2023 |
/* * When the acpi_video_bus is loaded successfully, increase * the counter reference. */ register_count = 1; |
d550d98d3 ACPI: delete trac... |
2024 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
2025 |
} |
8e5c2b776 Revert "ACPI / vi... |
2026 |
EXPORT_SYMBOL(acpi_video_register); |
74a365b3f ACPI: Populate DI... |
2027 |
|
86e437f07 ACPI: Add the ref... |
2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 |
void acpi_video_unregister(void) { if (!register_count) { /* * If the acpi video bus is already unloaded, don't * unload it again and return directly. */ return; } acpi_bus_unregister_driver(&acpi_video_bus); |
86e437f07 ACPI: Add the ref... |
2038 2039 2040 2041 2042 |
register_count = 0; return; } EXPORT_SYMBOL(acpi_video_unregister); |
1b7f37e12 ACPI / video: Add... |
2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 |
void acpi_video_unregister_backlight(void) { struct acpi_video_bus *video; if (!register_count) return; mutex_lock(&video_list_lock); list_for_each_entry(video, &video_bus_head, entry) acpi_video_bus_unregister_backlight(video); mutex_unlock(&video_list_lock); } EXPORT_SYMBOL(acpi_video_unregister_backlight); |
74a365b3f ACPI: Populate DI... |
2056 2057 2058 2059 2060 2061 2062 2063 2064 |
/* * This is kind of nasty. Hardware using Intel chipsets may require * the video opregion code to be run first in order to initialise * state before any ACPI video calls are made. To handle this we defer * registration of the video class until the opregion code has run. */ static int __init acpi_video_init(void) { |
45cb50e64 ACPI video: dmi c... |
2065 |
dmi_check_system(video_dmi_table); |
74a365b3f ACPI: Populate DI... |
2066 2067 2068 2069 2070 |
if (intel_opregion_present()) return 0; return acpi_video_register(); } |
1da177e4c Linux-2.6.12-rc2 |
2071 |
|
86e437f07 ACPI: Add the ref... |
2072 |
static void __exit acpi_video_exit(void) |
1da177e4c Linux-2.6.12-rc2 |
2073 |
{ |
86e437f07 ACPI: Add the ref... |
2074 |
acpi_video_unregister(); |
1da177e4c Linux-2.6.12-rc2 |
2075 |
|
d550d98d3 ACPI: delete trac... |
2076 |
return; |
1da177e4c Linux-2.6.12-rc2 |
2077 2078 2079 2080 |
} module_init(acpi_video_init); module_exit(acpi_video_exit); |