Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ITE SuperIO fan control #72

Merged
merged 15 commits into from Jun 10, 2023
Merged

ITE SuperIO fan control #72

merged 15 commits into from Jun 10, 2023

Conversation

xCuri0
Copy link
Contributor

@xCuri0 xCuri0 commented Apr 28, 2023

Working fan control for ITE SuperIOs

image

There are some issues however.

  • I can't figure out how to add the F#Md key without messing up all the SMC fan keys. For this reason it's commented out and it's not possible to restore automatic fan control by motherboard unless you reboot.
  • Hardcoded RPM ranges.
  • Control index doesn't always match the tachometer index which you can see in my screenshot (Fan Main uses control of Fan 2).
  • Possible issues with code structure/style

So far it's only been tested on my Gigabyte B75M-D3H (IT8728F) but it should work on most ITE SuperIOs. I've used LibreHardwareMonitor's code to as a reference for the registers, etc.

I'm also looking for suggestions of how to expose configuration (rpm/pwm curve, correcting index, hiding fans, etc). Currently planning on doing something similar to how it's done for EC Device.

Configurable through fan#-hide (hide fan), fan#-control (set control index) and fan#-pwm (pwm curve)

@xCuri0
Copy link
Contributor Author

xCuri0 commented May 13, 2023

Any update on this ? I know it's not yet ready for merge, just looking for guidance on how I should expose the configuration and other things.

@vit9696
Copy link
Contributor

vit9696 commented May 13, 2023

Are you sure you add the SMC keys in ASCII sorted order? This is a documented requirement. I think x goes before d, thus adding keys in the wrong order corrupts VSMC.

@vit9696
Copy link
Contributor

vit9696 commented May 13, 2023

As for configuration, I think your best is injecting device properties into the EC device. Could you please outline the suggestions you have in mind, and I guess we can handle it.

@xCuri0
Copy link
Contributor Author

xCuri0 commented May 13, 2023

@vit9696

Are you sure you add the SMC keys in ASCII sorted order? This is a documented requirement. I think x goes before d, thus adding keys in the wrong order corrupts VSMC.

That worked thanks, finally fixed it and can restore system fan control.

As for configuration, I think your best is injecting device properties into the EC device. Could you please outline the suggestions you have in mind, and I guess we can handle it.

Here is my suggestion. # will be the fan index.

  • fan#-pwm: RPM corresponding to PWM value (0 to 255) separated by vertical bar(|). Example 900,0|1200,130|1600,255. Default value will be 0,0|3315,255 which will function identical to the current state of it. It could be possible to automatically generate this if manually entering a few values doesn't give enough precision.
  • fan#-control: Index of control this fan will use, if not set it will default to the fan index.
  • fan#-hide: Hides this fan if present.

Also FYI, LibreHardwareMonitor source shows that some recent Gigabyte motherboards have an additional controller that needs to be disabled https://github.com/LibreHardwareMonitor/LibreHardwareMonitor/blob/master/LibreHardwareMonitorLib/Hardware/Motherboard/Lpc/GigabyteController.cs , not planning on implementing this though

@vit9696
Copy link
Contributor

vit9696 commented May 14, 2023

That sounds about right, I am not sure whether this should be just fan to avoid conflicts, but we can rename later if needed. What approximation formula do you plan to use for value interpolation?

Used to configure RPM->PWM curve
@xCuri0
Copy link
Contributor Author

xCuri0 commented May 22, 2023

@vit9696 Hi I was able to successfully implement everything I said

Screenshot 2023-05-22 at 9 57 12 AM

I'm just using linear interpolation for figuring out the PWM values, works good just need to pre-compute them before to reduce overhead from nested loop every time value is set. done

void computeCurve(uint8_t index) {
	for (int i = 0; i <= 255; i++) {
		if (_pwmCurve[index][i] == UINT16_MAX)
			continue;

		for (int j = i + 1; j <= 255; j++) {
			if (_pwmCurve[index][j] == UINT16_MAX)
				continue;

			// No points in between
			if (j == i + 1)
				break;

			// We have the 2 points now so lets interpolate in between them.
			for (int k = i + 1; k <= j ; ++k) {
				_pwmCurve[index][k] = lerp(_pwmCurve[index][i], _pwmCurve[index][j], (float)(k - i) / (float)(j - i));
			}

			i = j - 1;
			break;
		}
	}
}

You can probably see in my screenshot that PWM/RPM curve of the fan isn't exactly linear so the values are off, need to add more values to the fan#-pwm so that it's correct. Can probably make a program that automatically generates these curves.

Shouldn't some of this code be shared in SuperIODevice though ? So that's it's easier to implement PWM curve for other SuperIOs

@xCuri0
Copy link
Contributor Author

xCuri0 commented May 22, 2023

Even when using a manually created 8 point curve it's quite accurate.

image

Probably will add a tool to automatically generate the PWM/RPM curves

@vit9696
Copy link
Contributor

