[GH-ISSUE #801] Clevo laptops based configuration. #700

Closed
opened 2026-02-26 00:33:21 +03:00 by kerem · 4 comments
Owner

Originally created by @ivan-habl on GitHub (Dec 9, 2019).
Original GitHub issue: https://github.com/hirschmann/nbfc/issues/801

Hi, dear hirschmann! Thanks for helpful program.
On Clevo based laptops can control CPU, GPU1 and GPU2 fan from EC. It confirms linux utilite https://github.com/tuxedocomputers/tuxedo-fan-control (I tested it on my Clevo P157SM - it fully works).

The EC code describes on https://github.com/tuxedocomputers/tuxedo-fan-control/blob/master/native/ec_access.cc

I found code for create nbfc config, but it not work ( It is EC code

#define EC_COMMAND_PORT         0x66
#define EC_DATA_PORT            0x62

static void SendCommand(int command)
{
   int tt = 0;
    while((inb(EC_COMMAND_PORT) & 2))
    {
        tt++;
        if(tt>30000)
        {
            break;
        }
    }

    outb(command, EC_COMMAND_PORT);
}

static void WriteData(int data)
{
    while((inb(EC_COMMAND_PORT) & 2));

    outb(data, EC_DATA_PORT);
}

Napi::Boolean SetFanDuty(const Napi::CallbackInfo& info)
{
    EcInit();
    SendCommand(0x99); //in 0x66=102 port command 0x99=153

    switch(index)
    {
        case 1:
            WriteData(0x01); //in 0x62=98 port command 0x1=1
            break;
        case 2:
            WriteData(0x02);
            break;
        case 3:
            WriteData(0x03);
            break;
        default:
            return Napi::Boolean::New(env, false);
    }

    WriteData(fanDuty); //in 0x62 port fan speed
    return Napi::Boolean::New(env, true);
}

And we can read CPU FAN data from 0xCE=206 registry.
There is my config, but it cannot work - only correct read, don't write (( Please, help me to write correct config for my Clevo and other Clevo based laptops.

<?xml version="1.0"?>
<FanControlConfigV2 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <NotebookModel>Clevo P15SM</NotebookModel>
  <Author>Habl</Author>
  <EcPollInterval>2000</EcPollInterval>
  <ReadWriteWords>false</ReadWriteWords>
  <CriticalTemperature>90</CriticalTemperature>
  <FanConfigurations>
    <FanConfiguration>
      <ReadRegister>206</ReadRegister>
      <WriteRegister>98</WriteRegister>
      <MinSpeedValue>0</MinSpeedValue>
      <MaxSpeedValue>255</MaxSpeedValue>
      <IndependentReadMinMaxValues>false</IndependentReadMinMaxValues>
      <MinSpeedValueRead>0</MinSpeedValueRead>
      <MaxSpeedValueRead>255</MaxSpeedValueRead>
      <ResetRequired>true</ResetRequired>
      <FanSpeedResetValue>0</FanSpeedResetValue>
      <FanDisplayName>CPU fan</FanDisplayName>
      <TemperatureThresholds>
        <TemperatureThreshold>
          <UpThreshold>0</UpThreshold>
          <DownThreshold>0</DownThreshold>
          <FanSpeed>0</FanSpeed>
        </TemperatureThreshold>
        <TemperatureThreshold>
          <UpThreshold>65</UpThreshold>
          <DownThreshold>55</DownThreshold>
          <FanSpeed>100</FanSpeed>
        </TemperatureThreshold>
        <TemperatureThreshold>
          <UpThreshold>75</UpThreshold>
          <DownThreshold>60</DownThreshold>
          <FanSpeed>100</FanSpeed>
        </TemperatureThreshold>
        <TemperatureThreshold>
          <UpThreshold>85</UpThreshold>
          <DownThreshold>70</DownThreshold>
          <FanSpeed>100</FanSpeed>
        </TemperatureThreshold>
        <TemperatureThreshold>
          <UpThreshold>95</UpThreshold>
          <DownThreshold>80</DownThreshold>
          <FanSpeed>100</FanSpeed>
        </TemperatureThreshold>
      </TemperatureThresholds>
      <FanSpeedPercentageOverrides />
    </FanConfiguration>
  </FanConfigurations>
  <RegisterWriteConfigurations>
    <RegisterWriteConfiguration>
      <WriteMode>Set</WriteMode>
      <WriteOccasion>OnInitialization</WriteOccasion>
      <Register>102</Register>
      <Value>153</Value>
      <ResetRequired>true</ResetRequired>
      <ResetValue>0</ResetValue>
      <ResetWriteMode>Set</ResetWriteMode>
      <Description>Set EC to manual control</Description>
    </RegisterWriteConfiguration>
    <RegisterWriteConfiguration>
      <WriteMode>Set</WriteMode>
      <WriteOccasion>OnWriteFanSpeed</WriteOccasion>
      <Register>98</Register>
      <Value>1</Value>
      <ResetRequired>true</ResetRequired>
      <ResetValue>0</ResetValue>
      <ResetWriteMode>Set</ResetWriteMode>
      <Description>Set fan duty</Description>
    </RegisterWriteConfiguration>
  </RegisterWriteConfigurations>
</FanControlConfigV2>
Originally created by @ivan-habl on GitHub (Dec 9, 2019). Original GitHub issue: https://github.com/hirschmann/nbfc/issues/801 Hi, dear hirschmann! Thanks for helpful program. On Clevo based laptops can control CPU, GPU1 and GPU2 fan from EC. It confirms linux utilite https://github.com/tuxedocomputers/tuxedo-fan-control (I tested it on my Clevo P157SM - it fully works). The EC code describes on https://github.com/tuxedocomputers/tuxedo-fan-control/blob/master/native/ec_access.cc I found code for create nbfc config, but it not work ( It is EC code ``` #define EC_COMMAND_PORT 0x66 #define EC_DATA_PORT 0x62 static void SendCommand(int command) { int tt = 0; while((inb(EC_COMMAND_PORT) & 2)) { tt++; if(tt>30000) { break; } } outb(command, EC_COMMAND_PORT); } static void WriteData(int data) { while((inb(EC_COMMAND_PORT) & 2)); outb(data, EC_DATA_PORT); } Napi::Boolean SetFanDuty(const Napi::CallbackInfo& info) { EcInit(); SendCommand(0x99); //in 0x66=102 port command 0x99=153 switch(index) { case 1: WriteData(0x01); //in 0x62=98 port command 0x1=1 break; case 2: WriteData(0x02); break; case 3: WriteData(0x03); break; default: return Napi::Boolean::New(env, false); } WriteData(fanDuty); //in 0x62 port fan speed return Napi::Boolean::New(env, true); } ``` And we can read CPU FAN data from 0xCE=206 registry. There is my config, but it cannot work - only correct read, don't write (( Please, help me to write correct config for my Clevo and other Clevo based laptops. ```` <?xml version="1.0"?> <FanControlConfigV2 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <NotebookModel>Clevo P15SM</NotebookModel> <Author>Habl</Author> <EcPollInterval>2000</EcPollInterval> <ReadWriteWords>false</ReadWriteWords> <CriticalTemperature>90</CriticalTemperature> <FanConfigurations> <FanConfiguration> <ReadRegister>206</ReadRegister> <WriteRegister>98</WriteRegister> <MinSpeedValue>0</MinSpeedValue> <MaxSpeedValue>255</MaxSpeedValue> <IndependentReadMinMaxValues>false</IndependentReadMinMaxValues> <MinSpeedValueRead>0</MinSpeedValueRead> <MaxSpeedValueRead>255</MaxSpeedValueRead> <ResetRequired>true</ResetRequired> <FanSpeedResetValue>0</FanSpeedResetValue> <FanDisplayName>CPU fan</FanDisplayName> <TemperatureThresholds> <TemperatureThreshold> <UpThreshold>0</UpThreshold> <DownThreshold>0</DownThreshold> <FanSpeed>0</FanSpeed> </TemperatureThreshold> <TemperatureThreshold> <UpThreshold>65</UpThreshold> <DownThreshold>55</DownThreshold> <FanSpeed>100</FanSpeed> </TemperatureThreshold> <TemperatureThreshold> <UpThreshold>75</UpThreshold> <DownThreshold>60</DownThreshold> <FanSpeed>100</FanSpeed> </TemperatureThreshold> <TemperatureThreshold> <UpThreshold>85</UpThreshold> <DownThreshold>70</DownThreshold> <FanSpeed>100</FanSpeed> </TemperatureThreshold> <TemperatureThreshold> <UpThreshold>95</UpThreshold> <DownThreshold>80</DownThreshold> <FanSpeed>100</FanSpeed> </TemperatureThreshold> </TemperatureThresholds> <FanSpeedPercentageOverrides /> </FanConfiguration> </FanConfigurations> <RegisterWriteConfigurations> <RegisterWriteConfiguration> <WriteMode>Set</WriteMode> <WriteOccasion>OnInitialization</WriteOccasion> <Register>102</Register> <Value>153</Value> <ResetRequired>true</ResetRequired> <ResetValue>0</ResetValue> <ResetWriteMode>Set</ResetWriteMode> <Description>Set EC to manual control</Description> </RegisterWriteConfiguration> <RegisterWriteConfiguration> <WriteMode>Set</WriteMode> <WriteOccasion>OnWriteFanSpeed</WriteOccasion> <Register>98</Register> <Value>1</Value> <ResetRequired>true</ResetRequired> <ResetValue>0</ResetValue> <ResetWriteMode>Set</ResetWriteMode> <Description>Set fan duty</Description> </RegisterWriteConfiguration> </RegisterWriteConfigurations> </FanControlConfigV2> ````
kerem 2026-02-26 00:33:21 +03:00
  • closed this issue
  • added the
    Stale
    label
Author
Owner

@junocomp commented on GitHub (Jan 17, 2020):

Hi, take a look at this.

https://github.com/SkyLandTW/clevo-indicator

You might be able to get more information here.

<!-- gh-comment-id:575551439 --> @junocomp commented on GitHub (Jan 17, 2020): Hi, take a look at this. https://github.com/SkyLandTW/clevo-indicator You might be able to get more information here.
Author
Owner

@ivan-habl commented on GitHub (Jan 17, 2020):

Hi, take a look at this.

https://github.com/SkyLandTW/clevo-indicator

You might be able to get more information here.

Thanks. I looked at the clevo-indicator code. There, the same algorithm controls the registers EC_DATA_PORT and EC_COMMAND_PORT.

<!-- gh-comment-id:575557290 --> @ivan-habl commented on GitHub (Jan 17, 2020): > Hi, take a look at this. > > https://github.com/SkyLandTW/clevo-indicator > > You might be able to get more information here. Thanks. I looked at the clevo-indicator code. There, the same algorithm controls the registers EC_DATA_PORT and EC_COMMAND_PORT.
Author
Owner

@deebfeast commented on GitHub (Feb 24, 2020):

Hi I'm starting to work on a config for my Clevo NH55RDQ. It has two fans although I'm not sure yet about Nvidia/GPU modes. It might be similar for the whole Clevo NH55xx range and others

As proof of concept I first changed clevo-indicator until it worked so I can now read and set speeds on both fans and this is the logic:

Reading registers (BTW you can also read these directly with EC dumps):
EC_REG_CPU_TEMP 0x07
EC_REG_FAN_DUTY 0xCE
EC_REG_FA2_DUTY 0xCF
EC_REG_FAN_RPMS_HI 0xD0
EC_REG_FAN_RPMS_LO 0xD1
EC_REG_FA2_RPMS_HI 0xD2
EC_REG_FA2_RPMS_LO 0xD3

EC_SC 0x66
EC_DATA 0x62
EC_SC_READ_CMD = 0x80

  • wait for byte to be read on EC_SC with bit 1 set (ec_io_wait)
  • write EC_SC_READ_CMD to EC_SC
  • wait for byte to be read on EC_SC with bit 1 set (ec_io_wait)
  • write EC_REG_xx to EC_DATA
  • wait for byte to be read on EC_SC with bit 0 unset (ec_io_wait)
  • read EC_DATA

For writing it goes like this:

DUTY = duty_percentage / 100.0 * 255.0
EC_SC 0x66
EC_DATA 0x62
EC_WRITE_CMD 0x99
EC_FAN 0x01 or 0x02 (so for two fans run it twice)

  • wait for byte to be read on EC_SC with bit 1 set (ec_io_wait)
  • write EC_WRITE_CMD to EC_SC
  • wait for byte to be read on EC_SC with bit 1 set (ec_io_wait)
  • write EC_FAN to EC_DATA
  • wait for byte to be read on EC_SC with bit 1 set (ec_io_wait)
  • write DUTY to EC_DATA
  • wait for byte to be read on EC_SC with bit 1 set (ec_io_wait)

Now this seems to work well enough but next step to see if nbfc can do the controlling. The clevo-indicator can do some auto-magic but it's setuid in the end which doesn't feel right. Well I'm putting it out here in case since I don't know when I can work on the next step. If anyone really wants clevo-indicator I can supply the modifications but perhaps let me test it another week :)

<!-- gh-comment-id:590557532 --> @deebfeast commented on GitHub (Feb 24, 2020): Hi I'm starting to work on a config for my Clevo NH55RDQ. It has two fans although I'm not sure yet about Nvidia/GPU modes. It might be similar for the whole Clevo NH55xx range and others As proof of concept I first changed clevo-indicator until it worked **so I can now read and set speeds on both fans** and this is the logic: _Reading registers_ _(BTW you can also read these directly with EC dumps):_ EC_REG_CPU_TEMP 0x07 EC_REG_FAN_DUTY 0xCE EC_REG_FA2_DUTY 0xCF EC_REG_FAN_RPMS_HI 0xD0 EC_REG_FAN_RPMS_LO 0xD1 EC_REG_FA2_RPMS_HI 0xD2 EC_REG_FA2_RPMS_LO 0xD3 EC_SC 0x66 EC_DATA 0x62 EC_SC_READ_CMD = 0x80 - wait for byte to be read on EC_SC with bit 1 set (ec_io_wait) - write EC_SC_READ_CMD to EC_SC - wait for byte to be read on EC_SC with bit 1 set (ec_io_wait) - write EC_REG_xx to EC_DATA - wait for byte to be read on EC_SC with bit 0 unset (ec_io_wait) - read EC_DATA _For writing it goes like this:_ DUTY = duty_percentage / 100.0 * 255.0 EC_SC 0x66 EC_DATA 0x62 EC_WRITE_CMD 0x99 EC_FAN 0x01 or 0x02 (so for two fans run it twice) - wait for byte to be read on EC_SC with bit 1 set (ec_io_wait) - write EC_WRITE_CMD to EC_SC - wait for byte to be read on EC_SC with bit 1 set (ec_io_wait) - write EC_FAN to EC_DATA - wait for byte to be read on EC_SC with bit 1 set (ec_io_wait) - write DUTY to EC_DATA - wait for byte to be read on EC_SC with bit 1 set (ec_io_wait) Now this seems to work well enough but next step to see if nbfc can do the controlling. The clevo-indicator can do some auto-magic but it's setuid in the end which doesn't feel right. Well I'm putting it out here in case since I don't know when I can work on the next step. If anyone really wants clevo-indicator I can supply the modifications but perhaps let me test it another week :)
Author
Owner

@github-actions[bot] commented on GitHub (Aug 26, 2020):

This issue is stale because it has been open more than 180 days with no activity. If nobody comments within 7 days, this issue will be closed

<!-- gh-comment-id:680327708 --> @github-actions[bot] commented on GitHub (Aug 26, 2020): This issue is stale because it has been open more than 180 days with no activity. If nobody comments within 7 days, this issue will be closed
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/nbfc-hirschmann#700
No description provided.