]> Git Repo - linux.git/blob - drivers/acpi/video_detect.c
Merge tag 'tty-6.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
[linux.git] / drivers / acpi / video_detect.c
1 /*
2  *  Copyright (C) 2015       Red Hat Inc.
3  *                           Hans de Goede <[email protected]>
4  *  Copyright (C) 2008       SuSE Linux Products GmbH
5  *                           Thomas Renninger <[email protected]>
6  *
7  *  May be copied or modified under the terms of the GNU General Public License
8  *
9  * video_detect.c:
10  * After PCI devices are glued with ACPI devices
11  * acpi_get_pci_dev() can be called to identify ACPI graphics
12  * devices for which a real graphics card is plugged in
13  *
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  *
17  * Otherwise vendor specific drivers like thinkpad_acpi, asus-laptop,
18  * sony_acpi,... can take care about backlight brightness.
19  *
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.
23  *
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.
27  */
28
29 #include <linux/export.h>
30 #include <linux/acpi.h>
31 #include <linux/apple-gmux.h>
32 #include <linux/backlight.h>
33 #include <linux/dmi.h>
34 #include <linux/module.h>
35 #include <linux/pci.h>
36 #include <linux/platform_data/x86/nvidia-wmi-ec-backlight.h>
37 #include <linux/pnp.h>
38 #include <linux/types.h>
39 #include <linux/workqueue.h>
40 #include <acpi/video.h>
41
42 static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef;
43 static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef;
44
45 static void acpi_video_parse_cmdline(void)
46 {
47         if (!strcmp("vendor", acpi_video_backlight_string))
48                 acpi_backlight_cmdline = acpi_backlight_vendor;
49         if (!strcmp("video", acpi_video_backlight_string))
50                 acpi_backlight_cmdline = acpi_backlight_video;
51         if (!strcmp("native", acpi_video_backlight_string))
52                 acpi_backlight_cmdline = acpi_backlight_native;
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;
57         if (!strcmp("none", acpi_video_backlight_string))
58                 acpi_backlight_cmdline = acpi_backlight_none;
59 }
60
61 static acpi_status
62 find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
63 {
64         struct acpi_device *acpi_dev = acpi_fetch_acpi_dev(handle);
65         long *cap = context;
66         struct pci_dev *dev;
67
68         static const struct acpi_device_id video_ids[] = {
69                 {ACPI_VIDEO_HID, 0},
70                 {"", 0},
71         };
72
73         if (acpi_dev && !acpi_match_device_ids(acpi_dev, video_ids)) {
74                 dev = acpi_get_pci_dev(handle);
75                 if (!dev)
76                         return AE_OK;
77                 pci_dev_put(dev);
78                 *cap |= acpi_is_video_device(handle);
79         }
80         return AE_OK;
81 }
82
83 /* This depends on ACPI_WMI which is X86 only */
84 #ifdef CONFIG_X86
85 static 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
107 static bool nvidia_wmi_ec_supported(void)
108 {
109         return false;
110 }
111 #endif
112
113 static 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
133 /* Force to use vendor driver when the ACPI device is known to be
134  * buggy */
135 static int video_detect_force_vendor(const struct dmi_system_id *d)
136 {
137         acpi_backlight_dmi = acpi_backlight_vendor;
138         return 0;
139 }
140
141 static int video_detect_force_video(const struct dmi_system_id *d)
142 {
143         acpi_backlight_dmi = acpi_backlight_video;
144         return 0;
145 }
146
147 static int video_detect_force_native(const struct dmi_system_id *d)
148 {
149         acpi_backlight_dmi = acpi_backlight_native;
150         return 0;
151 }
152
153 static int video_detect_force_none(const struct dmi_system_id *d)
154 {
155         acpi_backlight_dmi = acpi_backlight_none;
156         return 0;
157 }
158
159 static const struct dmi_system_id video_detect_dmi_table[] = {
160         /*
161          * Models which should use the vendor backlight interface,
162          * because of broken ACPI video backlight control.
163          */
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         },
173         {
174          .callback = video_detect_force_vendor,
175          /* Asus UL30VT */
176          .matches = {
177                 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
178                 DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"),
179                 },
180         },
181         {
182          .callback = video_detect_force_vendor,
183          /* Asus UL30A */
184          .matches = {
185                 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
186                 DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
187                 },
188         },
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         {
198          /* https://bugs.launchpad.net/bugs/1000146 */
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         {
223          /* https://bugs.launchpad.net/bugs/1000146 */
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         },
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         },
258         {
259          .callback = video_detect_force_vendor,
260          /* Xiaomi Mi Pad 2 */
261          .matches = {
262                         DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
263                         DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
264                 },
265         },
266
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
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
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,
308          /* ThinkPad T420 */
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,
316          /* ThinkPad T520 */
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,
324          /* ThinkPad X201s */
325          .matches = {
326                 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
327                 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"),
328                 },
329         },
330         {
331          .callback = video_detect_force_video,
332          /* ThinkPad X201T */
333          .matches = {
334                 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
335                 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201T"),
336                 },
337         },
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,
343          /* HP ENVY 15 Notebook */
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,
351          /* SAMSUNG 870Z5E/880Z5E/680Z5E */
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,
359          /* SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V */
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,
369          /* SAMSUNG 3570R/370R/470R/450R/510R/4450RV */
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         },
376         {
377          /* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */
378          .callback = video_detect_force_video,
379          /* SAMSUNG 670Z5E */
380          .matches = {
381                 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
382                 DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"),
383                 },
384         },
385         {
386          /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */
387          .callback = video_detect_force_video,
388          /* SAMSUNG 730U3E/740U3E */
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,
397          /* SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D */
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         },
404         {
405          /* https://bugzilla.redhat.com/show_bug.cgi?id=1272633 */
406          .callback = video_detect_force_video,
407          /* Dell XPS14 L421X */
408          .matches = {
409                 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
410                 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"),
411                 },
412         },
413         {
414          /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */
415          .callback = video_detect_force_video,
416          /* Dell XPS15 L521X */
417          .matches = {
418                 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
419                 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"),
420                 },
421         },
422         {
423          /* https://bugzilla.kernel.org/show_bug.cgi?id=108971 */
424          .callback = video_detect_force_video,
425          /* SAMSUNG 530U4E/540U4E */
426          .matches = {
427                 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
428                 DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"),
429                 },
430         },
431         {
432          /* https://bugs.launchpad.net/bugs/1894667 */
433          .callback = video_detect_force_video,
434          /* HP 635 Notebook */
435          .matches = {
436                 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
437                 DMI_MATCH(DMI_PRODUCT_NAME, "HP 635 Notebook PC"),
438                 },
439         },
440
441         /* Non win8 machines which need native backlight nevertheless */
442         {
443          /* https://bugzilla.redhat.com/show_bug.cgi?id=1201530 */
444          .callback = video_detect_force_native,
445          /* Lenovo Ideapad S405 */
446          .matches = {
447                 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
448                 DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"),
449                 },
450         },
451         {
452          /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */
453          .callback = video_detect_force_native,
454          /* Lenovo Ideapad Z570 */
455          .matches = {
456                 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
457                 DMI_MATCH(DMI_PRODUCT_NAME, "102434U"),
458                 },
459         },
460         {
461          .callback = video_detect_force_native,
462          /* Lenovo E41-25 */
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,
470          /* Lenovo E41-45 */
471          .matches = {
472                 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
473                 DMI_MATCH(DMI_PRODUCT_NAME, "82BK"),
474                 },
475         },
476         {
477          /* https://bugzilla.redhat.com/show_bug.cgi?id=1217249 */
478          .callback = video_detect_force_native,
479          /* Apple MacBook Pro 12,1 */
480          .matches = {
481                 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
482                 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"),
483                 },
484         },
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         },
493         {
494          .callback = video_detect_force_native,
495          /* Dell Vostro V131 */
496          .matches = {
497                 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
498                 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
499                 },
500         },
501         {
502          /* https://bugzilla.redhat.com/show_bug.cgi?id=1123661 */
503          .callback = video_detect_force_native,
504          /* Dell XPS 17 L702X */
505          .matches = {
506                 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
507                 DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"),
508                 },
509         },
510         {
511          .callback = video_detect_force_native,
512          /* Dell Precision 7510 */
513          .matches = {
514                 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
515                 DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"),
516                 },
517         },
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         },
526         {
527          .callback = video_detect_force_native,
528          /* Acer Aspire 5738z */
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         },
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         },
570         {
571          /* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */
572          .callback = video_detect_force_native,
573          /* Acer TravelMate 5735Z */
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         },
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         },
589         {
590          .callback = video_detect_force_native,
591          /* ASUSTeK COMPUTER INC. GA401 */
592          .matches = {
593                 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
594                 DMI_MATCH(DMI_PRODUCT_NAME, "GA401"),
595                 },
596         },
597         {
598          .callback = video_detect_force_native,
599          /* ASUSTeK COMPUTER INC. GA502 */
600          .matches = {
601                 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
602                 DMI_MATCH(DMI_PRODUCT_NAME, "GA502"),
603                 },
604         },
605         {
606          .callback = video_detect_force_native,
607          /* ASUSTeK COMPUTER INC. GA503 */
608          .matches = {
609                 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
610                 DMI_MATCH(DMI_PRODUCT_NAME, "GA503"),
611                 },
612         },
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         },
621         {
622          .callback = video_detect_force_native,
623          /* Samsung N150P */
624          .matches = {
625                 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
626                 DMI_MATCH(DMI_PRODUCT_NAME, "N150P"),
627                 DMI_MATCH(DMI_BOARD_NAME, "N150P"),
628                 },
629         },
630         {
631          .callback = video_detect_force_native,
632          /* Samsung N145P/N250P/N260P */
633          .matches = {
634                 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
635                 DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"),
636                 DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"),
637                 },
638         },
639         {
640          .callback = video_detect_force_native,
641          /* Samsung N250P */
642          .matches = {
643                 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
644                 DMI_MATCH(DMI_PRODUCT_NAME, "N250P"),
645                 DMI_MATCH(DMI_BOARD_NAME, "N250P"),
646                 },
647         },
648         {
649          /* https://bugzilla.kernel.org/show_bug.cgi?id=202401 */
650          .callback = video_detect_force_native,
651          /* Sony Vaio VPCEH3U1E */
652          .matches = {
653                 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
654                 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
655                 },
656         },
657         {
658          .callback = video_detect_force_native,
659          /* Sony Vaio VPCY11S1E */
660          .matches = {
661                 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
662                 DMI_MATCH(DMI_PRODUCT_NAME, "VPCY11S1E"),
663                 },
664         },
665
666         /*
667          * These Toshibas have a broken acpi-video interface for brightness
668          * control. They also have an issue where the panel is off after
669          * suspend until a special firmware call is made to turn it back
670          * on. This is handled by the toshiba_acpi kernel module, so that
671          * module must be enabled for these models to work correctly.
672          */
673         {
674          /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
675          .callback = video_detect_force_native,
676          /* Toshiba Portégé R700 */
677          .matches = {
678                 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
679                 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"),
680                 },
681         },
682         {
683          /* Portégé: https://bugs.freedesktop.org/show_bug.cgi?id=82634 */
684          /* Satellite: https://bugzilla.kernel.org/show_bug.cgi?id=21012 */
685          .callback = video_detect_force_native,
686          /* Toshiba Satellite/Portégé R830 */
687          .matches = {
688                 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
689                 DMI_MATCH(DMI_PRODUCT_NAME, "R830"),
690                 },
691         },
692         {
693          .callback = video_detect_force_native,
694          /* Toshiba Satellite/Portégé Z830 */
695          .matches = {
696                 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
697                 DMI_MATCH(DMI_PRODUCT_NAME, "Z830"),
698                 },
699         },
700
701         /*
702          * Models which have nvidia-ec-wmi support, but should not use it.
703          * Note this indicates a likely firmware bug on these models and should
704          * be revisited if/when Linux gets support for dynamic mux mode.
705          */
706         {
707          .callback = video_detect_force_native,
708          /* Dell G15 5515 */
709          .matches = {
710                 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
711                 DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
712                 },
713         },
714
715         /*
716          * Desktops which falsely report a backlight and which our heuristics
717          * for this do not catch.
718          */
719         {
720          .callback = video_detect_force_none,
721          /* Dell OptiPlex 9020M */
722          .matches = {
723                 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
724                 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"),
725                 },
726         },
727         {
728          .callback = video_detect_force_none,
729          /* GIGABYTE GB-BXBT-2807 */
730          .matches = {
731                 DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
732                 DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
733                 },
734         },
735         {
736          .callback = video_detect_force_none,
737          /* MSI MS-7721 */
738          .matches = {
739                 DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
740                 DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"),
741                 },
742         },
743         { },
744 };
745
746 static bool google_cros_ec_present(void)
747 {
748         return acpi_dev_found("GOOG0004") || acpi_dev_found("GOOG000C");
749 }
750
751 /*
752  * Windows 8 and newer no longer use the ACPI video interface, so it often
753  * does not work. So on win8+ systems prefer native brightness control.
754  * Chromebooks should always prefer native backlight control.
755  */
756 static bool prefer_native_over_acpi_video(void)
757 {
758         return acpi_osi_is_win8() || google_cros_ec_present();
759 }
760
761 /*
762  * Determine which type of backlight interface to use on this system,
763  * First check cmdline, then dmi quirks, then do autodetect.
764  */
765 static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
766 {
767         static DEFINE_MUTEX(init_mutex);
768         static bool nvidia_wmi_ec_present;
769         static bool native_available;
770         static bool init_done;
771         static long video_caps;
772
773         /* Parse cmdline, dmi and acpi only once */
774         mutex_lock(&init_mutex);
775         if (!init_done) {
776                 acpi_video_parse_cmdline();
777                 dmi_check_system(video_detect_dmi_table);
778                 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
779                                     ACPI_UINT32_MAX, find_video, NULL,
780                                     &video_caps, NULL);
781                 nvidia_wmi_ec_present = nvidia_wmi_ec_supported();
782                 init_done = true;
783         }
784         if (native)
785                 native_available = true;
786         mutex_unlock(&init_mutex);
787
788         /*
789          * The below heuristics / detection steps are in order of descending
790          * presedence. The commandline takes presedence over anything else.
791          */
792         if (acpi_backlight_cmdline != acpi_backlight_undef)
793                 return acpi_backlight_cmdline;
794
795         /* DMI quirks override any autodetection. */
796         if (acpi_backlight_dmi != acpi_backlight_undef)
797                 return acpi_backlight_dmi;
798
799         /* Special cases such as nvidia_wmi_ec and apple gmux. */
800         if (nvidia_wmi_ec_present)
801                 return acpi_backlight_nvidia_wmi_ec;
802
803         if (apple_gmux_backlight_present())
804                 return acpi_backlight_apple_gmux;
805
806         /* Use ACPI video if available, except when native should be preferred. */
807         if ((video_caps & ACPI_VIDEO_BACKLIGHT) &&
808              !(native_available && prefer_native_over_acpi_video()))
809                 return acpi_backlight_video;
810
811         /* Use native if available */
812         if (native_available)
813                 return acpi_backlight_native;
814
815         /* No ACPI video/native (old hw), use vendor specific fw methods. */
816         return acpi_backlight_vendor;
817 }
818
819 enum acpi_backlight_type acpi_video_get_backlight_type(void)
820 {
821         return __acpi_video_get_backlight_type(false);
822 }
823 EXPORT_SYMBOL(acpi_video_get_backlight_type);
824
825 bool acpi_video_backlight_use_native(void)
826 {
827         return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
828 }
829 EXPORT_SYMBOL(acpi_video_backlight_use_native);
This page took 0.085675 seconds and 4 git commands to generate.