From 1bab01f93b97695f412a23a406f5940295ae504a Mon Sep 17 00:00:00 2001 From: Christoffer Sandberg Date: Fri, 10 Feb 2023 16:12:12 +0100 Subject: [PATCH] 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; }