Open-source project
Shuzhengz/TPFanCtrl2 avatar
Shuzhengz/TPFanCtrl2

TPFanCtrl2: putting both ThinkPad fans under manual control on Windows

ThinkPad Fan Control 2 (Dual Fan) for Windows 10 and 11

552 stars64 forksC++Unlicense

At a glance

What is it?
TPFanCtrl2 is a fork of the original ThinkPad Fan Control that drives two fan devices instead of one, with a per level table, a plain text INI file and an explicit no warranty release. It is a small Windows utility with real hardware caveats, not a polished background service.
Who is it for?
TPFanCtrl2 suits a ThinkPad owner with a dual fan machine who wants the fans off below 60C and accepts editing an INI file and running with administrator rights, and it does not suit a ThinkBook or a P50 user who wants a working automatic curve.
Can I use it commercially?
Yes. Unlicense is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 51 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A dual fan fork of the original ThinkPad Fan Control

The lineage matters more than anything else about this project. TPFanCtrl2 is a fork of the original TPFC, the ThinkPad Forum utility, and it is based on byrnes' dual fan mod. The change it makes is stated plainly: the fork was updated to work with two fan devices.

That is the entire scope of the difference, and it is a meaningful one. The original tool was built for a ThinkPad generation where the embedded controller exposed a single fan, so there was one curve to configure and one level to set. A later generation of hardware has two fans driven by the same controller, and the single fan logic leaves the second one unmanaged. A utility that writes the same register for both devices is what the community wanted.

The default behaviour follows the same philosophy. The default fan profile prioritises fan noise, with the fans only turning on at 60C. In practice that means a quiet machine until it is genuinely warm, which is the opposite of what a fan utility that spins up aggressively would do.

The code base is C++ and the project topics list Visual Studio alongside the ThinkPad tags, which matches the build instructions further down. A plugin exists as a separate project by scorpion421 for fan control integration, so the utility is not isolated on the machine either.

The driver layer is a prerequisite, not an optional extra

Before the program can do anything, a low level driver has to be present. The requirements section is direct about it: to avoid errors, either install tvicport manually or install the original version of TPFanControl and run the dual fan version instead of the original version.

That second option is the interesting one. The upstream utility is itself the vehicle for the driver, so installing the original and swapping in the dual fan build gives you the driver without a separate download. Either way, the same kernel level access is required, and the documentation does not treat this as optional.

Two other requirements are stated. Administration permission is required for the program to be able to control system fan speed, which follows from the previous point: writing to the embedded controller is a privileged operation. And Windows 10 or 11 is required to run the program. Windows XP, Vista, 7 and 8 may work, but the text is careful to add that they are untested and should not be expected to.

The repository root shows why the driver documentation is bundled: there is a TVicPortDocs directory next to the TPFCIcon folders, so the port driver documentation is kept alongside the source rather than being left to a third party page.

This is worth pausing on for anyone assessing risk. A fan control utility that runs as administrator, talks to the embedded controller through a kernel driver, and ships with no warranty and no promise of bug fixes is not a low stakes install, and the project's own release note says the binaries and source are provided as is and should be used at your own risk.

Fan levels are a table, and the advanced range is hex

The manual mode exposes a set of discrete levels, and the documentation presents two different scales for them.

bash
| 0 - Off | 0 - Off |
| 1 - 30% | 50 - 40% |
| 2 - 40% | 60 - 60% |
| 3 - 45% | 70 - 100% |
| 4 - 50% | 80 - 100% |
| 5 - 60% |
| 6 - 65% |
| 7 - 65% |

The left column is the Normal scale and the right column is Advanced. The two scales do not line up one to one, and the higher rows only exist in the Normal column, so the Advanced scale runs from 0 and then jumps to 50 as its first real step. A level of 3 in Normal is 45 percent while the same number in Advanced is 70 and fully on.

Two notes under the table explain the mechanics. The advanced level value is converted into hex before being read by the EC, and the numbers in the table are a rough estimate of what to expect rather than a measured figure. The 0 to 7 range is intended to be used as the fan levels intended by the manufacturer, with 7 being the highest the laptop BIOS can go, and to take full advantage of the fan you need to enter 0 to 128 in hex, with the example given that 128 in hex is 0x80, which is entered as 80.

So there are two ways to run the fan. The 0 to 7 range is the safe one because it matches what the BIOS itself will ask for. Going beyond that means writing raw hex values into the controller, and the documentation describes the table above as an estimate rather than a guarantee.

Everything is configured in TPFanControl.ini next to the executable

Configuration is a plain text file, and the documentation is specific about where it has to live: the TPFanControl.ini file should always be in the same directory as the fancontrol.exe executable file. There is no registry key and no menu-driven settings store that matters here, which means the settings travel with a copy of the folder.

The parameters the documentation lists as examples include the temperature refresh cycle time, whether to start minimized in the taskbar tray, the maximum read errors before the program auto shuts down, logging of the program log to file and data to a CSV file, the fan curve in smart mode, a second smart mode reachable from the tray, and the temperature threshold to exit manual mode.

The auto shutdown on repeated read errors is the one worth noticing. It suggests the utility treats a controller that stops answering as a condition to retreat from rather than to keep hammering, and a program that gives up cleanly when the hardware stops responding is a reasonable design for something that writes to a fan controller.

The dual smart modes also hint at the intended usage. One curve is the normal one and a second is available from the tray, so you can switch to a different profile without editing the file. The documentation does not say how the two are distinguished in the INI, and the naming of the keys is not given, so a first time user will have to open the shipped file and look.

Building needs Visual Studio 2022 and two icon projects

