Skip to content

Instantly share code, notes, and snippets.

@Yatoom
Last active May 15, 2024 07:34
Show Gist options
  • Save Yatoom/1c80b8afe7fa47a938d3b667ce234559 to your computer and use it in GitHub Desktop.
Save Yatoom/1c80b8afe7fa47a938d3b667ce234559 to your computer and use it in GitHub Desktop.
Thinkfan configuration

Thinkfan setup

Note: I configured this thinkfan setup for my old Thinkpad w520 on Ubuntu 17.10.

1. Install necessary programs

Install lm-sensors and thinkfan.

sudo apt-get install lm-sensors thinkfan

2. Setup configuration

Find the temperature control devices with

find /sys/devices -type f -name "temp*_input"

Add them to /etc/thinkfan.conf, including (level, min_temperature, max_temperature):

hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp3_input
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp4_input
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp5_input
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp1_input
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp2_input

(0,	0,	60)
(1,	60,	65)
(2,	65,	70)
(3,	70,	75)
(4,	75,	80)
(5,	80,	85)
(7,	85,	32767)

3. Enable fan control

echo "options thinkpad_acpi fan_control=1" > /etc/modprobe.d/thinkfan.conf
modprobe thinkpad_acpi
  • You can check with lsmod if thinkfan_acpi is running
  • To reload a module you need to remove it with sudo modprobe -r <module>, but this is not always possible, so we might need a reboot here.

4. Testing and running

To test thinkfan, use:

thinkfan -n

And to run it, use:

sudo service thinkfan start

And to retrieve the status, use:

service thinkfan status

5. Running on startup

To make it run at startup, we need to edit /etc/modules and add the lines below, to make the modules thinkpad_acpi and coretemp load at boot time. The thinkpad_acpi has to be loaded before coretemp.

thinkpad_acpi
coretemp

Note that this may change the /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp*_input paths (hwmon3 can become hwmon2 or vice versa), probably because of the order in which the modules are loaded or something. So, in the /etc/thinkfan.conf config, you might need to update these lines.

Furthermore, we need to enable the thinkfan service via systemctl.

sudo systemctl enable thinkfan.service
######################################################################
# thinkfan 0.7 example config file
# ================================
#
# ATTENTION: There is only very basic sanity checking on the configuration.
# That means you can set your temperature limits as insane as you like. You
# can do anything stupid, e.g. turn off your fan when your CPU reaches 70°C.
#
# That's why this program is called THINKfan: You gotta think for yourself.
#
######################################################################
#
# IBM/Lenovo Thinkpads (thinkpad_acpi, /proc/acpi/ibm)
# ====================================================
#
# IMPORTANT:
#
# To keep your HD from overheating, you have to specify a correction value for
# the sensor that has the HD's temperature. You need to do this because
# thinkfan uses only the highest temperature it can find in the system, and
# that'll most likely never be your HD, as most HDs are already out of spec
# when they reach 55 °C.
# Correction values are applied from left to right in the same order as the
# temperatures are read from the file.
#
# For example:
# tp_thermal /proc/acpi/ibm/thermal (0, 0, 10)
# will add a fixed value of 10 °C the 3rd value read from that file. Check out
# http://www.thinkwiki.org/wiki/Thermal_Sensors to find out how much you may
# want to add to certain temperatures.
# Syntax:
# (LEVEL, LOW, HIGH)
# LEVEL is the fan level to use (0-7 with thinkpad_acpi)
# LOW is the temperature at which to step down to the previous level
# HIGH is the temperature at which to step up to the next level
# All numbers are integers.
#
# I use this on my T61p:
#tp_fan /proc/acpi/ibm/fan
#hwmon /proc/acpi/ibm/thermal (0, 10, 15, 2, 10, 5, 0, 3, 0, 3)
#hwmon /sys/devices/virtual/hwmon/hwmon0/temp1_input
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp3_input
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp4_input
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp5_input
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp1_input
hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon3/temp2_input
(0, 0, 60)
(1, 60, 65)
(2, 65, 70)
(3, 70, 75)
(4, 75, 80)
(5, 80, 85)
(7, 85, 32767)
@amirrezaalavi
Copy link

amirrezaalavi commented Nov 15, 2023

ThinkPad T490 Intel GPU:

