From 1bab01f93b97695f412a23a406f5940295ae504a Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Fri, 10 Feb 2023 16:12:12 +0100 Subject: [PATCH 1/5] charging_profile: Remember state and re-write on power change event --- src/uniwill_keyboard.h | 83 ++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 23 deletions(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index c17b5cb..3578b68 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -57,6 +57,8 @@ #define UNIWILL_BRIGHTNESS_DEFAULT UNIWILL_BRIGHTNESS_MAX * 0.30 #define UNIWILL_COLOR_DEFAULT 0xffffff +static void uw_charging_profile_write_state(void); + struct tuxedo_keyboard_driver uniwill_keyboard_driver; struct kbd_led_state_uw_t { @@ -380,9 +382,10 @@ void uniwill_event_callb(u32 code) kbd_led_state_uw.brightness = 0xc8; uniwill_write_kbd_bl_state(); break; - // Also refresh keyboard state on cable switch event + // Refresh keyboard state and charging profile on cable switch event case UNIWILL_OSD_DC_ADAPTER_CHANGE: uniwill_write_kbd_bl_state(); + uw_charging_profile_write_state(); break; } } @@ -822,6 +825,35 @@ static int uw_has_charging_priority(bool *status) } static bool uw_charging_profile_loaded = false; +static bool uw_charging_profile_value; + +static ssize_t uw_charging_profiles_available_show(struct device *child, + struct device_attribute *attr, + char *buffer); +static ssize_t uw_charging_profile_show(struct device *child, + struct device_attribute *attr, char *buffer); +static ssize_t uw_charging_profile_store(struct device *child, + struct device_attribute *attr, + const char *buffer, size_t size); + +struct uw_charging_profile_attrs_t { + struct device_attribute charging_profiles_available; + struct device_attribute charging_profile; +} uw_charging_profile_attrs = { + .charging_profiles_available = __ATTR(charging_profiles_available, 0444, uw_charging_profiles_available_show, NULL), + .charging_profile = __ATTR(charging_profile, 0644, uw_charging_profile_show, uw_charging_profile_store) +}; + +static struct attribute *uw_charging_profile_attrs_list[] = { + &uw_charging_profile_attrs.charging_profiles_available.attr, + &uw_charging_profile_attrs.charging_profile.attr, + NULL +}; + +static struct attribute_group uw_charging_profile_attr_group = { + .name = "charging_profile", + .attrs = uw_charging_profile_attrs_list +}; /* * charging_profile values @@ -843,13 +875,19 @@ static int uw_set_charging_profile(u8 charging_profile) next_data = (previous_data & ~(0x03 << 4)) | charging_profile; result = uniwill_write_ec_ram(0x07a6, next_data); + if (result == 0) + uw_charging_profile_value = charging_profile; + return result; } static int uw_get_charging_profile(u8 *charging_profile) { int result = uniwill_read_ec_ram(0x07a6, charging_profile); - *charging_profile = (*charging_profile >> 4) & 0x03; + if (result == 0) { + *charging_profile = (*charging_profile >> 4) & 0x03; + uw_charging_profile_value = *charging_profile; + } return result; } @@ -878,6 +916,25 @@ static int uw_has_charging_profile(bool *status) return result; } +static void uw_charging_profile_write_state(void) +{ + if (uw_charging_profile_loaded) + uw_set_charging_profile(uw_charging_profile_value); +} + +static void uw_charging_profile_init(struct platform_device *dev) +{ + u8 dummy; + struct uniwill_device_features_t *uw_feats = &uniwill_device_features; + + if (uw_feats->uniwill_has_charging_profile) + uw_charging_profile_loaded = sysfs_create_group(&dev->dev.kobj, &uw_charging_profile_attr_group) == 0; + + // Trigger read for state init + if (uw_charging_profile_loaded) + uw_get_charging_profile(&dummy); +} + struct char_to_u8_t { char* descriptor; u8 value; @@ -960,25 +1017,6 @@ static ssize_t uw_charging_profile_store(struct device *child, return -EINVAL; } -struct uw_charging_profile_attrs_t { - struct device_attribute charging_profiles_available; - struct device_attribute charging_profile; -} uw_charging_profile_attrs = { - .charging_profiles_available = __ATTR(charging_profiles_available, 0444, uw_charging_profiles_available_show, NULL), - .charging_profile = __ATTR(charging_profile, 0644, uw_charging_profile_show, uw_charging_profile_store) -}; - -static struct attribute *uw_charging_profile_attrs_list[] = { - &uw_charging_profile_attrs.charging_profiles_available.attr, - &uw_charging_profile_attrs.charging_profile.attr, - NULL -}; - -static struct attribute_group uw_charging_profile_attr_group = { - .name = "charging_profile", - .attrs = uw_charging_profile_attrs_list -}; - static struct char_to_u8_t charging_prio_options[] = { { .descriptor = "charge_battery", .value = 0x00 }, { .descriptor = "performance", .value = 0x01 } @@ -1175,8 +1213,7 @@ static int uniwill_keyboard_probe(struct platform_device *dev) if (uw_feats->uniwill_has_charging_prio) uw_charging_prio_loaded = sysfs_create_group(&dev->dev.kobj, &uw_charging_prio_attr_group) == 0; - if (uw_feats->uniwill_has_charging_profile) - uw_charging_profile_loaded = sysfs_create_group(&dev->dev.kobj, &uw_charging_profile_attr_group) == 0; + uw_charging_profile_init(dev); return 0; } From b35bc84de0895c394da769b55d7551e3d8bc5816 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Mon, 13 Feb 2023 09:56:07 +0100 Subject: [PATCH 2/5] charging_priority: Remember state and re-write on power change event --- src/uniwill_keyboard.h | 77 ++++++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 3578b68..4854dc1 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -57,6 +57,7 @@ #define UNIWILL_BRIGHTNESS_DEFAULT UNIWILL_BRIGHTNESS_MAX * 0.30 #define UNIWILL_COLOR_DEFAULT 0xffffff +static void uw_charging_priority_write_state(void); static void uw_charging_profile_write_state(void); struct tuxedo_keyboard_driver uniwill_keyboard_driver; @@ -386,6 +387,7 @@ void uniwill_event_callb(u32 code) case UNIWILL_OSD_DC_ADAPTER_CHANGE: uniwill_write_kbd_bl_state(); uw_charging_profile_write_state(); + uw_charging_priority_write_state(); break; } } @@ -769,6 +771,35 @@ static int uw_lightbar_remove(struct platform_device *dev) } static bool uw_charging_prio_loaded = false; +static bool uw_charging_prio_value; + +static ssize_t uw_charging_prios_available_show(struct device *child, + struct device_attribute *attr, + char *buffer); +static ssize_t uw_charging_prio_show(struct device *child, + struct device_attribute *attr, char *buffer); +static ssize_t uw_charging_prio_store(struct device *child, + struct device_attribute *attr, + const char *buffer, size_t size); + +struct uw_charging_prio_attrs_t { + struct device_attribute charging_prios_available; + struct device_attribute charging_prio; +} uw_charging_prio_attrs = { + .charging_prios_available = __ATTR(charging_prios_available, 0444, uw_charging_prios_available_show, NULL), + .charging_prio = __ATTR(charging_prio, 0644, uw_charging_prio_show, uw_charging_prio_store) +}; + +static struct attribute *uw_charging_prio_attrs_list[] = { + &uw_charging_prio_attrs.charging_prios_available.attr, + &uw_charging_prio_attrs.charging_prio.attr, + NULL +}; + +static struct attribute_group uw_charging_prio_attr_group = { + .name = "charging_priority", + .attrs = uw_charging_prio_attrs_list +}; /* * charging_prio values @@ -788,6 +819,8 @@ static int uw_set_charging_priority(u8 charging_priority) next_data = (previous_data & ~(1 << 7)) | charging_priority; result = uniwill_write_ec_ram(0x07cc, next_data); + if (result == 0) + uw_charging_prio_value = charging_priority; return result; } @@ -796,6 +829,8 @@ static int uw_get_charging_priority(u8 *charging_priority) { int result = uniwill_read_ec_ram(0x07cc, charging_priority); *charging_priority = (*charging_priority >> 7) & 0x01; + if (result == 0) + uw_charging_prio_value = *charging_priority; return result; } @@ -824,6 +859,25 @@ static int uw_has_charging_priority(bool *status) return result; } +static void uw_charging_priority_write_state(void) +{ + if (uw_charging_prio_loaded) + uw_set_charging_priority(uw_charging_prio_value); +} + +static void uw_charging_priority_init(struct platform_device *dev) +{ + u8 dummy; + struct uniwill_device_features_t *uw_feats = &uniwill_device_features; + + if (uw_feats->uniwill_has_charging_prio) + uw_charging_prio_loaded = sysfs_create_group(&dev->dev.kobj, &uw_charging_prio_attr_group) == 0; + + // Trigger read for state init + if (uw_charging_prio_loaded) + uw_get_charging_priority(&dummy); +} + static bool uw_charging_profile_loaded = false; static bool uw_charging_profile_value; @@ -1093,25 +1147,6 @@ static ssize_t uw_charging_prio_store(struct device *child, return -EINVAL; } -struct uw_charging_prio_attrs_t { - struct device_attribute charging_prios_available; - struct device_attribute charging_prio; -} uw_charging_prio_attrs = { - .charging_prios_available = __ATTR(charging_prios_available, 0444, uw_charging_prios_available_show, NULL), - .charging_prio = __ATTR(charging_prio, 0644, uw_charging_prio_show, uw_charging_prio_store) -}; - -static struct attribute *uw_charging_prio_attrs_list[] = { - &uw_charging_prio_attrs.charging_prios_available.attr, - &uw_charging_prio_attrs.charging_prio.attr, - NULL -}; - -static struct attribute_group uw_charging_prio_attr_group = { - .name = "charging_priority", - .attrs = uw_charging_prio_attrs_list -}; - struct uniwill_device_features_t *uniwill_get_device_features(void) { struct uniwill_device_features_t *uw_feats = &uniwill_device_features; @@ -1210,9 +1245,7 @@ static int uniwill_keyboard_probe(struct platform_device *dev) status = uw_lightbar_init(dev); uw_lightbar_loaded = (status >= 0); - if (uw_feats->uniwill_has_charging_prio) - uw_charging_prio_loaded = sysfs_create_group(&dev->dev.kobj, &uw_charging_prio_attr_group) == 0; - + uw_charging_priority_init(dev); uw_charging_profile_init(dev); return 0; From 4f9b49abe74df9899724fc3a792d12e1d7b12ef9 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Tue, 14 Feb 2023 12:01:04 +0100 Subject: [PATCH 3/5] charging profile/prio: Change to remember last written state To be able to re-write when necessary --- src/uniwill_keyboard.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 4854dc1..2e9a257 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -771,7 +771,7 @@ static int uw_lightbar_remove(struct platform_device *dev) } static bool uw_charging_prio_loaded = false; -static bool uw_charging_prio_value; +static bool uw_charging_prio_last_written_value; static ssize_t uw_charging_prios_available_show(struct device *child, struct device_attribute *attr, @@ -820,7 +820,7 @@ static int uw_set_charging_priority(u8 charging_priority) next_data = (previous_data & ~(1 << 7)) | charging_priority; result = uniwill_write_ec_ram(0x07cc, next_data); if (result == 0) - uw_charging_prio_value = charging_priority; + uw_charging_prio_last_written_value = charging_priority; return result; } @@ -829,8 +829,6 @@ static int uw_get_charging_priority(u8 *charging_priority) { int result = uniwill_read_ec_ram(0x07cc, charging_priority); *charging_priority = (*charging_priority >> 7) & 0x01; - if (result == 0) - uw_charging_prio_value = *charging_priority; return result; } @@ -862,24 +860,26 @@ static int uw_has_charging_priority(bool *status) static void uw_charging_priority_write_state(void) { if (uw_charging_prio_loaded) - uw_set_charging_priority(uw_charging_prio_value); + uw_set_charging_priority(uw_charging_prio_last_written_value); } static void uw_charging_priority_init(struct platform_device *dev) { - u8 dummy; + u8 value; struct uniwill_device_features_t *uw_feats = &uniwill_device_features; if (uw_feats->uniwill_has_charging_prio) uw_charging_prio_loaded = sysfs_create_group(&dev->dev.kobj, &uw_charging_prio_attr_group) == 0; - // Trigger read for state init - if (uw_charging_prio_loaded) - uw_get_charging_priority(&dummy); + // Read for state init + if (uw_charging_prio_loaded) { + uw_get_charging_priority(&value); + uw_charging_prio_last_written_value = value; + } } static bool uw_charging_profile_loaded = false; -static bool uw_charging_profile_value; +static bool uw_charging_profile_last_written_value; static ssize_t uw_charging_profiles_available_show(struct device *child, struct device_attribute *attr, @@ -930,7 +930,7 @@ static int uw_set_charging_profile(u8 charging_profile) result = uniwill_write_ec_ram(0x07a6, next_data); if (result == 0) - uw_charging_profile_value = charging_profile; + uw_charging_profile_last_written_value = charging_profile; return result; } @@ -938,10 +938,8 @@ static int uw_set_charging_profile(u8 charging_profile) static int uw_get_charging_profile(u8 *charging_profile) { int result = uniwill_read_ec_ram(0x07a6, charging_profile); - if (result == 0) { + if (result == 0) *charging_profile = (*charging_profile >> 4) & 0x03; - uw_charging_profile_value = *charging_profile; - } return result; } @@ -973,20 +971,22 @@ static int uw_has_charging_profile(bool *status) static void uw_charging_profile_write_state(void) { if (uw_charging_profile_loaded) - uw_set_charging_profile(uw_charging_profile_value); + uw_set_charging_profile(uw_charging_profile_last_written_value); } static void uw_charging_profile_init(struct platform_device *dev) { - u8 dummy; + u8 value; struct uniwill_device_features_t *uw_feats = &uniwill_device_features; if (uw_feats->uniwill_has_charging_profile) uw_charging_profile_loaded = sysfs_create_group(&dev->dev.kobj, &uw_charging_profile_attr_group) == 0; - // Trigger read for state init - if (uw_charging_profile_loaded) - uw_get_charging_profile(&dummy); + // Read for state init + if (uw_charging_profile_loaded) { + uw_get_charging_profile(&value); + uw_charging_profile_last_written_value = value; + } } struct char_to_u8_t { From 646abc0426950e68b6a7c4035645f96b0a5e19ed Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Tue, 14 Feb 2023 16:56:22 +0100 Subject: [PATCH 4/5] charging: Move event catch to appropriate place and tweak setting - Charging profile prepared but not included (most likely not needed) - Charging prio kept with slight delay to catch some timing issues Note: Workaround not perfect but catches most cases where connecting barrel plug would make charging prio setting jump to charge battery --- src/uniwill_keyboard.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 2e9a257..e2810c0 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -386,11 +386,16 @@ void uniwill_event_callb(u32 code) // Refresh keyboard state and charging profile on cable switch event case UNIWILL_OSD_DC_ADAPTER_CHANGE: uniwill_write_kbd_bl_state(); - uw_charging_profile_write_state(); - uw_charging_priority_write_state(); break; } } + + switch (code) { + case UNIWILL_OSD_DC_ADAPTER_CHANGE: + msleep(50); + uw_charging_priority_write_state(); + break; + } } static ssize_t uw_brightness_show(struct device *child, From 334bff5f3039fae1a1bac4854b7feb513fadb180 Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Tue, 14 Feb 2023 17:09:13 +0100 Subject: [PATCH 5/5] Remove old comment remnants --- src/uniwill_keyboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index e2810c0..9dc2764 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -383,7 +383,7 @@ void uniwill_event_callb(u32 code) kbd_led_state_uw.brightness = 0xc8; uniwill_write_kbd_bl_state(); break; - // Refresh keyboard state and charging profile on cable switch event + // Refresh keyboard state on cable switch event case UNIWILL_OSD_DC_ADAPTER_CHANGE: uniwill_write_kbd_bl_state(); break;