View | Details | Raw Unified | Return to bug 16379 | Differences between
and this patch

Collapse All | Expand All

(-)a/drivers/acpi/video.c (-11 / +136 lines)
Lines 481-486 acpi_video_device_set_state(struct acpi_video_device *device, int state) Link Here
481
	return status;
481
	return status;
482
}
482
}
483
483
484
static unsigned int (*acpi_brightness_hook_routine)
485
			(void *dev, unsigned int brightness) = NULL;
486
static char *acpi_brightness_hook_driver;
487
static void *acpi_brightness_hook_dev;
488
static unsigned int acpi_brightness_hook_max;
489
484
static int
490
static int
485
acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
491
acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
486
				   union acpi_object **levels)
492
				   union acpi_object **levels)
Lines 520-532 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) Link Here
520
	struct acpi_object_list args = { 1, &arg0 };
526
	struct acpi_object_list args = { 1, &arg0 };
521
	int state;
527
	int state;
522
528
523
	arg0.integer.value = level;
529
	/* If another driver has registered a brightness hook override,
530
	 * set the brightness using that method, otherwise set the brightness
531
	 * using the acpi _BCM method. */
532
	if ( acpi_brightness_hook_routine ) {
533
		status = acpi_brightness_hook_routine(acpi_brightness_hook_dev,
534
				level * acpi_brightness_hook_max / 100);
535
		if ( status != 0 ) {
536
			ACPI_ERROR((AE_INFO, "brightness hook failed"));
537
			return -EIO;
538
		}
539
	} else {
540
		arg0.integer.value = level;
524
541
525
	status = acpi_evaluate_object(device->dev->handle, "_BCM",
542
		status = acpi_evaluate_object(device->dev->handle, "_BCM",
526
				      &args, NULL);
543
					      &args, NULL);
527
	if (ACPI_FAILURE(status)) {
544
		if (ACPI_FAILURE(status)) {
528
		ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
545
			ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
529
		return -EIO;
546
			return -EIO;
547
		}
530
	}
548
	}
531
549
532
	device->brightness->curr = level;
550
	device->brightness->curr = level;
Lines 607-613 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, Link Here
607
	acpi_status status = AE_OK;
625
	acpi_status status = AE_OK;
608
	int i;
626
	int i;
