1/* 2 * video.c - ACPI Video Driver ($Revision:$) 3 * 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> 7 * 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 * 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. 14 * 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. 19 * 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. 23 * 24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 25 */ 26 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/thermal.h> 38#include <linux/video_output.h> 39#include <linux/sort.h> 40#include <linux/pci.h> 41#include <linux/pci_ids.h> 42#include <linux/slab.h> 43#include <asm/uaccess.h> 44#include <linux/dmi.h> 45#include <acpi/acpi_bus.h> 46#include <acpi/acpi_drivers.h> 47#include <linux/suspend.h> 48#include <acpi/video.h> 49 50#define PREFIX "ACPI: " 51 52#define ACPI_VIDEO_CLASS "video" 53#define ACPI_VIDEO_BUS_NAME "Video Bus" 54#define ACPI_VIDEO_DEVICE_NAME "Video Device" 55#define ACPI_VIDEO_NOTIFY_SWITCH 0x80 56#define ACPI_VIDEO_NOTIFY_PROBE 0x81 57#define ACPI_VIDEO_NOTIFY_CYCLE 0x82 58#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 59#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 60 61#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85 62#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 63#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 64#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 65#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 66 67#define MAX_NAME_LEN 20 68 69#define _COMPONENT ACPI_VIDEO_COMPONENT 70ACPI_MODULE_NAME("video"); 71 72MODULE_AUTHOR("Bruno Ducrot"); 73MODULE_DESCRIPTION("ACPI Video Driver"); 74MODULE_LICENSE("GPL"); 75 76static int brightness_switch_enabled = 1; 77module_param(brightness_switch_enabled, bool, 0644); 78 79/* 80 * By default, we don't allow duplicate ACPI video bus devices 81 * under the same VGA controller 82 */ 83static int allow_duplicates; 84module_param(allow_duplicates, bool, 0644); 85 86static int register_count = 0; 87static int acpi_video_bus_add(struct acpi_device *device); 88static int acpi_video_bus_remove(struct acpi_device *device, int type); 89static void acpi_video_bus_notify(struct acpi_device *device, u32 event); 90 91static const struct acpi_device_id video_device_ids[] = { 92 {ACPI_VIDEO_HID, 0}, 93 {"", 0}, 94}; 95MODULE_DEVICE_TABLE(acpi, video_device_ids); 96 97static struct acpi_driver acpi_video_bus = { 98 .name = "video", 99 .class = ACPI_VIDEO_CLASS, 100 .ids = video_device_ids, 101 .ops = { 102 .add = acpi_video_bus_add, 103 .remove = acpi_video_bus_remove, 104 .notify = acpi_video_bus_notify, 105 }, 106}; 107 108struct acpi_video_bus_flags { 109 u8 multihead:1; /* can switch video heads */ 110 u8 rom:1; /* can retrieve a video rom */ 111 u8 post:1; /* can configure the head to */ 112 u8 reserved:5; 113}; 114 115struct acpi_video_bus_cap { 116 u8 _DOS:1; /*Enable/Disable output switching */ 117 u8 _DOD:1; /*Enumerate all devices attached to display adapter */ 118 u8 _ROM:1; /*Get ROM Data */ 119 u8 _GPD:1; /*Get POST Device */ 120 u8 _SPD:1; /*Set POST Device */ 121 u8 _VPO:1; /*Video POST Options */ 122 u8 reserved:2; 123}; 124 125struct acpi_video_device_attrib { 126 u32 display_index:4; /* A zero-based instance of the Display */ 127 u32 display_port_attachment:4; /*This field differentiates the display type */ 128 u32 display_type:4; /*Describe the specific type in use */ 129 u32 vendor_specific:4; /*Chipset Vendor Specific */ 130 u32 bios_can_detect:1; /*BIOS can detect the device */ 131 u32 depend_on_vga:1; /*Non-VGA output device whose power is related to 132 the VGA device. */ 133 u32 pipe_id:3; /*For VGA multiple-head devices. */ 134 u32 reserved:10; /*Must be 0 */ 135 u32 device_id_scheme:1; /*Device ID Scheme */ 136}; 137 138struct acpi_video_enumerated_device { 139 union { 140 u32 int_val; 141 struct acpi_video_device_attrib attrib; 142 } value; 143 struct acpi_video_device *bind_info; 144}; 145 146struct acpi_video_bus { 147 struct acpi_device *device; 148 u8 dos_setting; 149 struct acpi_video_enumerated_device *attached_array; 150 u8 attached_count; 151 struct acpi_video_bus_cap cap; 152 struct acpi_video_bus_flags flags; 153 struct list_head video_device_list; 154 struct mutex device_list_lock; /* protects video_device_list */ 155#ifdef CONFIG_ACPI_PROCFS 156 struct proc_dir_entry *dir; 157#endif 158 struct input_dev *input; 159 char phys[32]; /* for input device */ 160 struct notifier_block pm_nb; 161}; 162 163struct acpi_video_device_flags { 164 u8 crt:1; 165 u8 lcd:1; 166 u8 tvout:1; 167 u8 dvi:1; 168 u8 bios:1; 169 u8 unknown:1; 170 u8 reserved:2; 171}; 172 173struct acpi_video_device_cap { 174 u8 _ADR:1; /*Return the unique ID */ 175 u8 _BCL:1; /*Query list of brightness control levels supported */ 176 u8 _BCM:1; /*Set the brightness level */ 177 u8 _BQC:1; /* Get current brightness level */ 178 u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ 179 u8 _DDC:1; /*Return the EDID for this device */ 180 u8 _DCS:1; /*Return status of output device */ 181 u8 _DGS:1; /*Query graphics state */ 182 u8 _DSS:1; /*Device state set */ 183}; 184 185struct acpi_video_brightness_flags { 186 u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */ 187 u8 _BCL_reversed:1; /* _BCL package is in a reversed order*/ 188 u8 _BCL_use_index:1; /* levels in _BCL are index values */ 189 u8 _BCM_use_index:1; /* input of _BCM is an index value */ 190 u8 _BQC_use_index:1; /* _BQC returns an index value */ 191}; 192 193struct acpi_video_device_brightness { 194 int curr; 195 int count; 196 int *levels; 197 struct acpi_video_brightness_flags flags; 198}; 199 200struct acpi_video_device { 201 unsigned long device_id; 202 struct acpi_video_device_flags flags; 203 struct acpi_video_device_cap cap; 204 struct list_head entry; 205 struct acpi_video_bus *video; 206 struct acpi_device *dev; 207 struct acpi_video_device_brightness *brightness; 208 struct backlight_device *backlight; 209 struct thermal_cooling_device *cooling_dev; 210 struct output_device *output_dev; 211}; 212 213#ifdef CONFIG_ACPI_PROCFS 214/* bus */ 215static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); 216static const struct file_operations acpi_video_bus_info_fops = { 217 .owner = THIS_MODULE, 218 .open = acpi_video_bus_info_open_fs, 219 .read = seq_read, 220 .llseek = seq_lseek, 221 .release = single_release, 222}; 223 224static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file); 225static const struct file_operations acpi_video_bus_ROM_fops = { 226 .owner = THIS_MODULE, 227 .open = acpi_video_bus_ROM_open_fs, 228 .read = seq_read, 229 .llseek = seq_lseek, 230 .release = single_release, 231}; 232 233static int acpi_video_bus_POST_info_open_fs(struct inode *inode, 234 struct file *file); 235static const struct file_operations acpi_video_bus_POST_info_fops = { 236 .owner = THIS_MODULE, 237 .open = acpi_video_bus_POST_info_open_fs, 238 .read = seq_read, 239 .llseek = seq_lseek, 240 .release = single_release, 241}; 242 243static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file); 244static ssize_t acpi_video_bus_write_POST(struct file *file, 245 const char __user *buffer, size_t count, loff_t *data); 246static const struct file_operations acpi_video_bus_POST_fops = { 247 .owner = THIS_MODULE, 248 .open = acpi_video_bus_POST_open_fs, 249 .read = seq_read, 250 .write = acpi_video_bus_write_POST, 251 .llseek = seq_lseek, 252 .release = single_release, 253}; 254 255static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file); 256static ssize_t acpi_video_bus_write_DOS(struct file *file, 257 const char __user *buffer, size_t count, loff_t *data); 258static const struct file_operations acpi_video_bus_DOS_fops = { 259 .owner = THIS_MODULE, 260 .open = acpi_video_bus_DOS_open_fs, 261 .read = seq_read, 262 .write = acpi_video_bus_write_DOS, 263 .llseek = seq_lseek, 264 .release = single_release, 265}; 266 267/* device */ 268static int acpi_video_device_info_open_fs(struct inode *inode, 269 struct file *file); 270static const struct file_operations acpi_video_device_info_fops = { 271 .owner = THIS_MODULE, 272 .open = acpi_video_device_info_open_fs, 273 .read = seq_read, 274 .llseek = seq_lseek, 275 .release = single_release, 276}; 277 278static int acpi_video_device_state_open_fs(struct inode *inode, 279 struct file *file); 280static ssize_t acpi_video_device_write_state(struct file *file, 281 const char __user *buffer, size_t count, loff_t *data); 282static const struct file_operations acpi_video_device_state_fops = { 283 .owner = THIS_MODULE, 284 .open = acpi_video_device_state_open_fs, 285 .read = seq_read, 286 .write = acpi_video_device_write_state, 287 .llseek = seq_lseek, 288 .release = single_release, 289}; 290 291static int acpi_video_device_brightness_open_fs(struct inode *inode, 292 struct file *file); 293static ssize_t acpi_video_device_write_brightness(struct file *file, 294 const char __user *buffer, size_t count, loff_t *data); 295static const struct file_operations acpi_video_device_brightness_fops = { 296 .owner = THIS_MODULE, 297 .open = acpi_video_device_brightness_open_fs, 298 .read = seq_read, 299 .write = acpi_video_device_write_brightness, 300 .llseek = seq_lseek, 301 .release = single_release, 302}; 303 304static int acpi_video_device_EDID_open_fs(struct inode *inode, 305 struct file *file); 306static const struct file_operations acpi_video_device_EDID_fops = { 307 .owner = THIS_MODULE, 308 .open = acpi_video_device_EDID_open_fs, 309 .read = seq_read, 310 .llseek = seq_lseek, 311 .release = single_release, 312}; 313#endif /* CONFIG_ACPI_PROCFS */ 314 315static const char device_decode[][30] = { 316 "motherboard VGA device", 317 "PCI VGA device", 318 "AGP VGA device", 319 "UNKNOWN", 320}; 321 322static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data); 323static void acpi_video_device_rebind(struct acpi_video_bus *video); 324static void acpi_video_device_bind(struct acpi_video_bus *video, 325 struct acpi_video_device *device); 326static int acpi_video_device_enumerate(struct acpi_video_bus *video); 327static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, 328 int level); 329static int acpi_video_device_lcd_get_level_current( 330 struct acpi_video_device *device, 331 unsigned long long *level, int init); 332static int acpi_video_get_next_level(struct acpi_video_device *device, 333 u32 level_current, u32 event); 334static int acpi_video_switch_brightness(struct acpi_video_device *device, 335 int event); 336static int acpi_video_device_get_state(struct acpi_video_device *device, 337 unsigned long long *state); 338static int acpi_video_output_get(struct output_device *od); 339static int acpi_video_device_set_state(struct acpi_video_device *device, int state); 340 341/*backlight device sysfs support*/ 342static int acpi_video_get_brightness(struct backlight_device *bd) 343{ 344 unsigned long long cur_level; 345 int i; 346 struct acpi_video_device *vd = 347 (struct acpi_video_device *)bl_get_data(bd); 348 349 if (acpi_video_device_lcd_get_level_current(vd, &cur_level, 0)) 350 return -EINVAL; 351 for (i = 2; i < vd->brightness->count; i++) { 352 if (vd->brightness->levels[i] == cur_level) 353 /* The first two entries are special - see page 575 354 of the ACPI spec 3.0 */ 355 return i-2; 356 } 357 return 0; 358} 359 360static int acpi_video_set_brightness(struct backlight_device *bd) 361{ 362 int request_level = bd->props.brightness + 2; 363 struct acpi_video_device *vd = 364 (struct acpi_video_device *)bl_get_data(bd); 365 366 return acpi_video_device_lcd_set_level(vd, 367 vd->brightness->levels[request_level]); 368} 369 370static struct backlight_ops acpi_backlight_ops = { 371 .get_brightness = acpi_video_get_brightness, 372 .update_status = acpi_video_set_brightness, 373}; 374 375/*video output device sysfs support*/ 376static int acpi_video_output_get(struct output_device *od) 377{ 378 unsigned long long state; 379 struct acpi_video_device *vd = 380 (struct acpi_video_device *)dev_get_drvdata(&od->dev); 381 acpi_video_device_get_state(vd, &state); 382 return (int)state; 383} 384 385static int acpi_video_output_set(struct output_device *od) 386{ 387 unsigned long state = od->request_state; 388 struct acpi_video_device *vd= 389 (struct acpi_video_device *)dev_get_drvdata(&od->dev); 390 return acpi_video_device_set_state(vd, state); 391} 392 393static struct output_properties acpi_output_properties = { 394 .set_state = acpi_video_output_set, 395 .get_status = acpi_video_output_get, 396}; 397 398 399/* thermal cooling device callbacks */ 400static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned 401 long *state) 402{ 403 struct acpi_device *device = cooling_dev->devdata; 404 struct acpi_video_device *video = acpi_driver_data(device); 405 406 *state = video->brightness->count - 3; 407 return 0; 408} 409 410static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned 411 long *state) 412{ 413 struct acpi_device *device = cooling_dev->devdata; 414 struct acpi_video_device *video = acpi_driver_data(device); 415 unsigned long long level; 416 int offset; 417 418 if (acpi_video_device_lcd_get_level_current(video, &level, 0)) 419 return -EINVAL; 420 for (offset = 2; offset < video->brightness->count; offset++) 421 if (level == video->brightness->levels[offset]) { 422 *state = video->brightness->count - offset - 1; 423 return 0; 424 } 425 426 return -EINVAL; 427} 428 429static int 430video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state) 431{ 432 struct acpi_device *device = cooling_dev->devdata; 433 struct acpi_video_device *video = acpi_driver_data(device); 434 int level; 435 436 if ( state >= video->brightness->count - 2) 437 return -EINVAL; 438 439 state = video->brightness->count - state; 440 level = video->brightness->levels[state -1]; 441 return acpi_video_device_lcd_set_level(video, level); 442} 443 444static struct thermal_cooling_device_ops video_cooling_ops = { 445 .get_max_state = video_get_max_state, 446 .get_cur_state = video_get_cur_state, 447 .set_cur_state = video_set_cur_state, 448}; 449 450/* -------------------------------------------------------------------------- 451 Video Management 452 -------------------------------------------------------------------------- */ 453 454/* device */ 455 456static int 457acpi_video_device_get_state(struct acpi_video_device *device, 458 unsigned long long *state) 459{ 460 int status; 461 462 status = acpi_evaluate_integer(device->dev->handle, "_DCS", NULL, state); 463 464 return status; 465} 466 467static int 468acpi_video_device_set_state(struct acpi_video_device *device, int state) 469{ 470 int status; 471 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 472 struct acpi_object_list args = { 1, &arg0 }; 473 unsigned long long ret; 474 475 476 arg0.integer.value = state; 477 status = acpi_evaluate_integer(device->dev->handle, "_DSS", &args, &ret); 478 479 return status; 480} 481 482static int 483acpi_video_device_lcd_query_levels(struct acpi_video_device *device, 484 union acpi_object **levels) 485{ 486 int status; 487 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 488 union acpi_object *obj; 489 490 491 *levels = NULL; 492 493 status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer); 494 if (!ACPI_SUCCESS(status)) 495 return status; 496 obj = (union acpi_object *)buffer.pointer; 497 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { 498 printk(KERN_ERR PREFIX "Invalid _BCL data\n"); 499 status = -EFAULT; 500 goto err; 501 } 502 503 *levels = obj; 504 505 return 0; 506 507 err: 508 kfree(buffer.pointer); 509 510 return status; 511} 512 513static int 514acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) 515{ 516 int status; 517 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 518 struct acpi_object_list args = { 1, &arg0 }; 519 int state; 520 521 arg0.integer.value = level; 522 523 status = acpi_evaluate_object(device->dev->handle, "_BCM", 524 &args, NULL); 525 if (ACPI_FAILURE(status)) { 526 ACPI_ERROR((AE_INFO, "Evaluating _BCM failed")); 527 return -EIO; 528 } 529 530 device->brightness->curr = level; 531 for (state = 2; state < device->brightness->count; state++) 532 if (level == device->brightness->levels[state]) { 533 if (device->backlight) 534 device->backlight->props.brightness = state - 2; 535 return 0; 536 } 537 538 ACPI_ERROR((AE_INFO, "Current brightness invalid")); 539 return -EINVAL; 540} 541 542/* 543 * For some buggy _BQC methods, we need to add a constant value to 544 * the _BQC return value to get the actual current brightness level 545 */ 546 547static int bqc_offset_aml_bug_workaround; 548static int __init video_set_bqc_offset(const struct dmi_system_id *d) 549{ 550 bqc_offset_aml_bug_workaround = 9; 551 return 0; 552} 553 554static struct dmi_system_id video_dmi_table[] __initdata = { 555 { 556 .callback = video_set_bqc_offset, 557 .ident = "Acer Aspire 5720", 558 .matches = { 559 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 560 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), 561 }, 562 }, 563 { 564 .callback = video_set_bqc_offset, 565 .ident = "Acer Aspire 5710Z", 566 .matches = { 567 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 568 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"), 569 }, 570 }, 571 { 572 .callback = video_set_bqc_offset, 573 .ident = "eMachines E510", 574 .matches = { 575 DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"), 576 DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"), 577 }, 578 }, 579 { 580 .callback = video_set_bqc_offset, 581 .ident = "Acer Aspire 5315", 582 .matches = { 583 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 584 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), 585 }, 586 }, 587 { 588 .callback = video_set_bqc_offset, 589 .ident = "Acer Aspire 7720", 590 .matches = { 591 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 592 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), 593 }, 594 }, 595 {} 596}; 597 598static int 599acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, 600 unsigned long long *level, int init) 601{ 602 acpi_status status = AE_OK; 603 int i; 604 605 if (device->cap._BQC || device->cap._BCQ) { 606 char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; 607 608 status = acpi_evaluate_integer(device->dev->handle, buf, 609 NULL, level); 610 if (ACPI_SUCCESS(status)) { 611 if (device->brightness->flags._BQC_use_index) { 612 if (device->brightness->flags._BCL_reversed) 613 *level = device->brightness->count 614 - 3 - (*level); 615 *level = device->brightness->levels[*level + 2]; 616 617 } 618 *level += bqc_offset_aml_bug_workaround; 619 for (i = 2; i < device->brightness->count; i++) 620 if (device->brightness->levels[i] == *level) { 621 device->brightness->curr = *level; 622 return 0; 623 } 624 if (!init) { 625 /* 626 * BQC returned an invalid level. 627 * Stop using it. 628 */ 629 ACPI_WARNING((AE_INFO, 630 "%s returned an invalid level", 631 buf)); 632 device->cap._BQC = device->cap._BCQ = 0; 633 } 634 } else { 635 ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf)); 636 device->cap._BQC = device->cap._BCQ = 0; 637 } 638 } 639 640 *level = device->brightness->curr; 641 return 0; 642} 643 644static int 645acpi_video_device_EDID(struct acpi_video_device *device, 646 union acpi_object **edid, ssize_t length) 647{ 648 int status; 649 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 650 union acpi_object *obj; 651 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 652 struct acpi_object_list args = { 1, &arg0 }; 653 654 655 *edid = NULL; 656 657 if (!device) 658 return -ENODEV; 659 if (length == 128) 660 arg0.integer.value = 1; 661 else if (length == 256) 662 arg0.integer.value = 2; 663 else 664 return -EINVAL; 665 666 status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer); 667 if (ACPI_FAILURE(status)) 668 return -ENODEV; 669 670 obj = buffer.pointer; 671 672 if (obj && obj->type == ACPI_TYPE_BUFFER) 673 *edid = obj; 674 else { 675 printk(KERN_ERR PREFIX "Invalid _DDC data\n"); 676 status = -EFAULT; 677 kfree(obj); 678 } 679 680 return status; 681} 682 683/* bus */ 684 685/* 686 * Arg: 687 * video : video bus device pointer 688 * bios_flag : 689 * 0. The system BIOS should NOT automatically switch(toggle) 690 * the active display output. 691 * 1. The system BIOS should automatically switch (toggle) the 692 * active display output. No switch event. 693 * 2. The _DGS value should be locked. 694 * 3. The system BIOS should not automatically switch (toggle) the 695 * active display output, but instead generate the display switch 696 * event notify code. 697 * lcd_flag : 698 * 0. The system BIOS should automatically control the brightness level 699 * of the LCD when the power changes from AC to DC 700 * 1. The system BIOS should NOT automatically control the brightness 701 * level of the LCD when the power changes from AC to DC. 702 * Return Value: 703 * -1 wrong arg. 704 */ 705 706static int 707acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) 708{ 709 u64 status = 0; 710 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 711 struct acpi_object_list args = { 1, &arg0 }; 712 713 714 if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) { 715 status = -1; 716 goto Failed; 717 } 718 arg0.integer.value = (lcd_flag << 2) | bios_flag; 719 video->dos_setting = arg0.integer.value; 720 acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL); 721 722 Failed: 723 return status; 724} 725 726/* 727 * Simple comparison function used to sort backlight levels. 728 */ 729 730static int 731acpi_video_cmp_level(const void *a, const void *b) 732{ 733 return *(int *)a - *(int *)b; 734} 735 736/* 737 * Arg: 738 * device : video output device (LCD, CRT, ..) 739 * 740 * Return Value: 741 * Maximum brightness level 742 * 743 * Allocate and initialize device->brightness. 744 */ 745 746static int 747acpi_video_init_brightness(struct acpi_video_device *device) 748{ 749 union acpi_object *obj = NULL; 750 int i, max_level = 0, count = 0, level_ac_battery = 0; 751 unsigned long long level, level_old; 752 union acpi_object *o; 753 struct acpi_video_device_brightness *br = NULL; 754 int result = -EINVAL; 755 756 if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { 757 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " 758 "LCD brightness level\n")); 759 goto out; 760 } 761 762 if (obj->package.count < 2) 763 goto out; 764 765 br = kzalloc(sizeof(*br), GFP_KERNEL); 766 if (!br) { 767 printk(KERN_ERR "can't allocate memory\n"); 768 result = -ENOMEM; 769 goto out; 770 } 771 772 br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels), 773 GFP_KERNEL); 774 if (!br->levels) { 775 result = -ENOMEM; 776 goto out_free; 777 } 778 779 for (i = 0; i < obj->package.count; i++) { 780 o = (union acpi_object *)&obj->package.elements[i]; 781 if (o->type != ACPI_TYPE_INTEGER) { 782 printk(KERN_ERR PREFIX "Invalid data\n"); 783 continue; 784 } 785 br->levels[count] = (u32) o->integer.value; 786 787 if (br->levels[count] > max_level) 788 max_level = br->levels[count]; 789 count++; 790 } 791 792 /* 793 * some buggy BIOS don't export the levels 794 * when machine is on AC/Battery in _BCL package. 795 * In this case, the first two elements in _BCL packages 796 * are also supported brightness levels that OS should take care of. 797 */ 798 for (i = 2; i < count; i++) { 799 if (br->levels[i] == br->levels[0]) 800 level_ac_battery++; 801 if (br->levels[i] == br->levels[1]) 802 level_ac_battery++; 803 } 804 805 if (level_ac_battery < 2) { 806 level_ac_battery = 2 - level_ac_battery; 807 br->flags._BCL_no_ac_battery_levels = 1; 808 for (i = (count - 1 + level_ac_battery); i >= 2; i--) 809 br->levels[i] = br->levels[i - level_ac_battery]; 810 count += level_ac_battery; 811 } else if (level_ac_battery > 2) 812 ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n")); 813 814 /* Check if the _BCL package is in a reversed order */ 815 if (max_level == br->levels[2]) { 816 br->flags._BCL_reversed = 1; 817 sort(&br->levels[2], count - 2, sizeof(br->levels[2]), 818 acpi_video_cmp_level, NULL); 819 } else if (max_level != br->levels[count - 1]) 820 ACPI_ERROR((AE_INFO, 821 "Found unordered _BCL package\n")); 822 823 br->count = count; 824 device->brightness = br; 825 826 /* Check the input/output of _BQC/_BCL/_BCM */ 827 if ((max_level < 100) && (max_level <= (count - 2))) 828 br->flags._BCL_use_index = 1; 829 830 /* 831 * _BCM is always consistent with _BCL, 832 * at least for all the laptops we have ever seen. 833 */ 834 br->flags._BCM_use_index = br->flags._BCL_use_index; 835 836 /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ 837 br->curr = level = max_level; 838 839 if (!device->cap._BQC) 840 goto set_level; 841 842 result = acpi_video_device_lcd_get_level_current(device, &level_old, 1); 843 if (result) 844 goto out_free_levels; 845 846 /* 847 * Set the level to maximum and check if _BQC uses indexed value 848 */ 849 result = acpi_video_device_lcd_set_level(device, max_level); 850 if (result) 851 goto out_free_levels; 852 853 result = acpi_video_device_lcd_get_level_current(device, &level, 0); 854 if (result) 855 goto out_free_levels; 856 857 br->flags._BQC_use_index = (level == max_level ? 0 : 1); 858 859 if (!br->flags._BQC_use_index) { 860 /* 861 * Set the backlight to the initial state. 862 * On some buggy laptops, _BQC returns an uninitialized value 863 * when invoked for the first time, i.e. level_old is invalid. 864 * set the backlight to max_level in this case 865 */ 866 for (i = 2; i < br->count; i++) 867 if (level_old == br->levels[i]) 868 level = level_old; 869 goto set_level; 870 } 871 872 if (br->flags._BCL_reversed) 873 level_old = (br->count - 1) - level_old; 874 level = br->levels[level_old]; 875 876set_level: 877 result = acpi_video_device_lcd_set_level(device, level); 878 if (result) 879 goto out_free_levels; 880 881 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 882 "found %d brightness levels\n", count - 2)); 883 kfree(obj); 884 return result; 885 886out_free_levels: 887 kfree(br->levels); 888out_free: 889 kfree(br); 890out: 891 device->brightness = NULL; 892 kfree(obj); 893 return result; 894} 895 896/* 897 * Arg: 898 * device : video output device (LCD, CRT, ..) 899 * 900 * Return Value: 901 * None 902 * 903 * Find out all required AML methods defined under the output 904 * device. 905 */ 906 907static void acpi_video_device_find_cap(struct acpi_video_device *device) 908{ 909 acpi_handle h_dummy1; 910 911 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { 912 device->cap._ADR = 1; 913 } 914 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) { 915 device->cap._BCL = 1; 916 } 917 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { 918 device->cap._BCM = 1; 919 } 920 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) 921 device->cap._BQC = 1; 922 else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ", 923 &h_dummy1))) { 924 printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n"); 925 device->cap._BCQ = 1; 926 } 927 928 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { 929 device->cap._DDC = 1; 930 } 931 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DCS", &h_dummy1))) { 932 device->cap._DCS = 1; 933 } 934 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DGS", &h_dummy1))) { 935 device->cap._DGS = 1; 936 } 937 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DSS", &h_dummy1))) { 938 device->cap._DSS = 1; 939 } 940 941 if (acpi_video_backlight_support()) { 942 struct backlight_properties props; 943 int result; 944 static int count = 0; 945 char *name; 946 947 result = acpi_video_init_brightness(device); 948 if (result) 949 return; 950 name = kasprintf(GFP_KERNEL, "acpi_video%d", count); 951 if (!name) 952 return; 953 count++; 954 955 memset(&props, 0, sizeof(struct backlight_properties)); 956 props.max_brightness = device->brightness->count - 3; 957 device->backlight = backlight_device_register(name, NULL, device, 958 &acpi_backlight_ops, 959 &props); 960 kfree(name); 961 if (IS_ERR(device->backlight)) 962 return; 963 964 /* 965 * Save current brightness level in case we have to restore it 966 * before acpi_video_device_lcd_set_level() is called next time. 967 */ 968 device->backlight->props.brightness = 969 acpi_video_get_brightness(device->backlight); 970 971 result = sysfs_create_link(&device->backlight->dev.kobj, 972 &device->dev->dev.kobj, "device"); 973 if (result) 974 printk(KERN_ERR PREFIX "Create sysfs link\n"); 975 976 device->cooling_dev = thermal_cooling_device_register("LCD", 977 device->dev, &video_cooling_ops); 978 if (IS_ERR(device->cooling_dev)) { 979 /* 980 * Set cooling_dev to NULL so we don't crash trying to 981 * free it. 982 * Also, why the hell we are returning early and 983 * not attempt to register video output if cooling 984 * device registration failed? 985 * -- dtor 986 */ 987 device->cooling_dev = NULL; 988 return; 989 } 990 991 dev_info(&device->dev->dev, "registered as cooling_device%d\n", 992 device->cooling_dev->id); 993 result = sysfs_create_link(&device->dev->dev.kobj, 994 &device->cooling_dev->device.kobj, 995 "thermal_cooling"); 996 if (result) 997 printk(KERN_ERR PREFIX "Create sysfs link\n"); 998 result = sysfs_create_link(&device->cooling_dev->device.kobj, 999 &device->dev->dev.kobj, "device"); 1000 if (result) 1001 printk(KERN_ERR PREFIX "Create sysfs link\n"); 1002 1003 } 1004 1005 if (acpi_video_display_switch_support()) { 1006 1007 if (device->cap._DCS && device->cap._DSS) { 1008 static int count; 1009 char *name; 1010 name = kasprintf(GFP_KERNEL, "acpi_video%d", count); 1011 if (!name) 1012 return; 1013 count++; 1014 device->output_dev = video_output_register(name, 1015 NULL, device, &acpi_output_properties); 1016 kfree(name); 1017 } 1018 } 1019} 1020 1021/* 1022 * Arg: 1023 * device : video output device (VGA) 1024 * 1025 * Return Value: 1026 * None 1027 * 1028 * Find out all required AML methods defined under the video bus device. 1029 */ 1030 1031static void acpi_video_bus_find_cap(struct acpi_video_bus *video) 1032{ 1033 acpi_handle h_dummy1; 1034 1035 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { 1036 video->cap._DOS = 1; 1037 } 1038 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) { 1039 video->cap._DOD = 1; 1040 } 1041 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) { 1042 video->cap._ROM = 1; 1043 } 1044 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) { 1045 video->cap._GPD = 1; 1046 } 1047 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) { 1048 video->cap._SPD = 1; 1049 } 1050 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) { 1051 video->cap._VPO = 1; 1052 } 1053} 1054 1055/* 1056 * Check whether the video bus device has required AML method to 1057 * support the desired features 1058 */ 1059 1060static int acpi_video_bus_check(struct acpi_video_bus *video) 1061{ 1062 acpi_status status = -ENOENT; 1063 struct pci_dev *dev; 1064 1065 if (!video) 1066 return -EINVAL; 1067 1068 dev = acpi_get_pci_dev(video->device->handle); 1069 if (!dev) 1070 return -ENODEV; 1071 pci_dev_put(dev); 1072 1073 /* Since there is no HID, CID and so on for VGA driver, we have 1074 * to check well known required nodes. 1075 */ 1076 1077 /* Does this device support video switching? */ 1078 if (video->cap._DOS || video->cap._DOD) { 1079 if (!video->cap._DOS) { 1080 printk(KERN_WARNING FW_BUG 1081 "ACPI(%s) defines _DOD but not _DOS\n", 1082 acpi_device_bid(video->device)); 1083 } 1084 video->flags.multihead = 1; 1085 status = 0; 1086 } 1087 1088 /* Does this device support retrieving a video ROM? */ 1089 if (video->cap._ROM) { 1090 video->flags.rom = 1; 1091 status = 0; 1092 } 1093 1094 /* Does this device support configuring which video device to POST? */ 1095 if (video->cap._GPD && video->cap._SPD && video->cap._VPO) { 1096 video->flags.post = 1; 1097 status = 0; 1098 } 1099 1100 return status; 1101} 1102 1103/* -------------------------------------------------------------------------- 1104 FS Interface (/proc) 1105 -------------------------------------------------------------------------- */ 1106#ifdef CONFIG_ACPI_PROCFS 1107 1108static struct proc_dir_entry *acpi_video_dir; 1109 1110/* video devices */ 1111 1112static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) 1113{ 1114 struct acpi_video_device *dev = seq->private; 1115 1116 1117 if (!dev) 1118 goto end; 1119 1120 seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id); 1121 seq_printf(seq, "type: "); 1122 if (dev->flags.crt) 1123 seq_printf(seq, "CRT\n"); 1124 else if (dev->flags.lcd) 1125 seq_printf(seq, "LCD\n"); 1126 else if (dev->flags.tvout) 1127 seq_printf(seq, "TVOUT\n"); 1128 else if (dev->flags.dvi) 1129 seq_printf(seq, "DVI\n"); 1130 else 1131 seq_printf(seq, "UNKNOWN\n"); 1132 1133 seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no"); 1134 1135 end: 1136 return 0; 1137} 1138 1139static int 1140acpi_video_device_info_open_fs(struct inode *inode, struct file *file) 1141{ 1142 return single_open(file, acpi_video_device_info_seq_show, 1143 PDE(inode)->data); 1144} 1145 1146static int 1147acpi_video_device_query(struct acpi_video_device *device, 1148 unsigned long long *state) 1149{ 1150 int status; 1151 1152 status = acpi_evaluate_integer(device->dev->handle, "_DGS", 1153 NULL, state); 1154 1155 return status; 1156} 1157 1158static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) 1159{ 1160 int status; 1161 struct acpi_video_device *dev = seq->private; 1162 unsigned long long state; 1163 1164 1165 if (!dev) 1166 goto end; 1167 1168 status = acpi_video_device_get_state(dev, &state); 1169 seq_printf(seq, "state: "); 1170 if (ACPI_SUCCESS(status)) 1171 seq_printf(seq, "0x%02llx\n", state); 1172 else 1173 seq_printf(seq, "<not supported>\n"); 1174 1175 status = acpi_video_device_query(dev, &state); 1176 seq_printf(seq, "query: "); 1177 if (ACPI_SUCCESS(status)) 1178 seq_printf(seq, "0x%02llx\n", state); 1179 else 1180 seq_printf(seq, "<not supported>\n"); 1181 1182 end: 1183 return 0; 1184} 1185 1186static int 1187acpi_video_device_state_open_fs(struct inode *inode, struct file *file) 1188{ 1189 return single_open(file, acpi_video_device_state_seq_show, 1190 PDE(inode)->data); 1191} 1192 1193static ssize_t 1194acpi_video_device_write_state(struct file *file, 1195 const char __user * buffer, 1196 size_t count, loff_t * data) 1197{ 1198 int status; 1199 struct seq_file *m = file->private_data; 1200 struct acpi_video_device *dev = m->private; 1201 char str[12] = { 0 }; 1202 u32 state = 0; 1203 1204 1205 if (!dev || count >= sizeof(str)) 1206 return -EINVAL; 1207 1208 if (copy_from_user(str, buffer, count)) 1209 return -EFAULT; 1210 1211 str[count] = 0; 1212 state = simple_strtoul(str, NULL, 0); 1213 state &= ((1ul << 31) | (1ul << 30) | (1ul << 0)); 1214 1215 status = acpi_video_device_set_state(dev, state); 1216 1217 if (status) 1218 return -EFAULT; 1219 1220 return count; 1221} 1222 1223static int 1224acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) 1225{ 1226 struct acpi_video_device *dev = seq->private; 1227 int i; 1228 1229 1230 if (!dev || !dev->brightness) { 1231 seq_printf(seq, "<not supported>\n"); 1232 return 0; 1233 } 1234 1235 seq_printf(seq, "levels: "); 1236 for (i = 2; i < dev->brightness->count; i++) 1237 seq_printf(seq, " %d", dev->brightness->levels[i]); 1238 seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); 1239 1240 return 0; 1241} 1242 1243static int 1244acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file) 1245{ 1246 return single_open(file, acpi_video_device_brightness_seq_show, 1247 PDE(inode)->data); 1248} 1249 1250static ssize_t 1251acpi_video_device_write_brightness(struct file *file, 1252 const char __user * buffer, 1253 size_t count, loff_t * data) 1254{ 1255 struct seq_file *m = file->private_data; 1256 struct acpi_video_device *dev = m->private; 1257 char str[5] = { 0 }; 1258 unsigned int level = 0; 1259 int i; 1260 1261 1262 if (!dev || !dev->brightness || count >= sizeof(str)) 1263 return -EINVAL; 1264 1265 if (copy_from_user(str, buffer, count)) 1266 return -EFAULT; 1267 1268 str[count] = 0; 1269 level = simple_strtoul(str, NULL, 0); 1270 1271 if (level > 100) 1272 return -EFAULT; 1273 1274 /* validate through the list of available levels */ 1275 for (i = 2; i < dev->brightness->count; i++) 1276 if (level == dev->brightness->levels[i]) { 1277 if (!acpi_video_device_lcd_set_level(dev, level)) 1278 return count; 1279 break; 1280 } 1281 1282 return -EINVAL; 1283} 1284 1285static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) 1286{ 1287 struct acpi_video_device *dev = seq->private; 1288 int status; 1289 int i; 1290 union acpi_object *edid = NULL; 1291 1292 1293 if (!dev) 1294 goto out; 1295 1296 status = acpi_video_device_EDID(dev, &edid, 128); 1297 if (ACPI_FAILURE(status)) { 1298 status = acpi_video_device_EDID(dev, &edid, 256); 1299 } 1300 1301 if (ACPI_FAILURE(status)) { 1302 goto out; 1303 } 1304 1305 if (edid && edid->type == ACPI_TYPE_BUFFER) { 1306 for (i = 0; i < edid->buffer.length; i++) 1307 seq_putc(seq, edid->buffer.pointer[i]); 1308 } 1309 1310 out: 1311 if (!edid) 1312 seq_printf(seq, "<not supported>\n"); 1313 else 1314 kfree(edid); 1315 1316 return 0; 1317} 1318 1319static int 1320acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file) 1321{ 1322 return single_open(file, acpi_video_device_EDID_seq_show, 1323 PDE(inode)->data); 1324} 1325 1326static int acpi_video_device_add_fs(struct acpi_device *device) 1327{ 1328 struct proc_dir_entry *entry, *device_dir; 1329 struct acpi_video_device *vid_dev; 1330 1331 vid_dev = acpi_driver_data(device); 1332 if (!vid_dev) 1333 return -ENODEV; 1334 1335 device_dir = proc_mkdir(acpi_device_bid(device), 1336 vid_dev->video->dir); 1337 if (!device_dir) 1338 return -ENOMEM; 1339 1340 /* 'info' [R] */ 1341 entry = proc_create_data("info", S_IRUGO, device_dir, 1342 &acpi_video_device_info_fops, acpi_driver_data(device)); 1343 if (!entry) 1344 goto err_remove_dir; 1345 1346 /* 'state' [R/W] */ 1347 entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR, 1348 device_dir, 1349 &acpi_video_device_state_fops, 1350 acpi_driver_data(device)); 1351 if (!entry) 1352 goto err_remove_info; 1353 1354 /* 'brightness' [R/W] */ 1355 entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR, 1356 device_dir, 1357 &acpi_video_device_brightness_fops, 1358 acpi_driver_data(device)); 1359 if (!entry) 1360 goto err_remove_state; 1361 1362 /* 'EDID' [R] */ 1363 entry = proc_create_data("EDID", S_IRUGO, device_dir, 1364 &acpi_video_device_EDID_fops, 1365 acpi_driver_data(device)); 1366 if (!entry) 1367 goto err_remove_brightness; 1368 1369 acpi_device_dir(device) = device_dir; 1370 1371 return 0; 1372 1373 err_remove_brightness: 1374 remove_proc_entry("brightness", device_dir); 1375 err_remove_state: 1376 remove_proc_entry("state", device_dir); 1377 err_remove_info: 1378 remove_proc_entry("info", device_dir); 1379 err_remove_dir: 1380 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); 1381 return -ENOMEM; 1382} 1383 1384static int acpi_video_device_remove_fs(struct acpi_device *device) 1385{ 1386 struct acpi_video_device *vid_dev; 1387 struct proc_dir_entry *device_dir; 1388 1389 vid_dev = acpi_driver_data(device); 1390 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) 1391 return -ENODEV; 1392 1393 device_dir = acpi_device_dir(device); 1394 if (device_dir) { 1395 remove_proc_entry("info", device_dir); 1396 remove_proc_entry("state", device_dir); 1397 remove_proc_entry("brightness", device_dir); 1398 remove_proc_entry("EDID", device_dir); 1399 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); 1400 acpi_device_dir(device) = NULL; 1401 } 1402 1403 return 0; 1404} 1405 1406/* video bus */ 1407static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) 1408{ 1409 struct acpi_video_bus *video = seq->private; 1410 1411 1412 if (!video) 1413 goto end; 1414 1415 seq_printf(seq, "Switching heads: %s\n", 1416 video->flags.multihead ? "yes" : "no"); 1417 seq_printf(seq, "Video ROM: %s\n", 1418 video->flags.rom ? "yes" : "no"); 1419 seq_printf(seq, "Device to be POSTed on boot: %s\n", 1420 video->flags.post ? "yes" : "no"); 1421 1422 end: 1423 return 0; 1424} 1425 1426static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file) 1427{ 1428 return single_open(file, acpi_video_bus_info_seq_show, 1429 PDE(inode)->data); 1430} 1431 1432static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) 1433{ 1434 struct acpi_video_bus *video = seq->private; 1435 1436 1437 if (!video) 1438 goto end; 1439 1440 printk(KERN_INFO PREFIX "Please implement %s\n", __func__); 1441 seq_printf(seq, "<TODO>\n"); 1442 1443 end: 1444 return 0; 1445} 1446 1447static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) 1448{ 1449 return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); 1450} 1451 1452static int 1453acpi_video_bus_POST_options(struct acpi_video_bus *video, 1454 unsigned long long *options) 1455{ 1456 int status; 1457 1458 status = acpi_evaluate_integer(video->device->handle, "_VPO", 1459 NULL, options); 1460 *options &= 3; 1461 1462 return status; 1463} 1464 1465static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) 1466{ 1467 struct acpi_video_bus *video = seq->private; 1468 unsigned long long options; 1469 int status; 1470 1471 1472 if (!video) 1473 goto end; 1474 1475 status = acpi_video_bus_POST_options(video, &options); 1476 if (ACPI_SUCCESS(status)) { 1477 if (!(options & 1)) { 1478 printk(KERN_WARNING PREFIX 1479 "The motherboard VGA device is not listed as a possible POST device.\n"); 1480 printk(KERN_WARNING PREFIX 1481 "This indicates a BIOS bug. Please contact the manufacturer.\n"); 1482 } 1483 printk(KERN_WARNING "%llx\n", options); 1484 seq_printf(seq, "can POST: <integrated video>"); 1485 if (options & 2) 1486 seq_printf(seq, " <PCI video>"); 1487 if (options & 4) 1488 seq_printf(seq, " <AGP video>"); 1489 seq_putc(seq, '\n'); 1490 } else 1491 seq_printf(seq, "<not supported>\n"); 1492 end: 1493 return 0; 1494} 1495 1496static int 1497acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file) 1498{ 1499 return single_open(file, acpi_video_bus_POST_info_seq_show, 1500 PDE(inode)->data); 1501} 1502 1503static int 1504acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) 1505{ 1506 int status; 1507 1508 status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); 1509 1510 return status; 1511} 1512 1513static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) 1514{ 1515 struct acpi_video_bus *video = seq->private; 1516 int status; 1517 unsigned long long id; 1518 1519 1520 if (!video) 1521 goto end; 1522 1523 status = acpi_video_bus_get_POST(video, &id); 1524 if (!ACPI_SUCCESS(status)) { 1525 seq_printf(seq, "<not supported>\n"); 1526 goto end; 1527 } 1528 seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]); 1529 1530 end: 1531 return 0; 1532} 1533 1534static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) 1535{ 1536 struct acpi_video_bus *video = seq->private; 1537 1538 1539 seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); 1540 1541 return 0; 1542} 1543 1544static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file) 1545{ 1546 return single_open(file, acpi_video_bus_POST_seq_show, 1547 PDE(inode)->data); 1548} 1549 1550static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file) 1551{ 1552 return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); 1553} 1554 1555static int 1556acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) 1557{ 1558 int status; 1559 unsigned long long tmp; 1560 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 1561 struct acpi_object_list args = { 1, &arg0 }; 1562 1563 1564 arg0.integer.value = option; 1565 1566 status = acpi_evaluate_integer(video->device->handle, "_SPD", 1567 &args, &tmp); 1568 if (ACPI_SUCCESS(status)) 1569 status = tmp ? (-EINVAL) : (AE_OK); 1570 1571 return status; 1572} 1573 1574static ssize_t 1575acpi_video_bus_write_POST(struct file *file, 1576 const char __user * buffer, 1577 size_t count, loff_t * data) 1578{ 1579 int status; 1580 struct seq_file *m = file->private_data; 1581 struct acpi_video_bus *video = m->private; 1582 char str[12] = { 0 }; 1583 unsigned long long opt, options; 1584 1585 1586 if (!video || count >= sizeof(str)) 1587 return -EINVAL; 1588 1589 status = acpi_video_bus_POST_options(video, &options); 1590 if (!ACPI_SUCCESS(status)) 1591 return -EINVAL; 1592 1593 if (copy_from_user(str, buffer, count)) 1594 return -EFAULT; 1595 1596 str[count] = 0; 1597 opt = strtoul(str, NULL, 0); 1598 if (opt > 3) 1599 return -EFAULT; 1600 1601 /* just in case an OEM 'forgot' the motherboard... */ 1602 options |= 1; 1603 1604 if (options & (1ul << opt)) { 1605 status = acpi_video_bus_set_POST(video, opt); 1606 if (!ACPI_SUCCESS(status)) 1607 return -EFAULT; 1608 1609 } 1610 1611 return count; 1612} 1613 1614static ssize_t 1615acpi_video_bus_write_DOS(struct file *file, 1616 const char __user * buffer, 1617 size_t count, loff_t * data) 1618{ 1619 int status; 1620 struct seq_file *m = file->private_data; 1621 struct acpi_video_bus *video = m->private; 1622 char str[12] = { 0 }; 1623 unsigned long opt; 1624 1625 1626 if (!video || count >= sizeof(str)) 1627 return -EINVAL; 1628 1629 if (copy_from_user(str, buffer, count)) 1630 return -EFAULT; 1631 1632 str[count] = 0; 1633 opt = strtoul(str, NULL, 0); 1634 if (opt > 7) 1635 return -EFAULT; 1636 1637 status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2); 1638 1639 if (!ACPI_SUCCESS(status)) 1640 return -EFAULT; 1641 1642 return count; 1643} 1644 1645static int acpi_video_bus_add_fs(struct acpi_device *device) 1646{ 1647 struct acpi_video_bus *video = acpi_driver_data(device); 1648 struct proc_dir_entry *device_dir; 1649 struct proc_dir_entry *entry; 1650 1651 device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir); 1652 if (!device_dir) 1653 return -ENOMEM; 1654 1655 /* 'info' [R] */ 1656 entry = proc_create_data("info", S_IRUGO, device_dir, 1657 &acpi_video_bus_info_fops, 1658 acpi_driver_data(device)); 1659 if (!entry) 1660 goto err_remove_dir; 1661 1662 /* 'ROM' [R] */ 1663 entry = proc_create_data("ROM", S_IRUGO, device_dir, 1664 &acpi_video_bus_ROM_fops, 1665 acpi_driver_data(device)); 1666 if (!entry) 1667 goto err_remove_info; 1668 1669 /* 'POST_info' [R] */ 1670 entry = proc_create_data("POST_info", S_IRUGO, device_dir, 1671 &acpi_video_bus_POST_info_fops, 1672 acpi_driver_data(device)); 1673 if (!entry) 1674 goto err_remove_rom; 1675 1676 /* 'POST' [R/W] */ 1677 entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR, 1678 device_dir, 1679 &acpi_video_bus_POST_fops, 1680 acpi_driver_data(device)); 1681 if (!entry) 1682 goto err_remove_post_info; 1683 1684 /* 'DOS' [R/W] */ 1685 entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR, 1686 device_dir, 1687 &acpi_video_bus_DOS_fops, 1688 acpi_driver_data(device)); 1689 if (!entry) 1690 goto err_remove_post; 1691 1692 video->dir = acpi_device_dir(device) = device_dir; 1693 return 0; 1694 1695 err_remove_post: 1696 remove_proc_entry("POST", device_dir); 1697 err_remove_post_info: 1698 remove_proc_entry("POST_info", device_dir); 1699 err_remove_rom: 1700 remove_proc_entry("ROM", device_dir); 1701 err_remove_info: 1702 remove_proc_entry("info", device_dir); 1703 err_remove_dir: 1704 remove_proc_entry(acpi_device_bid(device), acpi_video_dir); 1705 return -ENOMEM; 1706} 1707 1708static int acpi_video_bus_remove_fs(struct acpi_device *device) 1709{ 1710 struct proc_dir_entry *device_dir = acpi_device_dir(device); 1711 1712 if (device_dir) { 1713 remove_proc_entry("info", device_dir); 1714 remove_proc_entry("ROM", device_dir); 1715 remove_proc_entry("POST_info", device_dir); 1716 remove_proc_entry("POST", device_dir); 1717 remove_proc_entry("DOS", device_dir); 1718 remove_proc_entry(acpi_device_bid(device), acpi_video_dir); 1719 acpi_device_dir(device) = NULL; 1720 } 1721 1722 return 0; 1723} 1724#else 1725static inline int acpi_video_device_add_fs(struct acpi_device *device) 1726{ 1727 return 0; 1728} 1729static inline int acpi_video_device_remove_fs(struct acpi_device *device) 1730{ 1731 return 0; 1732} 1733static inline int acpi_video_bus_add_fs(struct acpi_device *device) 1734{ 1735 return 0; 1736} 1737static inline int acpi_video_bus_remove_fs(struct acpi_device *device) 1738{ 1739 return 0; 1740} 1741#endif /* CONFIG_ACPI_PROCFS */ 1742 1743/* -------------------------------------------------------------------------- 1744 Driver Interface 1745 -------------------------------------------------------------------------- */ 1746 1747/* device interface */ 1748static struct acpi_video_device_attrib* 1749acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) 1750{ 1751 struct acpi_video_enumerated_device *ids; 1752 int i; 1753 1754 for (i = 0; i < video->attached_count; i++) { 1755 ids = &video->attached_array[i]; 1756 if ((ids->value.int_val & 0xffff) == device_id) 1757 return &ids->value.attrib; 1758 } 1759 1760 return NULL; 1761} 1762 1763static int 1764acpi_video_get_device_type(struct acpi_video_bus *video, 1765 unsigned long device_id) 1766{ 1767 struct acpi_video_enumerated_device *ids; 1768 int i; 1769 1770 for (i = 0; i < video->attached_count; i++) { 1771 ids = &video->attached_array[i]; 1772 if ((ids->value.int_val & 0xffff) == device_id) 1773 return ids->value.int_val; 1774 } 1775 1776 return 0; 1777} 1778 1779static int 1780acpi_video_bus_get_one_device(struct acpi_device *device, 1781 struct acpi_video_bus *video) 1782{ 1783 unsigned long long device_id; 1784 int status, device_type; 1785 struct acpi_video_device *data; 1786 struct acpi_video_device_attrib* attribute; 1787 1788 if (!device || !video) 1789 return -EINVAL; 1790 1791 status = 1792 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); 1793 if (ACPI_SUCCESS(status)) { 1794 1795 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); 1796 if (!data) 1797 return -ENOMEM; 1798 1799 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); 1800 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); 1801 device->driver_data = data; 1802 1803 data->device_id = device_id; 1804 data->video = video; 1805 data->dev = device; 1806 1807 attribute = acpi_video_get_device_attr(video, device_id); 1808 1809 if((attribute != NULL) && attribute->device_id_scheme) { 1810 switch (attribute->display_type) { 1811 case ACPI_VIDEO_DISPLAY_CRT: 1812 data->flags.crt = 1; 1813 break; 1814 case ACPI_VIDEO_DISPLAY_TV: 1815 data->flags.tvout = 1; 1816 break; 1817 case ACPI_VIDEO_DISPLAY_DVI: 1818 data->flags.dvi = 1; 1819 break; 1820 case ACPI_VIDEO_DISPLAY_LCD: 1821 data->flags.lcd = 1; 1822 break; 1823 default: 1824 data->flags.unknown = 1; 1825 break; 1826 } 1827 if(attribute->bios_can_detect) 1828 data->flags.bios = 1; 1829 } else { 1830 /* Check for legacy IDs */ 1831 device_type = acpi_video_get_device_type(video, 1832 device_id); 1833 /* Ignore bits 16 and 18-20 */ 1834 switch (device_type & 0xffe2ffff) { 1835 case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: 1836 data->flags.crt = 1; 1837 break; 1838 case ACPI_VIDEO_DISPLAY_LEGACY_PANEL: 1839 data->flags.lcd = 1; 1840 break; 1841 case ACPI_VIDEO_DISPLAY_LEGACY_TV: 1842 data->flags.tvout = 1; 1843 break; 1844 default: 1845 data->flags.unknown = 1; 1846 } 1847 } 1848 1849 acpi_video_device_bind(video, data); 1850 acpi_video_device_find_cap(data); 1851 1852 status = acpi_install_notify_handler(device->handle, 1853 ACPI_DEVICE_NOTIFY, 1854 acpi_video_device_notify, 1855 data); 1856 if (ACPI_FAILURE(status)) { 1857 printk(KERN_ERR PREFIX 1858 "Error installing notify handler\n"); 1859 if(data->brightness) 1860 kfree(data->brightness->levels); 1861 kfree(data->brightness); 1862 kfree(data); 1863 return -ENODEV; 1864 } 1865 1866 mutex_lock(&video->device_list_lock); 1867 list_add_tail(&data->entry, &video->video_device_list); 1868 mutex_unlock(&video->device_list_lock); 1869 1870 acpi_video_device_add_fs(device); 1871 1872 return 0; 1873 } 1874 1875 return -ENOENT; 1876} 1877 1878/* 1879 * Arg: 1880 * video : video bus device 1881 * 1882 * Return: 1883 * none 1884 * 1885 * Enumerate the video device list of the video bus, 1886 * bind the ids with the corresponding video devices 1887 * under the video bus. 1888 */ 1889 1890static void acpi_video_device_rebind(struct acpi_video_bus *video) 1891{ 1892 struct acpi_video_device *dev; 1893 1894 mutex_lock(&video->device_list_lock); 1895 1896 list_for_each_entry(dev, &video->video_device_list, entry) 1897 acpi_video_device_bind(video, dev); 1898 1899 mutex_unlock(&video->device_list_lock); 1900} 1901 1902/* 1903 * Arg: 1904 * video : video bus device 1905 * device : video output device under the video 1906 * bus 1907 * 1908 * Return: 1909 * none 1910 * 1911 * Bind the ids with the corresponding video devices 1912 * under the video bus. 1913 */ 1914 1915static void 1916acpi_video_device_bind(struct acpi_video_bus *video, 1917 struct acpi_video_device *device) 1918{ 1919 struct acpi_video_enumerated_device *ids; 1920 int i; 1921 1922 for (i = 0; i < video->attached_count; i++) { 1923 ids = &video->attached_array[i]; 1924 if (device->device_id == (ids->value.int_val & 0xffff)) { 1925 ids->bind_info = device; 1926 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i)); 1927 } 1928 } 1929} 1930 1931/* 1932 * Arg: 1933 * video : video bus device 1934 * 1935 * Return: 1936 * < 0 : error 1937 * 1938 * Call _DOD to enumerate all devices attached to display adapter 1939 * 1940 */ 1941 1942static int acpi_video_device_enumerate(struct acpi_video_bus *video) 1943{ 1944 int status; 1945 int count; 1946 int i; 1947 struct acpi_video_enumerated_device *active_list; 1948 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 1949 union acpi_object *dod = NULL; 1950 union acpi_object *obj; 1951 1952 status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer); 1953 if (!ACPI_SUCCESS(status)) { 1954 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD")); 1955 return status; 1956 } 1957 1958 dod = buffer.pointer; 1959 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { 1960 ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); 1961 status = -EFAULT; 1962 goto out; 1963 } 1964 1965 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n", 1966 dod->package.count)); 1967 1968 active_list = kcalloc(1 + dod->package.count, 1969 sizeof(struct acpi_video_enumerated_device), 1970 GFP_KERNEL); 1971 if (!active_list) { 1972 status = -ENOMEM; 1973 goto out; 1974 } 1975 1976 count = 0; 1977 for (i = 0; i < dod->package.count; i++) { 1978 obj = &dod->package.elements[i]; 1979 1980 if (obj->type != ACPI_TYPE_INTEGER) { 1981 printk(KERN_ERR PREFIX 1982 "Invalid _DOD data in element %d\n", i); 1983 continue; 1984 } 1985 1986 active_list[count].value.int_val = obj->integer.value; 1987 active_list[count].bind_info = NULL; 1988 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, 1989 (int)obj->integer.value)); 1990 count++; 1991 } 1992 1993 kfree(video->attached_array); 1994 1995 video->attached_array = active_list; 1996 video->attached_count = count; 1997 1998 out: 1999 kfree(buffer.pointer); 2000 return status; 2001} 2002 2003static int 2004acpi_video_get_next_level(struct acpi_video_device *device, 2005 u32 level_current, u32 event) 2006{ 2007 int min, max, min_above, max_below, i, l, delta = 255; 2008 max = max_below = 0; 2009 min = min_above = 255; 2010 /* Find closest level to level_current */ 2011 for (i = 2; i < device->brightness->count; i++) { 2012 l = device->brightness->levels[i]; 2013 if (abs(l - level_current) < abs(delta)) { 2014 delta = l - level_current; 2015 if (!delta) 2016 break; 2017 } 2018 } 2019 /* Ajust level_current to closest available level */ 2020 level_current += delta; 2021 for (i = 2; i < device->brightness->count; i++) { 2022 l = device->brightness->levels[i]; 2023 if (l < min) 2024 min = l; 2025 if (l > max) 2026 max = l; 2027 if (l < min_above && l > level_current) 2028 min_above = l; 2029 if (l > max_below && l < level_current) 2030 max_below = l; 2031 } 2032 2033 switch (event) { 2034 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: 2035 return (level_current < max) ? min_above : min; 2036 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: 2037 return (level_current < max) ? min_above : max; 2038 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: 2039 return (level_current > min) ? max_below : min; 2040 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: 2041 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: 2042 return 0; 2043 default: 2044 return level_current; 2045 } 2046} 2047 2048static int 2049acpi_video_switch_brightness(struct acpi_video_device *device, int event) 2050{ 2051 unsigned long long level_current, level_next; 2052 int result = -EINVAL; 2053 2054 /* no warning message if acpi_backlight=vendor is used */ 2055 if (!acpi_video_backlight_support()) 2056 return 0; 2057 2058 if (!device->brightness) 2059 goto out; 2060 2061 result = acpi_video_device_lcd_get_level_current(device, 2062 &level_current, 0); 2063 if (result) 2064 goto out; 2065 2066 level_next = acpi_video_get_next_level(device, level_current, event); 2067 2068 result = acpi_video_device_lcd_set_level(device, level_next); 2069 2070 if (!result) 2071 backlight_force_update(device->backlight, 2072 BACKLIGHT_UPDATE_HOTKEY); 2073 2074out: 2075 if (result) 2076 printk(KERN_ERR PREFIX "Failed to switch the brightness\n"); 2077 2078 return result; 2079} 2080 2081int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, 2082 void **edid) 2083{ 2084 struct acpi_video_bus *video; 2085 struct acpi_video_device *video_device; 2086 union acpi_object *buffer = NULL; 2087 acpi_status status; 2088 int i, length; 2089 2090 if (!device || !acpi_driver_data(device)) 2091 return -EINVAL; 2092 2093 video = acpi_driver_data(device); 2094 2095 for (i = 0; i < video->attached_count; i++) { 2096 video_device = video->attached_array[i].bind_info; 2097 length = 256; 2098 2099 if (!video_device) 2100 continue; 2101 2102 if (type) { 2103 switch (type) { 2104 case ACPI_VIDEO_DISPLAY_CRT: 2105 if (!video_device->flags.crt) 2106 continue; 2107 break; 2108 case ACPI_VIDEO_DISPLAY_TV: 2109 if (!video_device->flags.tvout) 2110 continue; 2111 break; 2112 case ACPI_VIDEO_DISPLAY_DVI: 2113 if (!video_device->flags.dvi) 2114 continue; 2115 break; 2116 case ACPI_VIDEO_DISPLAY_LCD: 2117 if (!video_device->flags.lcd) 2118 continue; 2119 break; 2120 } 2121 } else if (video_device->device_id != device_id) { 2122 continue; 2123 } 2124 2125 status = acpi_video_device_EDID(video_device, &buffer, length); 2126 2127 if (ACPI_FAILURE(status) || !buffer || 2128 buffer->type != ACPI_TYPE_BUFFER) { 2129 length = 128; 2130 status = acpi_video_device_EDID(video_device, &buffer, 2131 length); 2132 if (ACPI_FAILURE(status) || !buffer || 2133 buffer->type != ACPI_TYPE_BUFFER) { 2134 continue; 2135 } 2136 } 2137 2138 *edid = buffer->buffer.pointer; 2139 return length; 2140 } 2141 2142 return -ENODEV; 2143} 2144EXPORT_SYMBOL(acpi_video_get_edid); 2145 2146static int 2147acpi_video_bus_get_devices(struct acpi_video_bus *video, 2148 struct acpi_device *device) 2149{ 2150 int status = 0; 2151 struct acpi_device *dev; 2152 2153 acpi_video_device_enumerate(video); 2154 2155 list_for_each_entry(dev, &device->children, node) { 2156 2157 status = acpi_video_bus_get_one_device(dev, video); 2158 if (ACPI_FAILURE(status)) { 2159 printk(KERN_WARNING PREFIX 2160 "Cant attach device\n"); 2161 continue; 2162 } 2163 } 2164 return status; 2165} 2166 2167static int acpi_video_bus_put_one_device(struct acpi_video_device *device) 2168{ 2169 acpi_status status; 2170 2171 if (!device || !device->video) 2172 return -ENOENT; 2173 2174 acpi_video_device_remove_fs(device->dev); 2175 2176 status = acpi_remove_notify_handler(device->dev->handle, 2177 ACPI_DEVICE_NOTIFY, 2178 acpi_video_device_notify); 2179 if (ACPI_FAILURE(status)) { 2180 printk(KERN_WARNING PREFIX 2181 "Cant remove video notify handler\n"); 2182 } 2183 if (device->backlight) { 2184 sysfs_remove_link(&device->backlight->dev.kobj, "device"); 2185 backlight_device_unregister(device->backlight); 2186 device->backlight = NULL; 2187 } 2188 if (device->cooling_dev) { 2189 sysfs_remove_link(&device->dev->dev.kobj, 2190 "thermal_cooling"); 2191 sysfs_remove_link(&device->cooling_dev->device.kobj, 2192 "device"); 2193 thermal_cooling_device_unregister(device->cooling_dev); 2194 device->cooling_dev = NULL; 2195 } 2196 video_output_unregister(device->output_dev); 2197 2198 return 0; 2199} 2200 2201static int acpi_video_bus_put_devices(struct acpi_video_bus *video) 2202{ 2203 int status; 2204 struct acpi_video_device *dev, *next; 2205 2206 mutex_lock(&video->device_list_lock); 2207 2208 list_for_each_entry_safe(dev, next, &video->video_device_list, entry) { 2209 2210 status = acpi_video_bus_put_one_device(dev); 2211 if (ACPI_FAILURE(status)) 2212 printk(KERN_WARNING PREFIX 2213 "hhuuhhuu bug in acpi video driver.\n"); 2214 2215 if (dev->brightness) { 2216 kfree(dev->brightness->levels); 2217 kfree(dev->brightness); 2218 } 2219 list_del(&dev->entry); 2220 kfree(dev); 2221 } 2222 2223 mutex_unlock(&video->device_list_lock); 2224 2225 return 0; 2226} 2227 2228/* acpi_video interface */ 2229 2230static int acpi_video_bus_start_devices(struct acpi_video_bus *video) 2231{ 2232 return acpi_video_bus_DOS(video, 0, 0); 2233} 2234 2235static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) 2236{ 2237 return acpi_video_bus_DOS(video, 0, 1); 2238} 2239 2240static void acpi_video_bus_notify(struct acpi_device *device, u32 event) 2241{ 2242 struct acpi_video_bus *video = acpi_driver_data(device); 2243 struct input_dev *input; 2244 int keycode = 0; 2245 2246 if (!video) 2247 return; 2248 2249 input = video->input; 2250 2251 switch (event) { 2252 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, 2253 * most likely via hotkey. */ 2254 acpi_bus_generate_proc_event(device, event, 0); 2255 keycode = KEY_SWITCHVIDEOMODE; 2256 break; 2257 2258 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video 2259 * connector. */ 2260 acpi_video_device_enumerate(video); 2261 acpi_video_device_rebind(video); 2262 acpi_bus_generate_proc_event(device, event, 0); 2263 keycode = KEY_SWITCHVIDEOMODE; 2264 break; 2265 2266 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ 2267 acpi_bus_generate_proc_event(device, event, 0); 2268 keycode = KEY_SWITCHVIDEOMODE; 2269 break; 2270 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ 2271 acpi_bus_generate_proc_event(device, event, 0); 2272 keycode = KEY_VIDEO_NEXT; 2273 break; 2274 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ 2275 acpi_bus_generate_proc_event(device, event, 0); 2276 keycode = KEY_VIDEO_PREV; 2277 break; 2278 2279 default: 2280 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 2281 "Unsupported event [0x%x]\n", event)); 2282 break; 2283 } 2284 2285 acpi_notifier_call_chain(device, event, 0); 2286 2287 if (keycode) { 2288 input_report_key(input, keycode, 1); 2289 input_sync(input); 2290 input_report_key(input, keycode, 0); 2291 input_sync(input); 2292 } 2293 2294 return; 2295} 2296 2297static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) 2298{ 2299 struct acpi_video_device *video_device = data; 2300 struct acpi_device *device = NULL; 2301 struct acpi_video_bus *bus; 2302 struct input_dev *input; 2303 int keycode = 0; 2304 2305 if (!video_device) 2306 return; 2307 2308 device = video_device->dev; 2309 bus = video_device->video; 2310 input = bus->input; 2311 2312 switch (event) { 2313 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ 2314 if (brightness_switch_enabled) 2315 acpi_video_switch_brightness(video_device, event); 2316 acpi_bus_generate_proc_event(device, event, 0); 2317 keycode = KEY_BRIGHTNESS_CYCLE; 2318 break; 2319 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ 2320 if (brightness_switch_enabled) 2321 acpi_video_switch_brightness(video_device, event); 2322 acpi_bus_generate_proc_event(device, event, 0); 2323 keycode = KEY_BRIGHTNESSUP; 2324 break; 2325 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ 2326 if (brightness_switch_enabled) 2327 acpi_video_switch_brightness(video_device, event); 2328 acpi_bus_generate_proc_event(device, event, 0); 2329 keycode = KEY_BRIGHTNESSDOWN; 2330 break; 2331 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ 2332 if (brightness_switch_enabled) 2333 acpi_video_switch_brightness(video_device, event); 2334 acpi_bus_generate_proc_event(device, event, 0); 2335 keycode = KEY_BRIGHTNESS_ZERO; 2336 break; 2337 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ 2338 if (brightness_switch_enabled) 2339 acpi_video_switch_brightness(video_device, event); 2340 acpi_bus_generate_proc_event(device, event, 0); 2341 keycode = KEY_DISPLAY_OFF; 2342 break; 2343 default: 2344 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 2345 "Unsupported event [0x%x]\n", event)); 2346 break; 2347 } 2348 2349 acpi_notifier_call_chain(device, event, 0); 2350 2351 if (keycode) { 2352 input_report_key(input, keycode, 1); 2353 input_sync(input); 2354 input_report_key(input, keycode, 0); 2355 input_sync(input); 2356 } 2357 2358 return; 2359} 2360 2361static int acpi_video_resume(struct notifier_block *nb, 2362 unsigned long val, void *ign) 2363{ 2364 struct acpi_video_bus *video; 2365 struct acpi_video_device *video_device; 2366 int i; 2367 2368 switch (val) { 2369 case PM_HIBERNATION_PREPARE: 2370 case PM_SUSPEND_PREPARE: 2371 case PM_RESTORE_PREPARE: 2372 return NOTIFY_DONE; 2373 } 2374 2375 video = container_of(nb, struct acpi_video_bus, pm_nb); 2376 2377 dev_info(&video->device->dev, "Restoring backlight state\n"); 2378 2379 for (i = 0; i < video->attached_count; i++) { 2380 video_device = video->attached_array[i].bind_info; 2381 if (video_device && video_device->backlight) 2382 acpi_video_set_brightness(video_device->backlight); 2383 } 2384 2385 return NOTIFY_OK; 2386} 2387 2388static acpi_status 2389acpi_video_bus_match(acpi_handle handle, u32 level, void *context, 2390 void **return_value) 2391{ 2392 struct acpi_device *device = context; 2393 struct acpi_device *sibling; 2394 int result; 2395 2396 if (handle == device->handle) 2397 return AE_CTRL_TERMINATE; 2398 2399 result = acpi_bus_get_device(handle, &sibling); 2400 if (result) 2401 return AE_OK; 2402 2403 if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME)) 2404 return AE_ALREADY_EXISTS; 2405 2406 return AE_OK; 2407} 2408 2409static int instance; 2410 2411static int acpi_video_bus_add(struct acpi_device *device) 2412{ 2413 struct acpi_video_bus *video; 2414 struct input_dev *input; 2415 int error; 2416 acpi_status status; 2417 2418 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, 2419 device->parent->handle, 1, 2420 acpi_video_bus_match, NULL, 2421 device, NULL); 2422 if (status == AE_ALREADY_EXISTS) { 2423 printk(KERN_WARNING FW_BUG 2424 "Duplicate ACPI video bus devices for the" 2425 " same VGA controller, please try module " 2426 "parameter \"video.allow_duplicates=1\"" 2427 "if the current driver doesn't work.\n"); 2428 if (!allow_duplicates) 2429 return -ENODEV; 2430 } 2431 2432 video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); 2433 if (!video) 2434 return -ENOMEM; 2435 2436 /* a hack to fix the duplicate name "VID" problem on T61 */ 2437 if (!strcmp(device->pnp.bus_id, "VID")) { 2438 if (instance) 2439 device->pnp.bus_id[3] = '0' + instance; 2440 instance ++; 2441 } 2442 /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */ 2443 if (!strcmp(device->pnp.bus_id, "VGA")) { 2444 if (instance) 2445 device->pnp.bus_id[3] = '0' + instance; 2446 instance++; 2447 } 2448 2449 video->device = device; 2450 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); 2451 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); 2452 device->driver_data = video; 2453 2454 acpi_video_bus_find_cap(video); 2455 error = acpi_video_bus_check(video); 2456 if (error) 2457 goto err_free_video; 2458 2459 error = acpi_video_bus_add_fs(device); 2460 if (error) 2461 goto err_free_video; 2462 2463 mutex_init(&video->device_list_lock); 2464 INIT_LIST_HEAD(&video->video_device_list); 2465 2466 acpi_video_bus_get_devices(video, device); 2467 acpi_video_bus_start_devices(video); 2468 2469 video->input = input = input_allocate_device(); 2470 if (!input) { 2471 error = -ENOMEM; 2472 goto err_stop_video; 2473 } 2474 2475 snprintf(video->phys, sizeof(video->phys), 2476 "%s/video/input0", acpi_device_hid(video->device)); 2477 2478 input->name = acpi_device_name(video->device); 2479 input->phys = video->phys; 2480 input->id.bustype = BUS_HOST; 2481 input->id.product = 0x06; 2482 input->dev.parent = &device->dev; 2483 input->evbit[0] = BIT(EV_KEY); 2484 set_bit(KEY_SWITCHVIDEOMODE, input->keybit); 2485 set_bit(KEY_VIDEO_NEXT, input->keybit); 2486 set_bit(KEY_VIDEO_PREV, input->keybit); 2487 set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit); 2488 set_bit(KEY_BRIGHTNESSUP, input->keybit); 2489 set_bit(KEY_BRIGHTNESSDOWN, input->keybit); 2490 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); 2491 set_bit(KEY_DISPLAY_OFF, input->keybit); 2492 2493 error = input_register_device(input); 2494 if (error) 2495 goto err_free_input_dev; 2496 2497 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", 2498 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), 2499 video->flags.multihead ? "yes" : "no", 2500 video->flags.rom ? "yes" : "no", 2501 video->flags.post ? "yes" : "no"); 2502 2503 video->pm_nb.notifier_call = acpi_video_resume; 2504 video->pm_nb.priority = 0; 2505 register_pm_notifier(&video->pm_nb); 2506 2507 return 0; 2508 2509 err_free_input_dev: 2510 input_free_device(input); 2511 err_stop_video: 2512 acpi_video_bus_stop_devices(video); 2513 acpi_video_bus_put_devices(video); 2514 kfree(video->attached_array); 2515 acpi_video_bus_remove_fs(device); 2516 err_free_video: 2517 kfree(video); 2518 device->driver_data = NULL; 2519 2520 return error; 2521} 2522 2523static int acpi_video_bus_remove(struct acpi_device *device, int type) 2524{ 2525 struct acpi_video_bus *video = NULL; 2526 2527 2528 if (!device || !acpi_driver_data(device)) 2529 return -EINVAL; 2530 2531 video = acpi_driver_data(device); 2532 2533 unregister_pm_notifier(&video->pm_nb); 2534 2535 acpi_video_bus_stop_devices(video); 2536 acpi_video_bus_put_devices(video); 2537 acpi_video_bus_remove_fs(device); 2538 2539 input_unregister_device(video->input); 2540 kfree(video->attached_array); 2541 kfree(video); 2542 2543 return 0; 2544} 2545 2546static int __init intel_opregion_present(void) 2547{ 2548#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE) 2549 struct pci_dev *dev = NULL; 2550 u32 address; 2551 2552 for_each_pci_dev(dev) { 2553 if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) 2554 continue; 2555 if (dev->vendor != PCI_VENDOR_ID_INTEL) 2556 continue; 2557 pci_read_config_dword(dev, 0xfc, &address); 2558 if (!address) 2559 continue; 2560 return 1; 2561 } 2562#endif 2563 return 0; 2564} 2565 2566int acpi_video_register(void) 2567{ 2568 int result = 0; 2569 if (register_count) { 2570 /* 2571 * if the function of acpi_video_register is already called, 2572 * don't register the acpi_vide_bus again and return no error. 2573 */ 2574 return 0; 2575 } 2576 2577#ifdef CONFIG_ACPI_PROCFS 2578 acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); 2579 if (!acpi_video_dir) 2580 return -ENODEV; 2581#endif 2582 2583 result = acpi_bus_register_driver(&acpi_video_bus); 2584 if (result < 0) { 2585 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); 2586 return -ENODEV; 2587 } 2588 2589 /* 2590 * When the acpi_video_bus is loaded successfully, increase 2591 * the counter reference. 2592 */ 2593 register_count = 1; 2594 2595 return 0; 2596} 2597EXPORT_SYMBOL(acpi_video_register); 2598 2599void acpi_video_unregister(void) 2600{ 2601 if (!register_count) { 2602 /* 2603 * If the acpi video bus is already unloaded, don't 2604 * unload it again and return directly. 2605 */ 2606 return; 2607 } 2608 acpi_bus_unregister_driver(&acpi_video_bus); 2609 2610#ifdef CONFIG_ACPI_PROCFS 2611 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); 2612#endif 2613 2614 register_count = 0; 2615 2616 return; 2617} 2618EXPORT_SYMBOL(acpi_video_unregister); 2619 2620/* 2621 * This is kind of nasty. Hardware using Intel chipsets may require 2622 * the video opregion code to be run first in order to initialise 2623 * state before any ACPI video calls are made. To handle this we defer 2624 * registration of the video class until the opregion code has run. 2625 */ 2626 2627static int __init acpi_video_init(void) 2628{ 2629 dmi_check_system(video_dmi_table); 2630 2631 if (intel_opregion_present()) 2632 return 0; 2633 2634 return acpi_video_register(); 2635} 2636 2637static void __exit acpi_video_exit(void) 2638{ 2639 acpi_video_unregister(); 2640 2641 return; 2642} 2643 2644module_init(acpi_video_init); 2645module_exit(acpi_video_exit); 2646