summaryrefslogtreecommitdiff
path: root/drivers/platform/x86
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2023-04-30 19:58:06 +0300
committerHans de Goede <hdegoede@redhat.com>2023-05-09 13:35:03 +0300
commitfc4f1d88bc6b1780b9c807fab0b79755e7996116 (patch)
treef2b634edb4c613363478a3071d7c79b5fda0d393 /drivers/platform/x86
parent6df1523fa0b7991ea9c8e2ef8f9a238b19309a5d (diff)
downloadlinux-fc4f1d88bc6b1780b9c807fab0b79755e7996116.tar.xz
platform/x86: lenovo-yogabook: Add keyboard backlight control to platform driver
On the Android yb1-x90f/l models there is not ACPI method to control the keyboard backlight brightness. Instead the second PWM controller is exposed directly to the OS there. Add support for controlling keyboard backlight brightness on the Android model by using the PWM subsystem to directly control the PWM. The Android model also requires explicitly turning the backlight off on suspend, which on the Windows model was done automatically. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Link: https://lore.kernel.org/r/20230430165807.472798-19-hdegoede@redhat.com
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r--drivers/platform/x86/lenovo-yogabook-wmi.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/platform/x86/lenovo-yogabook-wmi.c b/drivers/platform/x86/lenovo-yogabook-wmi.c
index 00ca9f50f0da..b8d0239192cb 100644
--- a/drivers/platform/x86/lenovo-yogabook-wmi.c
+++ b/drivers/platform/x86/lenovo-yogabook-wmi.c
@@ -19,6 +19,7 @@
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/pwm.h>
#include <linux/wmi.h>
#include <linux/workqueue.h>
@@ -26,6 +27,7 @@
#define YB_KBD_BL_DEFAULT 128
#define YB_KBD_BL_MAX 255
+#define YB_KBD_BL_PWM_PERIOD 13333
#define YB_PDEV_NAME "yogabook-touch-kbd-digitizer-switch"
@@ -48,6 +50,7 @@ struct yogabook_data {
struct gpio_desc *pen_touch_event;
struct gpio_desc *kbd_bl_led_enable;
struct gpio_desc *backside_hall_gpio;
+ struct pwm_device *kbd_bl_pwm;
int (*set_kbd_backlight)(struct yogabook_data *data, uint8_t level);
int pen_touch_irq;
int backside_hall_irq;
@@ -267,8 +270,11 @@ static int yogabook_suspend(struct device *dev)
struct yogabook_data *data = dev_get_drvdata(dev);
set_bit(YB_SUSPENDED, &data->flags);
-
flush_work(&data->work);
+
+ if (test_bit(YB_KBD_IS_ON, &data->flags))
+ data->set_kbd_backlight(data, 0);
+
return 0;
}
@@ -423,6 +429,13 @@ static struct gpiod_lookup_table yogabook_pdev_gpios = {
static int yogabook_pdev_set_kbd_backlight(struct yogabook_data *data, u8 level)
{
+ struct pwm_state state = {
+ .period = YB_KBD_BL_PWM_PERIOD,
+ .duty_cycle = YB_KBD_BL_PWM_PERIOD * level / YB_KBD_BL_MAX,
+ .enabled = level,
+ };
+
+ pwm_apply_state(data->kbd_bl_pwm, &state);
gpiod_set_value(data->kbd_bl_led_enable, level ? 1 : 0);
return 0;
}
@@ -472,6 +485,13 @@ static int yogabook_pdev_probe(struct platform_device *pdev)
goto error_put_devs;
}
+ data->kbd_bl_pwm = devm_pwm_get(dev, "pwm_soc_lpss_2");
+ if (IS_ERR(data->kbd_bl_pwm)) {
+ r = dev_err_probe(dev, PTR_ERR(data->kbd_bl_pwm),
+ "Getting keyboard backlight PWM\n");
+ goto error_put_devs;
+ }
+
r = gpiod_to_irq(data->pen_touch_event);
if (r < 0) {
dev_err_probe(dev, r, "Getting pen_touch_event IRQ\n");