Merge remote-tracking branch 'origin/rework_white_only_kbl'

This commit is contained in:
Christoffer Sandberg 2023-06-28 08:53:52 +02:00
commit d86df4196f
8 changed files with 120 additions and 58 deletions

View file

@ -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);

View file

@ -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
@ -72,14 +74,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); \

View file

@ -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"
@ -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;
@ -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;
}
@ -382,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);
@ -420,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);

View file

@ -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);
@ -180,7 +181,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] = {
@ -276,7 +278,7 @@ static struct led_classdev_mc clevo_mcled_cdevs[3] = {
int clevo_leds_init(struct platform_device *dev)
{
int ret, i;
u32 status;
int status;
union acpi_object *result;
u32 result_fallback;
@ -408,6 +410,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);
@ -423,6 +427,21 @@ 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) {
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);
@ -438,6 +457,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;

View file

@ -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) {

View file

@ -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);

View file

@ -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;
@ -275,29 +274,41 @@ 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_KEY_KBDILLUMTOGGLE:
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);
}
}
@ -786,7 +797,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);
@ -1140,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

View file

@ -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,12 +285,29 @@ 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;
uniwill_led_cdev.brightness = data;
led_classdev_notify_brightness_hw_changed(&uniwill_led_cdev, data);
return true;
}
}
return false;
}
void uniwill_leds_restore_state_extern(void) {
u8 data;
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 +316,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");
}
}
}
}