This source file includes following definitions.
- acpi_video_parse_cmdline
- find_video
- video_detect_force_vendor
- video_detect_force_video
- video_detect_force_native
- video_detect_force_none
- acpi_video_backlight_notify_work
- acpi_video_backlight_notify
- acpi_video_get_backlight_type
- acpi_video_set_dmi_backlight_type
- acpi_video_detect_exit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <linux/export.h>
29 #include <linux/acpi.h>
30 #include <linux/backlight.h>
31 #include <linux/dmi.h>
32 #include <linux/module.h>
33 #include <linux/pci.h>
34 #include <linux/types.h>
35 #include <linux/workqueue.h>
36 #include <acpi/video.h>
37
38 ACPI_MODULE_NAME("video");
39 #define _COMPONENT ACPI_VIDEO_COMPONENT
40
41 void acpi_video_unregister_backlight(void);
42
43 static bool backlight_notifier_registered;
44 static struct notifier_block backlight_nb;
45 static struct work_struct backlight_notify_work;
46
47 static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef;
48 static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef;
49
50 static void acpi_video_parse_cmdline(void)
51 {
52 if (!strcmp("vendor", acpi_video_backlight_string))
53 acpi_backlight_cmdline = acpi_backlight_vendor;
54 if (!strcmp("video", acpi_video_backlight_string))
55 acpi_backlight_cmdline = acpi_backlight_video;
56 if (!strcmp("native", acpi_video_backlight_string))
57 acpi_backlight_cmdline = acpi_backlight_native;
58 if (!strcmp("none", acpi_video_backlight_string))
59 acpi_backlight_cmdline = acpi_backlight_none;
60 }
61
62 static acpi_status
63 find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
64 {
65 long *cap = context;
66 struct pci_dev *dev;
67 struct acpi_device *acpi_dev;
68
69 static const struct acpi_device_id video_ids[] = {
70 {ACPI_VIDEO_HID, 0},
71 {"", 0},
72 };
73 if (acpi_bus_get_device(handle, &acpi_dev))
74 return AE_OK;
75
76 if (!acpi_match_device_ids(acpi_dev, video_ids)) {
77 dev = acpi_get_pci_dev(handle);
78 if (!dev)
79 return AE_OK;
80 pci_dev_put(dev);
81 *cap |= acpi_is_video_device(handle);
82 }
83 return AE_OK;
84 }
85
86
87
88 static int video_detect_force_vendor(const struct dmi_system_id *d)
89 {
90 acpi_backlight_dmi = acpi_backlight_vendor;
91 return 0;
92 }
93
94 static int video_detect_force_video(const struct dmi_system_id *d)
95 {
96 acpi_backlight_dmi = acpi_backlight_video;
97 return 0;
98 }
99
100 static int video_detect_force_native(const struct dmi_system_id *d)
101 {
102 acpi_backlight_dmi = acpi_backlight_native;
103 return 0;
104 }
105
106 static int video_detect_force_none(const struct dmi_system_id *d)
107 {
108 acpi_backlight_dmi = acpi_backlight_none;
109 return 0;
110 }
111
112 static const struct dmi_system_id video_detect_dmi_table[] = {
113
114
115
116
117
118
119 {
120 .callback = video_detect_force_vendor,
121 .ident = "X360",
122 .matches = {
123 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
124 DMI_MATCH(DMI_PRODUCT_NAME, "X360"),
125 DMI_MATCH(DMI_BOARD_NAME, "X360"),
126 },
127 },
128 {
129 .callback = video_detect_force_vendor,
130 .ident = "Asus UL30VT",
131 .matches = {
132 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
133 DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"),
134 },
135 },
136 {
137 .callback = video_detect_force_vendor,
138 .ident = "Asus UL30A",
139 .matches = {
140 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
141 DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
142 },
143 },
144 {
145 .callback = video_detect_force_vendor,
146 .ident = "Sony VPCEH3U1E",
147 .matches = {
148 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
149 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
150 },
151 },
152
153
154
155
156
157
158
159
160 {
161 .callback = video_detect_force_video,
162 .ident = "ThinkPad T420",
163 .matches = {
164 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
165 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T420"),
166 },
167 },
168 {
169 .callback = video_detect_force_video,
170 .ident = "ThinkPad T520",
171 .matches = {
172 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
173 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T520"),
174 },
175 },
176 {
177 .callback = video_detect_force_video,
178 .ident = "ThinkPad X201s",
179 .matches = {
180 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
181 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"),
182 },
183 },
184 {
185 .callback = video_detect_force_video,
186 .ident = "ThinkPad X201T",
187 .matches = {
188 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
189 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201T"),
190 },
191 },
192
193
194 {
195
196 .callback = video_detect_force_video,
197 .ident = "HP ENVY 15 Notebook",
198 .matches = {
199 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
200 DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"),
201 },
202 },
203 {
204 .callback = video_detect_force_video,
205 .ident = "SAMSUNG 870Z5E/880Z5E/680Z5E",
206 .matches = {
207 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
208 DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"),
209 },
210 },
211 {
212 .callback = video_detect_force_video,
213 .ident = "SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V",
214 .matches = {
215 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
216 DMI_MATCH(DMI_PRODUCT_NAME,
217 "370R4E/370R4V/370R5E/3570RE/370R5V"),
218 },
219 },
220 {
221
222 .callback = video_detect_force_video,
223 .ident = "SAMSUNG 3570R/370R/470R/450R/510R/4450RV",
224 .matches = {
225 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
226 DMI_MATCH(DMI_PRODUCT_NAME,
227 "3570R/370R/470R/450R/510R/4450RV"),
228 },
229 },
230 {
231
232 .callback = video_detect_force_video,
233 .ident = "SAMSUNG 670Z5E",
234 .matches = {
235 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
236 DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"),
237 },
238 },
239 {
240
241 .callback = video_detect_force_video,
242 .ident = "SAMSUNG 730U3E/740U3E",
243 .matches = {
244 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
245 DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"),
246 },
247 },
248 {
249
250 .callback = video_detect_force_video,
251 .ident = "SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D",
252 .matches = {
253 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
254 DMI_MATCH(DMI_PRODUCT_NAME,
255 "900X3C/900X3D/900X3E/900X4C/900X4D"),
256 },
257 },
258 {
259
260 .callback = video_detect_force_video,
261 .ident = "Dell XPS14 L421X",
262 .matches = {
263 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
264 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"),
265 },
266 },
267 {
268
269 .callback = video_detect_force_video,
270 .ident = "Dell XPS15 L521X",
271 .matches = {
272 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
273 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"),
274 },
275 },
276 {
277
278 .callback = video_detect_force_video,
279 .ident = "SAMSUNG 530U4E/540U4E",
280 .matches = {
281 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
282 DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"),
283 },
284 },
285
286
287 {
288
289 .callback = video_detect_force_native,
290 .ident = "Lenovo Ideapad S405",
291 .matches = {
292 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
293 DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"),
294 },
295 },
296 {
297
298 .callback = video_detect_force_native,
299 .ident = "Lenovo Ideapad Z570",
300 .matches = {
301 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
302 DMI_MATCH(DMI_PRODUCT_NAME, "102434U"),
303 },
304 },
305 {
306
307 .callback = video_detect_force_native,
308 .ident = "Apple MacBook Pro 12,1",
309 .matches = {
310 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
311 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"),
312 },
313 },
314 {
315 .callback = video_detect_force_native,
316 .ident = "Dell Vostro V131",
317 .matches = {
318 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
319 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
320 },
321 },
322 {
323
324 .callback = video_detect_force_native,
325 .ident = "Dell XPS 17 L702X",
326 .matches = {
327 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
328 DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"),
329 },
330 },
331 {
332 .callback = video_detect_force_native,
333 .ident = "Dell Precision 7510",
334 .matches = {
335 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
336 DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"),
337 },
338 },
339
340
341
342
343
344 {
345 .callback = video_detect_force_none,
346 .ident = "Dell OptiPlex 9020M",
347 .matches = {
348 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
349 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"),
350 },
351 },
352 {
353 .callback = video_detect_force_none,
354 .ident = "MSI MS-7721",
355 .matches = {
356 DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
357 DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"),
358 },
359 },
360 { },
361 };
362
363
364 static void acpi_video_backlight_notify_work(struct work_struct *work)
365 {
366 if (acpi_video_get_backlight_type() != acpi_backlight_video)
367 acpi_video_unregister_backlight();
368 }
369
370 static int acpi_video_backlight_notify(struct notifier_block *nb,
371 unsigned long val, void *bd)
372 {
373 struct backlight_device *backlight = bd;
374
375
376 if (backlight->props.type == BACKLIGHT_RAW &&
377 val == BACKLIGHT_REGISTERED)
378 schedule_work(&backlight_notify_work);
379
380 return NOTIFY_OK;
381 }
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397 enum acpi_backlight_type acpi_video_get_backlight_type(void)
398 {
399 static DEFINE_MUTEX(init_mutex);
400 static bool init_done;
401 static long video_caps;
402
403
404 mutex_lock(&init_mutex);
405 if (!init_done) {
406 acpi_video_parse_cmdline();
407 dmi_check_system(video_detect_dmi_table);
408 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
409 ACPI_UINT32_MAX, find_video, NULL,
410 &video_caps, NULL);
411 INIT_WORK(&backlight_notify_work,
412 acpi_video_backlight_notify_work);
413 backlight_nb.notifier_call = acpi_video_backlight_notify;
414 backlight_nb.priority = 0;
415 if (backlight_register_notifier(&backlight_nb) == 0)
416 backlight_notifier_registered = true;
417 init_done = true;
418 }
419 mutex_unlock(&init_mutex);
420
421 if (acpi_backlight_cmdline != acpi_backlight_undef)
422 return acpi_backlight_cmdline;
423
424 if (acpi_backlight_dmi != acpi_backlight_undef)
425 return acpi_backlight_dmi;
426
427 if (!(video_caps & ACPI_VIDEO_BACKLIGHT))
428 return acpi_backlight_vendor;
429
430 if (acpi_osi_is_win8() && backlight_device_get_by_type(BACKLIGHT_RAW))
431 return acpi_backlight_native;
432
433 return acpi_backlight_video;
434 }
435 EXPORT_SYMBOL(acpi_video_get_backlight_type);
436
437
438
439
440
441
442 void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type)
443 {
444 acpi_backlight_dmi = type;
445
446 if (acpi_video_get_backlight_type() != acpi_backlight_video)
447 acpi_video_unregister_backlight();
448 }
449 EXPORT_SYMBOL(acpi_video_set_dmi_backlight_type);
450
451 void __exit acpi_video_detect_exit(void)
452 {
453 if (backlight_notifier_registered)
454 backlight_unregister_notifier(&backlight_nb);
455 }