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:
parent
a7ea19926f
commit
ac08052314
|
@ -226,6 +226,7 @@ static struct backlight_device *backlight_device;
|
||||||
static struct mutex sabi_mutex;
|
static struct mutex sabi_mutex;
|
||||||
static struct platform_device *sdev;
|
static struct platform_device *sdev;
|
||||||
static struct rfkill *rfk;
|
static struct rfkill *rfk;
|
||||||
|
static bool has_stepping_quirk;
|
||||||
|
|
||||||
static int force;
|
static int force;
|
||||||
module_param(force, bool, 0);
|
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;
|
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);
|
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();
|
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)
|
static int update_status(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
set_brightness(bd->props.brightness);
|
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 */
|
/* knock up a platform device to hang stuff off of */
|
||||||
sdev = platform_device_register_simple("samsung", -1, NULL, 0);
|
sdev = platform_device_register_simple("samsung", -1, NULL, 0);
|
||||||
if (IS_ERR(sdev))
|
if (IS_ERR(sdev))
|
||||||
|
|
Loading…
Reference in New Issue