lkml.org 
[lkml]   [2018]   [Apr]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.14 013/161] platform/x86: dell-laptop: Filter out spurious keyboard backlight change events
    Date
    From: Hans de Goede <hdegoede@redhat.com>

    [ Upstream commit 4d6bde512a86c32df3a1f289d2b4cd04b17758d1 ]

    On some Dell XPS models WMI events of type 0x0000 reporting a keycode of
    0xe00c get reported when the brightness of the LCD panel changes.

    This leads to us reporting false-positive kbd_led change events to
    userspace which in turn leads to the kbd backlight OSD showing when it
    should not.

    We already read the current keyboard backlight brightness value when
    reporting events because the led_classdev_notify_brightness_hw_changed
    API requires this. Compare this value to the last known value and filter
    out duplicate events, fixing this.

    Note the fixed issue is esp. a problem on XPS models with an ambient light
    sensor and automatic brightness adjustments turned on, this causes the kbd
    backlight OSD to show all the time there.

    BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1514969
    Fixes: 9c656b0799 ("platform/x86: dell-*: Call new led hw_changed API ...")
    Acked-by: Pali Rohár <pali.rohar@gmail.com>
    Signed-off-by: Hans de Goede <hdegoede@redhat.com>
    Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    drivers/platform/x86/dell-laptop.c | 24 ++++++++++++++++++++++--
    1 file changed, 22 insertions(+), 2 deletions(-)

    diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
    index 7424e53157b0..dd5043a6a114 100644
    --- a/drivers/platform/x86/dell-laptop.c
    +++ b/drivers/platform/x86/dell-laptop.c
    @@ -1177,6 +1177,7 @@ static u8 kbd_previous_mode_bit;

    static bool kbd_led_present;
    static DEFINE_MUTEX(kbd_led_mutex);
    +static enum led_brightness kbd_led_level;

    /*
    * NOTE: there are three ways to set the keyboard backlight level.
    @@ -2020,6 +2021,7 @@ static enum led_brightness kbd_led_level_get(struct led_classdev *led_cdev)
    static int kbd_led_level_set(struct led_classdev *led_cdev,
    enum led_brightness value)
    {
    + enum led_brightness new_value = value;
    struct kbd_state state;
    struct kbd_state new_state;
    u16 num;
    @@ -2049,6 +2051,9 @@ static int kbd_led_level_set(struct led_classdev *led_cdev,
    }

    out:
    + if (ret == 0)
    + kbd_led_level = new_value;
    +
    mutex_unlock(&kbd_led_mutex);
    return ret;
    }
    @@ -2076,6 +2081,9 @@ static int __init kbd_led_init(struct device *dev)
    if (kbd_led.max_brightness)
    kbd_led.max_brightness--;
    }
    +
    + kbd_led_level = kbd_led_level_get(NULL);
    +
    ret = led_classdev_register(dev, &kbd_led);
    if (ret)
    kbd_led_present = false;
    @@ -2100,13 +2108,25 @@ static void kbd_led_exit(void)
    static int dell_laptop_notifier_call(struct notifier_block *nb,
    unsigned long action, void *data)
    {
    + bool changed = false;
    + enum led_brightness new_kbd_led_level;
    +
    switch (action) {
    case DELL_LAPTOP_KBD_BACKLIGHT_BRIGHTNESS_CHANGED:
    if (!kbd_led_present)
    break;

    - led_classdev_notify_brightness_hw_changed(&kbd_led,
    - kbd_led_level_get(&kbd_led));
    + mutex_lock(&kbd_led_mutex);
    + new_kbd_led_level = kbd_led_level_get(&kbd_led);
    + if (kbd_led_level != new_kbd_led_level) {
    + kbd_led_level = new_kbd_led_level;
    + changed = true;
    + }
    + mutex_unlock(&kbd_led_mutex);
    +
    + if (changed)
    + led_classdev_notify_brightness_hw_changed(&kbd_led,
    + kbd_led_level);
    break;
    }

    --
    2.15.1
    \
     
     \ /
      Last update: 2018-04-09 05:26    [W:4.169 / U:0.504 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site