Platform: Brightness quirk for samsung laptop driver
On some Samsung laptops the brightness regulation works slightly different. All SABI commands except for set_brightness work as expected. The behaviour of set_brightness is as follows: - Setting a new brightness will only step one level toward the new brightness level. For example, setting a level of 5 when the current level is 2 will result in a brightness level of 3. - A spurious KEY_BRIGHTNESS_UP or KEY_BRIGHTNESS_DOWN event is also generated along with the change in brightness. - Neither of the above two issues occur when changing from/to brightness level 0. This patch adds detection and a non-intrusive workaround for the above issues. Signed-off-by: Jason Stubbs <jasonbstubbs@gmail.com> Tested-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Matthew Garrett <mjg@redhat.com>
This commit is contained in:
Родитель
a7ea19926f
Коммит
ac08052314
|
@ -226,6 +226,7 @@ static struct backlight_device *backlight_device;
|
|||
static struct mutex sabi_mutex;
|
||||
static struct platform_device *sdev;
|
||||
static struct rfkill *rfk;
|
||||
static bool has_stepping_quirk;
|
||||
|
||||
static int force;
|
||||
module_param(force, bool, 0);
|
||||
|
@ -382,6 +383,17 @@ static void set_brightness(u8 user_brightness)
|
|||
{
|
||||
u8 user_level = user_brightness + sabi_config->min_brightness;
|
||||
|
||||
if (has_stepping_quirk && user_level != 0) {
|
||||
/*
|
||||
* short circuit if the specified level is what's already set
|
||||
* to prevent the screen from flickering needlessly
|
||||
*/
|
||||
if (user_brightness == read_brightness())
|
||||
return;
|
||||
|
||||
sabi_set_command(sabi_config->commands.set_brightness, 0);
|
||||
}
|
||||
|
||||
sabi_set_command(sabi_config->commands.set_brightness, user_level);
|
||||
}
|
||||
|
||||
|
@ -390,6 +402,34 @@ static int get_brightness(struct backlight_device *bd)
|
|||
return (int)read_brightness();
|
||||
}
|
||||
|
||||
static void check_for_stepping_quirk(void)
|
||||
{
|
||||
u8 initial_level = read_brightness();
|
||||
u8 check_level;
|
||||
|
||||
/*
|
||||
* Some laptops exhibit the strange behaviour of stepping toward
|
||||
* (rather than setting) the brightness except when changing to/from
|
||||
* brightness level 0. This behaviour is checked for here and worked
|
||||
* around in set_brightness.
|
||||
*/
|
||||
|
||||
if (initial_level <= 2)
|
||||
check_level = initial_level + 2;
|
||||
else
|
||||
check_level = initial_level - 2;
|
||||
|
||||
has_stepping_quirk = false;
|
||||
set_brightness(check_level);
|
||||
|
||||
if (read_brightness() != check_level) {
|
||||
has_stepping_quirk = true;
|
||||
pr_info("enabled workaround for brightness stepping quirk\n");
|
||||
}
|
||||
|
||||
set_brightness(initial_level);
|
||||
}
|
||||
|
||||
static int update_status(struct backlight_device *bd)
|
||||
{
|
||||
set_brightness(bd->props.brightness);
|
||||
|
@ -805,6 +845,9 @@ static int __init samsung_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Check for stepping quirk */
|
||||
check_for_stepping_quirk();
|
||||
|
||||
/* knock up a platform device to hang stuff off of */
|
||||
sdev = platform_device_register_simple("samsung", -1, NULL, 0);
|
||||
if (IS_ERR(sdev))
|
||||
|
|
Загрузка…
Ссылка в новой задаче