Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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