Example: HP Pavilion 17 Notebook PC

Analyzing the DSDT DSL

By looking at the DSL file, we find the registers we are interested in:

        OperationRegion (ERAM, EmbeddedControl, Zero, 0xFF)
        Field (ERAM, ByteAcc, Lock, Preserve)
        {
            [...]
            Offset (0xB2), 
            RPM1,   8,
            RPM2,   8,
            [...]
            Offset (0xF4), 
            SFAN,   8,
            [...]
        }

Calculating Register Addresses

We calculate the register addresses as follows:

Finding the WriteRegister

We use the probing tool to find out which register controls the fan:

sudo ec_probe write 244 1
sudo ec_probe write 244 20
sudo ec_probe write 244 50
sudo ec_probe write 244 100
sudo ec_probe write 244 255
sudo ec_probe write 244 0

We see that:

Result:

Finding the ReadRegister

We found RPM1 and RPM2. One of them might hold the fan speed.

However, probing the registers with

sudo ec_probe read 178
sudo ec_probe read 179

while spinning the fan up and down does not yield values that are continuous or meaningful.

We search for RPM1 and RPM2 in the dsdt.dsl and find this:

        Method (FRSP, 0, NotSerialized)
        {
            Local2 = Zero
            If ((\_SB.PCI0.LPCB.EC0.ECOK == One))
            {
                Local0 = \_SB.PCI0.LPCB.EC0.RPM1
                Local1 = \_SB.PCI0.LPCB.EC0.RPM2
                Local1 <<= 0x08
                Local0 |= Local1
                If ((Local0 != Zero))
                {
                    Divide (0x00075300, Local0, Local0, Local2)
                }
            }

            Return (Local2)
        }

We see that FRSP is the method that combines the two registers into one, applies a division and returns the value.

Result: \_TZ.TZ01.FRSP is the ReadAcpiMethod.

Finding the Read values

We call the ReadAcpiMethod for each fan state (off, minimum speed, maximum speed):

sudo ec_probe write 244 1
sudo ec_probe acpi_call '\_TZ.TZ01.FRSP'
sudo ec_probe write 244 50
sudo ec_probe acpi_call '\_TZ.TZ01.FRSP'
sudo ec_probe write 244 100
sudo ec_probe acpi_call '\_TZ.TZ01.FRSP'

The output of the ReadAcpiMethod (in decimal) is: 0, ~300, ~1380.

Result:

Writing the Configuration File

For writing the fan speed we have:

For reading the fan speed we have:

Also:

See the configuration file on GitHub