2 * video.c - ACPI Video Driver ($Revision:$)
4 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
5 * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
6 * Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net>
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/types.h>
31 #include <linux/list.h>
32 #include <linux/mutex.h>
33 #include <linux/proc_fs.h>
34 #include <linux/seq_file.h>
35 #include <linux/input.h>
36 #include <linux/backlight.h>
37 #include <linux/video_output.h>
38 #include <asm/uaccess.h>
40 #include <acpi/acpi_bus.h>
41 #include <acpi/acpi_drivers.h>
43 #define ACPI_VIDEO_COMPONENT 0x08000000
44 #define ACPI_VIDEO_CLASS "video"
45 #define ACPI_VIDEO_BUS_NAME "Video Bus"
46 #define ACPI_VIDEO_DEVICE_NAME "Video Device"
47 #define ACPI_VIDEO_NOTIFY_SWITCH 0x80
48 #define ACPI_VIDEO_NOTIFY_PROBE 0x81
49 #define ACPI_VIDEO_NOTIFY_CYCLE 0x82
50 #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
51 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
53 #define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85
54 #define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
55 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
56 #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
57 #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
59 #define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
60 #define ACPI_VIDEO_HEAD_END (~0u)
61 #define MAX_NAME_LEN 20
63 #define ACPI_VIDEO_DISPLAY_CRT 1
64 #define ACPI_VIDEO_DISPLAY_TV 2
65 #define ACPI_VIDEO_DISPLAY_DVI 3
66 #define ACPI_VIDEO_DISPLAY_LCD 4
68 #define _COMPONENT ACPI_VIDEO_COMPONENT
69 ACPI_MODULE_NAME("video");
71 MODULE_AUTHOR("Bruno Ducrot");
72 MODULE_DESCRIPTION("ACPI Video Driver");
73 MODULE_LICENSE("GPL");
75 static int brightness_switch_enabled = 1;
76 module_param(brightness_switch_enabled, bool, 0644);
78 static int acpi_video_bus_add(struct acpi_device *device);
79 static int acpi_video_bus_remove(struct acpi_device *device, int type);
80 static int acpi_video_resume(struct acpi_device *device);
82 static const struct acpi_device_id video_device_ids[] = {
86 MODULE_DEVICE_TABLE(acpi, video_device_ids);
88 static struct acpi_driver acpi_video_bus = {
90 .class = ACPI_VIDEO_CLASS,
91 .ids = video_device_ids,
93 .add = acpi_video_bus_add,
94 .remove = acpi_video_bus_remove,
95 .resume = acpi_video_resume,
99 struct acpi_video_bus_flags {
100 u8 multihead:1; /* can switch video heads */
101 u8 rom:1; /* can retrieve a video rom */
102 u8 post:1; /* can configure the head to */
106 struct acpi_video_bus_cap {
107 u8 _DOS:1; /*Enable/Disable output switching */
108 u8 _DOD:1; /*Enumerate all devices attached to display adapter */
109 u8 _ROM:1; /*Get ROM Data */
110 u8 _GPD:1; /*Get POST Device */
111 u8 _SPD:1; /*Set POST Device */
112 u8 _VPO:1; /*Video POST Options */
116 struct acpi_video_device_attrib {
117 u32 display_index:4; /* A zero-based instance of the Display */
118 u32 display_port_attachment:4; /*This field differentiates the display type */
119 u32 display_type:4; /*Describe the specific type in use */
120 u32 vendor_specific:4; /*Chipset Vendor Specific */
121 u32 bios_can_detect:1; /*BIOS can detect the device */
122 u32 depend_on_vga:1; /*Non-VGA output device whose power is related to
124 u32 pipe_id:3; /*For VGA multiple-head devices. */
125 u32 reserved:10; /*Must be 0 */
126 u32 device_id_scheme:1; /*Device ID Scheme */
129 struct acpi_video_enumerated_device {
132 struct acpi_video_device_attrib attrib;
134 struct acpi_video_device *bind_info;
137 struct acpi_video_bus {
138 struct acpi_device *device;
140 struct acpi_video_enumerated_device *attached_array;
142 struct acpi_video_bus_cap cap;
143 struct acpi_video_bus_flags flags;
144 struct list_head video_device_list;
145 struct mutex device_list_lock; /* protects video_device_list */
146 struct proc_dir_entry *dir;
147 struct input_dev *input;
148 char phys[32]; /* for input device */
151 struct acpi_video_device_flags {
161 struct acpi_video_device_cap {
162 u8 _ADR:1; /*Return the unique ID */
163 u8 _BCL:1; /*Query list of brightness control levels supported */
164 u8 _BCM:1; /*Set the brightness level */
165 u8 _BQC:1; /* Get current brightness level */
166 u8 _DDC:1; /*Return the EDID for this device */
167 u8 _DCS:1; /*Return status of output device */
168 u8 _DGS:1; /*Query graphics state */
169 u8 _DSS:1; /*Device state set */
172 struct acpi_video_device_brightness {
178 struct acpi_video_device {
179 unsigned long device_id;
180 struct acpi_video_device_flags flags;
181 struct acpi_video_device_cap cap;
182 struct list_head entry;
183 struct acpi_video_bus *video;
184 struct acpi_device *dev;
185 struct acpi_video_device_brightness *brightness;
186 struct backlight_device *backlight;
187 struct output_device *output_dev;
191 static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
192 static struct file_operations acpi_video_bus_info_fops = {
193 .open = acpi_video_bus_info_open_fs,
196 .release = single_release,
199 static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
200 static struct file_operations acpi_video_bus_ROM_fops = {
201 .open = acpi_video_bus_ROM_open_fs,
204 .release = single_release,
207 static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
209 static struct file_operations acpi_video_bus_POST_info_fops = {
210 .open = acpi_video_bus_POST_info_open_fs,
213 .release = single_release,
216 static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
217 static struct file_operations acpi_video_bus_POST_fops = {
218 .open = acpi_video_bus_POST_open_fs,
221 .release = single_release,
224 static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
225 static struct file_operations acpi_video_bus_DOS_fops = {
226 .open = acpi_video_bus_DOS_open_fs,
229 .release = single_release,
233 static int acpi_video_device_info_open_fs(struct inode *inode,
235 static struct file_operations acpi_video_device_info_fops = {
236 .open = acpi_video_device_info_open_fs,
239 .release = single_release,
242 static int acpi_video_device_state_open_fs(struct inode *inode,
244 static struct file_operations acpi_video_device_state_fops = {
245 .open = acpi_video_device_state_open_fs,
248 .release = single_release,
251 static int acpi_video_device_brightness_open_fs(struct inode *inode,
253 static struct file_operations acpi_video_device_brightness_fops = {
254 .open = acpi_video_device_brightness_open_fs,
257 .release = single_release,
260 static int acpi_video_device_EDID_open_fs(struct inode *inode,
262 static struct file_operations acpi_video_device_EDID_fops = {
263 .open = acpi_video_device_EDID_open_fs,
266 .release = single_release,
269 static char device_decode[][30] = {
270 "motherboard VGA device",
276 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data);
277 static void acpi_video_device_rebind(struct acpi_video_bus *video);
278 static void acpi_video_device_bind(struct acpi_video_bus *video,
279 struct acpi_video_device *device);
280 static int acpi_video_device_enumerate(struct acpi_video_bus *video);
281 static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
283 static int acpi_video_device_lcd_get_level_current(
284 struct acpi_video_device *device,
285 unsigned long *level);
286 static int acpi_video_get_next_level(struct acpi_video_device *device,
287 u32 level_current, u32 event);
288 static void acpi_video_switch_brightness(struct acpi_video_device *device,
290 static int acpi_video_device_get_state(struct acpi_video_device *device,
291 unsigned long *state);
292 static int acpi_video_output_get(struct output_device *od);
293 static int acpi_video_device_set_state(struct acpi_video_device *device, int state);
295 /*backlight device sysfs support*/
296 static int acpi_video_get_brightness(struct backlight_device *bd)
298 unsigned long cur_level;
299 struct acpi_video_device *vd =
300 (struct acpi_video_device *)bl_get_data(bd);
301 acpi_video_device_lcd_get_level_current(vd, &cur_level);
302 return (int) cur_level;
305 static int acpi_video_set_brightness(struct backlight_device *bd)
307 int request_level = bd->props.brightness;
308 struct acpi_video_device *vd =
309 (struct acpi_video_device *)bl_get_data(bd);
310 acpi_video_device_lcd_set_level(vd, request_level);
314 static struct backlight_ops acpi_backlight_ops = {
315 .get_brightness = acpi_video_get_brightness,
316 .update_status = acpi_video_set_brightness,
319 /*video output device sysfs support*/
320 static int acpi_video_output_get(struct output_device *od)
323 struct acpi_video_device *vd =
324 (struct acpi_video_device *)dev_get_drvdata(&od->dev);
325 acpi_video_device_get_state(vd, &state);
329 static int acpi_video_output_set(struct output_device *od)
331 unsigned long state = od->request_state;
332 struct acpi_video_device *vd=
333 (struct acpi_video_device *)dev_get_drvdata(&od->dev);
334 return acpi_video_device_set_state(vd, state);
337 static struct output_properties acpi_output_properties = {
338 .set_state = acpi_video_output_set,
339 .get_status = acpi_video_output_get,
341 /* --------------------------------------------------------------------------
343 -------------------------------------------------------------------------- */
348 acpi_video_device_query(struct acpi_video_device *device, unsigned long *state)
352 status = acpi_evaluate_integer(device->dev->handle, "_DGS", NULL, state);
358 acpi_video_device_get_state(struct acpi_video_device *device,
359 unsigned long *state)
363 status = acpi_evaluate_integer(device->dev->handle, "_DCS", NULL, state);
369 acpi_video_device_set_state(struct acpi_video_device *device, int state)
372 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
373 struct acpi_object_list args = { 1, &arg0 };
377 arg0.integer.value = state;
378 status = acpi_evaluate_integer(device->dev->handle, "_DSS", &args, &ret);
384 acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
385 union acpi_object **levels)
388 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
389 union acpi_object *obj;
394 status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer);
395 if (!ACPI_SUCCESS(status))
397 obj = (union acpi_object *)buffer.pointer;
398 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
399 printk(KERN_ERR PREFIX "Invalid _BCL data\n");
409 kfree(buffer.pointer);
415 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
418 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
419 struct acpi_object_list args = { 1, &arg0 };
422 arg0.integer.value = level;
424 if (device->cap._BCM)
425 status = acpi_evaluate_object(device->dev->handle, "_BCM",
427 device->brightness->curr = level;
432 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
433 unsigned long *level)
435 if (device->cap._BQC)
436 return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
438 *level = device->brightness->curr;
443 acpi_video_device_EDID(struct acpi_video_device *device,
444 union acpi_object **edid, ssize_t length)
447 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
448 union acpi_object *obj;
449 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
450 struct acpi_object_list args = { 1, &arg0 };
458 arg0.integer.value = 1;
459 else if (length == 256)
460 arg0.integer.value = 2;
464 status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer);
465 if (ACPI_FAILURE(status))
468 obj = buffer.pointer;
470 if (obj && obj->type == ACPI_TYPE_BUFFER)
473 printk(KERN_ERR PREFIX "Invalid _DDC data\n");
484 acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
488 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
489 struct acpi_object_list args = { 1, &arg0 };
492 arg0.integer.value = option;
494 status = acpi_evaluate_integer(video->device->handle, "_SPD", &args, &tmp);
495 if (ACPI_SUCCESS(status))
496 status = tmp ? (-EINVAL) : (AE_OK);
502 acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long *id)
506 status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id);
512 acpi_video_bus_POST_options(struct acpi_video_bus *video,
513 unsigned long *options)
517 status = acpi_evaluate_integer(video->device->handle, "_VPO", NULL, options);
525 * video : video bus device pointer
527 * 0. The system BIOS should NOT automatically switch(toggle)
528 * the active display output.
529 * 1. The system BIOS should automatically switch (toggle) the
530 * active display output. No switch event.
531 * 2. The _DGS value should be locked.
532 * 3. The system BIOS should not automatically switch (toggle) the
533 * active display output, but instead generate the display switch
536 * 0. The system BIOS should automatically control the brightness level
537 * of the LCD when the power changes from AC to DC
538 * 1. The system BIOS should NOT automatically control the brightness
539 * level of the LCD when the power changes from AC to DC.
545 acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
547 acpi_integer status = 0;
548 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
549 struct acpi_object_list args = { 1, &arg0 };
552 if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) {
556 arg0.integer.value = (lcd_flag << 2) | bios_flag;
557 video->dos_setting = arg0.integer.value;
558 acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL);
566 * device : video output device (LCD, CRT, ..)
571 * Find out all required AML methods defined under the output
575 static void acpi_video_device_find_cap(struct acpi_video_device *device)
577 acpi_handle h_dummy1;
580 union acpi_object *obj = NULL;
581 struct acpi_video_device_brightness *br = NULL;
584 memset(&device->cap, 0, sizeof(device->cap));
586 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) {
587 device->cap._ADR = 1;
589 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) {
590 device->cap._BCL = 1;
592 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
593 device->cap._BCM = 1;
595 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
596 device->cap._BQC = 1;
597 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
598 device->cap._DDC = 1;
600 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DCS", &h_dummy1))) {
601 device->cap._DCS = 1;
603 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DGS", &h_dummy1))) {
604 device->cap._DGS = 1;
606 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DSS", &h_dummy1))) {
607 device->cap._DSS = 1;
610 if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
612 if (obj->package.count >= 2) {
614 union acpi_object *o;
616 br = kzalloc(sizeof(*br), GFP_KERNEL);
618 printk(KERN_ERR "can't allocate memory\n");
620 br->levels = kmalloc(obj->package.count *
621 sizeof *(br->levels), GFP_KERNEL);
625 for (i = 0; i < obj->package.count; i++) {
626 o = (union acpi_object *)&obj->package.
628 if (o->type != ACPI_TYPE_INTEGER) {
629 printk(KERN_ERR PREFIX "Invalid data\n");
632 br->levels[count] = (u32) o->integer.value;
634 if (br->levels[count] > max_level)
635 max_level = br->levels[count];
644 device->brightness = br;
645 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
646 "found %d brightness levels\n",
653 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n"));
658 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
660 static int count = 0;
662 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
666 sprintf(name, "acpi_video%d", count++);
667 acpi_video_device_lcd_get_level_current(device, &tmp);
668 device->backlight = backlight_device_register(name,
669 NULL, device, &acpi_backlight_ops);
670 device->backlight->props.max_brightness = max_level;
671 device->backlight->props.brightness = (int)tmp;
672 backlight_update_status(device->backlight);
676 if (device->cap._DCS && device->cap._DSS){
677 static int count = 0;
679 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
682 sprintf(name, "acpi_video%d", count++);
683 device->output_dev = video_output_register(name,
684 NULL, device, &acpi_output_properties);
692 * device : video output device (VGA)
697 * Find out all required AML methods defined under the video bus device.
700 static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
702 acpi_handle h_dummy1;
704 memset(&video->cap, 0, sizeof(video->cap));
705 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) {
708 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) {
711 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) {
714 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) {
717 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) {
720 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) {
726 * Check whether the video bus device has required AML method to
727 * support the desired features
730 static int acpi_video_bus_check(struct acpi_video_bus *video)
732 acpi_status status = -ENOENT;
738 /* Since there is no HID, CID and so on for VGA driver, we have
739 * to check well known required nodes.
742 /* Does this device support video switching? */
743 if (video->cap._DOS) {
744 video->flags.multihead = 1;
748 /* Does this device support retrieving a video ROM? */
749 if (video->cap._ROM) {
750 video->flags.rom = 1;
754 /* Does this device support configuring which video device to POST? */
755 if (video->cap._GPD && video->cap._SPD && video->cap._VPO) {
756 video->flags.post = 1;
763 /* --------------------------------------------------------------------------
765 -------------------------------------------------------------------------- */
767 static struct proc_dir_entry *acpi_video_dir;
771 static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
773 struct acpi_video_device *dev = seq->private;
779 seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id);
780 seq_printf(seq, "type: ");
782 seq_printf(seq, "CRT\n");
783 else if (dev->flags.lcd)
784 seq_printf(seq, "LCD\n");
785 else if (dev->flags.tvout)
786 seq_printf(seq, "TVOUT\n");
787 else if (dev->flags.dvi)
788 seq_printf(seq, "DVI\n");
790 seq_printf(seq, "UNKNOWN\n");
792 seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no");
799 acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
801 return single_open(file, acpi_video_device_info_seq_show,
805 static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
808 struct acpi_video_device *dev = seq->private;
815 status = acpi_video_device_get_state(dev, &state);
816 seq_printf(seq, "state: ");
817 if (ACPI_SUCCESS(status))
818 seq_printf(seq, "0x%02lx\n", state);
820 seq_printf(seq, "<not supported>\n");
822 status = acpi_video_device_query(dev, &state);
823 seq_printf(seq, "query: ");
824 if (ACPI_SUCCESS(status))
825 seq_printf(seq, "0x%02lx\n", state);
827 seq_printf(seq, "<not supported>\n");
834 acpi_video_device_state_open_fs(struct inode *inode, struct file *file)
836 return single_open(file, acpi_video_device_state_seq_show,
841 acpi_video_device_write_state(struct file *file,
842 const char __user * buffer,
843 size_t count, loff_t * data)
846 struct seq_file *m = file->private_data;
847 struct acpi_video_device *dev = m->private;
848 char str[12] = { 0 };
852 if (!dev || count + 1 > sizeof str)
855 if (copy_from_user(str, buffer, count))
859 state = simple_strtoul(str, NULL, 0);
860 state &= ((1ul << 31) | (1ul << 30) | (1ul << 0));
862 status = acpi_video_device_set_state(dev, state);
871 acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
873 struct acpi_video_device *dev = seq->private;
877 if (!dev || !dev->brightness) {
878 seq_printf(seq, "<not supported>\n");
882 seq_printf(seq, "levels: ");
883 for (i = 0; i < dev->brightness->count; i++)
884 seq_printf(seq, " %d", dev->brightness->levels[i]);
885 seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
891 acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file)
893 return single_open(file, acpi_video_device_brightness_seq_show,
898 acpi_video_device_write_brightness(struct file *file,
899 const char __user * buffer,
900 size_t count, loff_t * data)
902 struct seq_file *m = file->private_data;
903 struct acpi_video_device *dev = m->private;
905 unsigned int level = 0;
909 if (!dev || !dev->brightness || count + 1 > sizeof str)
912 if (copy_from_user(str, buffer, count))
916 level = simple_strtoul(str, NULL, 0);
921 /* validate through the list of available levels */
922 for (i = 0; i < dev->brightness->count; i++)
923 if (level == dev->brightness->levels[i]) {
925 (acpi_video_device_lcd_set_level(dev, level)))
926 dev->brightness->curr = level;
933 static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
935 struct acpi_video_device *dev = seq->private;
938 union acpi_object *edid = NULL;
944 status = acpi_video_device_EDID(dev, &edid, 128);
945 if (ACPI_FAILURE(status)) {
946 status = acpi_video_device_EDID(dev, &edid, 256);
949 if (ACPI_FAILURE(status)) {
953 if (edid && edid->type == ACPI_TYPE_BUFFER) {
954 for (i = 0; i < edid->buffer.length; i++)
955 seq_putc(seq, edid->buffer.pointer[i]);
960 seq_printf(seq, "<not supported>\n");
968 acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file)
970 return single_open(file, acpi_video_device_EDID_seq_show,
974 static int acpi_video_device_add_fs(struct acpi_device *device)
976 struct proc_dir_entry *entry = NULL;
977 struct acpi_video_device *vid_dev;
983 vid_dev = acpi_driver_data(device);
987 if (!acpi_device_dir(device)) {
988 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
989 vid_dev->video->dir);
990 if (!acpi_device_dir(device))
992 acpi_device_dir(device)->owner = THIS_MODULE;
996 entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device));
1000 entry->proc_fops = &acpi_video_device_info_fops;
1001 entry->data = acpi_driver_data(device);
1002 entry->owner = THIS_MODULE;
1007 create_proc_entry("state", S_IFREG | S_IRUGO | S_IWUSR,
1008 acpi_device_dir(device));
1012 acpi_video_device_state_fops.write = acpi_video_device_write_state;
1013 entry->proc_fops = &acpi_video_device_state_fops;
1014 entry->data = acpi_driver_data(device);
1015 entry->owner = THIS_MODULE;
1018 /* 'brightness' [R/W] */
1020 create_proc_entry("brightness", S_IFREG | S_IRUGO | S_IWUSR,
1021 acpi_device_dir(device));
1025 acpi_video_device_brightness_fops.write = acpi_video_device_write_brightness;
1026 entry->proc_fops = &acpi_video_device_brightness_fops;
1027 entry->data = acpi_driver_data(device);
1028 entry->owner = THIS_MODULE;
1032 entry = create_proc_entry("EDID", S_IRUGO, acpi_device_dir(device));
1036 entry->proc_fops = &acpi_video_device_EDID_fops;
1037 entry->data = acpi_driver_data(device);
1038 entry->owner = THIS_MODULE;
1044 static int acpi_video_device_remove_fs(struct acpi_device *device)
1046 struct acpi_video_device *vid_dev;
1048 vid_dev = acpi_driver_data(device);
1049 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
1052 if (acpi_device_dir(device)) {
1053 remove_proc_entry("info", acpi_device_dir(device));
1054 remove_proc_entry("state", acpi_device_dir(device));
1055 remove_proc_entry("brightness", acpi_device_dir(device));
1056 remove_proc_entry("EDID", acpi_device_dir(device));
1057 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1058 acpi_device_dir(device) = NULL;
1065 static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
1067 struct acpi_video_bus *video = seq->private;
1073 seq_printf(seq, "Switching heads: %s\n",
1074 video->flags.multihead ? "yes" : "no");
1075 seq_printf(seq, "Video ROM: %s\n",
1076 video->flags.rom ? "yes" : "no");
1077 seq_printf(seq, "Device to be POSTed on boot: %s\n",
1078 video->flags.post ? "yes" : "no");
1084 static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
1086 return single_open(file, acpi_video_bus_info_seq_show,
1090 static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
1092 struct acpi_video_bus *video = seq->private;
1098 printk(KERN_INFO PREFIX "Please implement %s\n", __FUNCTION__);
1099 seq_printf(seq, "<TODO>\n");
1105 static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
1107 return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data);
1110 static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
1112 struct acpi_video_bus *video = seq->private;
1113 unsigned long options;
1120 status = acpi_video_bus_POST_options(video, &options);
1121 if (ACPI_SUCCESS(status)) {
1122 if (!(options & 1)) {
1123 printk(KERN_WARNING PREFIX
1124 "The motherboard VGA device is not listed as a possible POST device.\n");
1125 printk(KERN_WARNING PREFIX
1126 "This indicates a BIOS bug. Please contact the manufacturer.\n");
1128 printk("%lx\n", options);
1129 seq_printf(seq, "can POST: <integrated video>");
1131 seq_printf(seq, " <PCI video>");
1133 seq_printf(seq, " <AGP video>");
1134 seq_putc(seq, '\n');
1136 seq_printf(seq, "<not supported>\n");
1142 acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
1144 return single_open(file, acpi_video_bus_POST_info_seq_show,
1148 static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
1150 struct acpi_video_bus *video = seq->private;
1158 status = acpi_video_bus_get_POST(video, &id);
1159 if (!ACPI_SUCCESS(status)) {
1160 seq_printf(seq, "<not supported>\n");
1163 seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]);
1169 static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
1171 struct acpi_video_bus *video = seq->private;
1174 seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
1179 static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file)
1181 return single_open(file, acpi_video_bus_POST_seq_show,
1185 static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file)
1187 return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data);
1191 acpi_video_bus_write_POST(struct file *file,
1192 const char __user * buffer,
1193 size_t count, loff_t * data)
1196 struct seq_file *m = file->private_data;
1197 struct acpi_video_bus *video = m->private;
1198 char str[12] = { 0 };
1199 unsigned long opt, options;
1202 if (!video || count + 1 > sizeof str)
1205 status = acpi_video_bus_POST_options(video, &options);
1206 if (!ACPI_SUCCESS(status))
1209 if (copy_from_user(str, buffer, count))
1213 opt = strtoul(str, NULL, 0);
1217 /* just in case an OEM 'forgot' the motherboard... */
1220 if (options & (1ul << opt)) {
1221 status = acpi_video_bus_set_POST(video, opt);
1222 if (!ACPI_SUCCESS(status))
1231 acpi_video_bus_write_DOS(struct file *file,
1232 const char __user * buffer,
1233 size_t count, loff_t * data)
1236 struct seq_file *m = file->private_data;
1237 struct acpi_video_bus *video = m->private;
1238 char str[12] = { 0 };
1242 if (!video || count + 1 > sizeof str)
1245 if (copy_from_user(str, buffer, count))
1249 opt = strtoul(str, NULL, 0);
1253 status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2);
1255 if (!ACPI_SUCCESS(status))
1261 static int acpi_video_bus_add_fs(struct acpi_device *device)
1263 struct proc_dir_entry *entry = NULL;
1264 struct acpi_video_bus *video;
1267 video = acpi_driver_data(device);
1269 if (!acpi_device_dir(device)) {
1270 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1272 if (!acpi_device_dir(device))
1274 video->dir = acpi_device_dir(device);
1275 acpi_device_dir(device)->owner = THIS_MODULE;
1279 entry = create_proc_entry("info", S_IRUGO, acpi_device_dir(device));
1283 entry->proc_fops = &acpi_video_bus_info_fops;
1284 entry->data = acpi_driver_data(device);
1285 entry->owner = THIS_MODULE;
1289 entry = create_proc_entry("ROM", S_IRUGO, acpi_device_dir(device));
1293 entry->proc_fops = &acpi_video_bus_ROM_fops;
1294 entry->data = acpi_driver_data(device);
1295 entry->owner = THIS_MODULE;
1298 /* 'POST_info' [R] */
1300 create_proc_entry("POST_info", S_IRUGO, acpi_device_dir(device));
1304 entry->proc_fops = &acpi_video_bus_POST_info_fops;
1305 entry->data = acpi_driver_data(device);
1306 entry->owner = THIS_MODULE;
1311 create_proc_entry("POST", S_IFREG | S_IRUGO | S_IRUSR,
1312 acpi_device_dir(device));
1316 acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
1317 entry->proc_fops = &acpi_video_bus_POST_fops;
1318 entry->data = acpi_driver_data(device);
1319 entry->owner = THIS_MODULE;
1324 create_proc_entry("DOS", S_IFREG | S_IRUGO | S_IRUSR,
1325 acpi_device_dir(device));
1329 acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
1330 entry->proc_fops = &acpi_video_bus_DOS_fops;
1331 entry->data = acpi_driver_data(device);
1332 entry->owner = THIS_MODULE;
1338 static int acpi_video_bus_remove_fs(struct acpi_device *device)
1340 struct acpi_video_bus *video;
1343 video = acpi_driver_data(device);
1345 if (acpi_device_dir(device)) {
1346 remove_proc_entry("info", acpi_device_dir(device));
1347 remove_proc_entry("ROM", acpi_device_dir(device));
1348 remove_proc_entry("POST_info", acpi_device_dir(device));
1349 remove_proc_entry("POST", acpi_device_dir(device));
1350 remove_proc_entry("DOS", acpi_device_dir(device));
1351 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1352 acpi_device_dir(device) = NULL;
1358 /* --------------------------------------------------------------------------
1360 -------------------------------------------------------------------------- */
1362 /* device interface */
1363 static struct acpi_video_device_attrib*
1364 acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1368 for(count = 0; count < video->attached_count; count++)
1369 if((video->attached_array[count].value.int_val & 0xffff) == device_id)
1370 return &(video->attached_array[count].value.attrib);
1375 acpi_video_bus_get_one_device(struct acpi_device *device,
1376 struct acpi_video_bus *video)
1378 unsigned long device_id;
1380 struct acpi_video_device *data;
1381 struct acpi_video_device_attrib* attribute;
1383 if (!device || !video)
1387 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
1388 if (ACPI_SUCCESS(status)) {
1390 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
1394 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
1395 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1396 acpi_driver_data(device) = data;
1398 data->device_id = device_id;
1399 data->video = video;
1402 attribute = acpi_video_get_device_attr(video, device_id);
1404 if((attribute != NULL) && attribute->device_id_scheme) {
1405 switch (attribute->display_type) {
1406 case ACPI_VIDEO_DISPLAY_CRT:
1407 data->flags.crt = 1;
1409 case ACPI_VIDEO_DISPLAY_TV:
1410 data->flags.tvout = 1;
1412 case ACPI_VIDEO_DISPLAY_DVI:
1413 data->flags.dvi = 1;
1415 case ACPI_VIDEO_DISPLAY_LCD:
1416 data->flags.lcd = 1;
1419 data->flags.unknown = 1;
1422 if(attribute->bios_can_detect)
1423 data->flags.bios = 1;
1425 data->flags.unknown = 1;
1427 acpi_video_device_bind(video, data);
1428 acpi_video_device_find_cap(data);
1430 status = acpi_install_notify_handler(device->handle,
1432 acpi_video_device_notify,
1434 if (ACPI_FAILURE(status)) {
1435 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1436 "Error installing notify handler\n"));
1437 if(data->brightness)
1438 kfree(data->brightness->levels);
1439 kfree(data->brightness);
1444 mutex_lock(&video->device_list_lock);
1445 list_add_tail(&data->entry, &video->video_device_list);
1446 mutex_unlock(&video->device_list_lock);
1448 acpi_video_device_add_fs(device);
1458 * video : video bus device
1463 * Enumerate the video device list of the video bus,
1464 * bind the ids with the corresponding video devices
1465 * under the video bus.
1468 static void acpi_video_device_rebind(struct acpi_video_bus *video)
1470 struct acpi_video_device *dev;
1472 mutex_lock(&video->device_list_lock);
1474 list_for_each_entry(dev, &video->video_device_list, entry)
1475 acpi_video_device_bind(video, dev);
1477 mutex_unlock(&video->device_list_lock);
1482 * video : video bus device
1483 * device : video output device under the video
1489 * Bind the ids with the corresponding video devices
1490 * under the video bus.
1494 acpi_video_device_bind(struct acpi_video_bus *video,
1495 struct acpi_video_device *device)
1499 #define IDS_VAL(i) video->attached_array[i].value.int_val
1500 #define IDS_BIND(i) video->attached_array[i].bind_info
1502 for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID &&
1503 i < video->attached_count; i++) {
1504 if (device->device_id == (IDS_VAL(i) & 0xffff)) {
1505 IDS_BIND(i) = device;
1506 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
1515 * video : video bus device
1520 * Call _DOD to enumerate all devices attached to display adapter
1524 static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1529 struct acpi_video_enumerated_device *active_device_list;
1530 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1531 union acpi_object *dod = NULL;
1532 union acpi_object *obj;
1534 status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer);
1535 if (!ACPI_SUCCESS(status)) {
1536 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD"));
1540 dod = buffer.pointer;
1541 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
1542 ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
1547 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
1548 dod->package.count));
1550 active_device_list = kmalloc((1 +
1551 dod->package.count) *
1553 acpi_video_enumerated_device),
1556 if (!active_device_list) {
1562 for (i = 0; i < dod->package.count; i++) {
1563 obj = &dod->package.elements[i];
1565 if (obj->type != ACPI_TYPE_INTEGER) {
1566 printk(KERN_ERR PREFIX "Invalid _DOD data\n");
1567 active_device_list[i].value.int_val =
1568 ACPI_VIDEO_HEAD_INVALID;
1570 active_device_list[i].value.int_val = obj->integer.value;
1571 active_device_list[i].bind_info = NULL;
1572 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
1573 (int)obj->integer.value));
1576 active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
1578 kfree(video->attached_array);
1580 video->attached_array = active_device_list;
1581 video->attached_count = count;
1583 kfree(buffer.pointer);
1588 acpi_video_get_next_level(struct acpi_video_device *device,
1589 u32 level_current, u32 event)
1591 int min, max, min_above, max_below, i, l, delta = 255;
1592 max = max_below = 0;
1593 min = min_above = 255;
1594 /* Find closest level to level_current */
1595 for (i = 0; i < device->brightness->count; i++) {
1596 l = device->brightness->levels[i];
1597 if (abs(l - level_current) < abs(delta)) {
1598 delta = l - level_current;
1603 /* Ajust level_current to closest available level */
1604 level_current += delta;
1605 for (i = 0; i < device->brightness->count; i++) {
1606 l = device->brightness->levels[i];
1611 if (l < min_above && l > level_current)
1613 if (l > max_below && l < level_current)
1618 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
1619 return (level_current < max) ? min_above : min;
1620 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
1621 return (level_current < max) ? min_above : max;
1622 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
1623 return (level_current > min) ? max_below : min;
1624 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
1625 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
1628 return level_current;
1633 acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1635 unsigned long level_current, level_next;
1636 acpi_video_device_lcd_get_level_current(device, &level_current);
1637 level_next = acpi_video_get_next_level(device, level_current, event);
1638 acpi_video_device_lcd_set_level(device, level_next);
1642 acpi_video_bus_get_devices(struct acpi_video_bus *video,
1643 struct acpi_device *device)
1646 struct acpi_device *dev;
1648 acpi_video_device_enumerate(video);
1650 list_for_each_entry(dev, &device->children, node) {
1652 status = acpi_video_bus_get_one_device(dev, video);
1653 if (ACPI_FAILURE(status)) {
1654 ACPI_EXCEPTION((AE_INFO, status, "Cant attach device"));
1661 static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1664 struct acpi_video_bus *video;
1667 if (!device || !device->video)
1670 video = device->video;
1672 acpi_video_device_remove_fs(device->dev);
1674 status = acpi_remove_notify_handler(device->dev->handle,
1676 acpi_video_device_notify);
1677 backlight_device_unregister(device->backlight);
1678 video_output_unregister(device->output_dev);
1683 static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1686 struct acpi_video_device *dev, *next;
1688 mutex_lock(&video->device_list_lock);
1690 list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
1692 status = acpi_video_bus_put_one_device(dev);
1693 if (ACPI_FAILURE(status))
1694 printk(KERN_WARNING PREFIX
1695 "hhuuhhuu bug in acpi video driver.\n");
1697 if (dev->brightness) {
1698 kfree(dev->brightness->levels);
1699 kfree(dev->brightness);
1701 list_del(&dev->entry);
1705 mutex_unlock(&video->device_list_lock);
1710 /* acpi_video interface */
1712 static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
1714 return acpi_video_bus_DOS(video, 0, 0);
1717 static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
1719 return acpi_video_bus_DOS(video, 0, 1);
1722 static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1724 struct acpi_video_bus *video = data;
1725 struct acpi_device *device = NULL;
1726 struct input_dev *input;
1732 device = video->device;
1733 input = video->input;
1736 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
1737 * most likely via hotkey. */
1738 acpi_bus_generate_proc_event(device, event, 0);
1739 keycode = KEY_SWITCHVIDEOMODE;
1742 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video
1744 acpi_video_device_enumerate(video);
1745 acpi_video_device_rebind(video);
1746 acpi_bus_generate_proc_event(device, event, 0);
1747 keycode = KEY_SWITCHVIDEOMODE;
1750 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */
1751 acpi_bus_generate_proc_event(device, event, 0);
1752 keycode = KEY_SWITCHVIDEOMODE;
1754 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
1755 acpi_bus_generate_proc_event(device, event, 0);
1756 keycode = KEY_VIDEO_NEXT;
1758 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
1759 acpi_bus_generate_proc_event(device, event, 0);
1760 keycode = KEY_VIDEO_PREV;
1764 keycode = KEY_UNKNOWN;
1765 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1766 "Unsupported event [0x%x]\n", event));
1770 acpi_notifier_call_chain(device, event, 0);
1771 input_report_key(input, keycode, 1);
1773 input_report_key(input, keycode, 0);
1779 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1781 struct acpi_video_device *video_device = data;
1782 struct acpi_device *device = NULL;
1783 struct acpi_video_bus *bus;
1784 struct input_dev *input;
1790 device = video_device->dev;
1791 bus = video_device->video;
1795 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
1796 if (brightness_switch_enabled)
1797 acpi_video_switch_brightness(video_device, event);
1798 acpi_bus_generate_proc_event(device, event, 0);
1799 keycode = KEY_BRIGHTNESS_CYCLE;
1801 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
1802 if (brightness_switch_enabled)
1803 acpi_video_switch_brightness(video_device, event);
1804 acpi_bus_generate_proc_event(device, event, 0);
1805 keycode = KEY_BRIGHTNESSUP;
1807 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
1808 if (brightness_switch_enabled)
1809 acpi_video_switch_brightness(video_device, event);
1810 acpi_bus_generate_proc_event(device, event, 0);
1811 keycode = KEY_BRIGHTNESSDOWN;
1813 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */
1814 if (brightness_switch_enabled)
1815 acpi_video_switch_brightness(video_device, event);
1816 acpi_bus_generate_proc_event(device, event, 0);
1817 keycode = KEY_BRIGHTNESS_ZERO;
1819 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
1820 if (brightness_switch_enabled)
1821 acpi_video_switch_brightness(video_device, event);
1822 acpi_bus_generate_proc_event(device, event, 0);
1823 keycode = KEY_DISPLAY_OFF;
1826 keycode = KEY_UNKNOWN;
1827 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1828 "Unsupported event [0x%x]\n", event));
1832 acpi_notifier_call_chain(device, event, 0);
1833 input_report_key(input, keycode, 1);
1835 input_report_key(input, keycode, 0);
1841 static int instance;
1842 static int acpi_video_resume(struct acpi_device *device)
1844 struct acpi_video_bus *video;
1845 struct acpi_video_device *video_device;
1848 if (!device || !acpi_driver_data(device))
1851 video = acpi_driver_data(device);
1853 for (i = 0; i < video->attached_count; i++) {
1854 video_device = video->attached_array[i].bind_info;
1855 if (video_device && video_device->backlight)
1856 acpi_video_set_brightness(video_device->backlight);
1861 static int acpi_video_bus_add(struct acpi_device *device)
1864 struct acpi_video_bus *video;
1865 struct input_dev *input;
1868 video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
1872 /* a hack to fix the duplicate name "VID" problem on T61 */
1873 if (!strcmp(device->pnp.bus_id, "VID")) {
1875 device->pnp.bus_id[3] = '0' + instance;
1879 video->device = device;
1880 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
1881 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1882 acpi_driver_data(device) = video;
1884 acpi_video_bus_find_cap(video);
1885 error = acpi_video_bus_check(video);
1887 goto err_free_video;
1889 error = acpi_video_bus_add_fs(device);
1891 goto err_free_video;
1893 mutex_init(&video->device_list_lock);
1894 INIT_LIST_HEAD(&video->video_device_list);
1896 acpi_video_bus_get_devices(video, device);
1897 acpi_video_bus_start_devices(video);
1899 status = acpi_install_notify_handler(device->handle,
1901 acpi_video_bus_notify, video);
1902 if (ACPI_FAILURE(status)) {
1903 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1904 "Error installing notify handler\n"));
1906 goto err_stop_video;
1909 video->input = input = input_allocate_device();
1912 goto err_uninstall_notify;
1915 snprintf(video->phys, sizeof(video->phys),
1916 "%s/video/input0", acpi_device_hid(video->device));
1918 input->name = acpi_device_name(video->device);
1919 input->phys = video->phys;
1920 input->id.bustype = BUS_HOST;
1921 input->id.product = 0x06;
1922 input->dev.parent = &device->dev;
1923 input->evbit[0] = BIT(EV_KEY);
1924 set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
1925 set_bit(KEY_VIDEO_NEXT, input->keybit);
1926 set_bit(KEY_VIDEO_PREV, input->keybit);
1927 set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);
1928 set_bit(KEY_BRIGHTNESSUP, input->keybit);
1929 set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
1930 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
1931 set_bit(KEY_DISPLAY_OFF, input->keybit);
1932 set_bit(KEY_UNKNOWN, input->keybit);
1934 error = input_register_device(input);
1936 goto err_free_input_dev;
1938 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
1939 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
1940 video->flags.multihead ? "yes" : "no",
1941 video->flags.rom ? "yes" : "no",
1942 video->flags.post ? "yes" : "no");
1947 input_free_device(input);
1948 err_uninstall_notify:
1949 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
1950 acpi_video_bus_notify);
1952 acpi_video_bus_stop_devices(video);
1953 acpi_video_bus_put_devices(video);
1954 kfree(video->attached_array);
1955 acpi_video_bus_remove_fs(device);
1958 acpi_driver_data(device) = NULL;
1963 static int acpi_video_bus_remove(struct acpi_device *device, int type)
1965 acpi_status status = 0;
1966 struct acpi_video_bus *video = NULL;
1969 if (!device || !acpi_driver_data(device))
1972 video = acpi_driver_data(device);
1974 acpi_video_bus_stop_devices(video);
1976 status = acpi_remove_notify_handler(video->device->handle,
1978 acpi_video_bus_notify);
1980 acpi_video_bus_put_devices(video);
1981 acpi_video_bus_remove_fs(device);
1983 input_unregister_device(video->input);
1984 kfree(video->attached_array);
1990 static int __init acpi_video_init(void)
1996 acpi_dbg_level = 0xFFFFFFFF;
1997 acpi_dbg_layer = 0x08000000;
2000 acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
2001 if (!acpi_video_dir)
2003 acpi_video_dir->owner = THIS_MODULE;
2005 result = acpi_bus_register_driver(&acpi_video_bus);
2007 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
2014 static void __exit acpi_video_exit(void)
2017 acpi_bus_unregister_driver(&acpi_video_bus);
2019 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
2024 module_init(acpi_video_init);
2025 module_exit(acpi_video_exit);