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