From 46b97534373f56a6689878bb894def74785f1ab7 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Tue, 30 May 2023 17:35:25 +0200 Subject: [PATCH 01/11] Make keycodes human readable --- src/uniwill_keyboard.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 20dcc02..d123a44 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -237,13 +237,12 @@ static int keyboard_notifier_callb(struct notifier_block *nb, unsigned long code int ret = NOTIFY_OK; if (!param->down) { - if (code == KBD_KEYCODE) { switch (param->value) { - case 125: + case KEY_LEFTMETA: // If the last keys up were 85 -> 29 -> 125 // manually report KEY_F21 - if (prevprev_key == 85 && prev_key == 29) { + if (prevprev_key == KEY_ZENKAKUHANKAKU && prev_key == KEY_LEFTCTRL) { TUXEDO_DEBUG("Touchpad Toggle\n"); schedule_work(&uniwill_key_event_work); ret = NOTIFY_OK; From 06f0798162f72e7e2b33e053ea554f283d00d0fc Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Tue, 30 May 2023 17:36:40 +0200 Subject: [PATCH 02/11] Slim down state restore by not rewriting unchanged values in led_cdev struct --- src/uniwill_leds.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/uniwill_leds.h b/src/uniwill_leds.h index 1f14ee7..a129f4c 100644 --- a/src/uniwill_leds.h +++ b/src/uniwill_leds.h @@ -287,7 +287,9 @@ void uniwill_leds_restore_state_extern(void) { if (uw_leds_initialized) { if (uniwill_kb_backlight_type == UNIWILL_KB_BACKLIGHT_TYPE_FIXED_COLOR) { - uniwill_led_cdev.brightness_set(&uniwill_led_cdev, uniwill_led_cdev.brightness); + if (uniwill_write_kbd_bl_white(uniwill_led_cdev.brightness)) { + pr_debug("uniwill_leds_restore_state_extern(): uniwill_write_kbd_bl_white() failed\n"); + } } else if (uniwill_kb_backlight_type == UNIWILL_KB_BACKLIGHT_TYPE_1_ZONE_RGB) { // reset @@ -296,7 +298,11 @@ void uniwill_leds_restore_state_extern(void) { uniwill_write_ec_ram(UW_EC_REG_KBD_BL_STATUS, data); // write - uniwill_mcled_cdev.led_cdev.brightness_set(&uniwill_mcled_cdev.led_cdev, uniwill_mcled_cdev.led_cdev.brightness); + if (uniwill_write_kbd_bl_rgb(uniwill_mcled_cdev.subled_info[0].brightness, + uniwill_mcled_cdev.subled_info[1].brightness, + uniwill_mcled_cdev.subled_info[2].brightness)) { + pr_debug("uniwill_leds_restore_state_extern(): uniwill_write_kbd_bl_rgb() failed\n"); + } } } } From 52cf5103036b84dcebd228bea9beb5a73c6313e5 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Wed, 31 May 2023 14:14:14 +0200 Subject: [PATCH 03/11] Add unused attributes to avoid compiler warnings --- src/tuxedo_io/tuxedo_io.c | 2 +- src/uniwill_keyboard.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 92ea34c..1d4b01e 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -52,7 +52,7 @@ static struct uniwill_device_features_t *uw_feats; /** * strstr version of dmi_match */ -static bool dmi_string_in(enum dmi_field f, const char *str) +static bool __attribute__ ((unused)) dmi_string_in(enum dmi_field f, const char *str) { const char *info = dmi_get_system_info(f); diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index d123a44..5dd1ae5 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -785,7 +785,7 @@ static int uw_has_charging_profile(bool *status) return 0; } -static void uw_charging_profile_write_state(void) +static void __attribute__ ((unused)) uw_charging_profile_write_state(void) { if (uw_charging_profile_loaded) uw_set_charging_profile(uw_charging_profile_last_written_value); From 319d7b14a13935b9bf20976b11124a1bb42c9e59 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Wed, 31 May 2023 14:17:11 +0200 Subject: [PATCH 04/11] Don't send key event for firmware controlled TF white only backlights, but only notify userspace of change --- src/uniwill_keyboard.h | 57 +++++++++++++++++++++++++----------------- src/uniwill_leds.h | 19 +++++++++++++- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 5dd1ae5..8a2fb84 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -274,29 +274,40 @@ static void uniwill_write_kbd_bl_enable(u8 enable) void uniwill_event_callb(u32 code) { - if (uniwill_keyboard_driver.input_device != NULL) - if (!sparse_keymap_report_known_event(uniwill_keyboard_driver.input_device, code, 1, true)) { - TUXEDO_DEBUG("Unknown code - %d (%0#6x)\n", code, code); - } - - // Special key combination when mode change key is pressed - if (code == UNIWILL_OSD_MODE_CHANGE_KEY_EVENT) { - input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTMETA, 1); - input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTALT, 1); - input_report_key(uniwill_keyboard_driver.input_device, KEY_F6, 1); - input_sync(uniwill_keyboard_driver.input_device); - input_report_key(uniwill_keyboard_driver.input_device, KEY_F6, 0); - input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTALT, 0); - input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTMETA, 0); - input_sync(uniwill_keyboard_driver.input_device); - } - - // Refresh keyboard state and charging prio on cable switch event - if (code == UNIWILL_OSD_DC_ADAPTER_CHANGE) { - uniwill_leds_restore_state_extern(); - - msleep(50); - uw_charging_priority_write_state(); + switch (code) { + case UNIWILL_OSD_MODE_CHANGE_KEY_EVENT: + // Special key combination when mode change key is pressed (the one next to + // the power key). Opens TCC by default when installed. + input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTMETA, 1); + input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTALT, 1); + input_report_key(uniwill_keyboard_driver.input_device, KEY_F6, 1); + input_sync(uniwill_keyboard_driver.input_device); + input_report_key(uniwill_keyboard_driver.input_device, KEY_F6, 0); + input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTALT, 0); + input_report_key(uniwill_keyboard_driver.input_device, KEY_LEFTMETA, 0); + input_sync(uniwill_keyboard_driver.input_device); + break; + case UNIWILL_OSD_DC_ADAPTER_CHANGE: + // Refresh keyboard state and charging prio on cable switch event + uniwill_leds_restore_state_extern(); + msleep(50); + uw_charging_priority_write_state(); + break; + case UNIWILL_OSD_KB_LED_LEVEL0: + case UNIWILL_OSD_KB_LED_LEVEL1: + case UNIWILL_OSD_KB_LED_LEVEL2: + case UNIWILL_OSD_KB_LED_LEVEL3: + case UNIWILL_OSD_KB_LED_LEVEL4: + // Notify userspace/UPower that the firmware changed the keyboard backlight + // brightness on white only keyboards. Fallthrough on other keyboards to + // emit KEY_KBDILLUMTOGGLE. + if (uniwill_leds_notify_brightness_change_extern()) + return; + fallthrough; + default: + if (uniwill_keyboard_driver.input_device != NULL) + if (!sparse_keymap_report_known_event(uniwill_keyboard_driver.input_device, code, 1, true)) + TUXEDO_DEBUG("Unknown code - %d (%0#6x)\n", code, code); } } diff --git a/src/uniwill_leds.h b/src/uniwill_leds.h index a129f4c..a572272 100644 --- a/src/uniwill_leds.h +++ b/src/uniwill_leds.h @@ -47,6 +47,7 @@ int uniwill_leds_init_early(struct platform_device *dev); int uniwill_leds_init_late(struct platform_device *dev); int uniwill_leds_remove(struct platform_device *dev); enum uniwill_kb_backlight_types uniwill_leds_get_backlight_type(void); +int uniwill_leds_notify_brightness_change_extern(void); void uniwill_leds_restore_state_extern(void); void uniwill_leds_set_brightness_extern(enum led_brightness brightness); void uniwill_leds_set_color_extern(u32 color); @@ -135,7 +136,8 @@ static struct led_classdev uniwill_led_cdev = { .name = "white:" LED_FUNCTION_KBD_BACKLIGHT, .max_brightness = UNIWILL_KBD_BRIGHTNESS_WHITE_MAX, .brightness_set = &uniwill_leds_set_brightness, - .brightness = UNIWILL_KBD_BRIGHTNESS_WHITE_DEFAULT + .brightness = UNIWILL_KBD_BRIGHTNESS_WHITE_DEFAULT, + .flags = LED_BRIGHT_HW_CHANGED }; static struct mc_subled uw_mcled_cdev_subleds[3] = { @@ -164,6 +166,7 @@ static struct led_classdev_mc uniwill_mcled_cdev = { .led_cdev.max_brightness = UNIWILL_KBD_BRIGHTNESS_MAX, .led_cdev.brightness_set = &uniwill_leds_set_brightness_mc, .led_cdev.brightness = UNIWILL_KBD_BRIGHTNESS_DEFAULT, + .led_cdev.flags = LED_BRIGHT_HW_CHANGED, .num_colors = 3, .subled_info = uw_mcled_cdev_subleds }; @@ -282,6 +285,20 @@ enum uniwill_kb_backlight_types uniwill_leds_get_backlight_type(void) { } EXPORT_SYMBOL(uniwill_leds_get_backlight_type); +int uniwill_leds_notify_brightness_change_extern(void) { + u8 data = 0; + + if (uw_leds_initialized) { + if (uniwill_kb_backlight_type == UNIWILL_KB_BACKLIGHT_TYPE_FIXED_COLOR) { + uniwill_read_ec_ram(UW_EC_REG_KBD_BL_STATUS, &data); + data = (data >> 5) & 0x3; + led_classdev_notify_brightness_hw_changed(&uniwill_led_cdev, data); + return true; + } + } + return false; +} + void uniwill_leds_restore_state_extern(void) { u8 data; From 91a69bab8cd7e0dbfa4df7fe35829fc85c82dcf2 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Wed, 31 May 2023 14:28:38 +0200 Subject: [PATCH 05/11] TF: KBL: Add additional event code for FW brightness change event --- src/uniwill_keyboard.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 8a2fb84..208be68 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -293,6 +293,7 @@ void uniwill_event_callb(u32 code) msleep(50); uw_charging_priority_write_state(); break; + case UNIWILL_KEY_KBDILLUMTOGGLE: case UNIWILL_OSD_KB_LED_LEVEL0: case UNIWILL_OSD_KB_LED_LEVEL1: case UNIWILL_OSD_KB_LED_LEVEL2: From 81d6fe0e10bb69e1c6cbb8fd42a9291b97633713 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Mon, 19 Jun 2023 16:09:59 +0200 Subject: [PATCH 06/11] Prepare clevo skeleton --- src/clevo_keyboard.h | 7 +++++-- src/clevo_leds.h | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/clevo_keyboard.h b/src/clevo_keyboard.h index d069fe2..7269017 100644 --- a/src/clevo_keyboard.h +++ b/src/clevo_keyboard.h @@ -54,8 +54,8 @@ static struct key_entry clevo_keymap[] = { { KE_KEY, CLEVO_EVENT_KB_LEDS_INCREASE, { KEY_KBDILLUMUP } }, { KE_KEY, CLEVO_EVENT_KB_LEDS_TOGGLE, { KEY_KBDILLUMTOGGLE } }, { KE_KEY, CLEVO_EVENT_KB_LEDS_CYCLE_MODE, { KEY_LIGHTS_TOGGLE } }, - // Single cycle key (white only versions) - { KE_KEY, CLEVO_EVENT_KB_LEDS_CYCLE_BRIGHTNESS, { KEY_KBDILLUMTOGGLE } }, + // Single cycle key (white only versions) (currently handled in driver) + // { KE_KEY, CLEVO_EVENT_KB_LEDS_CYCLE_BRIGHTNESS, { KEY_KBDILLUMTOGGLE } }, // Touchpad // The weirdly named touchpad toggle key that is implemented as KEY_F21 "everywhere" @@ -256,6 +256,9 @@ static void clevo_keyboard_event_callb(u32 event) case CLEVO_EVENT_KB_LEDS_CYCLE_MODE: set_next_color_whole_kb(); break; + case CLEVO_EVENT_KB_LEDS_CYCLE_BRIGHTNESS: + clevo_leds_notify_brightness_change_extern(); + break; default: break; } diff --git a/src/clevo_leds.h b/src/clevo_leds.h index ba1c11b..c3242eb 100644 --- a/src/clevo_leds.h +++ b/src/clevo_leds.h @@ -36,6 +36,7 @@ int clevo_leds_init(struct platform_device *dev); int clevo_leds_remove(struct platform_device *dev); enum clevo_kb_backlight_types clevo_leds_get_backlight_type(void); void clevo_leds_restore_state_extern(void); +void clevo_leds_notify_brightness_change_extern(void); void clevo_leds_set_brightness_extern(enum led_brightness brightness); void clevo_leds_set_color_extern(u32 color); @@ -414,6 +415,13 @@ void clevo_leds_restore_state_extern(void) { } EXPORT_SYMBOL(clevo_leds_restore_state_extern); +void clevo_leds_notify_brightness_change_extern(void) { + if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { + // TODO + } +} +EXPORT_SYMBOL(clevo_leds_notify_brightness_change_extern); + void clevo_leds_set_brightness_extern(enum led_brightness brightness) { if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { clevo_led_cdev.brightness_set(&clevo_led_cdev, brightness); From e66e2b1fb345a1f2dbf22653da3b43af897cfac9 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Mon, 19 Jun 2023 17:55:30 +0200 Subject: [PATCH 07/11] Fix compiler warning --- src/uniwill_keyboard.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 208be68..fb62732 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -1151,10 +1151,11 @@ static int uniwill_keyboard_probe(struct platform_device *dev) u32 i; u8 data; int status; + struct uniwill_device_features_t *uw_feats; set_rom_id(); - struct uniwill_device_features_t *uw_feats = uniwill_get_device_features(); + uw_feats = uniwill_get_device_features(); // FIXME Hard set balanced profile until we have implemented a way to // switch it while tuxedo_io is loaded From d13eaeb043c05aba58e5cd5c538ead59874ed9be Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Mon, 19 Jun 2023 17:56:50 +0200 Subject: [PATCH 08/11] Fix return types --- src/clevo_acpi.c | 10 +++++----- src/clevo_interfaces.h | 12 ++++++------ src/clevo_keyboard.h | 12 ++++++------ src/clevo_leds.h | 2 +- src/clevo_wmi.c | 8 ++++---- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/clevo_acpi.c b/src/clevo_acpi.c index e1abd8f..f8f5442 100644 --- a/src/clevo_acpi.c +++ b/src/clevo_acpi.c @@ -32,9 +32,9 @@ struct clevo_acpi_driver_data_t { static struct clevo_acpi_driver_data_t *active_driver_data = NULL; -static u32 clevo_acpi_evaluate(struct acpi_device *device, u8 cmd, u32 arg, union acpi_object **result) +static int clevo_acpi_evaluate(struct acpi_device *device, u8 cmd, u32 arg, union acpi_object **result) { - u32 status; + int status; acpi_handle handle; u64 dsm_rev_dummy = 0x00; // Dummy 0 value since not used u64 dsm_func = cmd; @@ -79,9 +79,9 @@ static u32 clevo_acpi_evaluate(struct acpi_device *device, u8 cmd, u32 arg, unio return status; } -u32 clevo_acpi_interface_method_call(u8 cmd, u32 arg, union acpi_object **result_value) +int clevo_acpi_interface_method_call(u8 cmd, u32 arg, union acpi_object **result_value) { - u32 status = 0; + int status = 0; if (!IS_ERR_OR_NULL(active_driver_data)) { status = clevo_acpi_evaluate(active_driver_data->adev, cmd, arg, result_value); @@ -141,7 +141,7 @@ void clevo_acpi_notify(struct acpi_device *device, u32 event) { u32 event_value; union acpi_object *out_obj; - u32 status; + int status; // struct clevo_acpi_driver_data_t *clevo_acpi_driver_data; status = clevo_acpi_evaluate(device, 0x01, 0, &out_obj); diff --git a/src/clevo_interfaces.h b/src/clevo_interfaces.h index fabeff5..9b87a6a 100644 --- a/src/clevo_interfaces.h +++ b/src/clevo_interfaces.h @@ -72,14 +72,14 @@ struct clevo_interface_t { char *string_id; void (*event_callb)(u32); - u32 (*method_call)(u8, u32, union acpi_object **); + int (*method_call)(u8, u32, union acpi_object **); }; -u32 clevo_keyboard_add_interface(struct clevo_interface_t *new_interface); -u32 clevo_keyboard_remove_interface(struct clevo_interface_t *interface); -u32 clevo_evaluate_method(u8 cmd, u32 arg, u32 *result); -u32 clevo_evaluate_method2(u8 cmd, u32 arg, union acpi_object **result); -u32 clevo_get_active_interface_id(char **id_str); +int clevo_keyboard_add_interface(struct clevo_interface_t *new_interface); +int clevo_keyboard_remove_interface(struct clevo_interface_t *interface); +int clevo_evaluate_method(u8 cmd, u32 arg, u32 *result); +int clevo_evaluate_method2(u8 cmd, u32 arg, union acpi_object **result); +int clevo_get_active_interface_id(char **id_str); #define MODULE_ALIAS_CLEVO_WMI() \ MODULE_ALIAS("wmi:" CLEVO_WMI_EVENT_GUID); \ diff --git a/src/clevo_keyboard.h b/src/clevo_keyboard.h index 7269017..8aea994 100644 --- a/src/clevo_keyboard.h +++ b/src/clevo_keyboard.h @@ -106,7 +106,7 @@ static struct kbd_backlight_mode_t { { .key = 7, .value = 0xB0000000, .name = "WAVE"} }; -u32 clevo_evaluate_method2(u8 cmd, u32 arg, union acpi_object **result) +int clevo_evaluate_method2(u8 cmd, u32 arg, union acpi_object **result) { if (IS_ERR_OR_NULL(active_clevo_interface)) { pr_err("clevo_keyboard: no active interface while attempting cmd %02x arg %08x\n", cmd, arg); @@ -116,9 +116,9 @@ u32 clevo_evaluate_method2(u8 cmd, u32 arg, union acpi_object **result) } EXPORT_SYMBOL(clevo_evaluate_method2); -u32 clevo_evaluate_method(u8 cmd, u32 arg, u32 *result) +int clevo_evaluate_method(u8 cmd, u32 arg, u32 *result) { - u32 status = 0; + int status = 0; union acpi_object *out_obj; status = clevo_evaluate_method2(cmd, arg, &out_obj); @@ -140,7 +140,7 @@ u32 clevo_evaluate_method(u8 cmd, u32 arg, u32 *result) } EXPORT_SYMBOL(clevo_evaluate_method); -u32 clevo_get_active_interface_id(char **id_str) +int clevo_get_active_interface_id(char **id_str) { if (IS_ERR_OR_NULL(active_clevo_interface)) return -ENODEV; @@ -385,7 +385,7 @@ static struct tuxedo_keyboard_driver clevo_keyboard_driver = { .key_map = clevo_keymap, }; -u32 clevo_keyboard_add_interface(struct clevo_interface_t *new_interface) +int clevo_keyboard_add_interface(struct clevo_interface_t *new_interface) { mutex_lock(&clevo_keyboard_interface_modification_lock); @@ -423,7 +423,7 @@ u32 clevo_keyboard_add_interface(struct clevo_interface_t *new_interface) } EXPORT_SYMBOL(clevo_keyboard_add_interface); -u32 clevo_keyboard_remove_interface(struct clevo_interface_t *interface) +int clevo_keyboard_remove_interface(struct clevo_interface_t *interface) { mutex_lock(&clevo_keyboard_interface_modification_lock); diff --git a/src/clevo_leds.h b/src/clevo_leds.h index c3242eb..4abe589 100644 --- a/src/clevo_leds.h +++ b/src/clevo_leds.h @@ -276,7 +276,7 @@ static struct led_classdev_mc clevo_mcled_cdevs[3] = { int clevo_leds_init(struct platform_device *dev) { int ret; - u32 status; + int status; union acpi_object *result; u32 result_fallback; diff --git a/src/clevo_wmi.c b/src/clevo_wmi.c index f7e0186..51adaaa 100644 --- a/src/clevo_wmi.c +++ b/src/clevo_wmi.c @@ -30,7 +30,7 @@ static int clevo_wmi_evaluate(u32 wmi_method_id, u32 wmi_arg, union acpi_object struct acpi_buffer acpi_buffer_out = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *acpi_result; acpi_status status_acpi; - u32 return_status = 0; + int return_status = 0; status_acpi = wmi_evaluate_method(CLEVO_WMI_METHOD_GUID, 0x00, wmi_method_id, @@ -55,7 +55,7 @@ static int clevo_wmi_evaluate(u32 wmi_method_id, u32 wmi_arg, union acpi_object return return_status; } -u32 clevo_wmi_interface_method_call(u8 cmd, u32 arg, union acpi_object **result_value) +int clevo_wmi_interface_method_call(u8 cmd, u32 arg, union acpi_object **result_value) { return clevo_wmi_evaluate(cmd, arg, result_value); } @@ -71,7 +71,7 @@ static int clevo_wmi_probe(struct wmi_device *wdev) static int clevo_wmi_probe(struct wmi_device *wdev, const void *dummy_context) #endif { - u32 status; + int status; union acpi_object *out_obj; pr_debug("clevo_wmi driver probe\n"); @@ -126,7 +126,7 @@ static void clevo_wmi_notify(struct wmi_device *wdev, union acpi_object *dummy) { u32 event_value; union acpi_object *out_obj; - u32 status; + int status; status = clevo_wmi_evaluate(0x01, 0, &out_obj); if (!status) { From 7ea3a0ac1325191489a3d7db1e43445720a54514 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Tue, 20 Jun 2023 18:15:48 +0200 Subject: [PATCH 09/11] Add new command --- src/clevo_interfaces.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/clevo_interfaces.h b/src/clevo_interfaces.h index 9b87a6a..d734295 100644 --- a/src/clevo_interfaces.h +++ b/src/clevo_interfaces.h @@ -48,6 +48,8 @@ #define CLEVO_CMD_GET_BIOS_FEATURES_2 0x7A #define CLEVO_CMD_GET_BIOS_FEATURES_2_SUB_WHITE_ONLY_KB_MAX_5 0x4000 +#define CLEVO_CMD_GET_KB_WHITE_LEDS 0x3D // Get brightness of white only keyboard backlights + // The clevo set commands expect a parameter #define CLEVO_CMD_SET_FANSPEED_VALUE 0x68 #define CLEVO_CMD_SET_FANSPEED_AUTO 0x69 @@ -58,7 +60,7 @@ #define CLEVO_CMD_SET_EVENTS_ENABLED 0x46 -#define CLEVO_CMD_SET_KB_WHITE_LEDS 0x27 // Set brightness of single color keyboard backlights +#define CLEVO_CMD_SET_KB_WHITE_LEDS 0x27 // Set brightness of white only keyboard backlights #define CLEVO_CMD_SET_KB_RGB_LEDS 0x67 // Used to set color, brightness, blinking pattern, etc. #define CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_0 0xF0000000 // 1-zone RGB and 3-zone RGB left #define CLEVO_CMD_SET_KB_LEDS_SUB_RGB_ZONE_1 0xF1000000 // 3-zone RGB center From 0845466b0b936820dc44da65b3af4ba1175c17fe Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Tue, 20 Jun 2023 18:35:47 +0200 Subject: [PATCH 10/11] Finish implementation of notify hw changed for Clevo --- src/clevo_leds.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/clevo_leds.h b/src/clevo_leds.h index 4abe589..9dcc915 100644 --- a/src/clevo_leds.h +++ b/src/clevo_leds.h @@ -180,7 +180,8 @@ static struct led_classdev clevo_led_cdev = { .name = "white:" LED_FUNCTION_KBD_BACKLIGHT, .max_brightness = CLEVO_KBD_BRIGHTNESS_WHITE_MAX, .brightness_set = &clevo_leds_set_brightness, - .brightness = CLEVO_KBD_BRIGHTNESS_WHITE_DEFAULT + .brightness = CLEVO_KBD_BRIGHTNESS_WHITE_DEFAULT, + .flags = LED_BRIGHT_HW_CHANGED }; static struct mc_subled clevo_mcled_cdevs_subleds[3][3] = { @@ -400,6 +401,8 @@ enum clevo_kb_backlight_types clevo_leds_get_backlight_type(void) { } EXPORT_SYMBOL(clevo_leds_get_backlight_type); +// TODO Don't reuse brightness_set as it is writing back the same brightness which could lead to race conditions. +// Reimplement brightness_set instead without writing back brightness value like in uniwill_leds.h. void clevo_leds_restore_state_extern(void) { if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { clevo_led_cdev.brightness_set(&clevo_led_cdev, clevo_led_cdev.brightness); @@ -416,12 +419,20 @@ void clevo_leds_restore_state_extern(void) { EXPORT_SYMBOL(clevo_leds_restore_state_extern); void clevo_leds_notify_brightness_change_extern(void) { + int status; + u32 result; + if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { - // TODO + status = clevo_evaluate_method(CLEVO_CMD_GET_KB_WHITE_LEDS, 0, &result); + pr_debug("Firmware set brightness: %u\n", result); + clevo_led_cdev.brightness = result; + led_classdev_notify_brightness_hw_changed(&clevo_led_cdev, result); } } EXPORT_SYMBOL(clevo_leds_notify_brightness_change_extern); +// TODO Not used externaly, but only on init. Should not be exposed because it would require a correct +// led_classdev_notify_brightness_hw_changed implementation when used outside of init. void clevo_leds_set_brightness_extern(enum led_brightness brightness) { if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_FIXED_COLOR) { clevo_led_cdev.brightness_set(&clevo_led_cdev, brightness); @@ -437,6 +448,8 @@ void clevo_leds_set_brightness_extern(enum led_brightness brightness) { } EXPORT_SYMBOL(clevo_leds_set_brightness_extern); +// TODO Not used externaly, but only on init. Should not be exposed because it would require a correct +// led_classdev_notify_brightness_hw_changed equivalent for color implementation when used outside of init. void clevo_leds_set_color_extern(u32 color) { if (clevo_kb_backlight_type == CLEVO_KB_BACKLIGHT_TYPE_1_ZONE_RGB) { clevo_mcled_cdevs[0].subled_info[0].intensity = (color >> 16) & 0xff; From 5ad584ca12af0122735d7ab9455dd2a75dc672d3 Mon Sep 17 00:00:00 2001 From: Werner Sembach Date: Tue, 20 Jun 2023 18:36:26 +0200 Subject: [PATCH 11/11] Fix leds brightness not getting updated on firmware controlled brightness change --- src/uniwill_leds.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uniwill_leds.h b/src/uniwill_leds.h index a572272..4fdbc29 100644 --- a/src/uniwill_leds.h +++ b/src/uniwill_leds.h @@ -292,6 +292,7 @@ int uniwill_leds_notify_brightness_change_extern(void) { if (uniwill_kb_backlight_type == UNIWILL_KB_BACKLIGHT_TYPE_FIXED_COLOR) { uniwill_read_ec_ram(UW_EC_REG_KBD_BL_STATUS, &data); data = (data >> 5) & 0x3; + uniwill_led_cdev.brightness = data; led_classdev_notify_brightness_hw_changed(&uniwill_led_cdev, data); return true; }