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