ACPI: video: Add backlight=native DMI quirk for HP EliteBook 8460p
[linux-block.git] / drivers / acpi / video_detect.c
CommitLineData
c3d6de69 1/*
87521e16
HG
2 * Copyright (C) 2015 Red Hat Inc.
3 * Hans de Goede <hdegoede@redhat.com>
c3d6de69
TR
4 * Copyright (C) 2008 SuSE Linux Products GmbH
5 * Thomas Renninger <trenn@suse.de>
6 *
7 * May be copied or modified under the terms of the GNU General Public License
8 *
9 * video_detect.c:
c3d6de69 10 * After PCI devices are glued with ACPI devices
1e4cffe7 11 * acpi_get_pci_dev() can be called to identify ACPI graphics
c3d6de69
TR
12 * devices for which a real graphics card is plugged in
13 *
c3d6de69
TR
14 * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B)
15 * are available, video.ko should be used to handle the device.
16 *
7ec48ced 17 * Otherwise vendor specific drivers like thinkpad_acpi, asus-laptop,
677bd810 18 * sony_acpi,... can take care about backlight brightness.
c3d6de69 19 *
2600bfa3
HG
20 * Backlight drivers can use acpi_video_get_backlight_type() to determine which
21 * driver should handle the backlight. RAW/GPU-driver backlight drivers must
22 * use the acpi_video_backlight_use_native() helper for this.
c3d6de69 23 *
87521e16
HG
24 * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
25 * this file will not be compiled and acpi_video_get_backlight_type() will
26 * always return acpi_backlight_vendor.
c3d6de69
TR
27 */
28
214f2c90 29#include <linux/export.h>
c3d6de69 30#include <linux/acpi.h>
21245df3 31#include <linux/apple-gmux.h>
87521e16 32#include <linux/backlight.h>
c3d6de69 33#include <linux/dmi.h>
14ca7a47 34#include <linux/module.h>
1e4cffe7 35#include <linux/pci.h>
fe7aebb4 36#include <linux/platform_data/x86/nvidia-wmi-ec-backlight.h>
3cf3b7f0 37#include <linux/pnp.h>
87521e16 38#include <linux/types.h>
7231ed1a 39#include <linux/workqueue.h>
87521e16 40#include <acpi/video.h>
c3d6de69 41
87521e16
HG
42static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef;
43static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef;
c3d6de69 44
14ca7a47
HG
45static void acpi_video_parse_cmdline(void)
46{
47 if (!strcmp("vendor", acpi_video_backlight_string))
87521e16 48 acpi_backlight_cmdline = acpi_backlight_vendor;
14ca7a47 49 if (!strcmp("video", acpi_video_backlight_string))
87521e16
HG
50 acpi_backlight_cmdline = acpi_backlight_video;
51 if (!strcmp("native", acpi_video_backlight_string))
52 acpi_backlight_cmdline = acpi_backlight_native;
420a1116
HG
53 if (!strcmp("nvidia_wmi_ec", acpi_video_backlight_string))
54 acpi_backlight_cmdline = acpi_backlight_nvidia_wmi_ec;
55 if (!strcmp("apple_gmux", acpi_video_backlight_string))
56 acpi_backlight_cmdline = acpi_backlight_apple_gmux;
87521e16
HG
57 if (!strcmp("none", acpi_video_backlight_string))
58 acpi_backlight_cmdline = acpi_backlight_none;
14ca7a47
HG
59}
60
c3d6de69
TR
61static acpi_status
62find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
63{
99ece713 64 struct acpi_device *acpi_dev = acpi_fetch_acpi_dev(handle);
c3d6de69 65 long *cap = context;
1e4cffe7 66 struct pci_dev *dev;
c3d6de69 67
4a4f01a6 68 static const struct acpi_device_id video_ids[] = {
c3d6de69
TR
69 {ACPI_VIDEO_HID, 0},
70 {"", 0},
71 };
c3d6de69 72
99ece713 73 if (acpi_dev && !acpi_match_device_ids(acpi_dev, video_ids)) {
1e4cffe7 74 dev = acpi_get_pci_dev(handle);
c3d6de69
TR
75 if (!dev)
76 return AE_OK;
1e4cffe7 77 pci_dev_put(dev);
d4e1a692 78 *cap |= acpi_is_video_device(handle);
c3d6de69
TR
79 }
80 return AE_OK;
81}
82
fe7aebb4
HG
83/* This depends on ACPI_WMI which is X86 only */
84#ifdef CONFIG_X86
85static bool nvidia_wmi_ec_supported(void)
86{
87 struct wmi_brightness_args args = {
88 .mode = WMI_BRIGHTNESS_MODE_GET,
89 .val = 0,
90 .ret = 0,
91 };
92 struct acpi_buffer buf = { (acpi_size)sizeof(args), &args };
93 acpi_status status;
94
95 status = wmi_evaluate_method(WMI_BRIGHTNESS_GUID, 0,
96 WMI_BRIGHTNESS_METHOD_SOURCE, &buf, &buf);
97 if (ACPI_FAILURE(status))
98 return false;
99
100 /*
101 * If brightness is handled by the EC then nvidia-wmi-ec-backlight
102 * should be used, else the GPU driver(s) should be used.
103 */
104 return args.ret == WMI_BRIGHTNESS_SOURCE_EC;
105}
106#else
107static bool nvidia_wmi_ec_supported(void)
108{
109 return false;
110}
111#endif
112
3cf3b7f0
HG
113static bool apple_gmux_backlight_present(void)
114{
115 struct acpi_device *adev;
116 struct device *dev;
117
118 adev = acpi_dev_get_first_match_dev(GMUX_ACPI_HID, NULL, -1);
119 if (!adev)
120 return false;
121
122 dev = acpi_get_first_physical_node(adev);
123 if (!dev)
124 return false;
125
126 /*
127 * drivers/platform/x86/apple-gmux.c only supports old style
128 * Apple GMUX with an IO-resource.
129 */
130 return pnp_get_resource(to_pnp_dev(dev), IORESOURCE_IO, 0) != NULL;
131}
132
084940d5
CC
133/* Force to use vendor driver when the ACPI device is known to be
134 * buggy */
135static int video_detect_force_vendor(const struct dmi_system_id *d)
136{
87521e16 137 acpi_backlight_dmi = acpi_backlight_vendor;
084940d5
CC
138 return 0;
139}
140
3bd6bce3
HG
141static int video_detect_force_video(const struct dmi_system_id *d)
142{
143 acpi_backlight_dmi = acpi_backlight_video;
144 return 0;
145}
146
147static int video_detect_force_native(const struct dmi_system_id *d)
148{
149 acpi_backlight_dmi = acpi_backlight_native;
150 return 0;
151}
152
1f59ab27
AH
153static int video_detect_force_none(const struct dmi_system_id *d)
154{
155 acpi_backlight_dmi = acpi_backlight_none;
156 return 0;
157}
158
4a4f01a6 159static const struct dmi_system_id video_detect_dmi_table[] = {
84d56f32
HG
160 /*
161 * Models which should use the vendor backlight interface,
162 * because of broken ACPI video backlight control.
163 */
0172df18
HG
164 {
165 /* https://bugzilla.redhat.com/show_bug.cgi?id=1128309 */
166 .callback = video_detect_force_vendor,
167 /* Acer KAV80 */
168 .matches = {
169 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
170 DMI_MATCH(DMI_PRODUCT_NAME, "KAV80"),
171 },
172 },
d0c2ce16 173 {
c2d6920e
HG
174 .callback = video_detect_force_vendor,
175 /* Asus UL30VT */
176 .matches = {
d0c2ce16
LT
177 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
178 DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"),
179 },
180 },
c8f6d835 181 {
c2d6920e
HG
182 .callback = video_detect_force_vendor,
183 /* Asus UL30A */
184 .matches = {
c8f6d835
BT
185 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
186 DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
187 },
188 },
52796b30
HG
189 {
190 .callback = video_detect_force_vendor,
191 /* Asus X55U */
192 .matches = {
193 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
194 DMI_MATCH(DMI_PRODUCT_NAME, "X55U"),
195 },
196 },
197 {
60f1fac2 198 /* https://bugs.launchpad.net/bugs/1000146 */
52796b30
HG
199 .callback = video_detect_force_vendor,
200 /* Asus X101CH */
201 .matches = {
202 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
203 DMI_MATCH(DMI_PRODUCT_NAME, "X101CH"),
204 },
205 },
206 {
207 .callback = video_detect_force_vendor,
208 /* Asus X401U */
209 .matches = {
210 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
211 DMI_MATCH(DMI_PRODUCT_NAME, "X401U"),
212 },
213 },
214 {
215 .callback = video_detect_force_vendor,
216 /* Asus X501U */
217 .matches = {
218 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
219 DMI_MATCH(DMI_PRODUCT_NAME, "X501U"),
220 },
221 },
222 {
60f1fac2 223 /* https://bugs.launchpad.net/bugs/1000146 */
52796b30
HG
224 .callback = video_detect_force_vendor,
225 /* Asus 1015CX */
226 .matches = {
227 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
228 DMI_MATCH(DMI_PRODUCT_NAME, "1015CX"),
229 },
230 },
8991d7d9
HG
231 {
232 .callback = video_detect_force_vendor,
233 /* Samsung N150/N210/N220 */
234 .matches = {
235 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
236 DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"),
237 DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"),
238 },
239 },
240 {
241 .callback = video_detect_force_vendor,
242 /* Samsung NF110/NF210/NF310 */
243 .matches = {
244 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
245 DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"),
246 DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"),
247 },
248 },
249 {
250 .callback = video_detect_force_vendor,
251 /* Samsung NC210 */
252 .matches = {
253 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
254 DMI_MATCH(DMI_PRODUCT_NAME, "NC210/NC110"),
255 DMI_MATCH(DMI_BOARD_NAME, "NC210/NC110"),
256 },
257 },
60e6655f 258 {
c2d6920e
HG
259 .callback = video_detect_force_vendor,
260 /* Xiaomi Mi Pad 2 */
261 .matches = {
60e6655f
HG
262 DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
263 DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
264 },
265 },
3bd6bce3 266
23735543
HG
267 /*
268 * Models which should use the vendor backlight interface,
269 * because of broken native backlight control.
270 */
271 {
272 .callback = video_detect_force_vendor,
273 /* Sony Vaio PCG-FRV35 */
274 .matches = {
275 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
276 DMI_MATCH(DMI_PRODUCT_NAME, "PCG-FRV35"),
277 },
278 },
279
a2ed70d0
HG
280 /*
281 * Toshiba models with Transflective display, these need to use
282 * the toshiba_acpi vendor driver for proper Transflective handling.
283 */
284 {
285 .callback = video_detect_force_vendor,
286 .matches = {
287 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
288 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R500"),
289 },
290 },
291 {
292 .callback = video_detect_force_vendor,
293 .matches = {
294 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
295 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R600"),
296 },
297 },
298
3bd6bce3
HG
299 /*
300 * These models have a working acpi_video backlight control, and using
301 * native backlight causes a regression where backlight does not work
302 * when userspace is not handling brightness key events. Disable
303 * native_backlight on these to fix this:
304 * https://bugzilla.kernel.org/show_bug.cgi?id=81691
305 */
306 {
307 .callback = video_detect_force_video,
3b6740bd 308 /* ThinkPad T420 */
3bd6bce3
HG
309 .matches = {
310 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
311 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T420"),
312 },
313 },
314 {
315 .callback = video_detect_force_video,
3b6740bd 316 /* ThinkPad T520 */
3bd6bce3
HG
317 .matches = {
318 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
319 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T520"),
320 },
321 },
322 {
323 .callback = video_detect_force_video,
3b6740bd 324 /* ThinkPad X201s */
3bd6bce3
HG
325 .matches = {
326 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
327 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"),
328 },
329 },
c6237b21
ML
330 {
331 .callback = video_detect_force_video,
3b6740bd 332 /* ThinkPad X201T */
c6237b21
ML
333 .matches = {
334 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
335 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201T"),
336 },
337 },
3bd6bce3
HG
338
339 /* The native backlight controls do not work on some older machines */
340 {
341 /* https://bugs.freedesktop.org/show_bug.cgi?id=81515 */
342 .callback = video_detect_force_video,
3b6740bd 343 /* HP ENVY 15 Notebook */
3bd6bce3
HG
344 .matches = {
345 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
346 DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"),
347 },
348 },
349 {
350 .callback = video_detect_force_video,
3b6740bd 351 /* SAMSUNG 870Z5E/880Z5E/680Z5E */
3bd6bce3
HG
352 .matches = {
353 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
354 DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"),
355 },
356 },
357 {
358 .callback = video_detect_force_video,
3b6740bd 359 /* SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V */
3bd6bce3
HG
360 .matches = {
361 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
362 DMI_MATCH(DMI_PRODUCT_NAME,
363 "370R4E/370R4V/370R5E/3570RE/370R5V"),
364 },
365 },
366 {
367 /* https://bugzilla.redhat.com/show_bug.cgi?id=1186097 */
368 .callback = video_detect_force_video,
3b6740bd 369 /* SAMSUNG 3570R/370R/470R/450R/510R/4450RV */
3bd6bce3
HG
370 .matches = {
371 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
372 DMI_MATCH(DMI_PRODUCT_NAME,
373 "3570R/370R/470R/450R/510R/4450RV"),
374 },
375 },
bbf03861
HG
376 {
377 /* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */
378 .callback = video_detect_force_video,
3b6740bd 379 /* SAMSUNG 670Z5E */
bbf03861
HG
380 .matches = {
381 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
382 DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"),
383 },
384 },
3bd6bce3
HG
385 {
386 /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */
387 .callback = video_detect_force_video,
3b6740bd 388 /* SAMSUNG 730U3E/740U3E */
3bd6bce3
HG
389 .matches = {
390 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
391 DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"),
392 },
393 },
394 {
395 /* https://bugs.freedesktop.org/show_bug.cgi?id=87286 */
396 .callback = video_detect_force_video,
3b6740bd 397 /* SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D */
3bd6bce3
HG
398 .matches = {
399 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
400 DMI_MATCH(DMI_PRODUCT_NAME,
401 "900X3C/900X3D/900X3E/900X4C/900X4D"),
402 },
403 },
61f9738d
HG
404 {
405 /* https://bugzilla.redhat.com/show_bug.cgi?id=1272633 */
406 .callback = video_detect_force_video,
3b6740bd 407 /* Dell XPS14 L421X */
61f9738d
HG
408 .matches = {
409 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
410 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"),
411 },
412 },
3bd6bce3
HG
413 {
414 /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */
415 .callback = video_detect_force_video,
3b6740bd 416 /* Dell XPS15 L521X */
3bd6bce3
HG
417 .matches = {
418 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
419 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"),
420 },
421 },
49eb5208
AL
422 {
423 /* https://bugzilla.kernel.org/show_bug.cgi?id=108971 */
424 .callback = video_detect_force_video,
3b6740bd 425 /* SAMSUNG 530U4E/540U4E */
49eb5208
AL
426 .matches = {
427 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
428 DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"),
429 },
430 },
b226faab 431 {
60f1fac2 432 /* https://bugs.launchpad.net/bugs/1894667 */
b226faab 433 .callback = video_detect_force_video,
3b6740bd 434 /* HP 635 Notebook */
b226faab
AH
435 .matches = {
436 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
437 DMI_MATCH(DMI_PRODUCT_NAME, "HP 635 Notebook PC"),
438 },
439 },
3bd6bce3
HG
440
441 /* Non win8 machines which need native backlight nevertheless */
584d8d1e
HG
442 {
443 /* https://bugzilla.redhat.com/show_bug.cgi?id=1201530 */
444 .callback = video_detect_force_native,
3b6740bd 445 /* Lenovo Ideapad S405 */
584d8d1e
HG
446 .matches = {
447 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
448 DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"),
449 },
450 },
3bd6bce3
HG
451 {
452 /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */
453 .callback = video_detect_force_native,
3b6740bd 454 /* Lenovo Ideapad Z570 */
3bd6bce3
HG
455 .matches = {
456 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
457 DMI_MATCH(DMI_PRODUCT_NAME, "102434U"),
458 },
459 },
53870cf0
AM
460 {
461 .callback = video_detect_force_native,
3b6740bd 462 /* Lenovo E41-25 */
53870cf0
AM
463 .matches = {
464 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
465 DMI_MATCH(DMI_PRODUCT_NAME, "81FS"),
466 },
467 },
468 {
469 .callback = video_detect_force_native,
3b6740bd 470 /* Lenovo E41-45 */
53870cf0
AM
471 .matches = {
472 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
473 DMI_MATCH(DMI_PRODUCT_NAME, "82BK"),
474 },
475 },
3bd6bce3
HG
476 {
477 /* https://bugzilla.redhat.com/show_bug.cgi?id=1217249 */
478 .callback = video_detect_force_native,
3b6740bd 479 /* Apple MacBook Pro 12,1 */
3bd6bce3
HG
480 .matches = {
481 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
482 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"),
483 },
484 },
03c440a2
HG
485 {
486 .callback = video_detect_force_native,
487 /* Dell Inspiron N4010 */
488 .matches = {
489 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
490 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron N4010"),
491 },
492 },
4b4b3b20
HG
493 {
494 .callback = video_detect_force_native,
3b6740bd 495 /* Dell Vostro V131 */
4b4b3b20
HG
496 .matches = {
497 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
498 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
499 },
500 },
350fa038
HG
501 {
502 /* https://bugzilla.redhat.com/show_bug.cgi?id=1123661 */
503 .callback = video_detect_force_native,
3b6740bd 504 /* Dell XPS 17 L702X */
350fa038
HG
505 .matches = {
506 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
507 DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"),
508 },
509 },
d37efb79
SYLF
510 {
511 .callback = video_detect_force_native,
3b6740bd 512 /* Dell Precision 7510 */
d37efb79
SYLF
513 .matches = {
514 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
515 DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"),
516 },
517 },
8ba5fc4c
HG
518 {
519 .callback = video_detect_force_native,
520 /* Acer Aspire 4810T */
521 .matches = {
522 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
523 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 4810T"),
524 },
525 },
1c8fbc1f
HG
526 {
527 .callback = video_detect_force_native,
3b6740bd 528 /* Acer Aspire 5738z */
1c8fbc1f
HG
529 .matches = {
530 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
531 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"),
532 DMI_MATCH(DMI_BOARD_NAME, "JV50"),
533 },
534 },
0172df18
HG
535 {
536 /* https://bugzilla.redhat.com/show_bug.cgi?id=1012674 */
537 .callback = video_detect_force_native,
538 /* Acer Aspire 5741 */
539 .matches = {
540 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
541 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5741"),
542 },
543 },
544 {
545 /* https://bugzilla.kernel.org/show_bug.cgi?id=42993 */
546 .callback = video_detect_force_native,
547 /* Acer Aspire 5750 */
548 .matches = {
549 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
550 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"),
551 },
552 },
553 {
554 /* https://bugzilla.kernel.org/show_bug.cgi?id=42833 */
555 .callback = video_detect_force_native,
556 /* Acer Extensa 5235 */
557 .matches = {
558 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
559 DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5235"),
560 },
561 },
562 {
563 .callback = video_detect_force_native,
564 /* Acer TravelMate 4750 */
565 .matches = {
566 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
567 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4750"),
568 },
569 },
c41c36e9
PM
570 {
571 /* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */
572 .callback = video_detect_force_native,
3b6740bd 573 /* Acer TravelMate 5735Z */
c41c36e9
PM
574 .matches = {
575 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
576 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5735Z"),
577 DMI_MATCH(DMI_BOARD_NAME, "BA51_MV"),
578 },
579 },
0172df18
HG
580 {
581 /* https://bugzilla.kernel.org/show_bug.cgi?id=36322 */
582 .callback = video_detect_force_native,
583 /* Acer TravelMate 5760 */
584 .matches = {
585 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
586 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5760"),
587 },
588 },
2dfbacc6 589 {
c2d6920e
HG
590 .callback = video_detect_force_native,
591 /* ASUSTeK COMPUTER INC. GA401 */
592 .matches = {
2dfbacc6
LJ
593 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
594 DMI_MATCH(DMI_PRODUCT_NAME, "GA401"),
595 },
596 },
597 {
c2d6920e
HG
598 .callback = video_detect_force_native,
599 /* ASUSTeK COMPUTER INC. GA502 */
600 .matches = {
2dfbacc6
LJ
601 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
602 DMI_MATCH(DMI_PRODUCT_NAME, "GA502"),
603 },
604 },
605 {
c2d6920e
HG
606 .callback = video_detect_force_native,
607 /* ASUSTeK COMPUTER INC. GA503 */
608 .matches = {
2dfbacc6
LJ
609 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
610 DMI_MATCH(DMI_PRODUCT_NAME, "GA503"),
611 },
612 },
1e3344d6
HG
613 {
614 .callback = video_detect_force_native,
615 /* Asus UX303UB */
616 .matches = {
617 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
618 DMI_MATCH(DMI_PRODUCT_NAME, "UX303UB"),
619 },
620 },
9dcb3423
HG
621 {
622 .callback = video_detect_force_native,
623 /* HP EliteBook 8460p */
624 .matches = {
625 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
626 DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8460p"),
627 },
628 },
d77596d4
HG
629 {
630 .callback = video_detect_force_native,
631 /* HP Pavilion g6-1d80nr / B4U19UA */
632 .matches = {
633 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
634 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion g6 Notebook PC"),
635 DMI_MATCH(DMI_PRODUCT_SKU, "B4U19UA"),
636 },
637 },
8991d7d9
HG
638 {
639 .callback = video_detect_force_native,
640 /* Samsung N150P */
641 .matches = {
642 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
643 DMI_MATCH(DMI_PRODUCT_NAME, "N150P"),
644 DMI_MATCH(DMI_BOARD_NAME, "N150P"),
645 },
646 },
647 {
648 .callback = video_detect_force_native,
649 /* Samsung N145P/N250P/N260P */
650 .matches = {
651 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
652 DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"),
653 DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"),
654 },
655 },
656 {
657 .callback = video_detect_force_native,
658 /* Samsung N250P */
659 .matches = {
660 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
661 DMI_MATCH(DMI_PRODUCT_NAME, "N250P"),
662 DMI_MATCH(DMI_BOARD_NAME, "N250P"),
663 },
664 },
84d56f32
HG
665 {
666 /* https://bugzilla.kernel.org/show_bug.cgi?id=202401 */
667 .callback = video_detect_force_native,
668 /* Sony Vaio VPCEH3U1E */
669 .matches = {
670 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
671 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
672 },
673 },
f5a6ff92
HG
674 {
675 .callback = video_detect_force_native,
676 /* Sony Vaio VPCY11S1E */
677 .matches = {
678 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
679 DMI_MATCH(DMI_PRODUCT_NAME, "VPCY11S1E"),
680 },
681 },
10212754 682
c5b94f5b
HG
683 /*
684 * These Toshibas have a broken acpi-video interface for brightness
685 * control. They also have an issue where the panel is off after
686 * suspend until a special firmware call is made to turn it back
687 * on. This is handled by the toshiba_acpi kernel module, so that
688 * module must be enabled for these models to work correctly.
689 */
690 {
691 /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
692 .callback = video_detect_force_native,
693 /* Toshiba Portégé R700 */
694 .matches = {
695 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
696 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"),
697 },
698 },
699 {
700 /* Portégé: https://bugs.freedesktop.org/show_bug.cgi?id=82634 */
701 /* Satellite: https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
702 .callback = video_detect_force_native,
703 /* Toshiba Satellite/Portégé R830 */
704 .matches = {
705 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
706 DMI_MATCH(DMI_PRODUCT_NAME, "R830"),
707 },
708 },
709 {
710 .callback = video_detect_force_native,
711 /* Toshiba Satellite/Portégé Z830 */
712 .matches = {
713 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
714 DMI_MATCH(DMI_PRODUCT_NAME, "Z830"),
715 },
716 },
717
f46acc1e
HG
718 /*
719 * Models which have nvidia-ec-wmi support, but should not use it.
720 * Note this indicates a likely firmware bug on these models and should
721 * be revisited if/when Linux gets support for dynamic mux mode.
722 */
723 {
724 .callback = video_detect_force_native,
725 /* Dell G15 5515 */
726 .matches = {
727 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
728 DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
729 },
730 },
731
d21a9162
HG
732 /*
733 * Desktops which falsely report a backlight and which our heuristics
734 * for this do not catch.
735 */
1f59ab27
AH
736 {
737 .callback = video_detect_force_none,
3b6740bd 738 /* Dell OptiPlex 9020M */
1f59ab27
AH
739 .matches = {
740 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
741 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"),
742 },
743 },
9f7dd272
HG
744 {
745 .callback = video_detect_force_none,
746 /* GIGABYTE GB-BXBT-2807 */
747 .matches = {
748 DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
749 DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
750 },
751 },
d21a9162
HG
752 {
753 .callback = video_detect_force_none,
3b6740bd 754 /* MSI MS-7721 */
d21a9162
HG
755 .matches = {
756 DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
757 DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"),
758 },
759 },
084940d5
CC
760 { },
761};
762
e9cf4d9b
DO
763static bool google_cros_ec_present(void)
764{
59dc2a7e 765 return acpi_dev_found("GOOG0004") || acpi_dev_found("GOOG000C");
e9cf4d9b
DO
766}
767
a5df4252
HG
768/*
769 * Windows 8 and newer no longer use the ACPI video interface, so it often
770 * does not work. So on win8+ systems prefer native brightness control.
771 * Chromebooks should always prefer native backlight control.
772 */
773static bool prefer_native_over_acpi_video(void)
774{
775 return acpi_osi_is_win8() || google_cros_ec_present();
776}
777
c3d6de69 778/*
87521e16
HG
779 * Determine which type of backlight interface to use on this system,
780 * First check cmdline, then dmi quirks, then do autodetect.
c3d6de69 781 */
2600bfa3 782static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
c3d6de69 783{
87521e16 784 static DEFINE_MUTEX(init_mutex);
fe7aebb4 785 static bool nvidia_wmi_ec_present;
2600bfa3 786 static bool native_available;
87521e16
HG
787 static bool init_done;
788 static long video_caps;
084940d5 789
87521e16
HG
790 /* Parse cmdline, dmi and acpi only once */
791 mutex_lock(&init_mutex);
792 if (!init_done) {
793 acpi_video_parse_cmdline();
084940d5 794 dmi_check_system(video_detect_dmi_table);
87521e16 795 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
2263576c 796 ACPI_UINT32_MAX, find_video, NULL,
87521e16 797 &video_caps, NULL);
fe7aebb4 798 nvidia_wmi_ec_present = nvidia_wmi_ec_supported();
87521e16 799 init_done = true;
c3d6de69 800 }
2600bfa3
HG
801 if (native)
802 native_available = true;
87521e16
HG
803 mutex_unlock(&init_mutex);
804
b39be9f4
HG
805 /*
806 * The below heuristics / detection steps are in order of descending
807 * presedence. The commandline takes presedence over anything else.
808 */
87521e16
HG
809 if (acpi_backlight_cmdline != acpi_backlight_undef)
810 return acpi_backlight_cmdline;
811
b39be9f4 812 /* DMI quirks override any autodetection. */
87521e16
HG
813 if (acpi_backlight_dmi != acpi_backlight_undef)
814 return acpi_backlight_dmi;
815
fe7aebb4
HG
816 /* Special cases such as nvidia_wmi_ec and apple gmux. */
817 if (nvidia_wmi_ec_present)
818 return acpi_backlight_nvidia_wmi_ec;
819
3cf3b7f0 820 if (apple_gmux_backlight_present())
21245df3
HG
821 return acpi_backlight_apple_gmux;
822
a5df4252
HG
823 /* Use ACPI video if available, except when native should be preferred. */
824 if ((video_caps & ACPI_VIDEO_BACKLIGHT) &&
825 !(native_available && prefer_native_over_acpi_video()))
826 return acpi_backlight_video;
59dc2a7e 827
a5df4252 828 /* Use native if available */
fb1836c9 829 if (native_available)
a5df4252 830 return acpi_backlight_native;
87521e16 831
fb1836c9 832 /* No ACPI video/native (old hw), use vendor specific fw methods. */
b39be9f4 833 return acpi_backlight_vendor;
c3d6de69 834}
2600bfa3
HG
835
836enum acpi_backlight_type acpi_video_get_backlight_type(void)
837{
838 return __acpi_video_get_backlight_type(false);
839}
87521e16 840EXPORT_SYMBOL(acpi_video_get_backlight_type);
c3d6de69 841
2600bfa3
HG
842bool acpi_video_backlight_use_native(void)
843{
fb1836c9 844 return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
2600bfa3
HG
845}
846EXPORT_SYMBOL(acpi_video_backlight_use_native);