[PATCH 18/19] platform/x86: lenovo-yogabook: Add keyboard backlight control to platform driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
---
 drivers/platform/x86/lenovo-yogabook-wmi.c | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/platform/x86/lenovo-yogabook-wmi.c b/drivers/platform/x86/lenovo-yogabook-wmi.c
index afb11d25abc8..8e12a625ee65 100644
--- a/drivers/platform/x86/lenovo-yogabook-wmi.c
+++ b/drivers/platform/x86/lenovo-yogabook-wmi.c
@@ -20,6 +20,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>
 
@@ -27,6 +28,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"
 
@@ -49,6 +51,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, u8 level);
 	int pen_touch_irq;
 	int backside_hall_irq;
@@ -433,8 +436,21 @@ static struct gpiod_lookup_table yogabook_pdev_gpios = {
 	},
 };
 
+static struct pwm_lookup yogabook_pdev_pwm_lookup[] = {
+	PWM_LOOKUP_WITH_MODULE("80862289:00", 0, YB_PDEV_NAME,
+			       "kbd_bl_pwm", 13333, PWM_POLARITY_NORMAL,
+			       "pwm-lpss-platform"),
+};
+
 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;
 }
@@ -484,6 +500,16 @@ static int yogabook_pdev_probe(struct platform_device *pdev)
 		goto error_put_devs;
 	}
 
+	pwm_add_table(yogabook_pdev_pwm_lookup, ARRAY_SIZE(yogabook_pdev_pwm_lookup));
+	data->kbd_bl_pwm = devm_pwm_get(dev, "kbd_bl_pwm");
+	pwm_remove_table(yogabook_pdev_pwm_lookup, ARRAY_SIZE(yogabook_pdev_pwm_lookup));
+
+	if (IS_ERR(data->kbd_bl_pwm)) {
+		r = PTR_ERR(data->kbd_bl_pwm);
+		dev_err_probe(dev, r, "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");
-- 
2.39.2




[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux