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, |