aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r--drivers/acpi/video.c84
1 files changed, 34 insertions, 50 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index ab06143672bc..d7ff61c0d571 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -79,6 +79,7 @@ module_param(brightness_switch_enabled, bool, 0644);
79static int acpi_video_bus_add(struct acpi_device *device); 79static int acpi_video_bus_add(struct acpi_device *device);
80static int acpi_video_bus_remove(struct acpi_device *device, int type); 80static int acpi_video_bus_remove(struct acpi_device *device, int type);
81static int acpi_video_resume(struct acpi_device *device); 81static int acpi_video_resume(struct acpi_device *device);
82static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
82 83
83static const struct acpi_device_id video_device_ids[] = { 84static const struct acpi_device_id video_device_ids[] = {
84 {ACPI_VIDEO_HID, 0}, 85 {ACPI_VIDEO_HID, 0},
@@ -94,6 +95,7 @@ static struct acpi_driver acpi_video_bus = {
94 .add = acpi_video_bus_add, 95 .add = acpi_video_bus_add,
95 .remove = acpi_video_bus_remove, 96 .remove = acpi_video_bus_remove,
96 .resume = acpi_video_resume, 97 .resume = acpi_video_resume,
98 .notify = acpi_video_bus_notify,
97 }, 99 },
98}; 100};
99 101
@@ -768,10 +770,12 @@ acpi_video_init_brightness(struct acpi_video_device *device)
768 * In this case, the first two elements in _BCL packages 770 * In this case, the first two elements in _BCL packages
769 * are also supported brightness levels that OS should take care of. 771 * are also supported brightness levels that OS should take care of.
770 */ 772 */
771 for (i = 2; i < count; i++) 773 for (i = 2; i < count; i++) {
772 if (br->levels[i] == br->levels[0] || 774 if (br->levels[i] == br->levels[0])
773 br->levels[i] == br->levels[1])
774 level_ac_battery++; 775 level_ac_battery++;
776 if (br->levels[i] == br->levels[1])
777 level_ac_battery++;
778 }
775 779
776 if (level_ac_battery < 2) { 780 if (level_ac_battery < 2) {
777 level_ac_battery = 2 - level_ac_battery; 781 level_ac_battery = 2 - level_ac_battery;
@@ -805,12 +809,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
805 br->flags._BCM_use_index = br->flags._BCL_use_index; 809 br->flags._BCM_use_index = br->flags._BCL_use_index;
806 810
807 /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ 811 /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
808 br->curr = max_level; 812 br->curr = level_old = max_level;
813
814 if (!device->cap._BQC)
815 goto set_level;
816
809 result = acpi_video_device_lcd_get_level_current(device, &level_old); 817 result = acpi_video_device_lcd_get_level_current(device, &level_old);
810 if (result) 818 if (result)
811 goto out_free_levels; 819 goto out_free_levels;
812 820
813 result = acpi_video_device_lcd_set_level(device, br->curr); 821 /*
822 * Set the level to maximum and check if _BQC uses indexed value
823 */
824 result = acpi_video_device_lcd_set_level(device, max_level);
814 if (result) 825 if (result)
815 goto out_free_levels; 826 goto out_free_levels;
816 827
@@ -818,25 +829,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
818 if (result) 829 if (result)
819 goto out_free_levels; 830 goto out_free_levels;
820 831
821 if ((level != level_old) && !br->flags._BCM_use_index) { 832 br->flags._BQC_use_index = (level == max_level ? 0 : 1);
822 /* Note: 833
823 * This piece of code does not work correctly if the current 834 if (!br->flags._BQC_use_index)
824 * brightness levels is 0. 835 goto set_level;
825 * But I guess boxes that boot with such a dark screen are rare 836
826 * and no more code is needed to cover this specifial case. 837 if (br->flags._BCL_reversed)
827 */ 838 level_old = (br->count - 1) - level_old;
828 839 level_old = br->levels[level_old];
829 if (level_ac_battery != 2) { 840
830 /* 841set_level:
831 * For now, we don't support the _BCL like this: 842 result = acpi_video_device_lcd_set_level(device, level_old);
832 * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16 843 if (result)
833 * because we may mess up the index returned by _BQC. 844 goto out_free_levels;
834 * Plus: we have not got a box like this.
835 */
836 ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
837 }
838 br->flags._BQC_use_index = 1;
839 }
840 845
841 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 846 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
842 "found %d brightness levels\n", count - 2)); 847 "found %d brightness levels\n", count - 2));
@@ -1986,17 +1991,15 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
1986 return acpi_video_bus_DOS(video, 0, 1); 1991 return acpi_video_bus_DOS(video, 0, 1);
1987} 1992}
1988 1993
1989static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) 1994static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
1990{ 1995{
1991 struct acpi_video_bus *video = data; 1996 struct acpi_video_bus *video = acpi_driver_data(device);
1992 struct acpi_device *device = NULL;
1993 struct input_dev *input; 1997 struct input_dev *input;
1994 int keycode; 1998 int keycode;
1995 1999
1996 if (!video) 2000 if (!video)
1997 return; 2001 return;
1998 2002
1999 device = video->device;
2000 input = video->input; 2003 input = video->input;
2001 2004
2002 switch (event) { 2005 switch (event) {
@@ -2127,7 +2130,6 @@ static int acpi_video_resume(struct acpi_device *device)
2127 2130
2128static int acpi_video_bus_add(struct acpi_device *device) 2131static int acpi_video_bus_add(struct acpi_device *device)
2129{ 2132{
2130 acpi_status status;
2131 struct acpi_video_bus *video; 2133 struct acpi_video_bus *video;
2132 struct input_dev *input; 2134 struct input_dev *input;
2133 int error; 2135 int error;
@@ -2169,20 +2171,10 @@ static int acpi_video_bus_add(struct acpi_device *device)
2169 acpi_video_bus_get_devices(video, device); 2171 acpi_video_bus_get_devices(video, device);
2170 acpi_video_bus_start_devices(video); 2172 acpi_video_bus_start_devices(video);
2171 2173
2172 status = acpi_install_notify_handler(device->handle,
2173 ACPI_DEVICE_NOTIFY,
2174 acpi_video_bus_notify, video);
2175 if (ACPI_FAILURE(status)) {
2176 printk(KERN_ERR PREFIX
2177 "Error installing notify handler\n");
2178 error = -ENODEV;
2179 goto err_stop_video;
2180 }
2181
2182 video->input = input = input_allocate_device(); 2174 video->input = input = input_allocate_device();
2183 if (!input) { 2175 if (!input) {
2184 error = -ENOMEM; 2176 error = -ENOMEM;
2185 goto err_uninstall_notify; 2177 goto err_stop_video;
2186 } 2178 }
2187 2179
2188 snprintf(video->phys, sizeof(video->phys), 2180 snprintf(video->phys, sizeof(video->phys),
@@ -2218,9 +2210,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
2218 2210
2219 err_free_input_dev: 2211 err_free_input_dev:
2220 input_free_device(input); 2212 input_free_device(input);
2221 err_uninstall_notify:
2222 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
2223 acpi_video_bus_notify);
2224 err_stop_video: 2213 err_stop_video:
2225 acpi_video_bus_stop_devices(video); 2214 acpi_video_bus_stop_devices(video);
2226 acpi_video_bus_put_devices(video); 2215 acpi_video_bus_put_devices(video);
@@ -2235,7 +2224,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
2235 2224
2236static int acpi_video_bus_remove(struct acpi_device *device, int type) 2225static int acpi_video_bus_remove(struct acpi_device *device, int type)
2237{ 2226{
2238 acpi_status status = 0;
2239 struct acpi_video_bus *video = NULL; 2227 struct acpi_video_bus *video = NULL;
2240 2228
2241 2229
@@ -2245,11 +2233,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
2245 video = acpi_driver_data(device); 2233 video = acpi_driver_data(device);
2246 2234
2247 acpi_video_bus_stop_devices(video); 2235 acpi_video_bus_stop_devices(video);
2248
2249 status = acpi_remove_notify_handler(video->device->handle,
2250 ACPI_DEVICE_NOTIFY,
2251 acpi_video_bus_notify);
2252
2253 acpi_video_bus_put_devices(video); 2236 acpi_video_bus_put_devices(video);
2254 acpi_video_bus_remove_fs(device); 2237 acpi_video_bus_remove_fs(device);
2255 2238
@@ -2313,7 +2296,7 @@ static int __init acpi_video_init(void)
2313 return acpi_video_register(); 2296 return acpi_video_register();
2314} 2297}
2315 2298
2316static void __exit acpi_video_exit(void) 2299void __exit acpi_video_exit(void)
2317{ 2300{
2318 2301
2319 acpi_bus_unregister_driver(&acpi_video_bus); 2302 acpi_bus_unregister_driver(&acpi_video_bus);
@@ -2322,6 +2305,7 @@ static void __exit acpi_video_exit(void)
2322 2305
2323 return; 2306 return;
2324} 2307}
2308EXPORT_SYMBOL(acpi_video_exit);
2325 2309
2326module_init(acpi_video_init); 2310module_init(acpi_video_init);
2327module_exit(acpi_video_exit); 2311module_exit(acpi_video_exit);