platform/x86: apple-gmux: Stop calling acpi/video.h functions
[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>
87521e16 37#include <linux/types.h>
7231ed1a 38#include <linux/workqueue.h>
87521e16 39#include <acpi/video.h>
c3d6de69 40
e7d024c0
HG
41void acpi_video_unregister_backlight(void);
42
87521e16
HG
43static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef;
44static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef;
c3d6de69 45
14ca7a47
HG
46static void acpi_video_parse_cmdline(void)
47{
48 if (!strcmp("vendor", acpi_video_backlight_string))
87521e16 49 acpi_backlight_cmdline = acpi_backlight_vendor;
14ca7a47 50 if (!strcmp("video", acpi_video_backlight_string))
87521e16
HG
51 acpi_backlight_cmdline = acpi_backlight_video;
52 if (!strcmp("native", acpi_video_backlight_string))
53 acpi_backlight_cmdline = acpi_backlight_native;
54 if (!strcmp("none", acpi_video_backlight_string))
55 acpi_backlight_cmdline = acpi_backlight_none;
14ca7a47
HG
56}
57
c3d6de69
TR
58static acpi_status
59find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
60{
99ece713 61 struct acpi_device *acpi_dev = acpi_fetch_acpi_dev(handle);
c3d6de69 62 long *cap = context;
1e4cffe7 63 struct pci_dev *dev;
c3d6de69 64
4a4f01a6 65 static const struct acpi_device_id video_ids[] = {
c3d6de69
TR
66 {ACPI_VIDEO_HID, 0},
67 {"", 0},
68 };
c3d6de69 69
99ece713 70 if (acpi_dev && !acpi_match_device_ids(acpi_dev, video_ids)) {
1e4cffe7 71 dev = acpi_get_pci_dev(handle);
c3d6de69
TR
72 if (!dev)
73 return AE_OK;
1e4cffe7 74 pci_dev_put(dev);
d4e1a692 75 *cap |= acpi_is_video_device(handle);
c3d6de69
TR
76 }
77 return AE_OK;
78}
79
fe7aebb4
HG
80/* This depends on ACPI_WMI which is X86 only */
81#ifdef CONFIG_X86
82static bool nvidia_wmi_ec_supported(void)
83{
84 struct wmi_brightness_args args = {
85 .mode = WMI_BRIGHTNESS_MODE_GET,
86 .val = 0,
87 .ret = 0,
88 };
89 struct acpi_buffer buf = { (acpi_size)sizeof(args), &args };
90 acpi_status status;
91
92 status = wmi_evaluate_method(WMI_BRIGHTNESS_GUID, 0,
93 WMI_BRIGHTNESS_METHOD_SOURCE, &buf, &buf);
94 if (ACPI_FAILURE(status))
95 return false;
96
97 /*
98 * If brightness is handled by the EC then nvidia-wmi-ec-backlight
99 * should be used, else the GPU driver(s) should be used.
100 */
101 return args.ret == WMI_BRIGHTNESS_SOURCE_EC;
102}
103#else
104static bool nvidia_wmi_ec_supported(void)
105{
106 return false;
107}
108#endif
109
084940d5
CC
110/* Force to use vendor driver when the ACPI device is known to be
111 * buggy */
112static int video_detect_force_vendor(const struct dmi_system_id *d)
113{
87521e16 114 acpi_backlight_dmi = acpi_backlight_vendor;
084940d5
CC
115 return 0;
116}
117
3bd6bce3
HG
118static int video_detect_force_video(const struct dmi_system_id *d)
119{
120 acpi_backlight_dmi = acpi_backlight_video;
121 return 0;
122}
123
124static int video_detect_force_native(const struct dmi_system_id *d)
125{
126 acpi_backlight_dmi = acpi_backlight_native;
127 return 0;
128}
129
1f59ab27
AH
130static int video_detect_force_none(const struct dmi_system_id *d)
131{
132 acpi_backlight_dmi = acpi_backlight_none;
133 return 0;
134}
135
4a4f01a6 136static const struct dmi_system_id video_detect_dmi_table[] = {
084940d5
CC
137 /* On Samsung X360, the BIOS will set a flag (VDRV) if generic
138 * ACPI backlight device is used. This flag will definitively break
603fadf3 139 * the backlight interface (even the vendor interface) until next
084940d5
CC
140 * reboot. It's why we should prevent video.ko from being used here
141 * and we can't rely on a later call to acpi_video_unregister().
142 */
143 {
144 .callback = video_detect_force_vendor,
3b6740bd 145 /* X360 */
084940d5
CC
146 .matches = {
147 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
148 DMI_MATCH(DMI_PRODUCT_NAME, "X360"),
149 DMI_MATCH(DMI_BOARD_NAME, "X360"),
150 },
151 },
d0c2ce16
LT
152 {
153 .callback = video_detect_force_vendor,
3b6740bd 154 /* Asus UL30VT */
d0c2ce16
LT
155 .matches = {
156 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
157 DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"),
158 },
159 },
c8f6d835
BT
160 {
161 .callback = video_detect_force_vendor,
3b6740bd 162 /* Asus UL30A */
c8f6d835
BT
163 .matches = {
164 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
165 DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
166 },
167 },
aefa763b
ZR
168 {
169 .callback = video_detect_force_vendor,
3b6740bd 170 /* GIGABYTE GB-BXBT-2807 */
25417185
JSP
171 .matches = {
172 DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
173 DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
174 },
175 },
176 {
c1d1e25a 177 .callback = video_detect_force_vendor,
3b6740bd 178 /* Sony VPCEH3U1E */
aefa763b
ZR
179 .matches = {
180 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
181 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
182 },
183 },
60e6655f
HG
184 {
185 .callback = video_detect_force_vendor,
186 /* Xiaomi Mi Pad 2 */
187 .matches = {
188 DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
189 DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
190 },
191 },
3bd6bce3
HG
192
193 /*
194 * These models have a working acpi_video backlight control, and using
195 * native backlight causes a regression where backlight does not work
196 * when userspace is not handling brightness key events. Disable
197 * native_backlight on these to fix this:
198 * https://bugzilla.kernel.org/show_bug.cgi?id=81691
199 */
200 {
201 .callback = video_detect_force_video,
3b6740bd 202 /* ThinkPad T420 */
3bd6bce3
HG
203 .matches = {
204 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
205 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T420"),
206 },
207 },
208 {
209 .callback = video_detect_force_video,
3b6740bd 210 /* ThinkPad T520 */
3bd6bce3
HG
211 .matches = {
212 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
213 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T520"),
214 },
215 },
216 {
217 .callback = video_detect_force_video,
3b6740bd 218 /* ThinkPad X201s */
3bd6bce3
HG
219 .matches = {
220 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
221 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"),
222 },
223 },
c6237b21
ML
224 {
225 .callback = video_detect_force_video,
3b6740bd 226 /* ThinkPad X201T */
c6237b21
ML
227 .matches = {
228 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
229 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201T"),
230 },
231 },
3bd6bce3
HG
232
233 /* The native backlight controls do not work on some older machines */
234 {
235 /* https://bugs.freedesktop.org/show_bug.cgi?id=81515 */
236 .callback = video_detect_force_video,
3b6740bd 237 /* HP ENVY 15 Notebook */
3bd6bce3
HG
238 .matches = {
239 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
240 DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"),
241 },
242 },
243 {
244 .callback = video_detect_force_video,
3b6740bd 245 /* SAMSUNG 870Z5E/880Z5E/680Z5E */
3bd6bce3
HG
246 .matches = {
247 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
248 DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"),
249 },
250 },
251 {
252 .callback = video_detect_force_video,
3b6740bd 253 /* SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V */
3bd6bce3
HG
254 .matches = {
255 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
256 DMI_MATCH(DMI_PRODUCT_NAME,
257 "370R4E/370R4V/370R5E/3570RE/370R5V"),
258 },
259 },
260 {
261 /* https://bugzilla.redhat.com/show_bug.cgi?id=1186097 */
262 .callback = video_detect_force_video,
3b6740bd 263 /* SAMSUNG 3570R/370R/470R/450R/510R/4450RV */
3bd6bce3
HG
264 .matches = {
265 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
266 DMI_MATCH(DMI_PRODUCT_NAME,
267 "3570R/370R/470R/450R/510R/4450RV"),
268 },
269 },
bbf03861
HG
270 {
271 /* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */
272 .callback = video_detect_force_video,
3b6740bd 273 /* SAMSUNG 670Z5E */
bbf03861
HG
274 .matches = {
275 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
276 DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"),
277 },
278 },
3bd6bce3
HG
279 {
280 /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */
281 .callback = video_detect_force_video,
3b6740bd 282 /* SAMSUNG 730U3E/740U3E */
3bd6bce3
HG
283 .matches = {
284 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
285 DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"),
286 },
287 },
288 {
289 /* https://bugs.freedesktop.org/show_bug.cgi?id=87286 */
290 .callback = video_detect_force_video,
3b6740bd 291 /* SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D */
3bd6bce3
HG
292 .matches = {
293 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
294 DMI_MATCH(DMI_PRODUCT_NAME,
295 "900X3C/900X3D/900X3E/900X4C/900X4D"),
296 },
297 },
61f9738d
HG
298 {
299 /* https://bugzilla.redhat.com/show_bug.cgi?id=1272633 */
300 .callback = video_detect_force_video,
3b6740bd 301 /* Dell XPS14 L421X */
61f9738d
HG
302 .matches = {
303 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
304 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"),
305 },
306 },
3bd6bce3
HG
307 {
308 /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */
309 .callback = video_detect_force_video,
3b6740bd 310 /* Dell XPS15 L521X */
3bd6bce3
HG
311 .matches = {
312 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
313 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"),
314 },
315 },
49eb5208
AL
316 {
317 /* https://bugzilla.kernel.org/show_bug.cgi?id=108971 */
318 .callback = video_detect_force_video,
3b6740bd 319 /* SAMSUNG 530U4E/540U4E */
49eb5208
AL
320 .matches = {
321 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
322 DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"),
323 },
324 },
b226faab
AH
325 /* https://bugs.launchpad.net/bugs/1894667 */
326 {
327 .callback = video_detect_force_video,
3b6740bd 328 /* HP 635 Notebook */
b226faab
AH
329 .matches = {
330 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
331 DMI_MATCH(DMI_PRODUCT_NAME, "HP 635 Notebook PC"),
332 },
333 },
3bd6bce3
HG
334
335 /* Non win8 machines which need native backlight nevertheless */
584d8d1e
HG
336 {
337 /* https://bugzilla.redhat.com/show_bug.cgi?id=1201530 */
338 .callback = video_detect_force_native,
3b6740bd 339 /* Lenovo Ideapad S405 */
584d8d1e
HG
340 .matches = {
341 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
342 DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"),
343 },
344 },
3bd6bce3
HG
345 {
346 /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */
347 .callback = video_detect_force_native,
3b6740bd 348 /* Lenovo Ideapad Z570 */
3bd6bce3
HG
349 .matches = {
350 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
351 DMI_MATCH(DMI_PRODUCT_NAME, "102434U"),
352 },
353 },
53870cf0
AM
354 {
355 .callback = video_detect_force_native,
3b6740bd 356 /* Lenovo E41-25 */
53870cf0
AM
357 .matches = {
358 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
359 DMI_MATCH(DMI_PRODUCT_NAME, "81FS"),
360 },
361 },
362 {
363 .callback = video_detect_force_native,
3b6740bd 364 /* Lenovo E41-45 */
53870cf0
AM
365 .matches = {
366 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
367 DMI_MATCH(DMI_PRODUCT_NAME, "82BK"),
368 },
369 },
3bd6bce3
HG
370 {
371 /* https://bugzilla.redhat.com/show_bug.cgi?id=1217249 */
372 .callback = video_detect_force_native,
3b6740bd 373 /* Apple MacBook Pro 12,1 */
3bd6bce3
HG
374 .matches = {
375 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
376 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"),
377 },
378 },
03c440a2
HG
379 {
380 .callback = video_detect_force_native,
381 /* Dell Inspiron N4010 */
382 .matches = {
383 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
384 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron N4010"),
385 },
386 },
4b4b3b20
HG
387 {
388 .callback = video_detect_force_native,
3b6740bd 389 /* Dell Vostro V131 */
4b4b3b20
HG
390 .matches = {
391 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
392 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
393 },
394 },
350fa038
HG
395 {
396 /* https://bugzilla.redhat.com/show_bug.cgi?id=1123661 */
397 .callback = video_detect_force_native,
3b6740bd 398 /* Dell XPS 17 L702X */
350fa038
HG
399 .matches = {
400 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
401 DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"),
402 },
403 },
d37efb79
SYLF
404 {
405 .callback = video_detect_force_native,
3b6740bd 406 /* Dell Precision 7510 */
d37efb79
SYLF
407 .matches = {
408 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
409 DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"),
410 },
411 },
1c8fbc1f
HG
412 {
413 .callback = video_detect_force_native,
3b6740bd 414 /* Acer Aspire 5738z */
1c8fbc1f
HG
415 .matches = {
416 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
417 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"),
418 DMI_MATCH(DMI_BOARD_NAME, "JV50"),
419 },
420 },
c41c36e9
PM
421 {
422 /* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */
423 .callback = video_detect_force_native,
3b6740bd 424 /* Acer TravelMate 5735Z */
c41c36e9
PM
425 .matches = {
426 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
427 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5735Z"),
428 DMI_MATCH(DMI_BOARD_NAME, "BA51_MV"),
429 },
430 },
2dfbacc6
LJ
431 {
432 .callback = video_detect_force_native,
3b6740bd 433 /* ASUSTeK COMPUTER INC. GA401 */
2dfbacc6
LJ
434 .matches = {
435 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
436 DMI_MATCH(DMI_PRODUCT_NAME, "GA401"),
437 },
438 },
439 {
440 .callback = video_detect_force_native,
3b6740bd 441 /* ASUSTeK COMPUTER INC. GA502 */
2dfbacc6
LJ
442 .matches = {
443 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
444 DMI_MATCH(DMI_PRODUCT_NAME, "GA502"),
445 },
446 },
447 {
448 .callback = video_detect_force_native,
3b6740bd 449 /* ASUSTeK COMPUTER INC. GA503 */
2dfbacc6
LJ
450 .matches = {
451 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
452 DMI_MATCH(DMI_PRODUCT_NAME, "GA503"),
453 },
454 },
c844d22f
WS
455 /*
456 * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a
457 * working native and video interface. However the default detection
458 * mechanism first registers the video interface before unregistering
459 * it again and switching to the native interface during boot. This
460 * results in a dangling SBIOS request for backlight change for some
461 * reason, causing the backlight to switch to ~2% once per boot on the
462 * first power cord connect or disconnect event. Setting the native
463 * interface explicitly circumvents this buggy behaviour, by avoiding
464 * the unregistering process.
465 */
466 {
467 .callback = video_detect_force_native,
468 .ident = "Clevo NL5xRU",
469 .matches = {
c844d22f
WS
470 DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
471 },
472 },
473 {
474 .callback = video_detect_force_native,
475 .ident = "Clevo NL5xRU",
476 .matches = {
477 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
478 DMI_MATCH(DMI_BOARD_NAME, "AURA1501"),
479 },
480 },
481 {
482 .callback = video_detect_force_native,
483 .ident = "Clevo NL5xRU",
484 .matches = {
485 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
486 DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"),
487 },
488 },
489 {
490 .callback = video_detect_force_native,
491 .ident = "Clevo NL5xNU",
492 .matches = {
c844d22f
WS
493 DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
494 },
495 },
c752089f
WS
496 /*
497 * The TongFang PF5PU1G, PF4NU1F, PF5NU1G, and PF5LUXG/TUXEDO BA15 Gen10,
498 * Pulse 14/15 Gen1, and Pulse 15 Gen2 have the same problem as the Clevo
499 * NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description
500 * above.
501 */
502 {
503 .callback = video_detect_force_native,
504 .ident = "TongFang PF5PU1G",
505 .matches = {
506 DMI_MATCH(DMI_BOARD_NAME, "PF5PU1G"),
507 },
508 },
509 {
510 .callback = video_detect_force_native,
511 .ident = "TongFang PF4NU1F",
512 .matches = {
513 DMI_MATCH(DMI_BOARD_NAME, "PF4NU1F"),
514 },
515 },
516 {
517 .callback = video_detect_force_native,
518 .ident = "TongFang PF4NU1F",
519 .matches = {
520 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
521 DMI_MATCH(DMI_BOARD_NAME, "PULSE1401"),
522 },
523 },
524 {
525 .callback = video_detect_force_native,
526 .ident = "TongFang PF5NU1G",
527 .matches = {
528 DMI_MATCH(DMI_BOARD_NAME, "PF5NU1G"),
529 },
530 },
531 {
532 .callback = video_detect_force_native,
533 .ident = "TongFang PF5NU1G",
534 .matches = {
535 DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
536 DMI_MATCH(DMI_BOARD_NAME, "PULSE1501"),
537 },
538 },
539 {
540 .callback = video_detect_force_native,
541 .ident = "TongFang PF5LUXG",
542 .matches = {
543 DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"),
544 },
545 },
d21a9162
HG
546 /*
547 * Desktops which falsely report a backlight and which our heuristics
548 * for this do not catch.
549 */
1f59ab27
AH
550 {
551 .callback = video_detect_force_none,
3b6740bd 552 /* Dell OptiPlex 9020M */
1f59ab27
AH
553 .matches = {
554 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
555 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"),
556 },
557 },
d21a9162
HG
558 {
559 .callback = video_detect_force_none,
3b6740bd 560 /* MSI MS-7721 */
d21a9162
HG
561 .matches = {
562 DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
563 DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"),
564 },
565 },
084940d5
CC
566 { },
567};
568
c3d6de69 569/*
87521e16
HG
570 * Determine which type of backlight interface to use on this system,
571 * First check cmdline, then dmi quirks, then do autodetect.
c3d6de69 572 */
2600bfa3 573static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
c3d6de69 574{
87521e16 575 static DEFINE_MUTEX(init_mutex);
fe7aebb4 576 static bool nvidia_wmi_ec_present;
2600bfa3 577 static bool native_available;
87521e16
HG
578 static bool init_done;
579 static long video_caps;
084940d5 580
87521e16
HG
581 /* Parse cmdline, dmi and acpi only once */
582 mutex_lock(&init_mutex);
583 if (!init_done) {
584 acpi_video_parse_cmdline();
084940d5 585 dmi_check_system(video_detect_dmi_table);
87521e16 586 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
2263576c 587 ACPI_UINT32_MAX, find_video, NULL,
87521e16 588 &video_caps, NULL);
fe7aebb4 589 nvidia_wmi_ec_present = nvidia_wmi_ec_supported();
87521e16 590 init_done = true;
c3d6de69 591 }
2600bfa3
HG
592 if (native)
593 native_available = true;
87521e16
HG
594 mutex_unlock(&init_mutex);
595
b39be9f4
HG
596 /*
597 * The below heuristics / detection steps are in order of descending
598 * presedence. The commandline takes presedence over anything else.
599 */
87521e16
HG
600 if (acpi_backlight_cmdline != acpi_backlight_undef)
601 return acpi_backlight_cmdline;
602
b39be9f4 603 /* DMI quirks override any autodetection. */
87521e16
HG
604 if (acpi_backlight_dmi != acpi_backlight_undef)
605 return acpi_backlight_dmi;
606
fe7aebb4
HG
607 /* Special cases such as nvidia_wmi_ec and apple gmux. */
608 if (nvidia_wmi_ec_present)
609 return acpi_backlight_nvidia_wmi_ec;
610
21245df3
HG
611 if (apple_gmux_present())
612 return acpi_backlight_apple_gmux;
613
b39be9f4
HG
614 /* On systems with ACPI video use either native or ACPI video. */
615 if (video_caps & ACPI_VIDEO_BACKLIGHT) {
616 /*
617 * Windows 8 and newer no longer use the ACPI video interface,
618 * so it often does not work. If the ACPI tables are written
619 * for win8 and native brightness ctl is available, use that.
620 *
621 * The native check deliberately is inside the if acpi-video
622 * block on older devices without acpi-video support native
623 * is usually not the best choice.
624 */
625 if (acpi_osi_is_win8() && native_available)
626 return acpi_backlight_native;
627 else
628 return acpi_backlight_video;
629 }
87521e16 630
b39be9f4
HG
631 /* No ACPI video (old hw), use vendor specific fw methods. */
632 return acpi_backlight_vendor;
c3d6de69 633}
2600bfa3
HG
634
635enum acpi_backlight_type acpi_video_get_backlight_type(void)
636{
637 return __acpi_video_get_backlight_type(false);
638}
87521e16 639EXPORT_SYMBOL(acpi_video_get_backlight_type);
c3d6de69 640
2600bfa3
HG
641bool acpi_video_backlight_use_native(void)
642{
643 return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
644}
645EXPORT_SYMBOL(acpi_video_backlight_use_native);
646
87521e16
HG
647/*
648 * Set the preferred backlight interface type based on DMI info.
649 * This function allows DMI blacklists to be implemented by external
650 * platform drivers instead of putting a big blacklist in video_detect.c
651 */
652void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type)
c3d6de69 653{
87521e16 654 acpi_backlight_dmi = type;
5fd677b7
HG
655 /* Remove acpi-video backlight interface if it is no longer desired */
656 if (acpi_video_get_backlight_type() != acpi_backlight_video)
657 acpi_video_unregister_backlight();
f838eb5b 658}
87521e16 659EXPORT_SYMBOL(acpi_video_set_dmi_backlight_type);