diff --git a/src/tuxedo_io/tuxedo_io.c b/src/tuxedo_io/tuxedo_io.c index 14785c1..3eee737 100644 --- a/src/tuxedo_io/tuxedo_io.c +++ b/src/tuxedo_io/tuxedo_io.c @@ -47,6 +47,8 @@ MODULE_ALIAS("wmi:" UNIWILL_WMI_MGMT_GUID_BC); static u32 id_check_clevo; static u32 id_check_uniwill; +static struct uniwill_device_features_t *uw_feats; + /** * strstr version of dmi_match */ @@ -65,71 +67,9 @@ static u32 clevo_identify(void) return clevo_get_active_interface_id(NULL) == 0 ? 1 : 0; } -/* - * Identification for uniwill_power_profile_v1 - * - * - Two profiles present in low power devices often called - * "power save" and "balanced". - * - Three profiles present mainly in devices with discrete - * graphics card often called "power save", "balanced" - * and "enthusiast" - */ -static bool uniwill_profile_v1; -static bool uniwill_profile_v1_two_profs; -static bool uniwill_profile_v1_three_profs; - -static bool uniwill_tdp_config_two; -static bool uniwill_tdp_config_three; - static u32 uniwill_identify(void) { - uniwill_profile_v1_two_profs = false - || dmi_match(DMI_BOARD_NAME, "PF5PU1G") - || dmi_match(DMI_BOARD_NAME, "PULSE1401") - || dmi_match(DMI_BOARD_NAME, "PULSE1501") - ; - - uniwill_profile_v1_three_profs = false - // Devices with "classic" profile support - || dmi_match(DMI_BOARD_NAME, "POLARIS1501A1650TI") - || dmi_match(DMI_BOARD_NAME, "POLARIS1501A2060") - || dmi_match(DMI_BOARD_NAME, "POLARIS1501I1650TI") - || dmi_match(DMI_BOARD_NAME, "POLARIS1501I2060") - || dmi_match(DMI_BOARD_NAME, "POLARIS1701A1650TI") - || dmi_match(DMI_BOARD_NAME, "POLARIS1701A2060") - || dmi_match(DMI_BOARD_NAME, "POLARIS1701I1650TI") - || dmi_match(DMI_BOARD_NAME, "POLARIS1701I2060") - // Devices where profile mainly controls power profile LED status - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") - ; - - uniwill_profile_v1 = - uniwill_profile_v1_two_profs || - uniwill_profile_v1_three_profs; - - // Device check for two configurable TDPs - uniwill_tdp_config_two = false -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) - || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX") - || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX") - || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") - || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") - || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") -#endif - ; - - // Device check for three configurable TDPs - uniwill_tdp_config_three = false; - + uw_feats = uniwill_get_device_features(); return uniwill_get_active_interface_id(NULL) == 0 ? 1 : 0; } @@ -343,9 +283,9 @@ static int uw_get_tdp(u8 tdp_index) u16 tdp_current_addr = tdp_base_addr + tdp_index; bool has_current_setting = false; - if (tdp_index < 2 && uniwill_tdp_config_two) + if (tdp_index < 2 && uw_feats->uniwill_tdp_config_two) has_current_setting = true; - else if (tdp_index < 3 && uniwill_tdp_config_three) + else if (tdp_index < 3 && uw_feats->uniwill_tdp_config_three) has_current_setting = true; if (!has_current_setting) @@ -363,9 +303,9 @@ static int uw_set_tdp(u8 tdp_index, u8 tdp_data) u16 tdp_current_addr = tdp_base_addr + tdp_index; bool has_current_setting = false; - if (tdp_index < 2 && uniwill_tdp_config_two) + if (tdp_index < 2 && uw_feats->uniwill_tdp_config_two) has_current_setting = true; - else if (tdp_index < 3 && uniwill_tdp_config_three) + else if (tdp_index < 3 && uw_feats->uniwill_tdp_config_three) has_current_setting = true; tdp_min = uw_get_tdp_min(tdp_index); @@ -512,9 +452,9 @@ static long uniwill_ioctl_interface(struct file *file, unsigned int cmd, unsigne break; case R_UW_PROFS_AVAILABLE: result = 0; - if (uniwill_profile_v1_two_profs) + if (uw_feats->uniwill_profile_v1_two_profs) result = 2; - else if (uniwill_profile_v1_three_profs) + else if (uw_feats->uniwill_profile_v1_three_profs) result = 3; copy_result = copy_to_user((void *) arg, &result, sizeof(result)); break; diff --git a/src/uniwill_interfaces.h b/src/uniwill_interfaces.h index 3c1bf45..10ae6e3 100644 --- a/src/uniwill_interfaces.h +++ b/src/uniwill_interfaces.h @@ -46,11 +46,34 @@ struct uniwill_interface_t { uniwill_write_ec_ram_t *write_ec_ram; }; +struct uniwill_device_features_t { + /** + * Identification for uniwill_power_profile_v1 + * + * - Two profiles present in low power devices often called + * "power save" and "balanced". + * - Three profiles present mainly in devices with discrete + * graphics card often called "power save", "balanced" + * and "enthusiast" + */ + bool uniwill_profile_v1; + bool uniwill_profile_v1_two_profs; + bool uniwill_profile_v1_three_profs; + /** + * Two or three configurable TDP values. Generally two for + * low power/more mobile devices and three for heavier workstations + * and gaming devices. + */ + bool uniwill_tdp_config_two; + bool uniwill_tdp_config_three; +}; + u32 uniwill_add_interface(struct uniwill_interface_t *new_interface); u32 uniwill_remove_interface(struct uniwill_interface_t *interface); uniwill_read_ec_ram_t uniwill_read_ec_ram; uniwill_write_ec_ram_t uniwill_write_ec_ram; u32 uniwill_get_active_interface_id(char **id_str); +struct uniwill_device_features_t *uniwill_get_device_features(void); union uw_ec_read_return { u32 dword; diff --git a/src/uniwill_keyboard.h b/src/uniwill_keyboard.h index 41f7b8d..969e3ca 100644 --- a/src/uniwill_keyboard.h +++ b/src/uniwill_keyboard.h @@ -67,6 +67,8 @@ struct kbd_led_state_uw_t { .color = UNIWILL_COLOR_DEFAULT, }; +struct uniwill_device_features_t uniwill_device_features; + static u8 uniwill_kbd_bl_enable_state_on_start; static bool uniwill_kbd_bl_type_rgb_single_color = true; @@ -180,6 +182,61 @@ u32 uniwill_get_active_interface_id(char **id_str) } EXPORT_SYMBOL(uniwill_get_active_interface_id); +struct uniwill_device_features_t *uniwill_get_device_features(void) +{ + struct uniwill_device_features_t *uw_feats = &uniwill_device_features; + + uw_feats->uniwill_profile_v1_two_profs = false + || dmi_match(DMI_BOARD_NAME, "PF5PU1G") + || dmi_match(DMI_BOARD_NAME, "PULSE1401") + || dmi_match(DMI_BOARD_NAME, "PULSE1501") + ; + + uw_feats->uniwill_profile_v1_three_profs = false + // Devices with "classic" profile support + || dmi_match(DMI_BOARD_NAME, "POLARIS1501A1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1501A2060") + || dmi_match(DMI_BOARD_NAME, "POLARIS1501I1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1501I2060") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701A1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701A2060") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701I1650TI") + || dmi_match(DMI_BOARD_NAME, "POLARIS1701I2060") + // Devices where profile mainly controls power profile LED status + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") + ; + + uw_feats->uniwill_profile_v1 = + uw_feats->uniwill_profile_v1_two_profs || + uw_feats->uniwill_profile_v1_three_profs; + + // Device check for two configurable TDPs + uw_feats->uniwill_tdp_config_two = false +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TUX") + || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TRX") + || dmi_string_in(DMI_PRODUCT_SERIAL, "PH4TQX") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI02") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XA03") + || dmi_match(DMI_PRODUCT_SKU, "POLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XI03") + || dmi_match(DMI_PRODUCT_SKU, "STELLARIS1XA03") +#endif + ; + + // Device check for three configurable TDPs + uw_feats->uniwill_tdp_config_three = false; + + return uw_feats; +} +EXPORT_SYMBOL(uniwill_get_device_features); + static void key_event_work(struct work_struct *work) { sparse_keymap_report_known_event( @@ -742,6 +799,8 @@ static int uniwill_keyboard_probe(struct platform_device *dev) u8 data; int status; + uniwill_get_device_features(); + // FIXME Hard set balanced profile until we have implemented a way to // switch it while tuxedo_io is loaded // uw_ec_write_addr(0x51, 0x07, 0x00, 0x00, ®_write_return);