From 1e308f2bd49cedde6bfb944ae7f874a341a3e4c9 Mon Sep 17 00:00:00 2001 From: Jiogo18 <30299784+Jiogo18@users.noreply.github.com> Date: Fri, 19 Sep 2025 19:39:50 -0400 Subject: [PATCH] Add cpu and gpu fan_speed_rpm --- ec_memory_configuration.h | 2 ++ msi-ec.c | 60 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/ec_memory_configuration.h b/ec_memory_configuration.h index ff9503f2..837ef879 100644 --- a/ec_memory_configuration.h +++ b/ec_memory_configuration.h @@ -58,11 +58,13 @@ struct msi_ec_fan_mode_conf { struct msi_ec_cpu_conf { int rt_temp_address; int rt_fan_speed_address; // realtime % RPM + int fan_speed_rpm_address_0; // 480000/n RPM }; struct msi_ec_gpu_conf { int rt_temp_address; int rt_fan_speed_address; // realtime % RPM + int fan_speed_rpm_address_0; // 480000/n RPM }; struct msi_ec_led_conf { diff --git a/msi-ec.c b/msi-ec.c index b932e1cf..f55f1171 100644 --- a/msi-ec.c +++ b/msi-ec.c @@ -691,10 +691,12 @@ static struct msi_ec_conf CONF_G1_8 __initdata = { .cpu = { .rt_temp_address = 0x68, .rt_fan_speed_address = 0x71, + .fan_speed_rpm_address_0 = 0xcc, }, .gpu = { .rt_temp_address = 0x80, .rt_fan_speed_address = 0x89, + .fan_speed_rpm_address_0 = 0xca, }, .leds = { .micmute_led_address = MSI_EC_ADDR_UNSUPP, @@ -2206,6 +2208,23 @@ static ssize_t cpu_realtime_fan_speed_show(struct device *device, return sysfs_emit(buf, "%i\n", rdata); } +static ssize_t cpu_fan_speed_rpm_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + u8 rdata[2]; + int result; + + result = ec_read_seq(conf.cpu.fan_speed_rpm_address_0, rdata, 2); + if (result < 0) + return result; + + int value = (rdata[0] << 8) | rdata[1]; + int rpm = value != 0 ? 480000 / value : 0; + + return sysfs_emit(buf, "%i\n", rpm); +} + static struct device_attribute dev_attr_cpu_realtime_temperature = { .attr = { .name = "realtime_temperature", @@ -2222,9 +2241,18 @@ static struct device_attribute dev_attr_cpu_realtime_fan_speed = { .show = cpu_realtime_fan_speed_show, }; +static struct device_attribute dev_attr_cpu_fan_speed_rpm = { + .attr = { + .name = "fan_speed_rpm", + .mode = 0444, + }, + .show = cpu_fan_speed_rpm_show, +}; + static struct attribute *msi_cpu_attrs[] = { &dev_attr_cpu_realtime_temperature.attr, &dev_attr_cpu_realtime_fan_speed.attr, + &dev_attr_cpu_fan_speed_rpm.attr, NULL }; @@ -2260,6 +2288,23 @@ static ssize_t gpu_realtime_fan_speed_show(struct device *device, return sysfs_emit(buf, "%i\n", rdata); } +static ssize_t gpu_fan_speed_rpm_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + u8 rdata[2]; + int result; + + result = ec_read_seq(conf.gpu.fan_speed_rpm_address_0, rdata, 2); + if (result < 0) + return result; + + int value = (rdata[0] << 8) | rdata[1]; + int rpm = value != 0 ? 480000 / value : 0; + + return sysfs_emit(buf, "%i\n", rpm); +} + static struct device_attribute dev_attr_gpu_realtime_temperature = { .attr = { .name = "realtime_temperature", @@ -2276,9 +2321,18 @@ static struct device_attribute dev_attr_gpu_realtime_fan_speed = { .show = gpu_realtime_fan_speed_show, }; +static struct device_attribute dev_attr_gpu_fan_speed_rpm = { + .attr = { + .name = "fan_speed_rpm", + .mode = 0444, + }, + .show = gpu_fan_speed_rpm_show, +}; + static struct attribute *msi_gpu_attrs[] = { &dev_attr_gpu_realtime_temperature.attr, &dev_attr_gpu_realtime_fan_speed.attr, + &dev_attr_gpu_fan_speed_rpm.attr, NULL }; @@ -2529,6 +2583,9 @@ static umode_t msi_ec_is_visible(struct kobject *kobj, else if (attr == &dev_attr_cpu_realtime_fan_speed.attr) address = conf.cpu.rt_fan_speed_address; + else if (attr == &dev_attr_cpu_fan_speed_rpm.attr) + address = conf.cpu.fan_speed_rpm_address_0; + /* gpu group */ else if (attr == &dev_attr_gpu_realtime_temperature.attr) address = conf.gpu.rt_temp_address; @@ -2536,6 +2593,9 @@ static umode_t msi_ec_is_visible(struct kobject *kobj, else if (attr == &dev_attr_gpu_realtime_fan_speed.attr) address = conf.gpu.rt_fan_speed_address; + else if (attr == &dev_attr_gpu_fan_speed_rpm.attr) + address = conf.gpu.fan_speed_rpm_address_0; + /* default */ else return attr->mode;