From: Jeremy Soller <jeremy@xxxxxxxxxxxx> System76 laptops models with OLED displays do not support the default Fn+F2 behavior of turning the embedded display on and off. Some models instead introduce a new notify event that is used to lock the screen so the OS will put the display in a low power state. Signed-off-by: Jeremy Soller <jeremy@xxxxxxxxxxxx> Signed-off-by: Tim Crawford <tcrawford@xxxxxxxxxxxx> --- drivers/platform/x86/system76_acpi.c | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/platform/x86/system76_acpi.c b/drivers/platform/x86/system76_acpi.c index 11f0e42386ba..e7c86b543930 100644 --- a/drivers/platform/x86/system76_acpi.c +++ b/drivers/platform/x86/system76_acpi.c @@ -13,6 +13,7 @@ #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> #include <linux/init.h> +#include <linux/input.h> #include <linux/kernel.h> #include <linux/leds.h> #include <linux/module.h> @@ -29,6 +30,7 @@ struct system76_data { struct device *therm; union acpi_object *nfan; union acpi_object *ntmp; + struct input_dev *input; }; static const struct acpi_device_id device_ids[] = { @@ -430,6 +432,15 @@ static const struct hwmon_chip_info thermal_chip_info = { .info = thermal_channel_info, }; +static void input_key(struct system76_data *data, unsigned int code) +{ + input_report_key(data->input, code, 1); + input_sync(data->input); + + input_report_key(data->input, code, 0); + input_sync(data->input); +} + // Handle ACPI notification static void system76_notify(struct acpi_device *acpi_dev, u32 event) { @@ -452,6 +463,9 @@ static void system76_notify(struct acpi_device *acpi_dev, u32 event) case 0x84: kb_led_hotkey_color(data); break; + case 0x85: + input_key(data, KEY_SCREENLOCK); + break; } } @@ -514,6 +528,22 @@ static int system76_add(struct acpi_device *acpi_dev) if (IS_ERR(data->therm)) return PTR_ERR(data->therm); + data->input = devm_input_allocate_device(&acpi_dev->dev); + if (!data->input) + return -ENOMEM; + + data->input->name = "System76 ACPI Hotkeys"; + data->input->phys = "system76_acpi/input0"; + data->input->id.bustype = BUS_HOST; + data->input->dev.parent = &acpi_dev->dev; + input_set_capability(data->input, EV_KEY, KEY_SCREENLOCK); + + err = input_register_device(data->input); + if (err) { + input_free_device(data->input); + return err; + } + return 0; } -- 2.31.1