AMD 7840 Fan and Temp issue (negative temp, fan is not starting)

Which Linux distro are you using?
Fedora Linux 42 (Workstation Edition) x86_64

Which release version?
updated July 18 2025

Which kernel are you using?
Linux 6.15.6-200.fc42.x86_64

Which BIOS version are you using?
3.09 (latest available)

Which Framework Laptop 13 model are you using?
AMD Ryzen 7 7840U

Hello,

I’m experiencing unusual behavior with my FW13 AMD 7840. Specifically, I’m observing negative temperature readings, and the fans are not engaging under load. However, manual fan control (via ectool and fw-fanctrl) appears to be functioning correctly.

I’ve already attempted to update Fedora and toggle the automatic fan management settings, but the issue persists.

k10temp sensor under load going up to 92 Celsius. No fan.

❯ acpi -t
Thermal 0: ok, -17.2 degrees C
Thermal 1: ok, 0.0 degrees C
Thermal 2: ok, -17.2 degrees C
Thermal 3: ok, -17.2 degrees C

I found a workaround using fw-fanctl.
By changing the temperature reading module to use the k10temp AMD sensor, I’ve made the laptop usable.
The modified module is src/fw_fanctrl/hardwareController/EctoolHardwareController.py

Function:

    def get_temperature(self):
        # Priority: k10temp -> EC sensors -> fallback

        # k10temp
        try:
            with open('/sys/class/hwmon/hwmon8/temp1_input', 'r') as f:
                temp_millidegrees = int(f.read().strip())
                temp_celsius = temp_millidegrees / 1000.0
                return float(round(temp_celsius, 2))
        except:
            pass

        # EC Sensors
        if self.noBatterySensorMode:
            raw_out = "".join(
                [
                    subprocess.run(
                        "ectool temps " + x,
                        stdout=subprocess.PIPE,
                        shell=True,
                        text=True,
                    ).stdout
                    for x in self.nonBatterySensors
                ]
            )
        else:
            raw_out = subprocess.run(
                "ectool temps all",
                stdout=subprocess.PIPE,
                shell=True,
                text=True,
            ).stdout

        raw_temps = re.findall(r"\(= (\d+) C\)", raw_out)
        temps = sorted([x for x in [int(x) for x in raw_temps] if x > 0], reverse=True)

        # safety fallback
        if len(temps) == 0:
            return 50
        return float(round(temps[0], 2))

Found the solution for my case.