609
627
610
	if (device->cap._BQC || device->cap._BCQ) {
628
	/* Try to get the current brightness using the _BQC/_BCQ method, only
629
	 * if another driver has not registered a brightness hook override. */
630
	if (!acpi_brightness_hook_routine
631
			&& (device->cap._BQC || device->cap._BCQ)) {
611
		char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
632
		char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
612
633
613
		status = acpi_evaluate_integer(device->dev->handle, buf,
634
		status = acpi_evaluate_integer(device->dev->handle, buf,
Lines 784-790 acpi_video_cmp_level(const void *a, const void *b) Link Here
784
 *  	device	: video output device (LCD, CRT, ..)
805
 *  	device	: video output device (LCD, CRT, ..)
785
 *
806
 *
786
 *  Return Value:
807
 *  Return Value:
787
 *	Maximum brightness level
808
 *  	0 on success, error code on failure.
788
 *
809
 *
789
 *  Allocate and initialize device->brightness.
810
 *  Allocate and initialize device->brightness.
790
 */
811
 */
Lines 944-949 out: Link Here
944
 *	device	: video output device (LCD, CRT, ..)
965
 *	device	: video output device (LCD, CRT, ..)
945
 *
966
 *
946
 *  Return Value:
967
 *  Return Value:
968
 *  	0 on success, error code on failure.
969
 *
970
 *  Allocate and initialize device->brightness. when a driver has registered
971
 *  a brightness hook override via acpi_brightness_hook_register.
972
 *
973
 *  Cobbles up a fake brightness 'levels' array (emulating a _BCL list) and
974
 *  sets max brightness -- effectively what acpi_video_init_brightness does
975
 *  for the native acpi brightness methods
976
 */
977
static int
978
acpi_brightness_hook_init(struct acpi_video_device *device)
979
{
980
	struct acpi_video_device_brightness *br = NULL;
981
	int result = -EINVAL;
982
	int nsteps = 10;
983
	int count, i;
984
	static int initialized = 0;
985
986
	if ( initialized )
987
	    return 1;
988
	initialized = 1;
989
990
	device->brightness = NULL;
991
992
	br = kzalloc(sizeof(*br), GFP_KERNEL);
993
	if (!br) {
994
		printk(KERN_ERR "can't allocate memory\n");
995
		result = -ENOMEM;
996
		return result;
997
	}
998
	br->levels = kmalloc((nsteps + 2) * sizeof *(br->levels),
999
				GFP_KERNEL);
1000
	if (!br->levels) {
1001
		result = -ENOMEM;
1002
		kfree(br);
1003
		return result;
1004
	}
1005
1006
	for (count=2, i = 1; i <= nsteps; i++)
1007
		br->levels[count++] = (u32) i * 100 / nsteps;
1008
	br->levels[0] = 100;
1009
	br->levels[1] = br->levels[2+(nsteps/2)];
1010
	br->count = count;
1011
	device->brightness = br;
1012
1013
	result = acpi_video_device_lcd_set_level(device, 100);
1014
	if (result) {
1015
	    kfree(br->levels);
1016
	    kfree(br);
1017
	    device->brightness = NULL;
1018
	    return result;
1019
	}
1020
1021
	/* Switch off acpi's native brightness switch control */
1022
	brightness_switch_enabled = 0;
1023
1024
	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1025
			  "set up %d brightness levels\n", nsteps));
1026
1027
	return 0;
1028
}
1029
1030
/*
1031
 *  Arg:
1032
 *	driver_name	: name of the registering driver
1033
 *	set_brightness_routine:	pointer to the new set_brightness method
1034
 *	dev		: arbitrary pointer passed to set_brightness_routine
1035
 *	max_brightness	: set_brightnes_routines' maximum brightness value
1036
 *
1037
 *  Return Value:
1038
 *  	None
1039
 *
1040
 *  Register a brightness hook override method, which ACPI will use
1041
 *  instead of its native _BCM/_BCL/_BQC methods.
1042
 */
1043
void acpi_brightness_hook_register(
1044
		char *driver_name,
1045
		unsigned int (*set_brightness_routine)
1046
				(void *dev, unsigned int brightness),
1047
		void *dev, int max_brightness)
1048
{
1049
	acpi_brightness_hook_routine = set_brightness_routine;
1050
	acpi_brightness_hook_driver = driver_name,
1051
	acpi_brightness_hook_dev = dev;
1052
	acpi_brightness_hook_max = max_brightness;
1053
}
1054
EXPORT_SYMBOL(acpi_brightness_hook_register);
1055
1056
/*
1057
 *  Arg:
1058
 *	device	: video output device (LCD, CRT, ..)
1059
 *
1060
 *  Return Value:
947
 *  	None
1061
 *  	None
948
 *
1062
 *
949
 *  Find out all required AML methods defined under the output
1063
 *  Find out all required AML methods defined under the output
Lines 984-1005 static void acpi_video_device_find_cap(struct acpi_video_device *device) Link Here
984
		device->cap._DSS = 1;
1098
		device->cap._DSS = 1;
985
	}
1099
	}
986
1100
987
	if (acpi_video_backlight_support()) {
1101
	if (acpi_brightness_hook_routine || acpi_video_backlight_support()) {
988
		int result;
1102
		int result;
989
		static int count = 0;
1103
		static int count = 0;
990
		char *name;
1104
		char *name;
991
1105
992
		result = acpi_video_init_brightness(device);
1106
		/* If another driver has registered a brightness hook override,
1107
		 * call the brightness_hook init, otherwise call the native
1108
		 * acpi_video brightness init. */
1109
		if (acpi_brightness_hook_routine)
1110
			result = acpi_brightness_hook_init(device);
1111
		else
1112
			result = acpi_video_init_brightness(device);
993
		if (result)
1113
		if (result)
994
			return;
1114
			return;
995
		name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
1115
		name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
996
		if (!name)
1116
		if (!name)
997
			return;
1117
			return;
998
1118
999
		sprintf(name, "acpi_video%d", count++);
1119
		if (acpi_brightness_hook_routine)
1120
			sprintf(name, "%s", acpi_brightness_hook_driver);
1121
		else
1122
			sprintf(name, "acpi_video%d", count++);
1000
		device->backlight = backlight_device_register(name,
1123
		device->backlight = backlight_device_register(name,
1001
			NULL, device, &acpi_backlight_ops);
1124
			NULL, device, &acpi_backlight_ops);
1002
		device->backlight->props.max_brightness = device->brightness->count-3;
1125
		device->backlight->props.max_brightness = device->brightness->count-3;
1126
		dev_info(&device->dev->dev,
1127
				"registered as backlight/%s\n", name);
1003
		kfree(name);
1128
		kfree(name);
1004
1129
1005
		result = sysfs_create_link(&device->backlight->dev.kobj,
1130
		result = sysfs_create_link(&device->backlight->dev.kobj,
(-)a/include/acpi/video.h (-1 / +10 lines)
Lines 2-10 Link Here
2
#define __ACPI_VIDEO_H
2
#define __ACPI_VIDEO_H
3
3
4
#if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE)
4
#if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE)
5
extern void acpi_brightness_hook_register(
6
		char *driver_name,
7
		unsigned int (*set_brightness_routine)
8
				(void *dev, unsigned int brightness),
9
		void *dev, unsigned int max_brightness);
5
extern int acpi_video_register(void);
10
extern int acpi_video_register(void);
6
extern void acpi_video_unregister(void);
11
extern void acpi_video_unregister(void);
7
#else
12
#else
13
static inline acpi_brightness_hook_register(
14
		char *driver_name,
15
		unsigned int (*set_brightness_routine)
16
				(void *dev, unsigned int brightness),
17
		void *dev, unsigned int max_brightness) { return; }
8
static inline int acpi_video_register(void) { return 0; }
18
static inline int acpi_video_register(void) { return 0; }
9
static inline void acpi_video_unregister(void) { return; }
19
static inline void acpi_video_unregister(void) { return; }
10
#endif
20
#endif
11
- 

Return to bug 16379