|
|
b5cf2a1 |
From 714fe15daa07e7691c9731c88de71aa57f84b6c2 Mon Sep 17 00:00:00 2001
|
|
|
b5cf2a1 |
From: Hans de Goede <hdegoede@redhat.com>
|
|
|
b5cf2a1 |
Date: Wed, 3 Jan 2018 11:13:54 +0100
|
|
|
b5cf2a1 |
Subject: [PATCH] platform/x86: dell-laptop: Filter out spurious keyboard
|
|
|
b5cf2a1 |
backlight change events
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
On some Dell XPS models WMI events of type 0x0000 reporting a keycode of
|
|
|
b5cf2a1 |
0xe00c get reported when the brightness of the LCD panel changes.
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
This leads to us reporting false-positive kbd_led change events to
|
|
|
b5cf2a1 |
userspace which in turn leads to the kbd backlight OSD showing when it
|
|
|
b5cf2a1 |
should not.
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
We already read the current keyboard backlight brightness value when
|
|
|
b5cf2a1 |
reporting events because the led_classdev_notify_brightness_hw_changed
|
|
|
b5cf2a1 |
API requires this. Compare this value to the last known value and filter
|
|
|
b5cf2a1 |
out duplicate events, fixing this.
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
Note the fixed issue is esp. a problem on XPS models with an ambient light
|
|
|
b5cf2a1 |
sensor and automatic brightness adjustments turned on, this causes the kbd
|
|
|
b5cf2a1 |
backlight OSD to show all the time there.
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1514969
|
|
|
b5cf2a1 |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
b5cf2a1 |
---
|
|
|
b5cf2a1 |
drivers/platform/x86/dell-laptop.c | 24 ++++++++++++++++++++++--
|
|
|
b5cf2a1 |
1 file changed, 22 insertions(+), 2 deletions(-)
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
|
|
|
b5cf2a1 |
index cd4725e7e0b5..2ef3297a9efc 100644
|
|
|
b5cf2a1 |
--- a/drivers/platform/x86/dell-laptop.c
|
|
|
b5cf2a1 |
+++ b/drivers/platform/x86/dell-laptop.c
|
|
|
b5cf2a1 |
@@ -1133,6 +1133,7 @@ static u8 kbd_previous_mode_bit;
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
static bool kbd_led_present;
|
|
|
b5cf2a1 |
static DEFINE_MUTEX(kbd_led_mutex);
|
|
|
b5cf2a1 |
+static enum led_brightness kbd_led_level;
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
/*
|
|
|
b5cf2a1 |
* NOTE: there are three ways to set the keyboard backlight level.
|
|
|
b5cf2a1 |
@@ -1947,6 +1948,7 @@ static enum led_brightness kbd_led_level_get(struct led_classdev *led_cdev)
|
|
|
b5cf2a1 |
static int kbd_led_level_set(struct led_classdev *led_cdev,
|
|
|
b5cf2a1 |
enum led_brightness value)
|
|
|
b5cf2a1 |
{
|
|
|
b5cf2a1 |
+ enum led_brightness new_value = value;
|
|
|
b5cf2a1 |
struct kbd_state state;
|
|
|
b5cf2a1 |
struct kbd_state new_state;
|
|
|
b5cf2a1 |
u16 num;
|
|
|
b5cf2a1 |
@@ -1976,6 +1978,9 @@ static int kbd_led_level_set(struct led_classdev *led_cdev,
|
|
|
b5cf2a1 |
}
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
out:
|
|
|
b5cf2a1 |
+ if (ret == 0)
|
|
|
b5cf2a1 |
+ kbd_led_level = new_value;
|
|
|
b5cf2a1 |
+
|
|
|
b5cf2a1 |
mutex_unlock(&kbd_led_mutex);
|
|
|
b5cf2a1 |
return ret;
|
|
|
b5cf2a1 |
}
|
|
|
b5cf2a1 |
@@ -2003,6 +2008,9 @@ static int __init kbd_led_init(struct device *dev)
|
|
|
b5cf2a1 |
if (kbd_led.max_brightness)
|
|
|
b5cf2a1 |
kbd_led.max_brightness--;
|
|
|
b5cf2a1 |
}
|
|
|
b5cf2a1 |
+
|
|
|
b5cf2a1 |
+ kbd_led_level = kbd_led_level_get(NULL);
|
|
|
b5cf2a1 |
+
|
|
|
b5cf2a1 |
ret = led_classdev_register(dev, &kbd_led);
|
|
|
b5cf2a1 |
if (ret)
|
|
|
b5cf2a1 |
kbd_led_present = false;
|
|
|
b5cf2a1 |
@@ -2027,13 +2035,25 @@ static void kbd_led_exit(void)
|
|
|
b5cf2a1 |
static int dell_laptop_notifier_call(struct notifier_block *nb,
|
|
|
b5cf2a1 |
unsigned long action, void *data)
|
|
|
b5cf2a1 |
{
|
|
|
b5cf2a1 |
+ bool changed = false;
|
|
|
b5cf2a1 |
+ enum led_brightness new_kbd_led_level;
|
|
|
b5cf2a1 |
+
|
|
|
b5cf2a1 |
switch (action) {
|
|
|
b5cf2a1 |
case DELL_LAPTOP_KBD_BACKLIGHT_BRIGHTNESS_CHANGED:
|
|
|
b5cf2a1 |
if (!kbd_led_present)
|
|
|
b5cf2a1 |
break;
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
- led_classdev_notify_brightness_hw_changed(&kbd_led,
|
|
|
b5cf2a1 |
- kbd_led_level_get(&kbd_led));
|
|
|
b5cf2a1 |
+ mutex_lock(&kbd_led_mutex);
|
|
|
b5cf2a1 |
+ new_kbd_led_level = kbd_led_level_get(&kbd_led);
|
|
|
b5cf2a1 |
+ if (kbd_led_level != new_kbd_led_level) {
|
|
|
b5cf2a1 |
+ kbd_led_level = new_kbd_led_level;
|
|
|
b5cf2a1 |
+ changed = true;
|
|
|
b5cf2a1 |
+ }
|
|
|
b5cf2a1 |
+ mutex_unlock(&kbd_led_mutex);
|
|
|
b5cf2a1 |
+
|
|
|
b5cf2a1 |
+ if (changed)
|
|
|
b5cf2a1 |
+ led_classdev_notify_brightness_hw_changed(&kbd_led,
|
|
|
b5cf2a1 |
+ kbd_led_level);
|
|
|
b5cf2a1 |
break;
|
|
|
b5cf2a1 |
}
|
|
|
b5cf2a1 |
|
|
|
b5cf2a1 |
--
|
|
|
b5cf2a1 |
2.14.3
|
|
|
b5cf2a1 |
|