SkyLandTW / clevo-indicator

Ubuntu fan control indicator for Clevo laptops
The Unlicense
136 stars 69 forks source link

Indicator only controls one fan #27

Open theangrydev opened 5 years ago

theangrydev commented 5 years ago

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 commented 5 years ago

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 commented 4 years ago

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 commented 4 years ago

@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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

@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 commented 4 years ago

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:

junocomp commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

deebfeast commented 4 years ago

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 commented 4 years ago

@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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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

deebfeast commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 1 year ago

当然。见附件。

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

clevo-indicator.c.txt 文件

It works good ~ Thank you very much!!!