sensors:
  - hwmon: /sys/class/hwmon/hwmon1/temp1_input
fans:
  - tpacpi: /proc/acpi/ibm/fan
levels:
  - [0, 0, 53]
  - [1, 52, 60]
  - [2, 59, 68]
  - [3, 65, 70]
  - [4, 69, 75]
  - [5, 74, 80]
  - [6, 79, 85]
  - [7, 84, 86]
  - ["level full-speed", 85, 32767]

@bizonek27
Copy link

ThinkPad T15g - Options

sensors:
  ######### Common CPU - Option 1 with GPU #########

  # GPU - [2] is a GPU - not used by me
  #- tpacpi: /proc/acpi/ibm/thermal
  #  name: GPU
  #  indices: [2]

  # CPU
  #- tpacpi: /proc/acpi/ibm/thermal
  #  name: CPU
  #  indices: [1]

  ######### Common CPU - Option 2 with GPU #########
  # CPU
  #- hwmon: /sys/devices/platform/thinkpad_hwmon/hwmon/hwmon9/temp1_input
  # GPU
  #- hwmon: /sys/devices/platform/thinkpad_hwmon/hwmon/hwmon9/temp2_input


  ######### Common CPU - Option 3 without GPU #########
  # Package id 0
  #- hwmon: /sys/devices/platform/coretemp.0/hwmon/hwmon11/temp1_input

  # CPU per Core
  # Core 0
  - hwmon: /sys/devices/platform/coretemp.0/hwmon/hwmon11/temp2_input
  # Core 1
  - hwmon: /sys/devices/platform/coretemp.0/hwmon/hwmon11/temp3_input
  # Core 2
  - hwmon: /sys/devices/platform/coretemp.0/hwmon/hwmon11/temp4_input
  # Core 3
  - hwmon: /sys/devices/platform/coretemp.0/hwmon/hwmon11/temp5_input
  # Core 4
  - hwmon: /sys/devices/platform/coretemp.0/hwmon/hwmon11/temp6_input
  # Core 5
  - hwmon: /sys/devices/platform/coretemp.0/hwmon/hwmon11/temp7_input
    #name: coretemp
    #indices: [1, 2, 3, 4, 5, 6, 7]

  ######### GPU nouveau #########
  #- hwmon: /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/hwmon/hwmon7/temp1_input
    #name: nouveau
    #indices: [1]

  ######### SSD nvme0 #########
  #- hwmon: /sys/devices/pci0000:00/0000:00:1b.0/0000:02:00.0/nvme/nvme0/hwmon3/temp1_input
  #- hwmon: /sys/devices/pci0000:00/0000:00:1b.0/0000:02:00.0/nvme/nvme0/hwmon3/temp2_input
  #- hwmon: /sys/devices/pci0000:00/0000:00:1b.0/0000:02:00.0/nvme/nvme0/hwmon3/temp3_input
    #name: nvme
    #indices: [1, 2, 3]
    #correction: [-5, 0, 0]

  ######### SSD nvme1 #########
  #- hwmon: /sys/devices/pci0000:00/0000:00:1d.0/0000:55:00.0/nvme/nvme1/hwmon4/temp1_input
  #- hwmon: /sys/devices/pci0000:00/0000:00:1d.0/0000:55:00.0/nvme/nvme1/hwmon4/temp2_input
    #name: nvme
    #indices: [1, 2]

  ######### acpitz #########
  - hwmon: /sys/devices/virtual/thermal/thermal_zone0/hwmon1/temp1_input
    #name: acpitz
    #indices: [1]

  # cometlake
  - hwmon: /sys/devices/virtual/thermal/thermal_zone4/hwmon8/temp1_input
    #name: pch_cometlake
    #indices: [1]

  # iwlwifi
  - hwmon: /sys/devices/virtual/thermal/thermal_zone10/hwmon12/temp1_input
    #name: iwlwifi_1
    #indices: [1]

fans:
  - tpacpi: /proc/acpi/ibm/fan

levels:
  - [0, 0, 52]
  - [1, 52, 60]
  - [2, 60, 65]
  - ["level auto", 65, 75]
  - ["level disengaged", 75, 255]

Testing