The build instructions are short but contain a dependency that is easy to miss. Building requires Microsoft Visual Studio 2022 Community, and the project should have the correct configuration upon opening the project file fancontrol.sln, though you might have to manually copy and paste the INI file into the Debug folder to test the built program.

The configuration that currently builds is Debug and Win32, and admin permission is needed to run the built program. Win32 is worth a second look, because it means the output is a 32 bit binary regardless of the Windows version it runs on.

The dependency warning is about the two icon projects. The instructions say not to build the project without TPFCIcon and TPFCIcon_noballons, because they are necessary parts of the application and the main fan control software will not function without them. Both directories are visible at the top level of the repository, so they are separate subprojects that have to be built and placed correctly, and the failure mode is a running program with missing pieces rather than a compile error.

There is also a historical angle. The source code of spinoff releases for different machines, with 2.1.5 B given as the example, is stored within the archive directory, and you can build them by substituting the main fancontrol directory with the fancontrol directory of the desired version. TPFCIcon and TPFCIcon_noballons should stay the same for every release.

One build error has a documented fix. If you hit Linker Tools Error LNK2026, module unsafe for SAFESEH image when building, the answer is a project property change.

bash
- Go to Project properties -> Configuration Properties -> Linker -> Advanced
- Disable option `Image has Safe Exception Handlers` (No (/SAFESEH:NO)

Known issues are hardware specific, and the P50 needs an old build

The known issues section is the most useful part of the documentation for anyone deciding whether this applies to their machine.

On single fan devices the fan speed will sometimes fail to show up, and the text says the problem is in the process of being fixed. Sometimes the fans will fail to sync, with one ramping up and the other not, and the manual fix is to switch to BIOS mode and then switch back to the desired mode. It will also sometimes take a longer time for the speed to update and the fans to spin up, which the documentation attributes to EC management for the newer ThinkPad BIOS, and it says there is currently no way around it.

That last point sets a boundary. On a recent BIOS, the utility can be outpaced by the firmware's own fan management, and there is no configuration that removes that delay.

Two model specific notes follow. ThinkPad P50 users should use the 2.1.5B release because the fan control parameters are different, and the temperature is currently broken in that build, so it is recommended to use it in manual mode only. Some ThinkBook models have a different EC address, so the program might not work on them at all.

The ThinkBook case is the one to check first. The embedded controller address is a hardware constant, and if your model's address differs then no amount of configuration will make the program talk to the right controller.

The bleeding edge branch is a separate early beta

There is a parallel line of development, and it is explicitly not the main branch. FanDjango is refactoring and cleaning up TPFanControl2, clarifying messages and log texts and adding enhancements requested in the issues, and these are early beta releases published under the V2.3.9 release on FanDjango's own fork. When sufficient feedback is received they may be incorporated into the main trunk.

The confirmed support list for that beta names specific machines: P53, Z13, Z16 Gen 1, Z16 Gen 2, P16 Gen1 AMD, T16 Gen1 AMD, X1 carbon gen12, X230T and P1 Gen7. That list is a useful signal, because it is the kind of hardware coverage a dual fan tool can only have for a subset of the ThinkPad range.

The stable line here is older. The release history shows 2.3.3, 2.2.1 and 2.3.2, with 2.3.3 published on 2025-05-06, while the last push to the branch was on 2026-09-01. The gap between a 2025 release and a 2026 commit is normal for a utility with a slow release cadence, but it means the released binary and the current source are not the same thing.

Contributions are handled on the same terms as the code. The guidance asks for a pull request with at least one review to merge it into main, and by doing so the contributor agrees to dedicate the contribution to the public domain in compliance with the Unlicense, with the dedication quoted in full. The repository carries a LICENSE file, a CODE_OF_CONDUCT.md and the Unlicense terms the release note points to.

Editorial conclusion

TPFanCtrl2 suits a ThinkPad owner with a dual fan machine who wants the fans off below 60C and accepts editing an INI file and running with administrator rights, and it does not suit a ThinkBook or a P50 user who wants a working automatic curve. Before you run it, install tvicport or the original ThinkPad Fan Control as the documentation asks, and confirm on your own model that the fan level table matches what the embedded controller accepts, since the last push was on 2026-09-01 and the 2.3.3 release predates the current work on the branch.

Frequently asked questions

What is TPFanCtrl2 and how does it differ from the original ThinkPad Fan Control?

TPFanCtrl2 is a fork of the original TPFC that was updated to work with two fan devices instead of one. Its default fan profile prioritises fan noise, with the fans only turning on at 60C.

What do I need before TPFanCtrl2 will work on a ThinkPad?

You need either tvicport installed manually or the original version of TPFanControl, running the dual fan version instead of the original one. Administration permission is required, and Windows 10 or 11 is required.

How do I configure TPFanCtrl2?

You edit the values in the TPFanControl.ini file that ships with the program, and that file must always sit in the same directory as fancontrol.exe. The documented settings include the temperature refresh cycle time, start minimized in the taskbar tray, and the maximum read errors before the program auto shuts down.

Can I control the fan speed manually on a ThinkPad P50?

The documentation says P50 users should use the 2.1.5B release because the fan control parameters are different, and that the temperature is currently broken in that build, so it is recommended to use it in manual mode only.

What are the manual fan levels in TPFanCtrl2?

The Normal scale runs from 0 (Off) through 7, which is the highest the laptop BIOS can go. The Advanced scale converts its level into hex before the embedded controller reads it, so to go beyond the manufacturer range you enter values from 0 to 128 in hex.

Official sources

  1. Issues
  2. License: Unlicense
  3. README
  4. Releases
  5. Shuzhengz/TPFanCtrl2 on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/shuzhengz-tpfanctrl2.svg)](https://hysenlabs.com/projects/shuzhengz-tpfanctrl2)

Was this useful?