2237 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * video.c - ACPI Video Driver4 *5 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com>6 * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org>7 * Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net>8 */9 10#define pr_fmt(fmt) "ACPI: video: " fmt11 12#include <linux/kernel.h>13#include <linux/module.h>14#include <linux/init.h>15#include <linux/types.h>16#include <linux/list.h>17#include <linux/mutex.h>18#include <linux/input.h>19#include <linux/backlight.h>20#include <linux/thermal.h>21#include <linux/sort.h>22#include <linux/pci.h>23#include <linux/pci_ids.h>24#include <linux/slab.h>25#include <linux/dmi.h>26#include <linux/suspend.h>27#include <linux/acpi.h>28#include <acpi/video.h>29#include <linux/uaccess.h>30 31#define ACPI_VIDEO_BUS_NAME "Video Bus"32#define ACPI_VIDEO_DEVICE_NAME "Video Device"33 34#define MAX_NAME_LEN 2035 36MODULE_AUTHOR("Bruno Ducrot");37MODULE_DESCRIPTION("ACPI Video Driver");38MODULE_LICENSE("GPL");39 40static bool brightness_switch_enabled = true;41module_param(brightness_switch_enabled, bool, 0644);42 43/*44 * By default, we don't allow duplicate ACPI video bus devices45 * under the same VGA controller46 */47static bool allow_duplicates;48module_param(allow_duplicates, bool, 0644);49 50#define REPORT_OUTPUT_KEY_EVENTS 0x0151#define REPORT_BRIGHTNESS_KEY_EVENTS 0x0252static int report_key_events = -1;53module_param(report_key_events, int, 0644);54MODULE_PARM_DESC(report_key_events,55 "0: none, 1: output changes, 2: brightness changes, 3: all");56 57static int hw_changes_brightness = -1;58module_param(hw_changes_brightness, int, 0644);59MODULE_PARM_DESC(hw_changes_brightness,60 "Set this to 1 on buggy hw which changes the brightness itself when "61 "a hotkey is pressed: -1: auto, 0: normal 1: hw-changes-brightness");62 63/*64 * Whether the struct acpi_video_device_attrib::device_id_scheme bit should be65 * assumed even if not actually set.66 */67static bool device_id_scheme = false;68module_param(device_id_scheme, bool, 0444);69 70static int only_lcd;71module_param(only_lcd, int, 0444);72 73static bool may_report_brightness_keys;74static int register_count;75static DEFINE_MUTEX(register_count_mutex);76static DEFINE_MUTEX(video_list_lock);77static LIST_HEAD(video_bus_head);78static int acpi_video_bus_add(struct acpi_device *device);79static void acpi_video_bus_remove(struct acpi_device *device);80static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data);81 82/*83 * Indices in the _BCL method response: the first two items are special,84 * the rest are all supported levels.85 *86 * See page 575 of the ACPI spec 3.087 */88enum acpi_video_level_idx {89 ACPI_VIDEO_AC_LEVEL, /* level when machine has full power */90 ACPI_VIDEO_BATTERY_LEVEL, /* level when machine is on batteries */91 ACPI_VIDEO_FIRST_LEVEL, /* actual supported levels begin here */92};93 94static const struct acpi_device_id video_device_ids[] = {95 {ACPI_VIDEO_HID, 0},96 {"", 0},97};98MODULE_DEVICE_TABLE(acpi, video_device_ids);99 100static struct acpi_driver acpi_video_bus = {101 .name = "video",102 .class = ACPI_VIDEO_CLASS,103 .ids = video_device_ids,104 .ops = {105 .add = acpi_video_bus_add,106 .remove = acpi_video_bus_remove,107 },108};109 110struct acpi_video_bus_flags {111 u8 multihead:1; /* can switch video heads */112 u8 rom:1; /* can retrieve a video rom */113 u8 post:1; /* can configure the head to */114 u8 reserved:5;115};116 117struct acpi_video_bus_cap {118 u8 _DOS:1; /* Enable/Disable output switching */119 u8 _DOD:1; /* Enumerate all devices attached to display adapter */120 u8 _ROM:1; /* Get ROM Data */121 u8 _GPD:1; /* Get POST Device */122 u8 _SPD:1; /* Set POST Device */123 u8 _VPO:1; /* Video POST Options */124 u8 reserved:2;125};126 127struct acpi_video_device_attrib {128 u32 display_index:4; /* A zero-based instance of the Display */129 u32 display_port_attachment:4; /* This field differentiates the display type */130 u32 display_type:4; /* Describe the specific type in use */131 u32 vendor_specific:4; /* Chipset Vendor Specific */132 u32 bios_can_detect:1; /* BIOS can detect the device */133 u32 depend_on_vga:1; /* Non-VGA output device whose power is related to134 the VGA device. */135 u32 pipe_id:3; /* For VGA multiple-head devices. */136 u32 reserved:10; /* Must be 0 */137 138 /*139 * The device ID might not actually follow the scheme described by this140 * struct acpi_video_device_attrib. If it does, then this bit141 * device_id_scheme is set; otherwise, other fields should be ignored.142 *143 * (but also see the global flag device_id_scheme)144 */145 u32 device_id_scheme:1;146};147 148struct acpi_video_enumerated_device {149 union {150 u32 int_val;151 struct acpi_video_device_attrib attrib;152 } value;153 struct acpi_video_device *bind_info;154};155 156struct acpi_video_bus {157 struct acpi_device *device;158 bool backlight_registered;159 u8 dos_setting;160 struct acpi_video_enumerated_device *attached_array;161 u8 attached_count;162 u8 child_count;163 struct acpi_video_bus_cap cap;164 struct acpi_video_bus_flags flags;165 struct list_head video_device_list;166 struct mutex device_list_lock; /* protects video_device_list */167 struct list_head entry;168 struct input_dev *input;169 char phys[32]; /* for input device */170 struct notifier_block pm_nb;171};172 173struct acpi_video_device_flags {174 u8 crt:1;175 u8 lcd:1;176 u8 tvout:1;177 u8 dvi:1;178 u8 bios:1;179 u8 unknown:1;180 u8 notify:1;181 u8 reserved:1;182};183 184struct acpi_video_device_cap {185 u8 _ADR:1; /* Return the unique ID */186 u8 _BCL:1; /* Query list of brightness control levels supported */187 u8 _BCM:1; /* Set the brightness level */188 u8 _BQC:1; /* Get current brightness level */189 u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */190 u8 _DDC:1; /* Return the EDID for this device */191};192 193struct acpi_video_device {194 unsigned long device_id;195 struct acpi_video_device_flags flags;196 struct acpi_video_device_cap cap;197 struct list_head entry;198 struct delayed_work switch_brightness_work;199 int switch_brightness_event;200 struct acpi_video_bus *video;201 struct acpi_device *dev;202 struct acpi_video_device_brightness *brightness;203 struct backlight_device *backlight;204 struct thermal_cooling_device *cooling_dev;205};206 207static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data);208static void acpi_video_device_rebind(struct acpi_video_bus *video);209static void acpi_video_device_bind(struct acpi_video_bus *video,210 struct acpi_video_device *device);211static int acpi_video_device_enumerate(struct acpi_video_bus *video);212static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,213 int level);214static int acpi_video_device_lcd_get_level_current(215 struct acpi_video_device *device,216 unsigned long long *level, bool raw);217static int acpi_video_get_next_level(struct acpi_video_device *device,218 u32 level_current, u32 event);219static void acpi_video_switch_brightness(struct work_struct *work);220 221/* backlight device sysfs support */222static int acpi_video_get_brightness(struct backlight_device *bd)223{224 unsigned long long cur_level;225 int i;226 struct acpi_video_device *vd = bl_get_data(bd);227 228 if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false))229 return -EINVAL;230 for (i = ACPI_VIDEO_FIRST_LEVEL; i < vd->brightness->count; i++) {231 if (vd->brightness->levels[i] == cur_level)232 return i - ACPI_VIDEO_FIRST_LEVEL;233 }234 return 0;235}236 237static int acpi_video_set_brightness(struct backlight_device *bd)238{239 int request_level = bd->props.brightness + ACPI_VIDEO_FIRST_LEVEL;240 struct acpi_video_device *vd = bl_get_data(bd);241 242 cancel_delayed_work(&vd->switch_brightness_work);243 return acpi_video_device_lcd_set_level(vd,244 vd->brightness->levels[request_level]);245}246 247static const struct backlight_ops acpi_backlight_ops = {248 .get_brightness = acpi_video_get_brightness,249 .update_status = acpi_video_set_brightness,250};251 252/* thermal cooling device callbacks */253static int video_get_max_state(struct thermal_cooling_device *cooling_dev,254 unsigned long *state)255{256 struct acpi_video_device *video = cooling_dev->devdata;257 258 *state = video->brightness->count - ACPI_VIDEO_FIRST_LEVEL - 1;259 return 0;260}261 262static int video_get_cur_state(struct thermal_cooling_device *cooling_dev,263 unsigned long *state)264{265 struct acpi_video_device *video = cooling_dev->devdata;266 unsigned long long level;267 int offset;268 269 if (acpi_video_device_lcd_get_level_current(video, &level, false))270 return -EINVAL;271 for (offset = ACPI_VIDEO_FIRST_LEVEL; offset < video->brightness->count;272 offset++)273 if (level == video->brightness->levels[offset]) {274 *state = video->brightness->count - offset - 1;275 return 0;276 }277 278 return -EINVAL;279}280 281static int282video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state)283{284 struct acpi_video_device *video = cooling_dev->devdata;285 int level;286 287 if (state >= video->brightness->count - ACPI_VIDEO_FIRST_LEVEL)288 return -EINVAL;289 290 state = video->brightness->count - state;291 level = video->brightness->levels[state - 1];292 return acpi_video_device_lcd_set_level(video, level);293}294 295static const struct thermal_cooling_device_ops video_cooling_ops = {296 .get_max_state = video_get_max_state,297 .get_cur_state = video_get_cur_state,298 .set_cur_state = video_set_cur_state,299};300 301/*302 * --------------------------------------------------------------------------303 * Video Management304 * --------------------------------------------------------------------------305 */306 307static int308acpi_video_device_lcd_query_levels(acpi_handle handle,309 union acpi_object **levels)310{311 int status;312 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };313 union acpi_object *obj;314 315 316 *levels = NULL;317 318 status = acpi_evaluate_object(handle, "_BCL", NULL, &buffer);319 if (ACPI_FAILURE(status))320 return status;321 obj = (union acpi_object *)buffer.pointer;322 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {323 acpi_handle_info(handle, "Invalid _BCL data\n");324 status = -EFAULT;325 goto err;326 }327 328 *levels = obj;329 330 return 0;331 332err:333 kfree(buffer.pointer);334 335 return status;336}337 338static int339acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)340{341 int status;342 int state;343 344 status = acpi_execute_simple_method(device->dev->handle,345 "_BCM", level);346 if (ACPI_FAILURE(status)) {347 acpi_handle_info(device->dev->handle, "_BCM evaluation failed\n");348 return -EIO;349 }350 351 device->brightness->curr = level;352 for (state = ACPI_VIDEO_FIRST_LEVEL; state < device->brightness->count;353 state++)354 if (level == device->brightness->levels[state]) {355 if (device->backlight)356 device->backlight->props.brightness =357 state - ACPI_VIDEO_FIRST_LEVEL;358 return 0;359 }360 361 acpi_handle_info(device->dev->handle, "Current brightness invalid\n");362 return -EINVAL;363}364 365/*366 * For some buggy _BQC methods, we need to add a constant value to367 * the _BQC return value to get the actual current brightness level368 */369 370static int bqc_offset_aml_bug_workaround;371static int video_set_bqc_offset(const struct dmi_system_id *d)372{373 bqc_offset_aml_bug_workaround = 9;374 return 0;375}376 377static int video_set_device_id_scheme(const struct dmi_system_id *d)378{379 device_id_scheme = true;380 return 0;381}382 383static int video_enable_only_lcd(const struct dmi_system_id *d)384{385 only_lcd = true;386 return 0;387}388 389static int video_set_report_key_events(const struct dmi_system_id *id)390{391 if (report_key_events == -1)392 report_key_events = (uintptr_t)id->driver_data;393 return 0;394}395 396static int video_hw_changes_brightness(397 const struct dmi_system_id *d)398{399 if (hw_changes_brightness == -1)400 hw_changes_brightness = 1;401 return 0;402}403 404static const struct dmi_system_id video_dmi_table[] = {405 /*406 * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121407 */408 {409 .callback = video_set_bqc_offset,410 .ident = "Acer Aspire 5720",411 .matches = {412 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),413 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),414 },415 },416 {417 .callback = video_set_bqc_offset,418 .ident = "Acer Aspire 5710Z",419 .matches = {420 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),421 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"),422 },423 },424 {425 .callback = video_set_bqc_offset,426 .ident = "eMachines E510",427 .matches = {428 DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"),429 DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"),430 },431 },432 {433 .callback = video_set_bqc_offset,434 .ident = "Acer Aspire 5315",435 .matches = {436 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),437 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),438 },439 },440 {441 .callback = video_set_bqc_offset,442 .ident = "Acer Aspire 7720",443 .matches = {444 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),445 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"),446 },447 },448 449 /*450 * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set451 * but the IDs actually follow the Device ID Scheme.452 */453 {454 /* https://bugzilla.kernel.org/show_bug.cgi?id=104121 */455 .callback = video_set_device_id_scheme,456 .ident = "ESPRIMO Mobile M9410",457 .matches = {458 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),459 DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"),460 },461 },462 /*463 * Some machines have multiple video output devices, but only the one464 * that is the type of LCD can do the backlight control so we should not465 * register backlight interface for other video output devices.466 */467 {468 /* https://bugzilla.kernel.org/show_bug.cgi?id=104121 */469 .callback = video_enable_only_lcd,470 .ident = "ESPRIMO Mobile M9410",471 .matches = {472 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),473 DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile M9410"),474 },475 },476 /*477 * Some machines report wrong key events on the acpi-bus, suppress478 * key event reporting on these. Note this is only intended to work479 * around events which are plain wrong. In some cases we get double480 * events, in this case acpi-video is considered the canonical source481 * and the events from the other source should be filtered. E.g.482 * by calling acpi_video_handles_brightness_key_presses() from the483 * vendor acpi/wmi driver or by using /lib/udev/hwdb.d/60-keyboard.hwdb484 */485 {486 .callback = video_set_report_key_events,487 .driver_data = (void *)((uintptr_t)REPORT_OUTPUT_KEY_EVENTS),488 .ident = "Dell Vostro V131",489 .matches = {490 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),491 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),492 },493 },494 {495 .callback = video_set_report_key_events,496 .driver_data = (void *)((uintptr_t)REPORT_BRIGHTNESS_KEY_EVENTS),497 .ident = "Dell Vostro 3350",498 .matches = {499 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),500 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3350"),501 },502 },503 {504 .callback = video_set_report_key_events,505 .driver_data = (void *)((uintptr_t)REPORT_BRIGHTNESS_KEY_EVENTS),506 .ident = "COLORFUL X15 AT 23",507 .matches = {508 DMI_MATCH(DMI_SYS_VENDOR, "COLORFUL"),509 DMI_MATCH(DMI_PRODUCT_NAME, "X15 AT 23"),510 },511 },512 /*513 * Some machines change the brightness themselves when a brightness514 * hotkey gets pressed, despite us telling them not to. In this case515 * acpi_video_device_notify() should only call backlight_force_update(516 * BACKLIGHT_UPDATE_HOTKEY) and not do anything else.517 */518 {519 /* https://bugzilla.kernel.org/show_bug.cgi?id=204077 */520 .callback = video_hw_changes_brightness,521 .ident = "Packard Bell EasyNote MZ35",522 .matches = {523 DMI_MATCH(DMI_SYS_VENDOR, "Packard Bell"),524 DMI_MATCH(DMI_PRODUCT_NAME, "EasyNote MZ35"),525 },526 },527 {}528};529 530static unsigned long long531acpi_video_bqc_value_to_level(struct acpi_video_device *device,532 unsigned long long bqc_value)533{534 unsigned long long level;535 536 if (device->brightness->flags._BQC_use_index) {537 /*538 * _BQC returns an index that doesn't account for the first 2539 * items with special meaning (see enum acpi_video_level_idx),540 * so we need to compensate for that by offsetting ourselves541 */542 if (device->brightness->flags._BCL_reversed)543 bqc_value = device->brightness->count -544 ACPI_VIDEO_FIRST_LEVEL - 1 - bqc_value;545 546 level = device->brightness->levels[bqc_value +547 ACPI_VIDEO_FIRST_LEVEL];548 } else {549 level = bqc_value;550 }551 552 level += bqc_offset_aml_bug_workaround;553 554 return level;555}556 557static int558acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,559 unsigned long long *level, bool raw)560{561 acpi_status status = AE_OK;562 int i;563 564 if (device->cap._BQC || device->cap._BCQ) {565 char *buf = device->cap._BQC ? "_BQC" : "_BCQ";566 567 status = acpi_evaluate_integer(device->dev->handle, buf,568 NULL, level);569 if (ACPI_SUCCESS(status)) {570 if (raw) {571 /*572 * Caller has indicated he wants the raw573 * value returned by _BQC, so don't furtherly574 * mess with the value.575 */576 return 0;577 }578 579 *level = acpi_video_bqc_value_to_level(device, *level);580 581 for (i = ACPI_VIDEO_FIRST_LEVEL;582 i < device->brightness->count; i++)583 if (device->brightness->levels[i] == *level) {584 device->brightness->curr = *level;585 return 0;586 }587 /*588 * BQC returned an invalid level.589 * Stop using it.590 */591 acpi_handle_info(device->dev->handle,592 "%s returned an invalid level", buf);593 device->cap._BQC = device->cap._BCQ = 0;594 } else {595 /*596 * Fixme:597 * should we return an error or ignore this failure?598 * dev->brightness->curr is a cached value which stores599 * the correct current backlight level in most cases.600 * ACPI video backlight still works w/ buggy _BQC.601 * http://bugzilla.kernel.org/show_bug.cgi?id=12233602 */603 acpi_handle_info(device->dev->handle,604 "%s evaluation failed", buf);605 device->cap._BQC = device->cap._BCQ = 0;606 }607 }608 609 *level = device->brightness->curr;610 return 0;611}612 613static int614acpi_video_device_EDID(struct acpi_video_device *device,615 union acpi_object **edid, int length)616{617 int status;618 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };619 union acpi_object *obj;620 union acpi_object arg0 = { ACPI_TYPE_INTEGER };621 struct acpi_object_list args = { 1, &arg0 };622 623 624 *edid = NULL;625 626 if (!device)627 return -ENODEV;628 if (!length || (length % 128))629 return -EINVAL;630 631 arg0.integer.value = length / 128;632 633 status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer);634 if (ACPI_FAILURE(status))635 return -ENODEV;636 637 obj = buffer.pointer;638 639 if (obj && obj->type == ACPI_TYPE_BUFFER)640 *edid = obj;641 else {642 acpi_handle_debug(device->dev->handle,643 "Invalid _DDC data for length %d\n", length);644 status = -EFAULT;645 kfree(obj);646 }647 648 return status;649}650 651/* bus */652 653/*654 * Arg:655 * video : video bus device pointer656 * bios_flag :657 * 0. The system BIOS should NOT automatically switch(toggle)658 * the active display output.659 * 1. The system BIOS should automatically switch (toggle) the660 * active display output. No switch event.661 * 2. The _DGS value should be locked.662 * 3. The system BIOS should not automatically switch (toggle) the663 * active display output, but instead generate the display switch664 * event notify code.665 * lcd_flag :666 * 0. The system BIOS should automatically control the brightness level667 * of the LCD when:668 * - the power changes from AC to DC (ACPI appendix B)669 * - a brightness hotkey gets pressed (implied by Win7/8 backlight docs)670 * 1. The system BIOS should NOT automatically control the brightness671 * level of the LCD when:672 * - the power changes from AC to DC (ACPI appendix B)673 * - a brightness hotkey gets pressed (implied by Win7/8 backlight docs)674 * Return Value:675 * -EINVAL wrong arg.676 */677 678static int679acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)680{681 acpi_status status;682 683 if (!video->cap._DOS)684 return 0;685 686 if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1)687 return -EINVAL;688 video->dos_setting = (lcd_flag << 2) | bios_flag;689 status = acpi_execute_simple_method(video->device->handle, "_DOS",690 (lcd_flag << 2) | bios_flag);691 if (ACPI_FAILURE(status))692 return -EIO;693 694 return 0;695}696 697/*698 * Simple comparison function used to sort backlight levels.699 */700 701static int702acpi_video_cmp_level(const void *a, const void *b)703{704 return *(int *)a - *(int *)b;705}706 707/*708 * Decides if _BQC/_BCQ for this system is usable709 *710 * We do this by changing the level first and then read out the current711 * brightness level, if the value does not match, find out if it is using712 * index. If not, clear the _BQC/_BCQ capability.713 */714static int acpi_video_bqc_quirk(struct acpi_video_device *device,715 int max_level, int current_level)716{717 struct acpi_video_device_brightness *br = device->brightness;718 int result;719 unsigned long long level;720 int test_level;721 722 /* don't mess with existing known broken systems */723 if (bqc_offset_aml_bug_workaround)724 return 0;725 726 /*727 * Some systems always report current brightness level as maximum728 * through _BQC, we need to test another value for them. However,729 * there is a subtlety:730 *731 * If the _BCL package ordering is descending, the first level732 * (br->levels[2]) is likely to be 0, and if the number of levels733 * matches the number of steps, we might confuse a returned level to734 * mean the index.735 *736 * For example:737 *738 * current_level = max_level = 100739 * test_level = 0740 * returned level = 100741 *742 * In this case 100 means the level, not the index, and _BCM failed.743 * Still, if the _BCL package ordering is descending, the index of744 * level 0 is also 100, so we assume _BQC is indexed, when it's not.745 *746 * This causes all _BQC calls to return bogus values causing weird747 * behavior from the user's perspective. For example:748 *749 * xbacklight -set 10; xbacklight -set 20;750 *751 * would flash to 90% and then slowly down to the desired level (20).752 *753 * The solution is simple; test anything other than the first level754 * (e.g. 1).755 */756 test_level = current_level == max_level757 ? br->levels[ACPI_VIDEO_FIRST_LEVEL + 1]758 : max_level;759 760 result = acpi_video_device_lcd_set_level(device, test_level);761 if (result)762 return result;763 764 result = acpi_video_device_lcd_get_level_current(device, &level, true);765 if (result)766 return result;767 768 if (level != test_level) {769 /* buggy _BQC found, need to find out if it uses index */770 if (level < br->count) {771 if (br->flags._BCL_reversed)772 level = br->count - ACPI_VIDEO_FIRST_LEVEL - 1 - level;773 if (br->levels[level + ACPI_VIDEO_FIRST_LEVEL] == test_level)774 br->flags._BQC_use_index = 1;775 }776 777 if (!br->flags._BQC_use_index)778 device->cap._BQC = device->cap._BCQ = 0;779 }780 781 return 0;782}783 784int acpi_video_get_levels(struct acpi_device *device,785 struct acpi_video_device_brightness **dev_br,786 int *pmax_level)787{788 union acpi_object *obj = NULL;789 int i, max_level = 0, count = 0, level_ac_battery = 0;790 union acpi_object *o;791 struct acpi_video_device_brightness *br = NULL;792 int result = 0;793 u32 value;794 795 if (ACPI_FAILURE(acpi_video_device_lcd_query_levels(device->handle, &obj))) {796 acpi_handle_debug(device->handle,797 "Could not query available LCD brightness level\n");798 result = -ENODEV;799 goto out;800 }801 802 if (obj->package.count < ACPI_VIDEO_FIRST_LEVEL) {803 result = -EINVAL;804 goto out;805 }806 807 br = kzalloc(sizeof(*br), GFP_KERNEL);808 if (!br) {809 result = -ENOMEM;810 goto out;811 }812 813 /*814 * Note that we have to reserve 2 extra items (ACPI_VIDEO_FIRST_LEVEL),815 * in order to account for buggy BIOS which don't export the first two816 * special levels (see below)817 */818 br->levels = kmalloc_array(obj->package.count + ACPI_VIDEO_FIRST_LEVEL,819 sizeof(*br->levels),820 GFP_KERNEL);821 if (!br->levels) {822 result = -ENOMEM;823 goto out_free;824 }825 826 for (i = 0; i < obj->package.count; i++) {827 o = (union acpi_object *)&obj->package.elements[i];828 if (o->type != ACPI_TYPE_INTEGER) {829 acpi_handle_info(device->handle, "Invalid data\n");830 continue;831 }832 value = (u32) o->integer.value;833 /* Skip duplicate entries */834 if (count > ACPI_VIDEO_FIRST_LEVEL835 && br->levels[count - 1] == value)836 continue;837 838 br->levels[count] = value;839 840 if (br->levels[count] > max_level)841 max_level = br->levels[count];842 count++;843 }844 845 /*846 * some buggy BIOS don't export the levels847 * when machine is on AC/Battery in _BCL package.848 * In this case, the first two elements in _BCL packages849 * are also supported brightness levels that OS should take care of.850 */851 for (i = ACPI_VIDEO_FIRST_LEVEL; i < count; i++) {852 if (br->levels[i] == br->levels[ACPI_VIDEO_AC_LEVEL])853 level_ac_battery++;854 if (br->levels[i] == br->levels[ACPI_VIDEO_BATTERY_LEVEL])855 level_ac_battery++;856 }857 858 if (level_ac_battery < ACPI_VIDEO_FIRST_LEVEL) {859 level_ac_battery = ACPI_VIDEO_FIRST_LEVEL - level_ac_battery;860 br->flags._BCL_no_ac_battery_levels = 1;861 for (i = (count - 1 + level_ac_battery);862 i >= ACPI_VIDEO_FIRST_LEVEL; i--)863 br->levels[i] = br->levels[i - level_ac_battery];864 count += level_ac_battery;865 } else if (level_ac_battery > ACPI_VIDEO_FIRST_LEVEL)866 acpi_handle_info(device->handle,867 "Too many duplicates in _BCL package");868 869 /* Check if the _BCL package is in a reversed order */870 if (max_level == br->levels[ACPI_VIDEO_FIRST_LEVEL]) {871 br->flags._BCL_reversed = 1;872 sort(&br->levels[ACPI_VIDEO_FIRST_LEVEL],873 count - ACPI_VIDEO_FIRST_LEVEL,874 sizeof(br->levels[ACPI_VIDEO_FIRST_LEVEL]),875 acpi_video_cmp_level, NULL);876 } else if (max_level != br->levels[count - 1])877 acpi_handle_info(device->handle,878 "Found unordered _BCL package");879 880 br->count = count;881 *dev_br = br;882 if (pmax_level)883 *pmax_level = max_level;884 885out:886 kfree(obj);887 return result;888out_free:889 kfree(br);890 goto out;891}892EXPORT_SYMBOL(acpi_video_get_levels);893 894/*895 * Arg:896 * device : video output device (LCD, CRT, ..)897 *898 * Return Value:899 * Maximum brightness level900 *901 * Allocate and initialize device->brightness.902 */903 904static int905acpi_video_init_brightness(struct acpi_video_device *device)906{907 int i, max_level = 0;908 unsigned long long level, level_old;909 struct acpi_video_device_brightness *br = NULL;910 int result;911 912 result = acpi_video_get_levels(device->dev, &br, &max_level);913 if (result)914 return result;915 device->brightness = br;916 917 /* _BQC uses INDEX while _BCL uses VALUE in some laptops */918 br->curr = level = max_level;919 920 if (!device->cap._BQC)921 goto set_level;922 923 result = acpi_video_device_lcd_get_level_current(device,924 &level_old, true);925 if (result)926 goto out_free_levels;927 928 result = acpi_video_bqc_quirk(device, max_level, level_old);929 if (result)930 goto out_free_levels;931 /*932 * cap._BQC may get cleared due to _BQC is found to be broken933 * in acpi_video_bqc_quirk, so check again here.934 */935 if (!device->cap._BQC)936 goto set_level;937 938 level = acpi_video_bqc_value_to_level(device, level_old);939 /*940 * On some buggy laptops, _BQC returns an uninitialized941 * value when invoked for the first time, i.e.942 * level_old is invalid (no matter whether it's a level943 * or an index). Set the backlight to max_level in this case.944 */945 for (i = ACPI_VIDEO_FIRST_LEVEL; i < br->count; i++)946 if (level == br->levels[i])947 break;948 if (i == br->count || !level)949 level = max_level;950 951set_level:952 result = acpi_video_device_lcd_set_level(device, level);953 if (result)954 goto out_free_levels;955 956 acpi_handle_debug(device->dev->handle, "found %d brightness levels\n",957 br->count - ACPI_VIDEO_FIRST_LEVEL);958 959 return 0;960 961out_free_levels:962 kfree(br->levels);963 kfree(br);964 device->brightness = NULL;965 return result;966}967 968/*969 * Arg:970 * device : video output device (LCD, CRT, ..)971 *972 * Return Value:973 * None974 *975 * Find out all required AML methods defined under the output976 * device.977 */978 979static void acpi_video_device_find_cap(struct acpi_video_device *device)980{981 if (acpi_has_method(device->dev->handle, "_ADR"))982 device->cap._ADR = 1;983 if (acpi_has_method(device->dev->handle, "_BCL"))984 device->cap._BCL = 1;985 if (acpi_has_method(device->dev->handle, "_BCM"))986 device->cap._BCM = 1;987 if (acpi_has_method(device->dev->handle, "_BQC")) {988 device->cap._BQC = 1;989 } else if (acpi_has_method(device->dev->handle, "_BCQ")) {990 acpi_handle_info(device->dev->handle,991 "_BCQ is used instead of _BQC\n");992 device->cap._BCQ = 1;993 }994 995 if (acpi_has_method(device->dev->handle, "_DDC"))996 device->cap._DDC = 1;997}998 999/*1000 * Arg:1001 * device : video output device (VGA)1002 *1003 * Return Value:1004 * None1005 *1006 * Find out all required AML methods defined under the video bus device.1007 */1008 1009static void acpi_video_bus_find_cap(struct acpi_video_bus *video)1010{1011 if (acpi_has_method(video->device->handle, "_DOS"))1012 video->cap._DOS = 1;1013 if (acpi_has_method(video->device->handle, "_DOD"))1014 video->cap._DOD = 1;1015 if (acpi_has_method(video->device->handle, "_ROM"))1016 video->cap._ROM = 1;1017 if (acpi_has_method(video->device->handle, "_GPD"))1018 video->cap._GPD = 1;1019 if (acpi_has_method(video->device->handle, "_SPD"))1020 video->cap._SPD = 1;1021 if (acpi_has_method(video->device->handle, "_VPO"))1022 video->cap._VPO = 1;1023}1024 1025/*1026 * Check whether the video bus device has required AML method to1027 * support the desired features1028 */1029 1030static int acpi_video_bus_check(struct acpi_video_bus *video)1031{1032 acpi_status status = -ENOENT;1033 struct pci_dev *dev;1034 1035 if (!video)1036 return -EINVAL;1037 1038 dev = acpi_get_pci_dev(video->device->handle);1039 if (!dev)1040 return -ENODEV;1041 pci_dev_put(dev);1042 1043 /*1044 * Since there is no HID, CID and so on for VGA driver, we have1045 * to check well known required nodes.1046 */1047 1048 /* Does this device support video switching? */1049 if (video->cap._DOS || video->cap._DOD) {1050 if (!video->cap._DOS) {1051 pr_info(FW_BUG "ACPI(%s) defines _DOD but not _DOS\n",1052 acpi_device_bid(video->device));1053 }1054 video->flags.multihead = 1;1055 status = 0;1056 }1057 1058 /* Does this device support retrieving a video ROM? */1059 if (video->cap._ROM) {1060 video->flags.rom = 1;1061 status = 0;1062 }1063 1064 /* Does this device support configuring which video device to POST? */1065 if (video->cap._GPD && video->cap._SPD && video->cap._VPO) {1066 video->flags.post = 1;1067 status = 0;1068 }1069 1070 return status;1071}1072 1073/*1074 * --------------------------------------------------------------------------1075 * Driver Interface1076 * --------------------------------------------------------------------------1077 */1078 1079/* device interface */1080static struct acpi_video_device_attrib *1081acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)1082{1083 struct acpi_video_enumerated_device *ids;1084 int i;1085 1086 for (i = 0; i < video->attached_count; i++) {1087 ids = &video->attached_array[i];1088 if ((ids->value.int_val & 0xffff) == device_id)1089 return &ids->value.attrib;1090 }1091 1092 return NULL;1093}1094 1095static int1096acpi_video_get_device_type(struct acpi_video_bus *video,1097 unsigned long device_id)1098{1099 struct acpi_video_enumerated_device *ids;1100 int i;1101 1102 for (i = 0; i < video->attached_count; i++) {1103 ids = &video->attached_array[i];1104 if ((ids->value.int_val & 0xffff) == device_id)1105 return ids->value.int_val;1106 }1107 1108 return 0;1109}1110 1111static int acpi_video_bus_get_one_device(struct acpi_device *device, void *arg)1112{1113 struct acpi_video_bus *video = arg;1114 struct acpi_video_device_attrib *attribute;1115 struct acpi_video_device *data;1116 unsigned long long device_id;1117 acpi_status status;1118 int device_type;1119 1120 status = acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);1121 /* Skip devices without _ADR instead of failing. */1122 if (ACPI_FAILURE(status))1123 goto exit;1124 1125 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);1126 if (!data) {1127 dev_dbg(&device->dev, "Cannot attach\n");1128 return -ENOMEM;1129 }1130 1131 strscpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);1132 strscpy(acpi_device_class(device), ACPI_VIDEO_CLASS);1133 1134 data->device_id = device_id;1135 data->video = video;1136 data->dev = device;1137 INIT_DELAYED_WORK(&data->switch_brightness_work,1138 acpi_video_switch_brightness);1139 1140 attribute = acpi_video_get_device_attr(video, device_id);1141 1142 if (attribute && (attribute->device_id_scheme || device_id_scheme)) {1143 switch (attribute->display_type) {1144 case ACPI_VIDEO_DISPLAY_CRT:1145 data->flags.crt = 1;1146 break;1147 case ACPI_VIDEO_DISPLAY_TV:1148 data->flags.tvout = 1;1149 break;1150 case ACPI_VIDEO_DISPLAY_DVI:1151 data->flags.dvi = 1;1152 break;1153 case ACPI_VIDEO_DISPLAY_LCD:1154 data->flags.lcd = 1;1155 break;1156 default:1157 data->flags.unknown = 1;1158 break;1159 }1160 if (attribute->bios_can_detect)1161 data->flags.bios = 1;1162 } else {1163 /* Check for legacy IDs */1164 device_type = acpi_video_get_device_type(video, device_id);1165 /* Ignore bits 16 and 18-20 */1166 switch (device_type & 0xffe2ffff) {1167 case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR:1168 data->flags.crt = 1;1169 break;1170 case ACPI_VIDEO_DISPLAY_LEGACY_PANEL:1171 data->flags.lcd = 1;1172 break;1173 case ACPI_VIDEO_DISPLAY_LEGACY_TV:1174 data->flags.tvout = 1;1175 break;1176 default:1177 data->flags.unknown = 1;1178 }1179 }1180 1181 acpi_video_device_bind(video, data);1182 acpi_video_device_find_cap(data);1183 1184 if (data->cap._BCM && data->cap._BCL)1185 may_report_brightness_keys = true;1186 1187 mutex_lock(&video->device_list_lock);1188 list_add_tail(&data->entry, &video->video_device_list);1189 mutex_unlock(&video->device_list_lock);1190 1191exit:1192 video->child_count++;1193 return 0;1194}1195 1196/*1197 * Arg:1198 * video : video bus device1199 *1200 * Return:1201 * none1202 *1203 * Enumerate the video device list of the video bus,1204 * bind the ids with the corresponding video devices1205 * under the video bus.1206 */1207 1208static void acpi_video_device_rebind(struct acpi_video_bus *video)1209{1210 struct acpi_video_device *dev;1211 1212 mutex_lock(&video->device_list_lock);1213 1214 list_for_each_entry(dev, &video->video_device_list, entry)1215 acpi_video_device_bind(video, dev);1216 1217 mutex_unlock(&video->device_list_lock);1218}1219 1220/*1221 * Arg:1222 * video : video bus device1223 * device : video output device under the video1224 * bus1225 *1226 * Return:1227 * none1228 *1229 * Bind the ids with the corresponding video devices1230 * under the video bus.1231 */1232 1233static void1234acpi_video_device_bind(struct acpi_video_bus *video,1235 struct acpi_video_device *device)1236{1237 struct acpi_video_enumerated_device *ids;1238 int i;1239 1240 for (i = 0; i < video->attached_count; i++) {1241 ids = &video->attached_array[i];1242 if (device->device_id == (ids->value.int_val & 0xffff)) {1243 ids->bind_info = device;1244 acpi_handle_debug(video->device->handle, "%s: %d\n",1245 __func__, i);1246 }1247 }1248}1249 1250static bool acpi_video_device_in_dod(struct acpi_video_device *device)1251{1252 struct acpi_video_bus *video = device->video;1253 int i;1254 1255 /*1256 * If we have a broken _DOD or we have more than 8 output devices1257 * under the graphics controller node that we can't proper deal with1258 * in the operation region code currently, no need to test.1259 */1260 if (!video->attached_count || video->child_count > 8)1261 return true;1262 1263 for (i = 0; i < video->attached_count; i++) {1264 if ((video->attached_array[i].value.int_val & 0xfff) ==1265 (device->device_id & 0xfff))1266 return true;1267 }1268 1269 return false;1270}1271 1272/*1273 * Arg:1274 * video : video bus device1275 *1276 * Return:1277 * < 0 : error1278 *1279 * Call _DOD to enumerate all devices attached to display adapter1280 *1281 */1282 1283static int acpi_video_device_enumerate(struct acpi_video_bus *video)1284{1285 int status;1286 int count;1287 int i;1288 struct acpi_video_enumerated_device *active_list;1289 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };1290 union acpi_object *dod = NULL;1291 union acpi_object *obj;1292 1293 if (!video->cap._DOD)1294 return AE_NOT_EXIST;1295 1296 status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer);1297 if (ACPI_FAILURE(status)) {1298 acpi_handle_info(video->device->handle,1299 "_DOD evaluation failed: %s\n",1300 acpi_format_exception(status));1301 return status;1302 }1303 1304 dod = buffer.pointer;1305 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {1306 acpi_handle_info(video->device->handle, "Invalid _DOD data\n");1307 status = -EFAULT;1308 goto out;1309 }1310 1311 acpi_handle_debug(video->device->handle, "Found %d video heads in _DOD\n",1312 dod->package.count);1313 1314 active_list = kcalloc(1 + dod->package.count,1315 sizeof(struct acpi_video_enumerated_device),1316 GFP_KERNEL);1317 if (!active_list) {1318 status = -ENOMEM;1319 goto out;1320 }1321 1322 count = 0;1323 for (i = 0; i < dod->package.count; i++) {1324 obj = &dod->package.elements[i];1325 1326 if (obj->type != ACPI_TYPE_INTEGER) {1327 acpi_handle_info(video->device->handle,1328 "Invalid _DOD data in element %d\n", i);1329 continue;1330 }1331 1332 active_list[count].value.int_val = obj->integer.value;1333 active_list[count].bind_info = NULL;1334 1335 acpi_handle_debug(video->device->handle,1336 "_DOD element[%d] = %d\n", i,1337 (int)obj->integer.value);1338 1339 count++;1340 }1341 1342 kfree(video->attached_array);1343 1344 video->attached_array = active_list;1345 video->attached_count = count;1346 1347out:1348 kfree(buffer.pointer);1349 return status;1350}1351 1352static int1353acpi_video_get_next_level(struct acpi_video_device *device,1354 u32 level_current, u32 event)1355{1356 int min, max, min_above, max_below, i, l, delta = 255;1357 max = max_below = 0;1358 min = min_above = 255;1359 /* Find closest level to level_current */1360 for (i = ACPI_VIDEO_FIRST_LEVEL; i < device->brightness->count; i++) {1361 l = device->brightness->levels[i];1362 if (abs(l - level_current) < abs(delta)) {1363 delta = l - level_current;1364 if (!delta)1365 break;1366 }1367 }1368 /* Adjust level_current to closest available level */1369 level_current += delta;1370 for (i = ACPI_VIDEO_FIRST_LEVEL; i < device->brightness->count; i++) {1371 l = device->brightness->levels[i];1372 if (l < min)1373 min = l;1374 if (l > max)1375 max = l;1376 if (l < min_above && l > level_current)1377 min_above = l;1378 if (l > max_below && l < level_current)1379 max_below = l;1380 }1381 1382 switch (event) {1383 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:1384 return (level_current < max) ? min_above : min;1385 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:1386 return (level_current < max) ? min_above : max;1387 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:1388 return (level_current > min) ? max_below : min;1389 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:1390 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:1391 return 0;1392 default:1393 return level_current;1394 }1395}1396 1397static void1398acpi_video_switch_brightness(struct work_struct *work)1399{1400 struct acpi_video_device *device = container_of(to_delayed_work(work),1401 struct acpi_video_device, switch_brightness_work);1402 unsigned long long level_current, level_next;1403 int event = device->switch_brightness_event;1404 int result = -EINVAL;1405 1406 /* no warning message if acpi_backlight=vendor or a quirk is used */1407 if (!device->backlight)1408 return;1409 1410 if (!device->brightness)1411 goto out;1412 1413 result = acpi_video_device_lcd_get_level_current(device,1414 &level_current,1415 false);1416 if (result)1417 goto out;1418 1419 level_next = acpi_video_get_next_level(device, level_current, event);1420 1421 result = acpi_video_device_lcd_set_level(device, level_next);1422 1423 if (!result)1424 backlight_force_update(device->backlight,1425 BACKLIGHT_UPDATE_HOTKEY);1426 1427out:1428 if (result)1429 acpi_handle_info(device->dev->handle,1430 "Failed to switch brightness\n");1431}1432 1433int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,1434 void **edid)1435{1436 struct acpi_video_bus *video;1437 struct acpi_video_device *video_device;1438 union acpi_object *buffer = NULL;1439 acpi_status status;1440 int i, length;1441 1442 if (!device || !acpi_driver_data(device))1443 return -EINVAL;1444 1445 video = acpi_driver_data(device);1446 1447 for (i = 0; i < video->attached_count; i++) {1448 video_device = video->attached_array[i].bind_info;1449 1450 if (!video_device)1451 continue;1452 1453 if (!video_device->cap._DDC)1454 continue;1455 1456 if (type) {1457 switch (type) {1458 case ACPI_VIDEO_DISPLAY_CRT:1459 if (!video_device->flags.crt)1460 continue;1461 break;1462 case ACPI_VIDEO_DISPLAY_TV:1463 if (!video_device->flags.tvout)1464 continue;1465 break;1466 case ACPI_VIDEO_DISPLAY_DVI:1467 if (!video_device->flags.dvi)1468 continue;1469 break;1470 case ACPI_VIDEO_DISPLAY_LCD:1471 if (!video_device->flags.lcd)1472 continue;1473 break;1474 }1475 } else if (video_device->device_id != device_id) {1476 continue;1477 }1478 1479 for (length = 512; length > 0; length -= 128) {1480 status = acpi_video_device_EDID(video_device, &buffer,1481 length);1482 if (ACPI_SUCCESS(status))1483 break;1484 }1485 if (!length)1486 continue;1487 1488 *edid = buffer->buffer.pointer;1489 return length;1490 }1491 1492 return -ENODEV;1493}1494EXPORT_SYMBOL(acpi_video_get_edid);1495 1496static int1497acpi_video_bus_get_devices(struct acpi_video_bus *video,1498 struct acpi_device *device)1499{1500 /*1501 * There are systems where video module known to work fine regardless1502 * of broken _DOD and ignoring returned value here doesn't cause1503 * any issues later.1504 */1505 acpi_video_device_enumerate(video);1506 1507 return acpi_dev_for_each_child(device, acpi_video_bus_get_one_device, video);1508}1509 1510/* acpi_video interface */1511 1512/*1513 * Win8 requires setting bit2 of _DOS to let firmware know it shouldn't1514 * perform any automatic brightness change on receiving a notification.1515 */1516static int acpi_video_bus_start_devices(struct acpi_video_bus *video)1517{1518 return acpi_video_bus_DOS(video, 0,1519 acpi_osi_is_win8() ? 1 : 0);1520}1521 1522static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)1523{1524 return acpi_video_bus_DOS(video, 0,1525 acpi_osi_is_win8() ? 0 : 1);1526}1527 1528static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)1529{1530 struct acpi_device *device = data;1531 struct acpi_video_bus *video = acpi_driver_data(device);1532 struct input_dev *input;1533 int keycode = 0;1534 1535 if (!video || !video->input)1536 return;1537 1538 input = video->input;1539 1540 switch (event) {1541 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,1542 * most likely via hotkey. */1543 keycode = KEY_SWITCHVIDEOMODE;1544 break;1545 1546 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video1547 * connector. */1548 acpi_video_device_enumerate(video);1549 acpi_video_device_rebind(video);1550 keycode = KEY_SWITCHVIDEOMODE;1551 break;1552 1553 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */1554 keycode = KEY_SWITCHVIDEOMODE;1555 break;1556 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */1557 keycode = KEY_VIDEO_NEXT;1558 break;1559 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */1560 keycode = KEY_VIDEO_PREV;1561 break;1562 1563 default:1564 acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",1565 event);1566 break;1567 }1568 1569 if (acpi_notifier_call_chain(device, event, 0))1570 /* Something vetoed the keypress. */1571 keycode = 0;1572 1573 if (keycode && (report_key_events & REPORT_OUTPUT_KEY_EVENTS)) {1574 input_report_key(input, keycode, 1);1575 input_sync(input);1576 input_report_key(input, keycode, 0);1577 input_sync(input);1578 }1579}1580 1581static void brightness_switch_event(struct acpi_video_device *video_device,1582 u32 event)1583{1584 if (!brightness_switch_enabled)1585 return;1586 1587 video_device->switch_brightness_event = event;1588 schedule_delayed_work(&video_device->switch_brightness_work, HZ / 10);1589}1590 1591static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)1592{1593 struct acpi_video_device *video_device = data;1594 struct acpi_device *device = NULL;1595 struct acpi_video_bus *bus;1596 struct input_dev *input;1597 int keycode = 0;1598 1599 if (!video_device)1600 return;1601 1602 device = video_device->dev;1603 bus = video_device->video;1604 input = bus->input;1605 1606 if (hw_changes_brightness > 0) {1607 if (video_device->backlight)1608 backlight_force_update(video_device->backlight,1609 BACKLIGHT_UPDATE_HOTKEY);1610 acpi_notifier_call_chain(device, event, 0);1611 return;1612 }1613 1614 switch (event) {1615 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */1616 brightness_switch_event(video_device, event);1617 keycode = KEY_BRIGHTNESS_CYCLE;1618 break;1619 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */1620 brightness_switch_event(video_device, event);1621 keycode = KEY_BRIGHTNESSUP;1622 break;1623 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */1624 brightness_switch_event(video_device, event);1625 keycode = KEY_BRIGHTNESSDOWN;1626 break;1627 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */1628 brightness_switch_event(video_device, event);1629 keycode = KEY_BRIGHTNESS_ZERO;1630 break;1631 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */1632 brightness_switch_event(video_device, event);1633 keycode = KEY_DISPLAY_OFF;1634 break;1635 default:1636 acpi_handle_debug(handle, "Unsupported event [0x%x]\n", event);1637 break;1638 }1639 1640 if (keycode)1641 may_report_brightness_keys = true;1642 1643 acpi_notifier_call_chain(device, event, 0);1644 1645 if (keycode && (report_key_events & REPORT_BRIGHTNESS_KEY_EVENTS)) {1646 input_report_key(input, keycode, 1);1647 input_sync(input);1648 input_report_key(input, keycode, 0);1649 input_sync(input);1650 }1651}1652 1653static int acpi_video_resume(struct notifier_block *nb,1654 unsigned long val, void *ign)1655{1656 struct acpi_video_bus *video;1657 struct acpi_video_device *video_device;1658 int i;1659 1660 switch (val) {1661 case PM_POST_HIBERNATION:1662 case PM_POST_SUSPEND:1663 case PM_POST_RESTORE:1664 video = container_of(nb, struct acpi_video_bus, pm_nb);1665 1666 dev_info(&video->device->dev, "Restoring backlight state\n");1667 1668 for (i = 0; i < video->attached_count; i++) {1669 video_device = video->attached_array[i].bind_info;1670 if (video_device && video_device->brightness)1671 acpi_video_device_lcd_set_level(video_device,1672 video_device->brightness->curr);1673 }1674 1675 return NOTIFY_OK;1676 }1677 return NOTIFY_DONE;1678}1679 1680static acpi_status1681acpi_video_bus_match(acpi_handle handle, u32 level, void *context,1682 void **return_value)1683{1684 struct acpi_device *device = context;1685 struct acpi_device *sibling;1686 1687 if (handle == device->handle)1688 return AE_CTRL_TERMINATE;1689 1690 sibling = acpi_fetch_acpi_dev(handle);1691 if (!sibling)1692 return AE_OK;1693 1694 if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME))1695 return AE_ALREADY_EXISTS;1696 1697 return AE_OK;1698}1699 1700static void acpi_video_dev_register_backlight(struct acpi_video_device *device)1701{1702 struct backlight_properties props;1703 struct pci_dev *pdev;1704 acpi_handle acpi_parent;1705 struct device *parent = NULL;1706 int result;1707 static int count;1708 char *name;1709 1710 result = acpi_video_init_brightness(device);1711 if (result)1712 return;1713 1714 name = kasprintf(GFP_KERNEL, "acpi_video%d", count);1715 if (!name)1716 return;1717 count++;1718 1719 if (ACPI_SUCCESS(acpi_get_parent(device->dev->handle, &acpi_parent))) {1720 pdev = acpi_get_pci_dev(acpi_parent);1721 if (pdev) {1722 parent = &pdev->dev;1723 pci_dev_put(pdev);1724 }1725 }1726 1727 memset(&props, 0, sizeof(struct backlight_properties));1728 props.type = BACKLIGHT_FIRMWARE;1729 props.max_brightness =1730 device->brightness->count - ACPI_VIDEO_FIRST_LEVEL - 1;1731 device->backlight = backlight_device_register(name,1732 parent,1733 device,1734 &acpi_backlight_ops,1735 &props);1736 kfree(name);1737 if (IS_ERR(device->backlight)) {1738 device->backlight = NULL;1739 return;1740 }1741 1742 /*1743 * Save current brightness level in case we have to restore it1744 * before acpi_video_device_lcd_set_level() is called next time.1745 */1746 device->backlight->props.brightness =1747 acpi_video_get_brightness(device->backlight);1748 1749 device->cooling_dev = thermal_cooling_device_register("LCD", device,1750 &video_cooling_ops);1751 if (IS_ERR(device->cooling_dev)) {1752 /*1753 * Set cooling_dev to NULL so we don't crash trying to free it.1754 * Also, why the hell we are returning early and not attempt to1755 * register video output if cooling device registration failed?1756 * -- dtor1757 */1758 device->cooling_dev = NULL;1759 return;1760 }1761 1762 dev_info(&device->dev->dev, "registered as cooling_device%d\n",1763 device->cooling_dev->id);1764 result = sysfs_create_link(&device->dev->dev.kobj,1765 &device->cooling_dev->device.kobj,1766 "thermal_cooling");1767 if (result)1768 pr_info("sysfs link creation failed\n");1769 1770 result = sysfs_create_link(&device->cooling_dev->device.kobj,1771 &device->dev->dev.kobj, "device");1772 if (result)1773 pr_info("Reverse sysfs link creation failed\n");1774}1775 1776static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video)1777{1778 struct acpi_video_device *dev;1779 union acpi_object *levels;1780 1781 mutex_lock(&video->device_list_lock);1782 list_for_each_entry(dev, &video->video_device_list, entry) {1783 if (!acpi_video_device_lcd_query_levels(dev->dev->handle, &levels))1784 kfree(levels);1785 }1786 mutex_unlock(&video->device_list_lock);1787}1788 1789static bool acpi_video_should_register_backlight(struct acpi_video_device *dev)1790{1791 /*1792 * Do not create backlight device for video output1793 * device that is not in the enumerated list.1794 */1795 if (!acpi_video_device_in_dod(dev)) {1796 dev_dbg(&dev->dev->dev, "not in _DOD list, ignore\n");1797 return false;1798 }1799 1800 if (only_lcd)1801 return dev->flags.lcd;1802 return true;1803}1804 1805static int acpi_video_bus_register_backlight(struct acpi_video_bus *video)1806{1807 struct acpi_video_device *dev;1808 1809 if (video->backlight_registered)1810 return 0;1811 1812 if (acpi_video_get_backlight_type() != acpi_backlight_video)1813 return 0;1814 1815 mutex_lock(&video->device_list_lock);1816 list_for_each_entry(dev, &video->video_device_list, entry) {1817 if (acpi_video_should_register_backlight(dev))1818 acpi_video_dev_register_backlight(dev);1819 }1820 mutex_unlock(&video->device_list_lock);1821 1822 video->backlight_registered = true;1823 1824 video->pm_nb.notifier_call = acpi_video_resume;1825 video->pm_nb.priority = 0;1826 return register_pm_notifier(&video->pm_nb);1827}1828 1829static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device)1830{1831 if (device->backlight) {1832 backlight_device_unregister(device->backlight);1833 device->backlight = NULL;1834 }1835 if (device->brightness) {1836 kfree(device->brightness->levels);1837 kfree(device->brightness);1838 device->brightness = NULL;1839 }1840 if (device->cooling_dev) {1841 sysfs_remove_link(&device->dev->dev.kobj, "thermal_cooling");1842 sysfs_remove_link(&device->cooling_dev->device.kobj, "device");1843 thermal_cooling_device_unregister(device->cooling_dev);1844 device->cooling_dev = NULL;1845 }1846}1847 1848static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video)1849{1850 struct acpi_video_device *dev;1851 int error;1852 1853 if (!video->backlight_registered)1854 return 0;1855 1856 error = unregister_pm_notifier(&video->pm_nb);1857 1858 mutex_lock(&video->device_list_lock);1859 list_for_each_entry(dev, &video->video_device_list, entry)1860 acpi_video_dev_unregister_backlight(dev);1861 mutex_unlock(&video->device_list_lock);1862 1863 video->backlight_registered = false;1864 1865 return error;1866}1867 1868static void acpi_video_dev_add_notify_handler(struct acpi_video_device *device)1869{1870 acpi_status status;1871 struct acpi_device *adev = device->dev;1872 1873 status = acpi_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY,1874 acpi_video_device_notify, device);1875 if (ACPI_FAILURE(status))1876 dev_err(&adev->dev, "Error installing notify handler\n");1877 else1878 device->flags.notify = 1;1879}1880 1881static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video)1882{1883 struct input_dev *input;1884 struct acpi_video_device *dev;1885 int error;1886 1887 video->input = input = input_allocate_device();1888 if (!input) {1889 error = -ENOMEM;1890 goto out;1891 }1892 1893 error = acpi_video_bus_start_devices(video);1894 if (error)1895 goto err_free_input;1896 1897 snprintf(video->phys, sizeof(video->phys),1898 "%s/video/input0", acpi_device_hid(video->device));1899 1900 input->name = acpi_device_name(video->device);1901 input->phys = video->phys;1902 input->id.bustype = BUS_HOST;1903 input->id.product = 0x06;1904 input->dev.parent = &video->device->dev;1905 input->evbit[0] = BIT(EV_KEY);1906 set_bit(KEY_SWITCHVIDEOMODE, input->keybit);1907 set_bit(KEY_VIDEO_NEXT, input->keybit);1908 set_bit(KEY_VIDEO_PREV, input->keybit);1909 set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);1910 set_bit(KEY_BRIGHTNESSUP, input->keybit);1911 set_bit(KEY_BRIGHTNESSDOWN, input->keybit);1912 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);1913 set_bit(KEY_DISPLAY_OFF, input->keybit);1914 1915 error = input_register_device(input);1916 if (error)1917 goto err_stop_dev;1918 1919 mutex_lock(&video->device_list_lock);1920 list_for_each_entry(dev, &video->video_device_list, entry)1921 acpi_video_dev_add_notify_handler(dev);1922 mutex_unlock(&video->device_list_lock);1923 1924 return 0;1925 1926err_stop_dev:1927 acpi_video_bus_stop_devices(video);1928err_free_input:1929 input_free_device(input);1930 video->input = NULL;1931out:1932 return error;1933}1934 1935static void acpi_video_dev_remove_notify_handler(struct acpi_video_device *dev)1936{1937 if (dev->flags.notify) {1938 acpi_remove_notify_handler(dev->dev->handle, ACPI_DEVICE_NOTIFY,1939 acpi_video_device_notify);1940 dev->flags.notify = 0;1941 }1942}1943 1944static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video)1945{1946 struct acpi_video_device *dev;1947 1948 mutex_lock(&video->device_list_lock);1949 list_for_each_entry(dev, &video->video_device_list, entry)1950 acpi_video_dev_remove_notify_handler(dev);1951 mutex_unlock(&video->device_list_lock);1952 1953 acpi_video_bus_stop_devices(video);1954 input_unregister_device(video->input);1955 video->input = NULL;1956}1957 1958static int acpi_video_bus_put_devices(struct acpi_video_bus *video)1959{1960 struct acpi_video_device *dev, *next;1961 1962 mutex_lock(&video->device_list_lock);1963 list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {1964 list_del(&dev->entry);1965 kfree(dev);1966 }1967 mutex_unlock(&video->device_list_lock);1968 1969 return 0;1970}1971 1972static int instance;1973 1974static int acpi_video_bus_add(struct acpi_device *device)1975{1976 struct acpi_video_bus *video;1977 bool auto_detect;1978 int error;1979 acpi_status status;1980 1981 status = acpi_walk_namespace(ACPI_TYPE_DEVICE,1982 acpi_dev_parent(device)->handle, 1,1983 acpi_video_bus_match, NULL,1984 device, NULL);1985 if (status == AE_ALREADY_EXISTS) {1986 pr_info(FW_BUG1987 "Duplicate ACPI video bus devices for the"1988 " same VGA controller, please try module "1989 "parameter \"video.allow_duplicates=1\""1990 "if the current driver doesn't work.\n");1991 if (!allow_duplicates)1992 return -ENODEV;1993 }1994 1995 video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);1996 if (!video)1997 return -ENOMEM;1998 1999 /* a hack to fix the duplicate name "VID" problem on T61 */2000 if (!strcmp(device->pnp.bus_id, "VID")) {2001 if (instance)2002 device->pnp.bus_id[3] = '0' + instance;2003 instance++;2004 }2005 /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */2006 if (!strcmp(device->pnp.bus_id, "VGA")) {2007 if (instance)2008 device->pnp.bus_id[3] = '0' + instance;2009 instance++;2010 }2011 2012 video->device = device;2013 strscpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);2014 strscpy(acpi_device_class(device), ACPI_VIDEO_CLASS);2015 device->driver_data = video;2016 2017 acpi_video_bus_find_cap(video);2018 error = acpi_video_bus_check(video);2019 if (error)2020 goto err_free_video;2021 2022 mutex_init(&video->device_list_lock);2023 INIT_LIST_HEAD(&video->video_device_list);2024 2025 error = acpi_video_bus_get_devices(video, device);2026 if (error)2027 goto err_put_video;2028 2029 /*2030 * HP ZBook Fury 16 G10 requires ACPI video's child devices have _PS02031 * evaluated to have functional panel brightness control.2032 */2033 acpi_device_fix_up_power_children(device);2034 2035 pr_info("%s [%s] (multi-head: %s rom: %s post: %s)\n",2036 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),2037 video->flags.multihead ? "yes" : "no",2038 video->flags.rom ? "yes" : "no",2039 video->flags.post ? "yes" : "no");2040 mutex_lock(&video_list_lock);2041 list_add_tail(&video->entry, &video_bus_head);2042 mutex_unlock(&video_list_lock);2043 2044 /*2045 * If backlight-type auto-detection is used then a native backlight may2046 * show up later and this may change the result from video to native.2047 * Therefor normally the userspace visible /sys/class/backlight device2048 * gets registered separately by the GPU driver calling2049 * acpi_video_register_backlight() when an internal panel is detected.2050 * Register the backlight now when not using auto-detection, so that2051 * when the kernel cmdline or DMI-quirks are used the backlight will2052 * get registered even if acpi_video_register_backlight() is not called.2053 */2054 acpi_video_run_bcl_for_osi(video);2055 if (__acpi_video_get_backlight_type(false, &auto_detect) == acpi_backlight_video &&2056 !auto_detect)2057 acpi_video_bus_register_backlight(video);2058 2059 error = acpi_video_bus_add_notify_handler(video);2060 if (error)2061 goto err_del;2062 2063 error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,2064 acpi_video_bus_notify, device);2065 if (error)2066 goto err_remove;2067 2068 return 0;2069 2070err_remove:2071 acpi_video_bus_remove_notify_handler(video);2072err_del:2073 mutex_lock(&video_list_lock);2074 list_del(&video->entry);2075 mutex_unlock(&video_list_lock);2076 acpi_video_bus_unregister_backlight(video);2077err_put_video:2078 acpi_video_bus_put_devices(video);2079 kfree(video->attached_array);2080err_free_video:2081 kfree(video);2082 device->driver_data = NULL;2083 2084 return error;2085}2086 2087static void acpi_video_bus_remove(struct acpi_device *device)2088{2089 struct acpi_video_bus *video = NULL;2090 2091 2092 if (!device || !acpi_driver_data(device))2093 return;2094 2095 video = acpi_driver_data(device);2096 2097 acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,2098 acpi_video_bus_notify);2099 2100 mutex_lock(&video_list_lock);2101 list_del(&video->entry);2102 mutex_unlock(&video_list_lock);2103 2104 acpi_video_bus_remove_notify_handler(video);2105 acpi_video_bus_unregister_backlight(video);2106 acpi_video_bus_put_devices(video);2107 2108 kfree(video->attached_array);2109 kfree(video);2110}2111 2112static int __init is_i740(struct pci_dev *dev)2113{2114 if (dev->device == 0x00D1)2115 return 1;2116 if (dev->device == 0x7000)2117 return 1;2118 return 0;2119}2120 2121static int __init intel_opregion_present(void)2122{2123 int opregion = 0;2124 struct pci_dev *dev = NULL;2125 u32 address;2126 2127 for_each_pci_dev(dev) {2128 if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)2129 continue;2130 if (dev->vendor != PCI_VENDOR_ID_INTEL)2131 continue;2132 /* We don't want to poke around undefined i740 registers */2133 if (is_i740(dev))2134 continue;2135 pci_read_config_dword(dev, 0xfc, &address);2136 if (!address)2137 continue;2138 opregion = 1;2139 }2140 return opregion;2141}2142 2143int acpi_video_register(void)2144{2145 int ret = 0;2146 2147 mutex_lock(®ister_count_mutex);2148 if (register_count) {2149 /*2150 * if the function of acpi_video_register is already called,2151 * don't register the acpi_video_bus again and return no error.2152 */2153 goto leave;2154 }2155 2156 dmi_check_system(video_dmi_table);2157 2158 ret = acpi_bus_register_driver(&acpi_video_bus);2159 if (ret)2160 goto leave;2161 2162 /*2163 * When the acpi_video_bus is loaded successfully, increase2164 * the counter reference.2165 */2166 register_count = 1;2167 2168leave:2169 mutex_unlock(®ister_count_mutex);2170 return ret;2171}2172EXPORT_SYMBOL(acpi_video_register);2173 2174void acpi_video_unregister(void)2175{2176 mutex_lock(®ister_count_mutex);2177 if (register_count) {2178 acpi_bus_unregister_driver(&acpi_video_bus);2179 register_count = 0;2180 may_report_brightness_keys = false;2181 }2182 mutex_unlock(®ister_count_mutex);2183}2184EXPORT_SYMBOL(acpi_video_unregister);2185 2186void acpi_video_register_backlight(void)2187{2188 struct acpi_video_bus *video;2189 2190 mutex_lock(&video_list_lock);2191 list_for_each_entry(video, &video_bus_head, entry)2192 acpi_video_bus_register_backlight(video);2193 mutex_unlock(&video_list_lock);2194}2195EXPORT_SYMBOL(acpi_video_register_backlight);2196 2197bool acpi_video_handles_brightness_key_presses(void)2198{2199 return may_report_brightness_keys &&2200 (report_key_events & REPORT_BRIGHTNESS_KEY_EVENTS);2201}2202EXPORT_SYMBOL(acpi_video_handles_brightness_key_presses);2203 2204/*2205 * This is kind of nasty. Hardware using Intel chipsets may require2206 * the video opregion code to be run first in order to initialise2207 * state before any ACPI video calls are made. To handle this we defer2208 * registration of the video class until the opregion code has run.2209 */2210 2211static int __init acpi_video_init(void)2212{2213 /*2214 * Let the module load even if ACPI is disabled (e.g. due to2215 * a broken BIOS) so that i915.ko can still be loaded on such2216 * old systems without an AcpiOpRegion.2217 *2218 * acpi_video_register() will report -ENODEV later as well due2219 * to acpi_disabled when i915.ko tries to register itself afterwards.2220 */2221 if (acpi_disabled)2222 return 0;2223 2224 if (intel_opregion_present())2225 return 0;2226 2227 return acpi_video_register();2228}2229 2230static void __exit acpi_video_exit(void)2231{2232 acpi_video_unregister();2233}2234 2235module_init(acpi_video_init);2236module_exit(acpi_video_exit);2237