Temperatures(bias): 55(0), 54(0), 53(0), 52(0), 51(0), 51(0), 51(0), 56(0), 59(0) -> Fans: level 1
Temperatures(bias): 58(-3), 67(-6), 58(-2), 59(-3), 57(-2), 57(-2), 56(-1), 55(0), 59(0) -> Fans: level 2
Temperatures(bias): 54(0), 56(0), 55(0), 54(0), 55(0), 54(0), 58(-1), 56(0), 59(0) -> Fans: level 1
Temperatures(bias): 53(0), 56(0), 54(0), 54(0), 53(0), 53(0), 55(0), 56(0), 60(0) -> Fans: level 2
Temperatures(bias): 53(0), 55(0), 54(0), 54(0), 54(0), 53(0), 56(0), 56(0), 59(0) -> Fans: level 1
Temperatures(bias): 55(0), 57(0), 55(0), 55(0), 55(0), 54(0), 56(0), 56(0), 60(0) -> Fans: level 2
Temperatures(bias): 53(0), 56(0), 55(0), 54(0), 54(0), 54(0), 56(0), 56(0), 59(0) -> Fans: level 1
Temperatures(bias): 53(0), 56(0), 55(0), 54(0), 54(0), 54(0), 56(0), 57(0), 60(0) -> Fans: level 2
Temperatures(bias): 54(0), 57(0), 56(0), 55(0), 55(0), 54(0), 57(0), 56(0), 59(0) -> Fans: level 1
Temperatures(bias): 54(0), 57(0), 56(0), 55(0), 55(0), 54(0), 57(0), 56(0), 60(0) -> Fans: level 2
Temperatures(bias): 54(0), 57(0), 56(0), 55(0), 54(0), 54(0), 57(0), 56(0), 59(0) -> Fans: level 1
Temperatures(bias): 55(0), 59(0), 57(0), 56(0), 57(-1), 56(0), 57(0), 57(0), 60(0) -> Fans: level 2
Temperatures(bias): 55(0), 58(0), 56(0), 56(0), 56(0), 56(0), 57(0), 56(0), 59(0) -> Fans: level 1
Temperatures(bias): 56(0), 58(0), 57(0), 57(0), 57(0), 55(0), 57(0), 56(0), 60(0) -> Fans: level 2

@5nizza
Copy link

5nizza commented Dec 11, 2023

Just a note: on my X1YogaGen7 I was getting errors

ERROR: Module thinkpad_acpi doesn't seem to support fan_control
ERROR: ~TpFanDriver: Resetting fan control in /proc/acpi/ibm/fan: Invalid argument

To resolve them, use

echo "options thinkpad_acpi fan_control=1 experimental=1" > /etc/modprobe.d/thinkfan.conf

instead of the original line without experimental=1. The issue may be related to the laptop having two fans instead of one (or maybe not).

And here is my config file, inspired by @managervcf. It works on thinkpad x1 yoga G7:

##
## This file shows how to use sensor-specific temperature limits.
## First of all, you need to specify temperature inputs. 
##
tp_thermal /proc/acpi/ibm/thermal  # provides 8 temperature inputs on x1 yoga G7, and only the first value is relevant

#
## Next we specify the fan we want to use. On a Thinkpad, this is:
#
tp_fan /proc/acpi/ibm/fan

#
## Then you need to specify the temperature limits for each of the sensors.
## A dot means that the corresponding sensor should be ignored. The length of the
## UPPER and LOWER limits must be the same as the number of temperatures. In this
## example, /proc/acpi/ibm/thermal contains 8 sensors, some of which are unused (hence the dots).
#

{ "level 0"   # the fan level
# ^-------^   This works for /proc/acpi/ibm/thermal.
#
#    Sensor count:
#    1  2  3  4  5  6  7  8
#    ======================
    (0  0  0  0  0  0  0  0)      # LOWER limit
    (53	.  .  .  .  .  .  .)      # UPPER limit
}


{ "level 1"
    (48 .  .  .  .  .  .  .)
    (60 .  .  .  .  .  .  .)
}

{ "level 2"
    (55 .  .  .  .  .  .  .)
    (65 .  .  .  .  .  .  .)
}

{ "level auto"
    (60 .  .  .  .  .  .  .)
    (99 .  .  .  .  .  .  .)
}

Probably there is no need for level 0, level 1, level 2, level auto separation,
and a simpler separation level 0, level auto will do just fine,
as my goal is to avoid the fan kicking in too early.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment