Closed yjmd2222 closed 3 months ago
Interesting findings here: https://www.hackintosh-forum.de/forum/thread/58108-asus-notebook-fan-control-acpi-schreiben-in-ec-ram/ and the issue link in it. There's a temperature table in the EC RAM which is picked up by the fan mechanism to spin at certain levels at the corresponding temperatures.
@HolzMichel, I'm guessing you are the one that started the thread above. Have you had any more progress other than updating this table with ACPIDebug? And I'm not trying to be offensive, but parts of your offsets and the SSDT are probably wrong, as hexadecimal numbering does not go from 9 to 10. It should be ..., 0x539, 0x53a, 0x53b,...
Hello @yjmd2222 , yes this is an excel auto fill issue, in my real implementation it is correct of course…. I have been using this method for more than a year now and it works very well. I have two Automator scripts, one runs on startup and sets the „silent“ fan curve. The other one has a small GUI and let’s me select different modes: silent, full speed, stock and so on.
If it is beneficial for you I can upload what I did here.
Hello. It'd be great to see your scripts. Not only me but all others could benefit from them.
@HolzMichel, please feel free to upload your scripts any time :)
Meanwhile, I tried to see if setting the values within the ACPI itself is possible. Ugly and nested usage of ECAV,
but the log shows successful writes. I only set the first five bytes though.
Scope (\_SB.PCI0.LPCB.EC0)
{
Device (YJMD)
{
Name (_ADR, Zero) // _ADR: Address
Method (_INI, 0, NotSerialized) // _INI: Initialize
{
If (ECAV ())
{
\RMDT.P1 ("RMDT debug: EC available")
\RMDT.P1 ("RMDT debug: Writing to Fan Temp table")
\_SB.PCI0.LPCB.EC0.WRAM (0x0537, 0x3C)
\_SB.PCI0.LPCB.EC0.WRAM (0x0538, 0x3E)
\_SB.PCI0.LPCB.EC0.WRAM (0x0539, 0x40)
\_SB.PCI0.LPCB.EC0.WRAM (0x053A, 0x42)
\_SB.PCI0.LPCB.EC0.WRAM (0x053B, 0x44)
\RMDT.P1 ("RMDT debug: Reading Fan Temp table")
\RMDT.P1 (\_SB.PCI0.LPCB.EC0.RRAM (0x0537))
\RMDT.P1 (\_SB.PCI0.LPCB.EC0.RRAM (0x0538))
\RMDT.P1 (\_SB.PCI0.LPCB.EC0.RRAM (0x0539))
\RMDT.P1 (\_SB.PCI0.LPCB.EC0.RRAM (0x053A))
\RMDT.P1 (\_SB.PCI0.LPCB.EC0.RRAM (0x053B))
\RMDT.P1 (\_SB.PCI0.LPCB.EC0.RRAM (0x053C))
\RMDT.P1 (\_SB.PCI0.LPCB.EC0.RRAM (0x053D))
\RMDT.P1 (\_SB.PCI0.LPCB.EC0.RRAM (0x053E))
}
Else
{
\RMDT.P1 ("RMDT debug: EC not available")
}
}
Method (_STA, 0, NotSerialized) // _STA: Status
{
If (_OSI ("Darwin"))
{
Return (0x0F)
}
Else
{
Return (Zero)
}
}
}
Interestingly, there are two definitions of
Sorry for misinformation if anybody was interested (This is to say the above striked-through writing was wrong, but my SSDT works sorry again). I was thinking I saw ECAV
object in the ACPI. One in H_EC
and the other in EC0
. I'm no expert in this area, but I chose EC0.ECAV
because it's about writing to and reading the EC RAM if I'm not wrong.LPCB.ECAV
and EC0.ECAV
, but I mistook H_EC
for LPCB
. LPCB
is the parent object of H_EC
or EC0
in Intel. In most ASUS DSDTs, there exist H_EC
and H_EC.ECAV
(and EC0
and EC0.ECAV
). No LPCB.ECAV
anywhere. H_EC
and EC0
are common ACPI names for embedded controller in Intel boards. To my knowledge, there can only be one embedded controller, and so either H_EC
or EC
but not both. And in our laptops, the only actual present device name for the embedded controller, EC0
. Checking for availability of H_EC
via H_EC.ECAV
would not have worked because it's not there and because I am probing EC0
. And checking availiability of LPCB.ECAV
if that was actually present would not fit here because as I said EC RAM (EC0
RAM) is what's important here.
@yjmd2222 your approach also looks promising and should work. If I remember correctly I initially tried to do it via SSDT but I couldn’t get the timing right so that either the system kept overwriting the registers with default values again or it never got set - did not know how to really debug this either. Finally I decided against a deeper dive into ACPI because in newer macOS versions the color banding issue of the iGPU can no longer be addressed by spoofing so the lifetime of this hardware is kind of limited. I did not forget about you, just couldn’t get my hands on the ZenBook yet.
Before someone mentioned the visual artifacts were fixed with AAPL.GfxYTile
set to 1
: https://github.com/EETagent/T480-OpenCore-Hackintosh/issues/32#issuecomment-692939634
The revised WEG manual says either spoof to SKL or set AAPL.GfxYTile
.
You might want to set that property in DeviceProperties
.
Another suggestion is use OCLP and spoof as SKL.
Wow, that’s nice. I did intense research this winter but could not find this. Will give it a try for sure. Maybe I will get hands on the zenbook this weekend.
AsusSMC-1.4.1-DEBUG.zip Fan mod enabled kext
This probably runs on top of already running EC fan mechanism. hunch:
I remember ACPIPoller.kext being quieter and not causing intermittent rapid spins. I need to compare the SSDT from the Clover branch and the kext source code.
afilipovich
\_SB.PCI0.LPCB.EC0.WRAM 0x0521 0xc5 # full fan speed, locks register 0x97; .TACH method shows current fan speed \_SB.PCI0.LPCB.EC0.WRAM 0x0521 0x85 # back to automatic fan speed control \_SB.PCI0.LPCB.EC0.WRAM 0x0521 0x35 # manual fan control. Fan speed can be controlled by .ST84 call. \_SB.PCI0.LPCB.EC0.ST84 Arg0 Arg1 # Arg0 - fan id (0x00 for CPU fan). Arg1 - speed 0x00 - 0xff
Maybe set manual speed to 0 in EC mechanism and give only the kext the control
whereas in ACPI
Local2 = Match (FTA1, MGE, Local0, MTR, Zero, Zero)
MatchGreaterThanOrEqualTo Local0
which holds average temperature (minimum match). The kext code reads "if exact match." It should actually be
for (uint32_t i = 0, count = arrsize(FTA1); i < count; i++) {
if (FTA1[i] >= avgtemp) {
idx = i;
break;
}
}
https://osxlatitude.com/forums/topic/10244-how-to-implement-custom-fan-control-on-asus-laptops/
When using 2 it passes Arg0 to ST98 as 0xFF (255) (Oh wait! according to ACPI spec, 255 is max allowed FAN value.)
// Scaling from values as low as 255 RPM to values as high as 5026 RPM (That's great!) // Scaling that ASUS provided was from 2200 RPM to 2900 RPM (Duh!)
// Temperatures. 0xFF means if temp is above 52C, let bios take control of things(auto).
Name(FTA1, Package()
{
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 0xFF,
})
// Fan speeds. 255(0xFF) is max/auto, 0(0x00) is for fan off
Name(FTA2, Package()
{
0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 160, 185, 205, 225, 245, 250, 255
})
Comments don't make sense. To me it reads either
1. At 52 degrees fan spins at 250 out of max 255, but above that temperature the RPM should go down if control is given to EC. So 2200 to 2900 RPM from 52 degrees up, but 255 to 5026 RPM from 52 degrees down?
2. Or some speed units of 250 at 52 degrees and EC default onward? that should not change the upper limit of 2900 RPM. False report from black.dragon74?
Probably 2 is what's going on. I noticed the difference between `ST84` and `ST98`. `ST98` makes fan spin at lower speeds when it receives high values and even 255. `ST84` seems to spin at speeds that scale from minimum 0 to maximum 255.
And `\_SB.PCI0.LPCB.EC0.WRAM 0x0521 0x35 # manual fan control. Fan speed can be controlled by .ST84 call.` this disables intermittent spins. Also seems to disable fan readings from `TACH`.
AsusSMC-1.4.1-DEBUG.zip 0x521 to 0x35, custom temperature map from 40 to 80.
SSDT-FanModeReset.aml.zip
AsusSMC-1.4.1-DEBUG.zip
The SSDT is for resetting Fan mode from manual control to automatic. This is needed if rebooting from macOS to any other OS. Cold boot doesn't matter as in this case EC is reset.
Load AsusSMCFanDataProvider.kext before AsusSMC.kext. You can set your own temperatures and speeds in the former kext. Just make sure the numbers of items in the respective arrays match. It is best if someone finds the best temperature and speed sets.
boot arg needed: -asussmcfanmod
Fork here: https://github.com/yjmd2222/AsusSMC
SSDT-FanModeReset.aml.zip This updated SSDT checks fan mode before overriding it. Exit if already in automatic mode.
And the kext and the SSDT won't work on newer Zenbooks. Need a check for generation/model. RRAM
and WRAM
have different numbers of arguments across different models, so that may be an option
I finally found some time to respond to this thread. Here is my SSDT-RMDT where I implemented the different fan curves (silent, cool, stock) and also the other commands mentioned above: SSDT-RMDT.aml.zip
I use ioio to call the methods from within MacOS. Scripts.zip
From there it is quite easy to add e. g. automator tasks that run on startup an automatically set a fan curve or do some quick and dirty gui tools:
Before someone mentioned the visual artifacts were fixed with
AAPL.GfxYTile
set to1
: EETagent/T480-OpenCore-Hackintosh#32 (comment) The revised WEG manual says either spoof to SKL or setAAPL.GfxYTile
.You might want to set that property in
DeviceProperties
.Another suggestion is use OCLP and spoof as SKL.
@yjmd2222 According to this https://github.com/acidanthera/WhateverGreen/blob/master/Manual/FAQ.IntelHD.en.md setting the AAPL,GfxYTile
is for "the other way around", they talk about spoofing skylake as kabylake but what I need to do to avoid color banding is spoof my kabylake as a skylake. Feel free to correct me if I got it wrong.
Thanks for your scripts!
As for colorbanding, the devs say the fixes the AAPL property does is not exclusive to SKL, but I read elsewhere it does not fix the color banding issues unless the display panel is replaced. So I think you might want to use OCLP to upgrade to newer OSes.
I will close this issue because the original question was answered and there was information gain.
@HolzMichel please open a new issue for the color banding problem.
After rebooting about 10 times, hibernation magically worked.
[ 1203.999436]: AsusSMC fan: @ (DBG) refreshFan speed 2840
[ 1203.999717]: AsusSMC fan: @ (DBG) setFanSpeed cpu temp 63
[ 1203.999720]: AsusSMC fan: @ (DBG) setFanSpeed average temp 57
[ 1205.001078]: AsusSMC fan: @ (DBG) refreshFan speed 3166
[ 1205.001732]: AsusSMC fan: @ (DBG) setFanSpeed cpu temp 63
[ 1205.001739]: AsusSMC fan: @ (DBG) setFanSpeed average temp 58
[ 1206.002461]: AsusSMC fan: @ (DBG) refreshFan speed 3252
[ 1206.003117]: AsusSMC fan: @ (DBG) setFanSpeed cpu temp 48
[ 1206.003124]: AsusSMC fan: @ (DBG) setFanSpeed average temp 58
[ 1207.003592]: AsusSMC fan: @ (DBG) refreshFan speed 3267
[ 1207.004143]: AsusSMC fan: @ (DBG) setFanSpeed cpu temp 62
[ 1207.004149]: AsusSMC fan: @ (DBG) setFanSpeed average temp 58
[ 1208.004351]: AsusSMC fan: @ (DBG) refreshFan speed 3267
[ 1208.004534]: AsusSMC fan: @ (DBG) setFanSpeed cpu temp 57
[ 1208.004536]: AsusSMC fan: @ (DBG) setFanSpeed average temp 58
…
[ 1265.272158]: [ACPI Debug] [ACPI Debug] "RRAM (0X0521) result: 0000000000000085"
Fan switches on and off every second or so as if in automatic mode. Fan log shows fan reading is available because it is not in manual mode. ACPIDebug log shows the fan is in fact in automatic mode (0x85).
So hibernation does reset EC. I will see if I can try to make the kext reinitialize fan mod on resume.
The most recent commits include some things about fan readings. Anybody knows anything about them? I think hiep tried to see if setting fan curve works directly via WMI/EC in the "experimental fan code," but have no idea on the current status. ACPIPoller introduces a third-party module to always poll on the fan to measure the current/cumulative fan/temperature, so I guess it uses up a lot of resources, hence not used in the OC branch of the Zenbook repo. The fan readings are not published as are. Had to use SMCSuperIO.kext and the corresponding properties for "generic" device kindly provided by BrandTime for the actual readings by iStat menus and Macs Fan Control. But even so the min/max rpms are invalid (65345 something). Anyone would like to share their experience or information?