Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac080523 authored by Jason Stubbs's avatar Jason Stubbs Committed by Matthew Garrett
Browse files

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: default avatarJason Stubbs <jasonbstubbs@gmail.com>
Tested-by: default avatarDavid Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: default avatarMatthew Garrett <mjg@redhat.com>
parent a7ea1992
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -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))