Skip to content

Commit

Permalink
Platform: Brightness quirk for samsung laptop driver
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jason Stubbs authored and Matthew Garrett committed Oct 24, 2011
1 parent a7ea199 commit ac08052
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions drivers/platform/x86/samsung-laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand All @@ -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);
Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit ac08052

Please sign in to comment.