vit9696 commented May 23, 2023

A tool might make some sense I guess, yeah. I am not positive it is a good idea to put this to the driver itself.

@xCuri0
Copy link
Contributor Author

xCuri0 commented May 24, 2023

@vit9696 I plan on making it into an external tool like smcread etc. Having generation of rpm/pwm curve built into the driver is a bad idea yeah and I don't plan on doing that.

@xCuri0 xCuri0 changed the title [WIP] ITE SuperIO fan control ITE SuperIO fan control May 28, 2023
@xCuri0
Copy link
Contributor Author

xCuri0 commented May 28, 2023

I've added fanpwmgen which will generate fan#-pwm curves, not the most accurate atm due to lack of averaging but works good enough. Also fixed issues with SMCWrite in smc command while doing it.

VirtualSMC fan#-pwm generation tool
Usage:
./fanpwmgen [options]
    -f <num>   : the fan number to use
    -s <steps> : number of steps to use when generating curve, default 16 and max 256
    -t <time>  : time to wait before going to next step, default 2 seconds
    -h         : help

image

Probably need to move the fan#-pwm stuff out of ITEDevice so if anyone wants to implement for Nuvoton they can use it. And also write docs for this (could be an optional post install step too once it's polished enough)

@xCuri0
Copy link
Contributor Author

xCuri0 commented Jun 2, 2023

I was also considering adding voltage reading because it's easy to read raw voltages. But every motherboard uses different input resistance, reference resistance and reference voltage.

LibreHardwareMonitor has a list of them for many motherboards though https://github.com/LibreHardwareMonitor/LibreHardwareMonitor/blob/master/LibreHardwareMonitorLib/Hardware/Motherboard/SuperIOHardware.cs

It would probably be too much configuration to expose with DeviceProperties so instead would need to use a .plist "SuperIO layout" which could also contain fan hide/control layout. So I dropped that idea because it would be alot of effort to expose the configuration.

And also unsure about the correct SMC keys to use for 3.3V/5V/12V/RTC battery because they seem to differ across models.

So far what I found that exists on actual Macs. I couldn't find a MacPro7,1 dump tho

VM0R: DIMM voltage
Vp0C: 12V PSU. Maybe use VD2R or VD0R instead
VD5R: 12V PSU standby (if needed)
VR3R: 3.3V PSU
IR35: 3.3V PSU standby
V50R: 5V PSU
IR54: 5V PSU standby
ICAB: VTT (ICVB for CPU 2)
VC0C: CPU Voltage. SMCProcessor adds this from VID but SuperIO is more accurate. Won't show in iStat for me using MacPro7,1 SMBIOS
VN0C: iGPU voltage

Can't find anything for RTC battery tho which sucks. I don't know of any other way it can be exposed

@vit9696
Copy link
Contributor

vit9696 commented Jun 10, 2023

For voltages we thought of going the tool way. I.e. we built a database here: https://github.com/CloverHackyColor/HWMonitorSMC2/tree/master/LPC

@vit9696 vit9696 merged commit b150248 into acidanthera:master Jun 10, 2023
3 checks passed
@xCuri0
Copy link
Contributor Author

xCuri0 commented Jun 10, 2023

HWMonitorSMC2 does work for me after making a configuration. But it seems like the project is dead as PRs are no longer being answered and last update is from 2020.

@vit9696
Copy link
Contributor

vit9696 commented Jun 11, 2023

That's a difficult question, perhaps somebody needs to take over.

@Lorys89
Copy link
Contributor

Lorys89 commented Jun 17, 2023

@xCuri0 can you make this work for Nuvoton chips as well?

@xCuri0
Copy link
Contributor Author

xCuri0 commented Jun 18, 2023

@Lorys89 If I do upgrade to a newer motherboard with Nuvoton chip yes.

You should try looking at the LibreHardwareMonitor source it's not too hard to adapt it here.

@Edwardwich
Copy link

Working fan control for ITE SuperIOs

image

There are some issues however.

  • I can't figure out how to add the F#Md key without messing up all the SMC fan keys. For this reason it's commented out and it's not possible to restore automatic fan control by motherboard unless you reboot.
  • Hardcoded RPM ranges.
  • Control index doesn't always match the tachometer index which you can see in my screenshot (Fan Main uses control of Fan 2).
  • Possible issues with code structure/style

So far it's only been tested on my Gigabyte B75M-D3H (IT8728F) but it should work on most ITE SuperIOs. I've used LibreHardwareMonitor's code to as a reference for the registers, etc.

I'm also looking for suggestions of how to expose configuration (rpm/pwm curve, correcting index, hiding fans, etc). Currently planning on doing something similar to how it's done for EC Device.

Configurable through fan#-hide (hide fan), fan#-control (set control index) and fan#-pwm (pwm curve)

can add fan#-pwm to ECDeviceGeneric for fixing max RPM and Min RPM ?
Just for beter filling
Screenshot 2024-03-07 at 00 36 57

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
4 participants