• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  video.c - ACPI Video Driver ($Revision:$)
3  *
4  *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
5  *  Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
6  *  Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net>
7  *
8  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or (at
13  *  your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful, but
16  *  WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License along
21  *  with this program; if not, write to the Free Software Foundation, Inc.,
22  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23  *
24  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25  */
26 
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/types.h>
31 #include <linux/list.h>
32 #include <linux/mutex.h>
33 #include <linux/proc_fs.h>
34 #include <linux/seq_file.h>
35 #include <linux/input.h>
36 #include <linux/backlight.h>
37 #include <linux/thermal.h>
38 #include <linux/video_output.h>
39 #include <linux/sort.h>
40 #include <asm/uaccess.h>
41 
42 #include <acpi/acpi_bus.h>
43 #include <acpi/acpi_drivers.h>
44 
45 #define ACPI_VIDEO_CLASS		"video"
46 #define ACPI_VIDEO_BUS_NAME		"Video Bus"
47 #define ACPI_VIDEO_DEVICE_NAME		"Video Device"
48 #define ACPI_VIDEO_NOTIFY_SWITCH	0x80
49 #define ACPI_VIDEO_NOTIFY_PROBE		0x81
50 #define ACPI_VIDEO_NOTIFY_CYCLE		0x82
51 #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT	0x83
52 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT	0x84
53 
54 #define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS	0x85
55 #define	ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS	0x86
56 #define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS	0x87
57 #define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS	0x88
58 #define ACPI_VIDEO_NOTIFY_DISPLAY_OFF		0x89
59 
60 #define MAX_NAME_LEN	20
61 
62 #define ACPI_VIDEO_DISPLAY_CRT	1
63 #define ACPI_VIDEO_DISPLAY_TV	2
64 #define ACPI_VIDEO_DISPLAY_DVI	3
65 #define ACPI_VIDEO_DISPLAY_LCD	4
66 
67 #define _COMPONENT		ACPI_VIDEO_COMPONENT
68 ACPI_MODULE_NAME("video");
69 
70 MODULE_AUTHOR("Bruno Ducrot");
71 MODULE_DESCRIPTION("ACPI Video Driver");
72 MODULE_LICENSE("GPL");
73 
74 static int brightness_switch_enabled = 1;
75 module_param(brightness_switch_enabled, bool, 0644);
76 
77 static int acpi_video_bus_add(struct acpi_device *device);
78 static int acpi_video_bus_remove(struct acpi_device *device, int type);
79 static int acpi_video_resume(struct acpi_device *device);
80 
81 static const struct acpi_device_id video_device_ids[] = {
82 	{ACPI_VIDEO_HID, 0},
83 	{"", 0},
84 };
85 MODULE_DEVICE_TABLE(acpi, video_device_ids);
86 
87 static struct acpi_driver acpi_video_bus = {
88 	.name = "video",
89 	.class = ACPI_VIDEO_CLASS,
90 	.ids = video_device_ids,
91 	.ops = {
92 		.add = acpi_video_bus_add,
93 		.remove = acpi_video_bus_remove,
94 		.resume = acpi_video_resume,
95 		},
96 };
97 
98 struct acpi_video_bus_flags {
99 	u8 multihead:1;		/* can switch video heads */
100 	u8 rom:1;		/* can retrieve a video rom */
101 	u8 post:1;		/* can configure the head to */
102 	u8 reserved:5;
103 };
104 
105 struct acpi_video_bus_cap {
106 	u8 _DOS:1;		/*Enable/Disable output switching */
107 	u8 _DOD:1;		/*Enumerate all devices attached to display adapter */
108 	u8 _ROM:1;		/*Get ROM Data */
109 	u8 _GPD:1;		/*Get POST Device */
110 	u8 _SPD:1;		/*Set POST Device */
111 	u8 _VPO:1;		/*Video POST Options */
112 	u8 reserved:2;
113 };
114 
115 struct acpi_video_device_attrib {
116 	u32 display_index:4;	/* A zero-based instance of the Display */
117 	u32 display_port_attachment:4;	/*This field differentiates the display type */
118 	u32 display_type:4;	/*Describe the specific type in use */
119 	u32 vendor_specific:4;	/*Chipset Vendor Specific */
120 	u32 bios_can_detect:1;	/*BIOS can detect the device */
121 	u32 depend_on_vga:1;	/*Non-VGA output device whose power is related to
122 				   the VGA device. */
123 	u32 pipe_id:3;		/*For VGA multiple-head devices. */
124 	u32 reserved:10;	/*Must be 0 */
125 	u32 device_id_scheme:1;	/*Device ID Scheme */
126 };
127 
128 struct acpi_video_enumerated_device {
129 	union {
130 		u32 int_val;
131 		struct acpi_video_device_attrib attrib;
132 	} value;
133 	struct acpi_video_device *bind_info;
134 };
135 
136 struct acpi_video_bus {
137 	struct acpi_device *device;
138 	u8 dos_setting;
139 	struct acpi_video_enumerated_device *attached_array;
140 	u8 attached_count;
141 	struct acpi_video_bus_cap cap;
142 	struct acpi_video_bus_flags flags;
143 	struct list_head video_device_list;
144 	struct mutex device_list_lock;	/* protects video_device_list */
145 	struct proc_dir_entry *dir;
146 	struct input_dev *input;
147 	char phys[32];	/* for input device */
148 };
149 
150 struct acpi_video_device_flags {
151 	u8 crt:1;
152 	u8 lcd:1;
153 	u8 tvout:1;
154 	u8 dvi:1;
155 	u8 bios:1;
156 	u8 unknown:1;
157 	u8 reserved:2;
158 };
159 
160 struct acpi_video_device_cap {
161 	u8 _ADR:1;		/*Return the unique ID */
162 	u8 _BCL:1;		/*Query list of brightness control levels supported */
163 	u8 _BCM:1;		/*Set the brightness level */
164 	u8 _BQC:1;		/* Get current brightness level */
165 	u8 _DDC:1;		/*Return the EDID for this device */
166 	u8 _DCS:1;		/*Return status of output device */
167 	u8 _DGS:1;		/*Query graphics state */
168 	u8 _DSS:1;		/*Device state set */
169 };
170 
171 struct acpi_video_device_brightness {
172 	int curr;
173 	int count;
174 	int *levels;
175 };
176 
177 struct acpi_video_device {
178 	unsigned long device_id;
179 	struct acpi_video_device_flags flags;
180 	struct acpi_video_device_cap cap;
181 	struct list_head entry;
182 	struct acpi_video_bus *video;
183 	struct acpi_device *dev;
184 	struct acpi_video_device_brightness *brightness;
185 	struct backlight_device *backlight;
186 	struct thermal_cooling_device *cdev;
187 	struct output_device *output_dev;
188 };
189 
190 /* bus */
191 static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
192 static struct file_operations acpi_video_bus_info_fops = {
193 	.owner = THIS_MODULE,
194 	.open = acpi_video_bus_info_open_fs,
195 	.read = seq_read,
196 	.llseek = seq_lseek,
197 	.release = single_release,
198 };
199 
200 static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
201 static struct file_operations acpi_video_bus_ROM_fops = {
202 	.owner = THIS_MODULE,
203 	.open = acpi_video_bus_ROM_open_fs,
204 	.read = seq_read,
205 	.llseek = seq_lseek,
206 	.release = single_release,
207 };
208 
209 static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
210 					    struct file *file);
211 static struct file_operations acpi_video_bus_POST_info_fops = {
212 	.owner = THIS_MODULE,
213 	.open = acpi_video_bus_POST_info_open_fs,
214 	.read = seq_read,
215 	.llseek = seq_lseek,
216 	.release = single_release,
217 };
218 
219 static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
220 static struct file_operations acpi_video_bus_POST_fops = {
221 	.owner = THIS_MODULE,
222 	.open = acpi_video_bus_POST_open_fs,
223 	.read = seq_read,
224 	.llseek = seq_lseek,
225 	.release = single_release,
226 };
227 
228 static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
229 static struct file_operations acpi_video_bus_DOS_fops = {
230 	.owner = THIS_MODULE,
231 	.open = acpi_video_bus_DOS_open_fs,
232 	.read = seq_read,
233 	.llseek = seq_lseek,
234 	.release = single_release,
235 };
236 
237 /* device */
238 static int acpi_video_device_info_open_fs(struct inode *inode,
239 					  struct file *file);
240 static struct file_operations acpi_video_device_info_fops = {
241 	.owner = THIS_MODULE,
242 	.open = acpi_video_device_info_open_fs,
243 	.read = seq_read,
244 	.llseek = seq_lseek,
245 	.release = single_release,
246 };
247 
248 static int acpi_video_device_state_open_fs(struct inode *inode,
249 					   struct file *file);
250 static struct file_operations acpi_video_device_state_fops = {
251 	.owner = THIS_MODULE,
252 	.open = acpi_video_device_state_open_fs,
253 	.read = seq_read,
254 	.llseek = seq_lseek,
255 	.release = single_release,
256 };
257 
258 static int acpi_video_device_brightness_open_fs(struct inode *inode,
259 						struct file *file);
260 static struct file_operations acpi_video_device_brightness_fops = {
261 	.owner = THIS_MODULE,
262 	.open = acpi_video_device_brightness_open_fs,
263 	.read = seq_read,
264 	.llseek = seq_lseek,
265 	.release = single_release,
266 };
267 
268 static int acpi_video_device_EDID_open_fs(struct inode *inode,
269 					  struct file *file);
270 static struct file_operations acpi_video_device_EDID_fops = {
271 	.owner = THIS_MODULE,
272 	.open = acpi_video_device_EDID_open_fs,
273 	.read = seq_read,
274 	.llseek = seq_lseek,
275 	.release = single_release,
276 };
277 
278 static char device_decode[][30] = {
279 	"motherboard VGA device",
280 	"PCI VGA device",
281 	"AGP VGA device",
282 	"UNKNOWN",
283 };
284 
285 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data);
286 static void acpi_video_device_rebind(struct acpi_video_bus *video);
287 static void acpi_video_device_bind(struct acpi_video_bus *video,
288 				   struct acpi_video_device *device);
289 static int acpi_video_device_enumerate(struct acpi_video_bus *video);
290 static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
291 			int level);
292 static int acpi_video_device_lcd_get_level_current(
293 			struct acpi_video_device *device,
294 			unsigned long long *level);
295 static int acpi_video_get_next_level(struct acpi_video_device *device,
296 				     u32 level_current, u32 event);
297 static void acpi_video_switch_brightness(struct acpi_video_device *device,
298 					 int event);
299 static int acpi_video_device_get_state(struct acpi_video_device *device,
300 			    unsigned long long *state);
301 static int acpi_video_output_get(struct output_device *od);
302 static int acpi_video_device_set_state(struct acpi_video_device *device, int state);
303 
304 /*backlight device sysfs support*/
acpi_video_get_brightness(struct backlight_device * bd)305 static int acpi_video_get_brightness(struct backlight_device *bd)
306 {
307 	unsigned long long cur_level;
308 	int i;
309 	struct acpi_video_device *vd =
310 		(struct acpi_video_device *)bl_get_data(bd);
311 	acpi_video_device_lcd_get_level_current(vd, &cur_level);
312 	for (i = 2; i < vd->brightness->count; i++) {
313 		if (vd->brightness->levels[i] == cur_level)
314 			/* The first two entries are special - see page 575
315 			   of the ACPI spec 3.0 */
316 			return i-2;
317 	}
318 	return 0;
319 }
320 
acpi_video_set_brightness(struct backlight_device * bd)321 static int acpi_video_set_brightness(struct backlight_device *bd)
322 {
323 	int request_level = bd->props.brightness+2;
324 	struct acpi_video_device *vd =
325 		(struct acpi_video_device *)bl_get_data(bd);
326 	acpi_video_device_lcd_set_level(vd,
327 					vd->brightness->levels[request_level]);
328 	return 0;
329 }
330 
331 static struct backlight_ops acpi_backlight_ops = {
332 	.get_brightness = acpi_video_get_brightness,
333 	.update_status  = acpi_video_set_brightness,
334 };
335 
336 /*video output device sysfs support*/
acpi_video_output_get(struct output_device * od)337 static int acpi_video_output_get(struct output_device *od)
338 {
339 	unsigned long long state;
340 	struct acpi_video_device *vd =
341 		(struct acpi_video_device *)dev_get_drvdata(&od->dev);
342 	acpi_video_device_get_state(vd, &state);
343 	return (int)state;
344 }
345 
acpi_video_output_set(struct output_device * od)346 static int acpi_video_output_set(struct output_device *od)
347 {
348 	unsigned long state = od->request_state;
349 	struct acpi_video_device *vd=
350 		(struct acpi_video_device *)dev_get_drvdata(&od->dev);
351 	return acpi_video_device_set_state(vd, state);
352 }
353 
354 static struct output_properties acpi_output_properties = {
355 	.set_state = acpi_video_output_set,
356 	.get_status = acpi_video_output_get,
357 };
358 
359 
360 /* thermal cooling device callbacks */
video_get_max_state(struct thermal_cooling_device * cdev,char * buf)361 static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf)
362 {
363 	struct acpi_device *device = cdev->devdata;
364 	struct acpi_video_device *video = acpi_driver_data(device);
365 
366 	return sprintf(buf, "%d\n", video->brightness->count - 3);
367 }
368 
video_get_cur_state(struct thermal_cooling_device * cdev,char * buf)369 static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
370 {
371 	struct acpi_device *device = cdev->devdata;
372 	struct acpi_video_device *video = acpi_driver_data(device);
373 	unsigned long long level;
374 	int state;
375 
376 	acpi_video_device_lcd_get_level_current(video, &level);
377 	for (state = 2; state < video->brightness->count; state++)
378 		if (level == video->brightness->levels[state])
379 			return sprintf(buf, "%d\n",
380 				       video->brightness->count - state - 1);
381 
382 	return -EINVAL;
383 }
384 
385 static int
video_set_cur_state(struct thermal_cooling_device * cdev,unsigned int state)386 video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
387 {
388 	struct acpi_device *device = cdev->devdata;
389 	struct acpi_video_device *video = acpi_driver_data(device);
390 	int level;
391 
392 	if ( state >= video->brightness->count - 2)
393 		return -EINVAL;
394 
395 	state = video->brightness->count - state;
396 	level = video->brightness->levels[state -1];
397 	return acpi_video_device_lcd_set_level(video, level);
398 }
399 
400 static struct thermal_cooling_device_ops video_cooling_ops = {
401 	.get_max_state = video_get_max_state,
402 	.get_cur_state = video_get_cur_state,
403 	.set_cur_state = video_set_cur_state,
404 };
405 
406 /* --------------------------------------------------------------------------
407                                Video Management
408    -------------------------------------------------------------------------- */
409 
410 /* device */
411 
412 static int
acpi_video_device_query(struct acpi_video_device * device,unsigned long long * state)413 acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state)
414 {
415 	int status;
416 
417 	status = acpi_evaluate_integer(device->dev->handle, "_DGS", NULL, state);
418 
419 	return status;
420 }
421 
422 static int
acpi_video_device_get_state(struct acpi_video_device * device,unsigned long long * state)423 acpi_video_device_get_state(struct acpi_video_device *device,
424 			    unsigned long long *state)
425 {
426 	int status;
427 
428 	status = acpi_evaluate_integer(device->dev->handle, "_DCS", NULL, state);
429 
430 	return status;
431 }
432 
433 static int
acpi_video_device_set_state(struct acpi_video_device * device,int state)434 acpi_video_device_set_state(struct acpi_video_device *device, int state)
435 {
436 	int status;
437 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
438 	struct acpi_object_list args = { 1, &arg0 };
439 	unsigned long long ret;
440 
441 
442 	arg0.integer.value = state;
443 	status = acpi_evaluate_integer(device->dev->handle, "_DSS", &args, &ret);
444 
445 	return status;
446 }
447 
448 static int
acpi_video_device_lcd_query_levels(struct acpi_video_device * device,union acpi_object ** levels)449 acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
450 				   union acpi_object **levels)
451 {
452 	int status;
453 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
454 	union acpi_object *obj;
455 
456 
457 	*levels = NULL;
458 
459 	status = acpi_evaluate_object(device->dev->handle, "_BCL", NULL, &buffer);
460 	if (!ACPI_SUCCESS(status))
461 		return status;
462 	obj = (union acpi_object *)buffer.pointer;
463 	if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
464 		printk(KERN_ERR PREFIX "Invalid _BCL data\n");
465 		status = -EFAULT;
466 		goto err;
467 	}
468 
469 	*levels = obj;
470 
471 	return 0;
472 
473       err:
474 	kfree(buffer.pointer);
475 
476 	return status;
477 }
478 
479 static int
acpi_video_device_lcd_set_level(struct acpi_video_device * device,int level)480 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
481 {
482 	int status = AE_OK;
483 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
484 	struct acpi_object_list args = { 1, &arg0 };
485 	int state;
486 
487 
488 	arg0.integer.value = level;
489 
490 	if (device->cap._BCM)
491 		status = acpi_evaluate_object(device->dev->handle, "_BCM",
492 					      &args, NULL);
493 	device->brightness->curr = level;
494 	for (state = 2; state < device->brightness->count; state++)
495 		if (level == device->brightness->levels[state])
496 			device->backlight->props.brightness = state - 2;
497 
498 	return status;
499 }
500 
501 static int
acpi_video_device_lcd_get_level_current(struct acpi_video_device * device,unsigned long long * level)502 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
503 					unsigned long long *level)
504 {
505 	if (device->cap._BQC)
506 		return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
507 					     level);
508 	*level = device->brightness->curr;
509 	return AE_OK;
510 }
511 
512 static int
acpi_video_device_EDID(struct acpi_video_device * device,union acpi_object ** edid,ssize_t length)513 acpi_video_device_EDID(struct acpi_video_device *device,
514 		       union acpi_object **edid, ssize_t length)
515 {
516 	int status;
517 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
518 	union acpi_object *obj;
519 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
520 	struct acpi_object_list args = { 1, &arg0 };
521 
522 
523 	*edid = NULL;
524 
525 	if (!device)
526 		return -ENODEV;
527 	if (length == 128)
528 		arg0.integer.value = 1;
529 	else if (length == 256)
530 		arg0.integer.value = 2;
531 	else
532 		return -EINVAL;
533 
534 	status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer);
535 	if (ACPI_FAILURE(status))
536 		return -ENODEV;
537 
538 	obj = buffer.pointer;
539 
540 	if (obj && obj->type == ACPI_TYPE_BUFFER)
541 		*edid = obj;
542 	else {
543 		printk(KERN_ERR PREFIX "Invalid _DDC data\n");
544 		status = -EFAULT;
545 		kfree(obj);
546 	}
547 
548 	return status;
549 }
550 
551 /* bus */
552 
553 static int
acpi_video_bus_set_POST(struct acpi_video_bus * video,unsigned long option)554 acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
555 {
556 	int status;
557 	unsigned long long tmp;
558 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
559 	struct acpi_object_list args = { 1, &arg0 };
560 
561 
562 	arg0.integer.value = option;
563 
564 	status = acpi_evaluate_integer(video->device->handle, "_SPD", &args, &tmp);
565 	if (ACPI_SUCCESS(status))
566 		status = tmp ? (-EINVAL) : (AE_OK);
567 
568 	return status;
569 }
570 
571 static int
acpi_video_bus_get_POST(struct acpi_video_bus * video,unsigned long long * id)572 acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id)
573 {
574 	int status;
575 
576 	status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id);
577 
578 	return status;
579 }
580 
581 static int
acpi_video_bus_POST_options(struct acpi_video_bus * video,unsigned long long * options)582 acpi_video_bus_POST_options(struct acpi_video_bus *video,
583 			    unsigned long long *options)
584 {
585 	int status;
586 
587 	status = acpi_evaluate_integer(video->device->handle, "_VPO", NULL, options);
588 	*options &= 3;
589 
590 	return status;
591 }
592 
593 /*
594  *  Arg:
595  *  	video		: video bus device pointer
596  *	bios_flag	:
597  *		0.	The system BIOS should NOT automatically switch(toggle)
598  *			the active display output.
599  *		1.	The system BIOS should automatically switch (toggle) the
600  *			active display output. No switch event.
601  *		2.	The _DGS value should be locked.
602  *		3.	The system BIOS should not automatically switch (toggle) the
603  *			active display output, but instead generate the display switch
604  *			event notify code.
605  *	lcd_flag	:
606  *		0.	The system BIOS should automatically control the brightness level
607  *			of the LCD when the power changes from AC to DC
608  *		1. 	The system BIOS should NOT automatically control the brightness
609  *			level of the LCD when the power changes from AC to DC.
610  * Return Value:
611  * 		-1	wrong arg.
612  */
613 
614 static int
acpi_video_bus_DOS(struct acpi_video_bus * video,int bios_flag,int lcd_flag)615 acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
616 {
617 	acpi_integer status = 0;
618 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
619 	struct acpi_object_list args = { 1, &arg0 };
620 
621 
622 	if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) {
623 		status = -1;
624 		goto Failed;
625 	}
626 	arg0.integer.value = (lcd_flag << 2) | bios_flag;
627 	video->dos_setting = arg0.integer.value;
628 	acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL);
629 
630       Failed:
631 	return status;
632 }
633 
634 /*
635  * Simple comparison function used to sort backlight levels.
636  */
637 
638 static int
acpi_video_cmp_level(const void * a,const void * b)639 acpi_video_cmp_level(const void *a, const void *b)
640 {
641 	return *(int *)a - *(int *)b;
642 }
643 
644 /*
645  *  Arg:
646  *  	device	: video output device (LCD, CRT, ..)
647  *
648  *  Return Value:
649  *	Maximum brightness level
650  *
651  *  Allocate and initialize device->brightness.
652  */
653 
654 static int
acpi_video_init_brightness(struct acpi_video_device * device)655 acpi_video_init_brightness(struct acpi_video_device *device)
656 {
657 	union acpi_object *obj = NULL;
658 	int i, max_level = 0, count = 0;
659 	union acpi_object *o;
660 	struct acpi_video_device_brightness *br = NULL;
661 
662 	if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
663 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
664 						"LCD brightness level\n"));
665 		goto out;
666 	}
667 
668 	if (obj->package.count < 2)
669 		goto out;
670 
671 	br = kzalloc(sizeof(*br), GFP_KERNEL);
672 	if (!br) {
673 		printk(KERN_ERR "can't allocate memory\n");
674 		goto out;
675 	}
676 
677 	br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
678 				GFP_KERNEL);
679 	if (!br->levels)
680 		goto out_free;
681 
682 	for (i = 0; i < obj->package.count; i++) {
683 		o = (union acpi_object *)&obj->package.elements[i];
684 		if (o->type != ACPI_TYPE_INTEGER) {
685 			printk(KERN_ERR PREFIX "Invalid data\n");
686 			continue;
687 		}
688 		br->levels[count] = (u32) o->integer.value;
689 
690 		if (br->levels[count] > max_level)
691 			max_level = br->levels[count];
692 		count++;
693 	}
694 
695 	/* don't sort the first two brightness levels */
696 	sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
697 		acpi_video_cmp_level, NULL);
698 
699 	if (count < 2)
700 		goto out_free_levels;
701 
702 	br->count = count;
703 	device->brightness = br;
704 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
705 	kfree(obj);
706 	return max_level;
707 
708 out_free_levels:
709 	kfree(br->levels);
710 out_free:
711 	kfree(br);
712 out:
713 	device->brightness = NULL;
714 	kfree(obj);
715 	return 0;
716 }
717 
718 /*
719  *  Arg:
720  *	device	: video output device (LCD, CRT, ..)
721  *
722  *  Return Value:
723  *  	None
724  *
725  *  Find out all required AML methods defined under the output
726  *  device.
727  */
728 
acpi_video_device_find_cap(struct acpi_video_device * device)729 static void acpi_video_device_find_cap(struct acpi_video_device *device)
730 {
731 	acpi_handle h_dummy1;
732 	u32 max_level = 0;
733 
734 
735 	memset(&device->cap, 0, sizeof(device->cap));
736 
737 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) {
738 		device->cap._ADR = 1;
739 	}
740 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCL", &h_dummy1))) {
741 		device->cap._BCL = 1;
742 	}
743 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
744 		device->cap._BCM = 1;
745 	}
746 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
747 		device->cap._BQC = 1;
748 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
749 		device->cap._DDC = 1;
750 	}
751 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DCS", &h_dummy1))) {
752 		device->cap._DCS = 1;
753 	}
754 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DGS", &h_dummy1))) {
755 		device->cap._DGS = 1;
756 	}
757 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DSS", &h_dummy1))) {
758 		device->cap._DSS = 1;
759 	}
760 
761 	if (acpi_video_backlight_support())
762 		max_level = acpi_video_init_brightness(device);
763 
764 	if (device->cap._BCL && device->cap._BCM && max_level > 0) {
765 		int result;
766 		static int count = 0;
767 		char *name;
768 		name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
769 		if (!name)
770 			return;
771 
772 		sprintf(name, "acpi_video%d", count++);
773 		device->backlight = backlight_device_register(name,
774 			NULL, device, &acpi_backlight_ops);
775 		device->backlight->props.max_brightness = device->brightness->count-3;
776 		/*
777 		 * If there exists the _BQC object, the _BQC object will be
778 		 * called to get the current backlight brightness. Otherwise
779 		 * the brightness will be set to the maximum.
780 		 */
781 		if (device->cap._BQC)
782 			device->backlight->props.brightness =
783 				acpi_video_get_brightness(device->backlight);
784 		else
785 			device->backlight->props.brightness =
786 				device->backlight->props.max_brightness;
787 		backlight_update_status(device->backlight);
788 		kfree(name);
789 
790 		device->cdev = thermal_cooling_device_register("LCD",
791 					device->dev, &video_cooling_ops);
792 		if (IS_ERR(device->cdev))
793 			return;
794 
795 		dev_info(&device->dev->dev, "registered as cooling_device%d\n",
796 			 device->cdev->id);
797 		result = sysfs_create_link(&device->dev->dev.kobj,
798 				&device->cdev->device.kobj,
799 				"thermal_cooling");
800 		if (result)
801 			printk(KERN_ERR PREFIX "Create sysfs link\n");
802 		result = sysfs_create_link(&device->cdev->device.kobj,
803 				&device->dev->dev.kobj, "device");
804 		if (result)
805 			printk(KERN_ERR PREFIX "Create sysfs link\n");
806 
807 	}
808 
809 	if (acpi_video_display_switch_support()) {
810 
811 		if (device->cap._DCS && device->cap._DSS) {
812 			static int count;
813 			char *name;
814 			name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
815 			if (!name)
816 				return;
817 			sprintf(name, "acpi_video%d", count++);
818 			device->output_dev = video_output_register(name,
819 					NULL, device, &acpi_output_properties);
820 			kfree(name);
821 		}
822 	}
823 }
824 
825 /*
826  *  Arg:
827  *  	device	: video output device (VGA)
828  *
829  *  Return Value:
830  *  	None
831  *
832  *  Find out all required AML methods defined under the video bus device.
833  */
834 
acpi_video_bus_find_cap(struct acpi_video_bus * video)835 static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
836 {
837 	acpi_handle h_dummy1;
838 
839 	memset(&video->cap, 0, sizeof(video->cap));
840 	if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) {
841 		video->cap._DOS = 1;
842 	}
843 	if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOD", &h_dummy1))) {
844 		video->cap._DOD = 1;
845 	}
846 	if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_ROM", &h_dummy1))) {
847 		video->cap._ROM = 1;
848 	}
849 	if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_GPD", &h_dummy1))) {
850 		video->cap._GPD = 1;
851 	}
852 	if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_SPD", &h_dummy1))) {
853 		video->cap._SPD = 1;
854 	}
855 	if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_VPO", &h_dummy1))) {
856 		video->cap._VPO = 1;
857 	}
858 }
859 
860 /*
861  * Check whether the video bus device has required AML method to
862  * support the desired features
863  */
864 
acpi_video_bus_check(struct acpi_video_bus * video)865 static int acpi_video_bus_check(struct acpi_video_bus *video)
866 {
867 	acpi_status status = -ENOENT;
868 	struct device *dev;
869 
870 	if (!video)
871 		return -EINVAL;
872 
873 	dev = acpi_get_physical_pci_device(video->device->handle);
874 	if (!dev)
875 		return -ENODEV;
876 	put_device(dev);
877 
878 	/* Since there is no HID, CID and so on for VGA driver, we have
879 	 * to check well known required nodes.
880 	 */
881 
882 	/* Does this device support video switching? */
883 	if (video->cap._DOS) {
884 		video->flags.multihead = 1;
885 		status = 0;
886 	}
887 
888 	/* Does this device support retrieving a video ROM? */
889 	if (video->cap._ROM) {
890 		video->flags.rom = 1;
891 		status = 0;
892 	}
893 
894 	/* Does this device support configuring which video device to POST? */
895 	if (video->cap._GPD && video->cap._SPD && video->cap._VPO) {
896 		video->flags.post = 1;
897 		status = 0;
898 	}
899 
900 	return status;
901 }
902 
903 /* --------------------------------------------------------------------------
904                               FS Interface (/proc)
905    -------------------------------------------------------------------------- */
906 
907 static struct proc_dir_entry *acpi_video_dir;
908 
909 /* video devices */
910 
acpi_video_device_info_seq_show(struct seq_file * seq,void * offset)911 static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
912 {
913 	struct acpi_video_device *dev = seq->private;
914 
915 
916 	if (!dev)
917 		goto end;
918 
919 	seq_printf(seq, "device_id:    0x%04x\n", (u32) dev->device_id);
920 	seq_printf(seq, "type:         ");
921 	if (dev->flags.crt)
922 		seq_printf(seq, "CRT\n");
923 	else if (dev->flags.lcd)
924 		seq_printf(seq, "LCD\n");
925 	else if (dev->flags.tvout)
926 		seq_printf(seq, "TVOUT\n");
927 	else if (dev->flags.dvi)
928 		seq_printf(seq, "DVI\n");
929 	else
930 		seq_printf(seq, "UNKNOWN\n");
931 
932 	seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no");
933 
934       end:
935 	return 0;
936 }
937 
938 static int
acpi_video_device_info_open_fs(struct inode * inode,struct file * file)939 acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
940 {
941 	return single_open(file, acpi_video_device_info_seq_show,
942 			   PDE(inode)->data);
943 }
944 
acpi_video_device_state_seq_show(struct seq_file * seq,void * offset)945 static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
946 {
947 	int status;
948 	struct acpi_video_device *dev = seq->private;
949 	unsigned long long state;
950 
951 
952 	if (!dev)
953 		goto end;
954 
955 	status = acpi_video_device_get_state(dev, &state);
956 	seq_printf(seq, "state:     ");
957 	if (ACPI_SUCCESS(status))
958 		seq_printf(seq, "0x%02llx\n", state);
959 	else
960 		seq_printf(seq, "<not supported>\n");
961 
962 	status = acpi_video_device_query(dev, &state);
963 	seq_printf(seq, "query:     ");
964 	if (ACPI_SUCCESS(status))
965 		seq_printf(seq, "0x%02llx\n", state);
966 	else
967 		seq_printf(seq, "<not supported>\n");
968 
969       end:
970 	return 0;
971 }
972 
973 static int
acpi_video_device_state_open_fs(struct inode * inode,struct file * file)974 acpi_video_device_state_open_fs(struct inode *inode, struct file *file)
975 {
976 	return single_open(file, acpi_video_device_state_seq_show,
977 			   PDE(inode)->data);
978 }
979 
980 static ssize_t
acpi_video_device_write_state(struct file * file,const char __user * buffer,size_t count,loff_t * data)981 acpi_video_device_write_state(struct file *file,
982 			      const char __user * buffer,
983 			      size_t count, loff_t * data)
984 {
985 	int status;
986 	struct seq_file *m = file->private_data;
987 	struct acpi_video_device *dev = m->private;
988 	char str[12] = { 0 };
989 	u32 state = 0;
990 
991 
992 	if (!dev || count + 1 > sizeof str)
993 		return -EINVAL;
994 
995 	if (copy_from_user(str, buffer, count))
996 		return -EFAULT;
997 
998 	str[count] = 0;
999 	state = simple_strtoul(str, NULL, 0);
1000 	state &= ((1ul << 31) | (1ul << 30) | (1ul << 0));
1001 
1002 	status = acpi_video_device_set_state(dev, state);
1003 
1004 	if (status)
1005 		return -EFAULT;
1006 
1007 	return count;
1008 }
1009 
1010 static int
acpi_video_device_brightness_seq_show(struct seq_file * seq,void * offset)1011 acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
1012 {
1013 	struct acpi_video_device *dev = seq->private;
1014 	int i;
1015 
1016 
1017 	if (!dev || !dev->brightness) {
1018 		seq_printf(seq, "<not supported>\n");
1019 		return 0;
1020 	}
1021 
1022 	seq_printf(seq, "levels: ");
1023 	for (i = 2; i < dev->brightness->count; i++)
1024 		seq_printf(seq, " %d", dev->brightness->levels[i]);
1025 	seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
1026 
1027 	return 0;
1028 }
1029 
1030 static int
acpi_video_device_brightness_open_fs(struct inode * inode,struct file * file)1031 acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file)
1032 {
1033 	return single_open(file, acpi_video_device_brightness_seq_show,
1034 			   PDE(inode)->data);
1035 }
1036 
1037 static ssize_t
acpi_video_device_write_brightness(struct file * file,const char __user * buffer,size_t count,loff_t * data)1038 acpi_video_device_write_brightness(struct file *file,
1039 				   const char __user * buffer,
1040 				   size_t count, loff_t * data)
1041 {
1042 	struct seq_file *m = file->private_data;
1043 	struct acpi_video_device *dev = m->private;
1044 	char str[5] = { 0 };
1045 	unsigned int level = 0;
1046 	int i;
1047 
1048 
1049 	if (!dev || !dev->brightness || count + 1 > sizeof str)
1050 		return -EINVAL;
1051 
1052 	if (copy_from_user(str, buffer, count))
1053 		return -EFAULT;
1054 
1055 	str[count] = 0;
1056 	level = simple_strtoul(str, NULL, 0);
1057 
1058 	if (level > 100)
1059 		return -EFAULT;
1060 
1061 	/* validate through the list of available levels */
1062 	for (i = 2; i < dev->brightness->count; i++)
1063 		if (level == dev->brightness->levels[i]) {
1064 			if (ACPI_SUCCESS
1065 			    (acpi_video_device_lcd_set_level(dev, level)))
1066 				dev->brightness->curr = level;
1067 			break;
1068 		}
1069 
1070 	return count;
1071 }
1072 
acpi_video_device_EDID_seq_show(struct seq_file * seq,void * offset)1073 static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
1074 {
1075 	struct acpi_video_device *dev = seq->private;
1076 	int status;
1077 	int i;
1078 	union acpi_object *edid = NULL;
1079 
1080 
1081 	if (!dev)
1082 		goto out;
1083 
1084 	status = acpi_video_device_EDID(dev, &edid, 128);
1085 	if (ACPI_FAILURE(status)) {
1086 		status = acpi_video_device_EDID(dev, &edid, 256);
1087 	}
1088 
1089 	if (ACPI_FAILURE(status)) {
1090 		goto out;
1091 	}
1092 
1093 	if (edid && edid->type == ACPI_TYPE_BUFFER) {
1094 		for (i = 0; i < edid->buffer.length; i++)
1095 			seq_putc(seq, edid->buffer.pointer[i]);
1096 	}
1097 
1098       out:
1099 	if (!edid)
1100 		seq_printf(seq, "<not supported>\n");
1101 	else
1102 		kfree(edid);
1103 
1104 	return 0;
1105 }
1106 
1107 static int
acpi_video_device_EDID_open_fs(struct inode * inode,struct file * file)1108 acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file)
1109 {
1110 	return single_open(file, acpi_video_device_EDID_seq_show,
1111 			   PDE(inode)->data);
1112 }
1113 
acpi_video_device_add_fs(struct acpi_device * device)1114 static int acpi_video_device_add_fs(struct acpi_device *device)
1115 {
1116 	struct proc_dir_entry *entry, *device_dir;
1117 	struct acpi_video_device *vid_dev;
1118 
1119 	vid_dev = acpi_driver_data(device);
1120 	if (!vid_dev)
1121 		return -ENODEV;
1122 
1123 	device_dir = proc_mkdir(acpi_device_bid(device),
1124 				vid_dev->video->dir);
1125 	if (!device_dir)
1126 		return -ENOMEM;
1127 
1128 	device_dir->owner = THIS_MODULE;
1129 
1130 	/* 'info' [R] */
1131 	entry = proc_create_data("info", S_IRUGO, device_dir,
1132 			&acpi_video_device_info_fops, acpi_driver_data(device));
1133 	if (!entry)
1134 		goto err_remove_dir;
1135 
1136 	/* 'state' [R/W] */
1137 	acpi_video_device_state_fops.write = acpi_video_device_write_state;
1138 	entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
1139 				 device_dir,
1140 				 &acpi_video_device_state_fops,
1141 				 acpi_driver_data(device));
1142 	if (!entry)
1143 		goto err_remove_info;
1144 
1145 	/* 'brightness' [R/W] */
1146 	acpi_video_device_brightness_fops.write =
1147 		acpi_video_device_write_brightness;
1148 	entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
1149 				 device_dir,
1150 				 &acpi_video_device_brightness_fops,
1151 				 acpi_driver_data(device));
1152 	if (!entry)
1153 		goto err_remove_state;
1154 
1155 	/* 'EDID' [R] */
1156 	entry = proc_create_data("EDID", S_IRUGO, device_dir,
1157 				 &acpi_video_device_EDID_fops,
1158 				 acpi_driver_data(device));
1159 	if (!entry)
1160 		goto err_remove_brightness;
1161 
1162 	acpi_device_dir(device) = device_dir;
1163 
1164 	return 0;
1165 
1166  err_remove_brightness:
1167 	remove_proc_entry("brightness", device_dir);
1168  err_remove_state:
1169 	remove_proc_entry("state", device_dir);
1170  err_remove_info:
1171 	remove_proc_entry("info", device_dir);
1172  err_remove_dir:
1173 	remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1174 	return -ENOMEM;
1175 }
1176 
acpi_video_device_remove_fs(struct acpi_device * device)1177 static int acpi_video_device_remove_fs(struct acpi_device *device)
1178 {
1179 	struct acpi_video_device *vid_dev;
1180 	struct proc_dir_entry *device_dir;
1181 
1182 	vid_dev = acpi_driver_data(device);
1183 	if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
1184 		return -ENODEV;
1185 
1186 	device_dir = acpi_device_dir(device);
1187 	if (device_dir) {
1188 		remove_proc_entry("info", device_dir);
1189 		remove_proc_entry("state", device_dir);
1190 		remove_proc_entry("brightness", device_dir);
1191 		remove_proc_entry("EDID", device_dir);
1192 		remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1193 		acpi_device_dir(device) = NULL;
1194 	}
1195 
1196 	return 0;
1197 }
1198 
1199 /* video bus */
acpi_video_bus_info_seq_show(struct seq_file * seq,void * offset)1200 static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
1201 {
1202 	struct acpi_video_bus *video = seq->private;
1203 
1204 
1205 	if (!video)
1206 		goto end;
1207 
1208 	seq_printf(seq, "Switching heads:              %s\n",
1209 		   video->flags.multihead ? "yes" : "no");
1210 	seq_printf(seq, "Video ROM:                    %s\n",
1211 		   video->flags.rom ? "yes" : "no");
1212 	seq_printf(seq, "Device to be POSTed on boot:  %s\n",
1213 		   video->flags.post ? "yes" : "no");
1214 
1215       end:
1216 	return 0;
1217 }
1218 
acpi_video_bus_info_open_fs(struct inode * inode,struct file * file)1219 static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
1220 {
1221 	return single_open(file, acpi_video_bus_info_seq_show,
1222 			   PDE(inode)->data);
1223 }
1224 
acpi_video_bus_ROM_seq_show(struct seq_file * seq,void * offset)1225 static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
1226 {
1227 	struct acpi_video_bus *video = seq->private;
1228 
1229 
1230 	if (!video)
1231 		goto end;
1232 
1233 	printk(KERN_INFO PREFIX "Please implement %s\n", __func__);
1234 	seq_printf(seq, "<TODO>\n");
1235 
1236       end:
1237 	return 0;
1238 }
1239 
acpi_video_bus_ROM_open_fs(struct inode * inode,struct file * file)1240 static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
1241 {
1242 	return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data);
1243 }
1244 
acpi_video_bus_POST_info_seq_show(struct seq_file * seq,void * offset)1245 static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
1246 {
1247 	struct acpi_video_bus *video = seq->private;
1248 	unsigned long long options;
1249 	int status;
1250 
1251 
1252 	if (!video)
1253 		goto end;
1254 
1255 	status = acpi_video_bus_POST_options(video, &options);
1256 	if (ACPI_SUCCESS(status)) {
1257 		if (!(options & 1)) {
1258 			printk(KERN_WARNING PREFIX
1259 			       "The motherboard VGA device is not listed as a possible POST device.\n");
1260 			printk(KERN_WARNING PREFIX
1261 			       "This indicates a BIOS bug. Please contact the manufacturer.\n");
1262 		}
1263 		printk(KERN_WARNING "%llx\n", options);
1264 		seq_printf(seq, "can POST: <integrated video>");
1265 		if (options & 2)
1266 			seq_printf(seq, " <PCI video>");
1267 		if (options & 4)
1268 			seq_printf(seq, " <AGP video>");
1269 		seq_putc(seq, '\n');
1270 	} else
1271 		seq_printf(seq, "<not supported>\n");
1272       end:
1273 	return 0;
1274 }
1275 
1276 static int
acpi_video_bus_POST_info_open_fs(struct inode * inode,struct file * file)1277 acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
1278 {
1279 	return single_open(file, acpi_video_bus_POST_info_seq_show,
1280 			   PDE(inode)->data);
1281 }
1282 
acpi_video_bus_POST_seq_show(struct seq_file * seq,void * offset)1283 static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
1284 {
1285 	struct acpi_video_bus *video = seq->private;
1286 	int status;
1287 	unsigned long long id;
1288 
1289 
1290 	if (!video)
1291 		goto end;
1292 
1293 	status = acpi_video_bus_get_POST(video, &id);
1294 	if (!ACPI_SUCCESS(status)) {
1295 		seq_printf(seq, "<not supported>\n");
1296 		goto end;
1297 	}
1298 	seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]);
1299 
1300       end:
1301 	return 0;
1302 }
1303 
acpi_video_bus_DOS_seq_show(struct seq_file * seq,void * offset)1304 static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
1305 {
1306 	struct acpi_video_bus *video = seq->private;
1307 
1308 
1309 	seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
1310 
1311 	return 0;
1312 }
1313 
acpi_video_bus_POST_open_fs(struct inode * inode,struct file * file)1314 static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file)
1315 {
1316 	return single_open(file, acpi_video_bus_POST_seq_show,
1317 			   PDE(inode)->data);
1318 }
1319 
acpi_video_bus_DOS_open_fs(struct inode * inode,struct file * file)1320 static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file)
1321 {
1322 	return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data);
1323 }
1324 
1325 static ssize_t
acpi_video_bus_write_POST(struct file * file,const char __user * buffer,size_t count,loff_t * data)1326 acpi_video_bus_write_POST(struct file *file,
1327 			  const char __user * buffer,
1328 			  size_t count, loff_t * data)
1329 {
1330 	int status;
1331 	struct seq_file *m = file->private_data;
1332 	struct acpi_video_bus *video = m->private;
1333 	char str[12] = { 0 };
1334 	unsigned long long opt, options;
1335 
1336 
1337 	if (!video || count + 1 > sizeof str)
1338 		return -EINVAL;
1339 
1340 	status = acpi_video_bus_POST_options(video, &options);
1341 	if (!ACPI_SUCCESS(status))
1342 		return -EINVAL;
1343 
1344 	if (copy_from_user(str, buffer, count))
1345 		return -EFAULT;
1346 
1347 	str[count] = 0;
1348 	opt = strtoul(str, NULL, 0);
1349 	if (opt > 3)
1350 		return -EFAULT;
1351 
1352 	/* just in case an OEM 'forgot' the motherboard... */
1353 	options |= 1;
1354 
1355 	if (options & (1ul << opt)) {
1356 		status = acpi_video_bus_set_POST(video, opt);
1357 		if (!ACPI_SUCCESS(status))
1358 			return -EFAULT;
1359 
1360 	}
1361 
1362 	return count;
1363 }
1364 
1365 static ssize_t
acpi_video_bus_write_DOS(struct file * file,const char __user * buffer,size_t count,loff_t * data)1366 acpi_video_bus_write_DOS(struct file *file,
1367 			 const char __user * buffer,
1368 			 size_t count, loff_t * data)
1369 {
1370 	int status;
1371 	struct seq_file *m = file->private_data;
1372 	struct acpi_video_bus *video = m->private;
1373 	char str[12] = { 0 };
1374 	unsigned long opt;
1375 
1376 
1377 	if (!video || count + 1 > sizeof str)
1378 		return -EINVAL;
1379 
1380 	if (copy_from_user(str, buffer, count))
1381 		return -EFAULT;
1382 
1383 	str[count] = 0;
1384 	opt = strtoul(str, NULL, 0);
1385 	if (opt > 7)
1386 		return -EFAULT;
1387 
1388 	status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2);
1389 
1390 	if (!ACPI_SUCCESS(status))
1391 		return -EFAULT;
1392 
1393 	return count;
1394 }
1395 
acpi_video_bus_add_fs(struct acpi_device * device)1396 static int acpi_video_bus_add_fs(struct acpi_device *device)
1397 {
1398 	struct acpi_video_bus *video = acpi_driver_data(device);
1399 	struct proc_dir_entry *device_dir;
1400 	struct proc_dir_entry *entry;
1401 
1402 	device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir);
1403 	if (!device_dir)
1404 		return -ENOMEM;
1405 
1406 	device_dir->owner = THIS_MODULE;
1407 
1408 	/* 'info' [R] */
1409 	entry = proc_create_data("info", S_IRUGO, device_dir,
1410 				 &acpi_video_bus_info_fops,
1411 				 acpi_driver_data(device));
1412 	if (!entry)
1413 		goto err_remove_dir;
1414 
1415 	/* 'ROM' [R] */
1416 	entry = proc_create_data("ROM", S_IRUGO, device_dir,
1417 				 &acpi_video_bus_ROM_fops,
1418 				 acpi_driver_data(device));
1419 	if (!entry)
1420 		goto err_remove_info;
1421 
1422 	/* 'POST_info' [R] */
1423 	entry = proc_create_data("POST_info", S_IRUGO, device_dir,
1424 				 &acpi_video_bus_POST_info_fops,
1425 				 acpi_driver_data(device));
1426 	if (!entry)
1427 		goto err_remove_rom;
1428 
1429 	/* 'POST' [R/W] */
1430 	acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
1431 	entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
1432 				 device_dir,
1433 				 &acpi_video_bus_POST_fops,
1434 				 acpi_driver_data(device));
1435 	if (!entry)
1436 		goto err_remove_post_info;
1437 
1438 	/* 'DOS' [R/W] */
1439 	acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
1440 	entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
1441 				 device_dir,
1442 				 &acpi_video_bus_DOS_fops,
1443 				 acpi_driver_data(device));
1444 	if (!entry)
1445 		goto err_remove_post;
1446 
1447 	video->dir = acpi_device_dir(device) = device_dir;
1448 	return 0;
1449 
1450  err_remove_post:
1451 	remove_proc_entry("POST", device_dir);
1452  err_remove_post_info:
1453 	remove_proc_entry("POST_info", device_dir);
1454  err_remove_rom:
1455 	remove_proc_entry("ROM", device_dir);
1456  err_remove_info:
1457 	remove_proc_entry("info", device_dir);
1458  err_remove_dir:
1459 	remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1460 	return -ENOMEM;
1461 }
1462 
acpi_video_bus_remove_fs(struct acpi_device * device)1463 static int acpi_video_bus_remove_fs(struct acpi_device *device)
1464 {
1465 	struct proc_dir_entry *device_dir = acpi_device_dir(device);
1466 
1467 	if (device_dir) {
1468 		remove_proc_entry("info", device_dir);
1469 		remove_proc_entry("ROM", device_dir);
1470 		remove_proc_entry("POST_info", device_dir);
1471 		remove_proc_entry("POST", device_dir);
1472 		remove_proc_entry("DOS", device_dir);
1473 		remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1474 		acpi_device_dir(device) = NULL;
1475 	}
1476 
1477 	return 0;
1478 }
1479 
1480 /* --------------------------------------------------------------------------
1481                                  Driver Interface
1482    -------------------------------------------------------------------------- */
1483 
1484 /* device interface */
1485 static struct acpi_video_device_attrib*
acpi_video_get_device_attr(struct acpi_video_bus * video,unsigned long device_id)1486 acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1487 {
1488 	struct acpi_video_enumerated_device *ids;
1489 	int i;
1490 
1491 	for (i = 0; i < video->attached_count; i++) {
1492 		ids = &video->attached_array[i];
1493 		if ((ids->value.int_val & 0xffff) == device_id)
1494 			return &ids->value.attrib;
1495 	}
1496 
1497 	return NULL;
1498 }
1499 
1500 static int
acpi_video_bus_get_one_device(struct acpi_device * device,struct acpi_video_bus * video)1501 acpi_video_bus_get_one_device(struct acpi_device *device,
1502 			      struct acpi_video_bus *video)
1503 {
1504 	unsigned long long device_id;
1505 	int status;
1506 	struct acpi_video_device *data;
1507 	struct acpi_video_device_attrib* attribute;
1508 
1509 	if (!device || !video)
1510 		return -EINVAL;
1511 
1512 	status =
1513 	    acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
1514 	if (ACPI_SUCCESS(status)) {
1515 
1516 		data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
1517 		if (!data)
1518 			return -ENOMEM;
1519 
1520 		strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
1521 		strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1522 		device->driver_data = data;
1523 
1524 		data->device_id = device_id;
1525 		data->video = video;
1526 		data->dev = device;
1527 
1528 		attribute = acpi_video_get_device_attr(video, device_id);
1529 
1530 		if((attribute != NULL) && attribute->device_id_scheme) {
1531 			switch (attribute->display_type) {
1532 			case ACPI_VIDEO_DISPLAY_CRT:
1533 				data->flags.crt = 1;
1534 				break;
1535 			case ACPI_VIDEO_DISPLAY_TV:
1536 				data->flags.tvout = 1;
1537 				break;
1538 			case ACPI_VIDEO_DISPLAY_DVI:
1539 				data->flags.dvi = 1;
1540 				break;
1541 			case ACPI_VIDEO_DISPLAY_LCD:
1542 				data->flags.lcd = 1;
1543 				break;
1544 			default:
1545 				data->flags.unknown = 1;
1546 				break;
1547 			}
1548 			if(attribute->bios_can_detect)
1549 				data->flags.bios = 1;
1550 		} else
1551 			data->flags.unknown = 1;
1552 
1553 		acpi_video_device_bind(video, data);
1554 		acpi_video_device_find_cap(data);
1555 
1556 		status = acpi_install_notify_handler(device->handle,
1557 						     ACPI_DEVICE_NOTIFY,
1558 						     acpi_video_device_notify,
1559 						     data);
1560 		if (ACPI_FAILURE(status)) {
1561 			printk(KERN_ERR PREFIX
1562 					  "Error installing notify handler\n");
1563 			if(data->brightness)
1564 				kfree(data->brightness->levels);
1565 			kfree(data->brightness);
1566 			kfree(data);
1567 			return -ENODEV;
1568 		}
1569 
1570 		mutex_lock(&video->device_list_lock);
1571 		list_add_tail(&data->entry, &video->video_device_list);
1572 		mutex_unlock(&video->device_list_lock);
1573 
1574 		acpi_video_device_add_fs(device);
1575 
1576 		return 0;
1577 	}
1578 
1579 	return -ENOENT;
1580 }
1581 
1582 /*
1583  *  Arg:
1584  *  	video	: video bus device
1585  *
1586  *  Return:
1587  *  	none
1588  *
1589  *  Enumerate the video device list of the video bus,
1590  *  bind the ids with the corresponding video devices
1591  *  under the video bus.
1592  */
1593 
acpi_video_device_rebind(struct acpi_video_bus * video)1594 static void acpi_video_device_rebind(struct acpi_video_bus *video)
1595 {
1596 	struct acpi_video_device *dev;
1597 
1598 	mutex_lock(&video->device_list_lock);
1599 
1600 	list_for_each_entry(dev, &video->video_device_list, entry)
1601 		acpi_video_device_bind(video, dev);
1602 
1603 	mutex_unlock(&video->device_list_lock);
1604 }
1605 
1606 /*
1607  *  Arg:
1608  *  	video	: video bus device
1609  *  	device	: video output device under the video
1610  *  		bus
1611  *
1612  *  Return:
1613  *  	none
1614  *
1615  *  Bind the ids with the corresponding video devices
1616  *  under the video bus.
1617  */
1618 
1619 static void
acpi_video_device_bind(struct acpi_video_bus * video,struct acpi_video_device * device)1620 acpi_video_device_bind(struct acpi_video_bus *video,
1621 		       struct acpi_video_device *device)
1622 {
1623 	struct acpi_video_enumerated_device *ids;
1624 	int i;
1625 
1626 	for (i = 0; i < video->attached_count; i++) {
1627 		ids = &video->attached_array[i];
1628 		if (device->device_id == (ids->value.int_val & 0xffff)) {
1629 			ids->bind_info = device;
1630 			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
1631 		}
1632 	}
1633 }
1634 
1635 /*
1636  *  Arg:
1637  *  	video	: video bus device
1638  *
1639  *  Return:
1640  *  	< 0	: error
1641  *
1642  *  Call _DOD to enumerate all devices attached to display adapter
1643  *
1644  */
1645 
acpi_video_device_enumerate(struct acpi_video_bus * video)1646 static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1647 {
1648 	int status;
1649 	int count;
1650 	int i;
1651 	struct acpi_video_enumerated_device *active_list;
1652 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1653 	union acpi_object *dod = NULL;
1654 	union acpi_object *obj;
1655 
1656 	status = acpi_evaluate_object(video->device->handle, "_DOD", NULL, &buffer);
1657 	if (!ACPI_SUCCESS(status)) {
1658 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _DOD"));
1659 		return status;
1660 	}
1661 
1662 	dod = buffer.pointer;
1663 	if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
1664 		ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
1665 		status = -EFAULT;
1666 		goto out;
1667 	}
1668 
1669 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
1670 			  dod->package.count));
1671 
1672 	active_list = kcalloc(1 + dod->package.count,
1673 			      sizeof(struct acpi_video_enumerated_device),
1674 			      GFP_KERNEL);
1675 	if (!active_list) {
1676 		status = -ENOMEM;
1677 		goto out;
1678 	}
1679 
1680 	count = 0;
1681 	for (i = 0; i < dod->package.count; i++) {
1682 		obj = &dod->package.elements[i];
1683 
1684 		if (obj->type != ACPI_TYPE_INTEGER) {
1685 			printk(KERN_ERR PREFIX
1686 				"Invalid _DOD data in element %d\n", i);
1687 			continue;
1688 		}
1689 
1690 		active_list[count].value.int_val = obj->integer.value;
1691 		active_list[count].bind_info = NULL;
1692 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
1693 				  (int)obj->integer.value));
1694 		count++;
1695 	}
1696 
1697 	kfree(video->attached_array);
1698 
1699 	video->attached_array = active_list;
1700 	video->attached_count = count;
1701 
1702  out:
1703 	kfree(buffer.pointer);
1704 	return status;
1705 }
1706 
1707 static int
acpi_video_get_next_level(struct acpi_video_device * device,u32 level_current,u32 event)1708 acpi_video_get_next_level(struct acpi_video_device *device,
1709 			  u32 level_current, u32 event)
1710 {
1711 	int min, max, min_above, max_below, i, l, delta = 255;
1712 	max = max_below = 0;
1713 	min = min_above = 255;
1714 	/* Find closest level to level_current */
1715 	for (i = 2; i < device->brightness->count; i++) {
1716 		l = device->brightness->levels[i];
1717 		if (abs(l - level_current) < abs(delta)) {
1718 			delta = l - level_current;
1719 			if (!delta)
1720 				break;
1721 		}
1722 	}
1723 	/* Ajust level_current to closest available level */
1724 	level_current += delta;
1725 	for (i = 2; i < device->brightness->count; i++) {
1726 		l = device->brightness->levels[i];
1727 		if (l < min)
1728 			min = l;
1729 		if (l > max)
1730 			max = l;
1731 		if (l < min_above && l > level_current)
1732 			min_above = l;
1733 		if (l > max_below && l < level_current)
1734 			max_below = l;
1735 	}
1736 
1737 	switch (event) {
1738 	case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
1739 		return (level_current < max) ? min_above : min;
1740 	case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
1741 		return (level_current < max) ? min_above : max;
1742 	case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
1743 		return (level_current > min) ? max_below : min;
1744 	case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
1745 	case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
1746 		return 0;
1747 	default:
1748 		return level_current;
1749 	}
1750 }
1751 
1752 static void
acpi_video_switch_brightness(struct acpi_video_device * device,int event)1753 acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1754 {
1755 	unsigned long long level_current, level_next;
1756 	if (!device->brightness)
1757 		return;
1758 	acpi_video_device_lcd_get_level_current(device, &level_current);
1759 	level_next = acpi_video_get_next_level(device, level_current, event);
1760 	acpi_video_device_lcd_set_level(device, level_next);
1761 }
1762 
1763 static int
acpi_video_bus_get_devices(struct acpi_video_bus * video,struct acpi_device * device)1764 acpi_video_bus_get_devices(struct acpi_video_bus *video,
1765 			   struct acpi_device *device)
1766 {
1767 	int status = 0;
1768 	struct acpi_device *dev;
1769 
1770 	acpi_video_device_enumerate(video);
1771 
1772 	list_for_each_entry(dev, &device->children, node) {
1773 
1774 		status = acpi_video_bus_get_one_device(dev, video);
1775 		if (ACPI_FAILURE(status)) {
1776 			printk(KERN_WARNING PREFIX
1777 					"Cant attach device");
1778 			continue;
1779 		}
1780 	}
1781 	return status;
1782 }
1783 
acpi_video_bus_put_one_device(struct acpi_video_device * device)1784 static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1785 {
1786 	acpi_status status;
1787 	struct acpi_video_bus *video;
1788 
1789 
1790 	if (!device || !device->video)
1791 		return -ENOENT;
1792 
1793 	video = device->video;
1794 
1795 	acpi_video_device_remove_fs(device->dev);
1796 
1797 	status = acpi_remove_notify_handler(device->dev->handle,
1798 					    ACPI_DEVICE_NOTIFY,
1799 					    acpi_video_device_notify);
1800 	backlight_device_unregister(device->backlight);
1801 	if (device->cdev) {
1802 		sysfs_remove_link(&device->dev->dev.kobj,
1803 				  "thermal_cooling");
1804 		sysfs_remove_link(&device->cdev->device.kobj,
1805 				  "device");
1806 		thermal_cooling_device_unregister(device->cdev);
1807 		device->cdev = NULL;
1808 	}
1809 	video_output_unregister(device->output_dev);
1810 
1811 	return 0;
1812 }
1813 
acpi_video_bus_put_devices(struct acpi_video_bus * video)1814 static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1815 {
1816 	int status;
1817 	struct acpi_video_device *dev, *next;
1818 
1819 	mutex_lock(&video->device_list_lock);
1820 
1821 	list_for_each_entry_safe(dev, next, &video->video_device_list, entry) {
1822 
1823 		status = acpi_video_bus_put_one_device(dev);
1824 		if (ACPI_FAILURE(status))
1825 			printk(KERN_WARNING PREFIX
1826 			       "hhuuhhuu bug in acpi video driver.\n");
1827 
1828 		if (dev->brightness) {
1829 			kfree(dev->brightness->levels);
1830 			kfree(dev->brightness);
1831 		}
1832 		list_del(&dev->entry);
1833 		kfree(dev);
1834 	}
1835 
1836 	mutex_unlock(&video->device_list_lock);
1837 
1838 	return 0;
1839 }
1840 
1841 /* acpi_video interface */
1842 
acpi_video_bus_start_devices(struct acpi_video_bus * video)1843 static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
1844 {
1845 	return acpi_video_bus_DOS(video, 0, 0);
1846 }
1847 
acpi_video_bus_stop_devices(struct acpi_video_bus * video)1848 static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
1849 {
1850 	return acpi_video_bus_DOS(video, 0, 1);
1851 }
1852 
acpi_video_bus_notify(acpi_handle handle,u32 event,void * data)1853 static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1854 {
1855 	struct acpi_video_bus *video = data;
1856 	struct acpi_device *device = NULL;
1857 	struct input_dev *input;
1858 	int keycode;
1859 
1860 	if (!video)
1861 		return;
1862 
1863 	device = video->device;
1864 	input = video->input;
1865 
1866 	switch (event) {
1867 	case ACPI_VIDEO_NOTIFY_SWITCH:	/* User requested a switch,
1868 					 * most likely via hotkey. */
1869 		acpi_bus_generate_proc_event(device, event, 0);
1870 		keycode = KEY_SWITCHVIDEOMODE;
1871 		break;
1872 
1873 	case ACPI_VIDEO_NOTIFY_PROBE:	/* User plugged in or removed a video
1874 					 * connector. */
1875 		acpi_video_device_enumerate(video);
1876 		acpi_video_device_rebind(video);
1877 		acpi_bus_generate_proc_event(device, event, 0);
1878 		keycode = KEY_SWITCHVIDEOMODE;
1879 		break;
1880 
1881 	case ACPI_VIDEO_NOTIFY_CYCLE:	/* Cycle Display output hotkey pressed. */
1882 		acpi_bus_generate_proc_event(device, event, 0);
1883 		keycode = KEY_SWITCHVIDEOMODE;
1884 		break;
1885 	case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT:	/* Next Display output hotkey pressed. */
1886 		acpi_bus_generate_proc_event(device, event, 0);
1887 		keycode = KEY_VIDEO_NEXT;
1888 		break;
1889 	case ACPI_VIDEO_NOTIFY_PREV_OUTPUT:	/* previous Display output hotkey pressed. */
1890 		acpi_bus_generate_proc_event(device, event, 0);
1891 		keycode = KEY_VIDEO_PREV;
1892 		break;
1893 
1894 	default:
1895 		keycode = KEY_UNKNOWN;
1896 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1897 				  "Unsupported event [0x%x]\n", event));
1898 		break;
1899 	}
1900 
1901 	acpi_notifier_call_chain(device, event, 0);
1902 	input_report_key(input, keycode, 1);
1903 	input_sync(input);
1904 	input_report_key(input, keycode, 0);
1905 	input_sync(input);
1906 
1907 	return;
1908 }
1909 
acpi_video_device_notify(acpi_handle handle,u32 event,void * data)1910 static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1911 {
1912 	struct acpi_video_device *video_device = data;
1913 	struct acpi_device *device = NULL;
1914 	struct acpi_video_bus *bus;
1915 	struct input_dev *input;
1916 	int keycode;
1917 
1918 	if (!video_device)
1919 		return;
1920 
1921 	device = video_device->dev;
1922 	bus = video_device->video;
1923 	input = bus->input;
1924 
1925 	switch (event) {
1926 	case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:	/* Cycle brightness */
1927 		if (brightness_switch_enabled)
1928 			acpi_video_switch_brightness(video_device, event);
1929 		acpi_bus_generate_proc_event(device, event, 0);
1930 		keycode = KEY_BRIGHTNESS_CYCLE;
1931 		break;
1932 	case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:	/* Increase brightness */
1933 		if (brightness_switch_enabled)
1934 			acpi_video_switch_brightness(video_device, event);
1935 		acpi_bus_generate_proc_event(device, event, 0);
1936 		keycode = KEY_BRIGHTNESSUP;
1937 		break;
1938 	case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:	/* Decrease brightness */
1939 		if (brightness_switch_enabled)
1940 			acpi_video_switch_brightness(video_device, event);
1941 		acpi_bus_generate_proc_event(device, event, 0);
1942 		keycode = KEY_BRIGHTNESSDOWN;
1943 		break;
1944 	case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:	/* zero brightnesss */
1945 		if (brightness_switch_enabled)
1946 			acpi_video_switch_brightness(video_device, event);
1947 		acpi_bus_generate_proc_event(device, event, 0);
1948 		keycode = KEY_BRIGHTNESS_ZERO;
1949 		break;
1950 	case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:	/* display device off */
1951 		if (brightness_switch_enabled)
1952 			acpi_video_switch_brightness(video_device, event);
1953 		acpi_bus_generate_proc_event(device, event, 0);
1954 		keycode = KEY_DISPLAY_OFF;
1955 		break;
1956 	default:
1957 		keycode = KEY_UNKNOWN;
1958 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1959 				  "Unsupported event [0x%x]\n", event));
1960 		break;
1961 	}
1962 
1963 	acpi_notifier_call_chain(device, event, 0);
1964 	input_report_key(input, keycode, 1);
1965 	input_sync(input);
1966 	input_report_key(input, keycode, 0);
1967 	input_sync(input);
1968 
1969 	return;
1970 }
1971 
1972 static int instance;
acpi_video_resume(struct acpi_device * device)1973 static int acpi_video_resume(struct acpi_device *device)
1974 {
1975 	struct acpi_video_bus *video;
1976 	struct acpi_video_device *video_device;
1977 	int i;
1978 
1979 	if (!device || !acpi_driver_data(device))
1980 		return -EINVAL;
1981 
1982 	video = acpi_driver_data(device);
1983 
1984 	for (i = 0; i < video->attached_count; i++) {
1985 		video_device = video->attached_array[i].bind_info;
1986 		if (video_device && video_device->backlight)
1987 			acpi_video_set_brightness(video_device->backlight);
1988 	}
1989 	return AE_OK;
1990 }
1991 
acpi_video_bus_add(struct acpi_device * device)1992 static int acpi_video_bus_add(struct acpi_device *device)
1993 {
1994 	acpi_status status;
1995 	struct acpi_video_bus *video;
1996 	struct input_dev *input;
1997 	int error;
1998 
1999 	video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
2000 	if (!video)
2001 		return -ENOMEM;
2002 
2003 	/* a hack to fix the duplicate name "VID" problem on T61 */
2004 	if (!strcmp(device->pnp.bus_id, "VID")) {
2005 		if (instance)
2006 			device->pnp.bus_id[3] = '0' + instance;
2007 		instance ++;
2008 	}
2009 	/* a hack to fix the duplicate name "VGA" problem on Pa 3553 */
2010 	if (!strcmp(device->pnp.bus_id, "VGA")) {
2011 		if (instance)
2012 			device->pnp.bus_id[3] = '0' + instance;
2013 		instance++;
2014 	}
2015 
2016 	video->device = device;
2017 	strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
2018 	strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
2019 	device->driver_data = video;
2020 
2021 	acpi_video_bus_find_cap(video);
2022 	error = acpi_video_bus_check(video);
2023 	if (error)
2024 		goto err_free_video;
2025 
2026 	error = acpi_video_bus_add_fs(device);
2027 	if (error)
2028 		goto err_free_video;
2029 
2030 	mutex_init(&video->device_list_lock);
2031 	INIT_LIST_HEAD(&video->video_device_list);
2032 
2033 	acpi_video_bus_get_devices(video, device);
2034 	acpi_video_bus_start_devices(video);
2035 
2036 	status = acpi_install_notify_handler(device->handle,
2037 					     ACPI_DEVICE_NOTIFY,
2038 					     acpi_video_bus_notify, video);
2039 	if (ACPI_FAILURE(status)) {
2040 		printk(KERN_ERR PREFIX
2041 				  "Error installing notify handler\n");
2042 		error = -ENODEV;
2043 		goto err_stop_video;
2044 	}
2045 
2046 	video->input = input = input_allocate_device();
2047 	if (!input) {
2048 		error = -ENOMEM;
2049 		goto err_uninstall_notify;
2050 	}
2051 
2052 	snprintf(video->phys, sizeof(video->phys),
2053 		"%s/video/input0", acpi_device_hid(video->device));
2054 
2055 	input->name = acpi_device_name(video->device);
2056 	input->phys = video->phys;
2057 	input->id.bustype = BUS_HOST;
2058 	input->id.product = 0x06;
2059 	input->dev.parent = &device->dev;
2060 	input->evbit[0] = BIT(EV_KEY);
2061 	set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
2062 	set_bit(KEY_VIDEO_NEXT, input->keybit);
2063 	set_bit(KEY_VIDEO_PREV, input->keybit);
2064 	set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);
2065 	set_bit(KEY_BRIGHTNESSUP, input->keybit);
2066 	set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
2067 	set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
2068 	set_bit(KEY_DISPLAY_OFF, input->keybit);
2069 	set_bit(KEY_UNKNOWN, input->keybit);
2070 
2071 	error = input_register_device(input);
2072 	if (error)
2073 		goto err_free_input_dev;
2074 
2075 	printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s  rom: %s  post: %s)\n",
2076 	       ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
2077 	       video->flags.multihead ? "yes" : "no",
2078 	       video->flags.rom ? "yes" : "no",
2079 	       video->flags.post ? "yes" : "no");
2080 
2081 	return 0;
2082 
2083  err_free_input_dev:
2084 	input_free_device(input);
2085  err_uninstall_notify:
2086 	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
2087 				   acpi_video_bus_notify);
2088  err_stop_video:
2089 	acpi_video_bus_stop_devices(video);
2090 	acpi_video_bus_put_devices(video);
2091 	kfree(video->attached_array);
2092 	acpi_video_bus_remove_fs(device);
2093  err_free_video:
2094 	kfree(video);
2095 	device->driver_data = NULL;
2096 
2097 	return error;
2098 }
2099 
acpi_video_bus_remove(struct acpi_device * device,int type)2100 static int acpi_video_bus_remove(struct acpi_device *device, int type)
2101 {
2102 	acpi_status status = 0;
2103 	struct acpi_video_bus *video = NULL;
2104 
2105 
2106 	if (!device || !acpi_driver_data(device))
2107 		return -EINVAL;
2108 
2109 	video = acpi_driver_data(device);
2110 
2111 	acpi_video_bus_stop_devices(video);
2112 
2113 	status = acpi_remove_notify_handler(video->device->handle,
2114 					    ACPI_DEVICE_NOTIFY,
2115 					    acpi_video_bus_notify);
2116 
2117 	acpi_video_bus_put_devices(video);
2118 	acpi_video_bus_remove_fs(device);
2119 
2120 	input_unregister_device(video->input);
2121 	kfree(video->attached_array);
2122 	kfree(video);
2123 
2124 	return 0;
2125 }
2126 
acpi_video_init(void)2127 static int __init acpi_video_init(void)
2128 {
2129 	int result = 0;
2130 
2131 	acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
2132 	if (!acpi_video_dir)
2133 		return -ENODEV;
2134 	acpi_video_dir->owner = THIS_MODULE;
2135 
2136 	result = acpi_bus_register_driver(&acpi_video_bus);
2137 	if (result < 0) {
2138 		remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
2139 		return -ENODEV;
2140 	}
2141 
2142 	return 0;
2143 }
2144 
acpi_video_exit(void)2145 static void __exit acpi_video_exit(void)
2146 {
2147 
2148 	acpi_bus_unregister_driver(&acpi_video_bus);
2149 
2150 	remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
2151 
2152 	return;
2153 }
2154 
2155 module_init(acpi_video_init);
2156 module_exit(acpi_video_exit);
2157