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

Indicator only controls one fan #27

Open
theangrydev opened this issue Aug 13, 2019 · 24 comments
Open

Indicator only controls one fan #27

theangrydev opened this issue Aug 13, 2019 · 24 comments

Comments

@theangrydev
Copy link

On my P7xxDM2(-G) (according to dmidecode -t baseboard) there are two fans.

I am only able to control the one on the left.

Is there another hardware register than can be manipulated to control the other fan? How did you manage to find the address?

@theangrydev
Copy link
Author

The embedded controller has some debug descriptors at /sys/kernel/debug/ec/*/{gpe,use_global_lock,io} that are documented here:
https://www.kernel.org/doc/Documentation/ABI/testing/debugfs-ec

There is a tool that can be used to read them here:
http://ftp.suse.com/pub/people/trenn/sources/ec/ec_access.c

@deebfeast
Copy link

This is how I have done it for Clevo NH55RDQ and its two fans. Just call function ec_write_fan_duty twice but use different values for the fan number.

Like:

ec_io_do(0x99, 0x01, v_i);
ec_io_do(0x99, 0x02, v_i);

Works like a charm.

For reading also twice, e.g. for Clevo NH55RDQ

#define EC_REG_FAN_1_DUTY 0xCE
#define EC_REG_FAN_2_DUTY 0xCF
#define EC_REG_FAN_1_RPMS_HI 0xD0
#define EC_REG_FAN_1_RPMS_LO 0xD1
#define EC_REG_FAN_2_RPMS_HI 0xD2
#define EC_REG_FAN_2_RPMS_LO 0xD3

// replace X with fan number of build a list or counter to loop
raw_duty = ec_io_read(EC_REG_FAN_X_DUTY);
raw_rpm_hi = ec_io_read(EC_REG_FAN_X_HI);
raw_rpm_lo = ec_io_read(EC_REF_FAN_X_LO);

@junocomp
Copy link

junocomp commented Jun 9, 2020

@deebfeast can you share your clevo-indicator.c if you still have it.

I tried your solution but I don't think I'm doing it right.

@deebfeast
Copy link

deebfeast commented Jun 9, 2020

Of course. See attachment.

For me e.g. clevo-indicator 20 silences the laptop but sticks to that cycle of course.
Start the usual clevo-indicator -? for a dump of values.
Just starting the GUI does work but you might want to tune the AUTO options a bit further.
GPU readings are not working here so I left it out for now.

clevo-indicator.c.txt

@junocomp
Copy link

junocomp commented Jun 9, 2020

I included part of your code into my script but it still only controls 1 fan (left). Would you mind trying mine and see if you have the same result please.

clevo-indicator.c.txt

@deebfeast
Copy link

Here you seem to still fix the fan number on 0x01. Diff:


535c534
<     return ec_io_do(0x99, fan_number, v_i);
---
>     return ec_io_do(0x99, 0x01, v_i);

@junocomp
Copy link

@deebfeast I made the changes and it compiled just fine but is still controlling only one fan. I was thinking of maybe just running the indicator for the second fan alone and two clevo-indicators for each fan but I can't seem to figure out how to do that either.

@deebfeast
Copy link

deebfeast commented Jun 10, 2020

Do you have the same model, Clevo NH55RDQ? Perhaps things have changed. You do see the second RPM when you run command "clevo-indicator -?" ?

Some other remarks for Linux and Clevo, although you might know already:

  • after updating kernel to 5.3.0-42 big improvements were noted in power consumption & average temperature on my laptop
  • TLP installed & enabled, check setting with tlp-stat | egrep 'State|Mode'

@junocomp
Copy link

I have a different Clevo model with Nvidia RTX 2060. I doubt the second fan is controlled by Nvidia. I tried other Nvidia fan controllers and they don't seem to work.

This is what I get when I run your script

Simple fan control utility for Clevo laptops
Indicator...
06/10 12:52:25 CPU=36°C, auto fan duty to 10%

I wonder if there is a way for me to detect the second fan.

@deebfeast
Copy link

deebfeast commented Jun 10, 2020

Try first without the GUI. Just run it

clevo-indicator 20
clevo-indicator 30
(etc. try higher just to see).

The output should list both fans speeds as it's read again (might take a second to kick in).
The GUI widget might have to be adjusted on thresholds a bit. It doesn't report on both temperatures or RPM's yet in my code. They are largely the same in any case. You can adjust the strings.

@junocomp
Copy link

junocomp commented Jun 10, 2020

You are right, I got it to work. Now both fans are detected when running from terminal.

Simple fan control utility for Clevo laptops
Change fan duty to 40%

Dump fan information
FAN Duty: 60%
FA2 Duty: 60%
FAN RPMs: 3593 RPM
FA2 RPMs: 3763 RPM
CPU Temp: 33°C
GPU Temp: 0°C

Do you have an idea how to make it work with the indicator?

Also, thank a million for all of your help

@deebfeast
Copy link

Yes, I've not finished that part, although it does work -- just not under all conditions. It's that bit of code in function ec_auto_duty_adjust. There the switching points are defined and I'm sure it could be improved. When I start with setting duty on 20 in the widget and then on auto it seems okay though. But I think it still needs improving a bit with all the thresholds or perhaps initial value somewhere.

@junocomp
Copy link

@deebfeast If you figure out how to do it, please let me know and I will buy you a beer/coffee/lunch.

@deebfeast
Copy link

deebfeast commented Jun 10, 2020

Seems okay for me if I start the indicator for the task bar. Note I changed the string to only show one temperature indicator in my source. Also check out that line "if (val < 40 || val > 100)" and change it to allow lower values, like 10 or 20 as well.

clevo-indicator.c.txt

You might still want to fine tune the levels in the following block. First when to go level up, second part is when to level down. This way you can find a reasonable setting for your usage pattern. I'd advice to have the fans really bring it down to under 60 or even 55 during use.


static int ec_auto_duty_adjust(void) {
    int temp = MAX(share_info->cpu_temp, share_info->gpu_temp);
    int duty = share_info->fan_duty;
    //
    if (temp >= 80 && duty < 50)
        return 75;
    if (temp >= 70 && duty < 50)
        return 50;
    if (temp >= 60 && duty < 30)
        return 30;
    if (temp >= 50 && duty < 25)
        return 25;
    if (temp >= 40 && duty < 20)
        return 20;
    if (temp >= 30 && duty < 10)
        return 10;
    //
    if (temp <= 15 && duty > 0)
        return 0;
    if (temp <= 25 && duty > 10)
        return 10;
    if (temp <= 35 && duty > 15)
        return 15;
    if (temp <= 45 && duty > 20)
        return 20;
    if (temp <= 55 && duty > 25)
        return 25;
    if (temp <= 65 && duty > 30)
        return 30;
    if (temp <= 75 && duty > 50)
        return 50;
    //
    return 0;
}

@junocomp
Copy link

@deebfeast I just tried your script and the indicator still only controls only one fan. Only when running from the terminal it (clevo-indicator 20) it picks up both fans.

Can you PM by any chance? My email is on my profile.

@werikscs
Copy link

werikscs commented Dec 4, 2021

Hey guys, I have a Clevo NB50TH and I have the same problems.
I tried both solutions but still only the left fan is running.
When I try the value 60, shows it:

Simple fan control utility for Clevo laptops
Change fan duty to 60%

Dump fan information
FAN Duty: 60%
FAN RPMs: 4227 RPM
CPU Temp: 47°C
GPU Temp: 0°C

Could you help me?
@giovannicaligaris
@deebfeast

@deebfeast
Copy link

This is the slightly improved code I'm running since last year without issues. I did hear from someone else a small issue with reacting too soon on brief temperature spikes on some models. So some delay would have to be added to prevent the whirring without need.

clevo-indicator.c.txt

However it's possible some models use different registers for the fans. In other words you need to find out those values from a source of from painstakingly monitoring using SMBIOS. These are the needed values

#define EC_REG_FA2_DUTY 0xCF
#define EC_REG_FA2_RPMS_HI 0xD2
#define EC_REG_FA2_RPMS_LO 0xD3

@werikscs
Copy link

werikscs commented Dec 4, 2021

Tried your code but nothing change.
Also, any value between 60 and 40 is shown as "Wrong fan duty to write". Any below is shown as "invalid fan duty!"

@deebfeast
Copy link

Looks some things have changed. The initial fan duty number comes from EC_REG_FAN_DUTY and EC_REG_FA2_DUTY (for second fan. So like I said your case sounds you need to find another number for 0xCF. In your case some strange number comes back and the program is not filtering that value right now but uses it as base.

Here's a comment from : https://www.techinferno.com/index.php?/topic/10746-software-mod-linux-fan-control-for-clevo-p775dm3/

"0xCF stores the GPU fan duty cycle, but only after starting the Hotkey utility under Windows, which seems to bring the EC in a different state. Booting Linux straight, 0xCF seems to store a constant random value. "

That's another possibility that it might only be filled with a proper value under certain circumstances. My Linux box runs in Intel mode with Nvidia-on-demand feature.

@werikscs
Copy link

werikscs commented Dec 4, 2021

Any tips on how to find this value? I've researched a lot but I still haven't found much information.

@deebfeast
Copy link

Sure, this is my road as I started with nfbc a tool used for my last laptop (but doesn't do Clevo)

  1. find your DSDT
    https://github.com/hirschmann/nbfc/wiki/Analyze-your-notebook%27s-DSDT
  2. find the fan that's already controllable(is it?): in my code it's 0xCE
  3. see if you can find the other address.
  4. or play with https://github.com/hirschmann/nbfc/wiki/Probe-the-EC%27s-registers

The reason I switched to clevo_indicator and not nbfc tool is that Clevo chip is using a common port EC_SC 0x66 (in my model) to which is sent the port and value in sequence to set.

Alternatively try to find in Google anything on 0x66, clevo, EC 8587 chip or anything in that direction.
However as you can see in my case it was easy, just counted upwards fro 0xCE to 0xCF

It's also possible the NVIDIA somehow controls this fan entirely in your setup somehow and the value is ignored.

@werikscs
Copy link

werikscs commented Dec 4, 2021

I found out if I click fn+1, my notebook turn both fans on at 100%. And with your script, I can slow down theirs speed. This is enough for me for awhile. Thanks for your help!

@deebfeast
Copy link

deebfeast commented Dec 5, 2021

Hey that fn+1 combination does same for me! Until my clevo-indicator on AUTO kicks in.

It's indeed in the manual, a toggle key for auto on/off. I suppose in default mode the bios overrides at least one of the fans. Might depend on all kinds of variables, BIOS setting or driver. For other seekers I'll put the key page below as PDF.

clevo-keys.pdf
.

@amorous-monk
Copy link

当然。见附件。

对我来说,例如clevo-indicator 20让笔记本电脑静音,但当然会坚持那个周期。 启动通常的 clevo-indicator -?用于转储值。 只需启动 GUI 就可以工作,但您可能需要进一步调整 AUTO 选项。 GPU 读数在这里不起作用,所以我暂时将其忽略。

clevo-indicator.c.txt 文件

It works good ~ Thank you very much!!!

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

No branches or pull requests

5 participants