YogaSMC icon indicating copy to clipboard operation
YogaSMC copied to clipboard

DYVPC: test ThermalQuery

Open zhen-zen opened this issue 3 years ago • 8 comments

ioio -s DYVPC ThermalQuery index

0x00 - CPUT 0x01 - GPTP 0x02 - PHTP 0x03 - FRPM (conversion involved) 0x04 - BTTP 0x06 - CPTR & 0x3F

0x10 - WTCP 0x11 - WTGP 0x12 - WTSP 0x13 - WTFP 0x14 - WTBP 0x15 - WTHP

0x20 - CPTV 0x21 - GPTV 0x22 - PHTV 0x23 - FNTV 0x24 - BTTV

0xAA - RSTV

zhen-zen avatar Jul 09 '21 07:07 zhen-zen

ThermalWrite arg (only try after ThermalQuery succeed):

                Local1 = Arg0
                SUBC = (Local1 & 0xFF)  // subcommand, correspond to index
                Local1 >>= 0x08
                SIZE = (Local1 & 0xFF)  // SIZE < 2, not used?
                Local1 >>= 0x08
                TDA0 = (Local1 & 0xFF)  // desired value

SUBC:

0x10 - WTCP 0x11 - WTGP 0x12 - WTSP 0x13 - WTFP 0x14 - WTBP 0x15 - WTHP

0x20 - CPTV 0x21 - GPTV 0x22 - PHTV 0x23 - FNTV 0x24 - BTTV

0xAA - RSTV (reset?)

zhen-zen avatar Jul 09 '21 07:07 zhen-zen

Hello! Just been poking around my own HP device. How do I get the same information you did about my own device? So far I know 3 important EC addresses

0x11 (Monitors fan speed when controlled by EC. When manual fan control is enabled, this register is not used.) 0x15 (Enable manual fan control. Accepts 0 as automatic (default) any other number denotes manual control. This is RESET after waking from sleep or rebooting the computer.) 0x17 (Manual Fan control WRITE and READ register. Accepts a value of 0 to 55. UNUSED if fan control is set to automatic) Some values between 0 and 55 are reserved for automatic control via the EC. Preferably we could skip these. The values are 26,31,38,43,47,53

The superIO chip is a ENE KB9022Q-D (Had to teardown the laptop to find that one...)

Overc1ocker avatar Aug 23 '21 00:08 Overc1ocker

Check your DSDT and those FieldUnits above should be at the same offset in EC.

zhen-zen avatar Aug 23 '21 00:08 zhen-zen

I have no idea how to read a DSDT but here's the section relating to fan control I think.

               Offset (0x08), 
                PSPD,   8, 
                BCPD,   8, 
                BSTH,   8, 
                PRDT,   8, 
                UCPT,   8, 
                HHKP,   8, 
                SADP,   8, 
                FANE,   1, 
                CPUO,   1, 
                M4GO,   1, 
                FNSW,   1, 
                SBTC,   1, 
                AMDK,   1, 
                    ,   1, 
                EHP1,   1, 
                SAD2,   8, 
                FRPM,   8, //Fan RPM? (0x11)
                FNMX,   8, 
                FNMN,   8, 
                FWPM,   8, //Fan Control on? (0x15)
                RSTV,   8, 
                CPTV,   8, 
                GPTV,   8, 
                PHTV,   8, 
                FNTV,   8, // Fan Control Variable? (0x19)
                BTTV,   8, 
                HDTV,   8, 
                    ,   1, 
                    ,   1, 
                W2BS,   1, 
                SK6U,   1, 
                BARD,   1, 
                    ,   1, 
                FNHK,   1, 

Overc1ocker avatar Aug 23 '21 17:08 Overc1ocker

FWPM doesn't appear in the sample I found. However, FRPM and FNTV do exist and are available in WMI functions. Related function is not hard to understand:

            Method (GTDC, 1, NotSerialized)
            {
                Local0 = Package (0x03)
                    {
                        Zero, 
                        0x80, 
                        Buffer (0x80){}
                    }
...
                If ((Arg0 == 0x03))
                {
                    Local1 = Zero
                    Local2 = Zero
                    DerefOf (Local0 [0x02]) [Zero] = One
                    Divide ((\_SB.PCI0.LPCB.EC0.FRPM * 0x64), 0x17D4, Local2, Local1)
                    Local2 = (Local1 * 0x64)
                    DerefOf (Local0 [0x02]) [One] = Local2
                }
...
                If ((Arg0 == 0x13))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = WTFP
                }
...
                If ((Arg0 == 0x23))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = \_SB.PCI0.LPCB.EC0.FNTV
                }
...
                If ((Arg0 == 0xAA))
                {
                    DerefOf (Local0 [0x02]) [Zero] = \_SB.PCI0.LPCB.EC0.RSTV
                }

                Return (Local0)
            }

            Method (STDC, 1, NotSerialized)
            {
                Local1 = Arg0
                SUBC = (Local1 & 0xFF)
                Local1 >>= 0x08
                SIZE = (Local1 & 0xFF)
                Local1 >>= 0x08
                TDA0 = (Local1 & 0xFF)
                If ((SIZE >= 0x02))
                {
                    Return (Package (0x02)
                    {
                        0x06, 
                        Zero
                    })
                }
...
                If ((SUBC == 0x13))
                {
                    WTFP = TDA0
                    Return (Package (0x02)
                    {
                        Zero, 
                        Zero
                    })
                }
...
                If ((SUBC == 0x23))
                {
                    \_SB.PCI0.LPCB.EC0.RSTV = One
                    \_SB.PCI0.LPCB.EC0.FNTV = TDA0
                    Return (Package (0x02)
                    {
                        Zero, 
                        Zero
                    })
                }
...
                If ((SUBC == 0xAA))
                {
                    \_SB.PCI0.LPCB.EC0.RSTV = TDA0
                    \_SB.PCI0.LPCB.EC0.CPTV = 0xFF
                    \_SB.PCI0.LPCB.EC0.GPTV = 0xFF
                    \_SB.PCI0.LPCB.EC0.PHTV = 0xFF
                    \_SB.PCI0.LPCB.EC0.FNTV = 0xFF
                    \_SB.PCI0.LPCB.EC0.BTTV = 0xFF
                    Return (Package (0x02)
                    {
                        Zero, 
                        Zero
                    })
                }

                Return (Package (0x02)
                {
                    0x06, 
                    Zero
                })
            }

zhen-zen avatar Aug 25 '21 06:08 zhen-zen

My Fan Control definitions are actually found in a SSDT which is fine because MACiasl can still read it. This seems to be close to what you found.

            Method (GTDC, 1, NotSerialized)
            {
                Local0 = Package (0x03)
                    {
                        Zero, 
                        0x80, 
                        Buffer (0x80){}
                    }
                If ((Arg0 == Zero))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = \_SB.PCI0.LPCB.EC0.CPUT /* External reference */
                }

                If ((Arg0 == One))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = \_SB.PCI0.LPCB.EC0.GPTP /* External reference */
                }

                If ((Arg0 == 0x02))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = \_SB.PCI0.LPCB.EC0.PHTP /* External reference */
                }

                If ((Arg0 == 0x03))
                {
                    Local1 = Zero
                    Local2 = Zero
                    DerefOf (Local0 [0x02]) [Zero] = One
                    Divide ((\_SB.PCI0.LPCB.EC0.FRPM * 0x64), 0x17D4, Local2, Local1)
                    Local2 = (Local1 * 0x64)
                    DerefOf (Local0 [0x02]) [One] = Local2
                }

                If ((Arg0 == 0x04))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = \_SB.PCI0.LPCB.EC0.BTTP /* External reference */
                }

                If ((Arg0 == 0x06))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    If (((\_SB.PCI0.LPCB.EC0.CPTR & 0x3F) == Zero))
                    {
                        DerefOf (Local0 [0x02]) [One] = Zero
                    }
                    Else
                    {
                        DerefOf (Local0 [0x02]) [One] = One
                    }
                }

                If ((Arg0 == 0x10))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = WTCP /* \_SB_.WMID.WTCP */
                }

                If ((Arg0 == 0x11))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = WTGP /* \_SB_.WMID.WTGP */
                }

                If ((Arg0 == 0x12))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = WTSP /* \_SB_.WMID.WTSP */
                }

                If ((Arg0 == 0x13))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = WTFP /* \_SB_.WMID.WTFP */
                }

                If ((Arg0 == 0x14))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = WTBP /* \_SB_.WMID.WTBP */
                }

                If ((Arg0 == 0x15))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = WTHP /* \_SB_.WMID.WTHP */
                }

                If ((Arg0 == 0x20))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = \_SB.PCI0.LPCB.EC0.CPTV /* External reference */
                }

                If ((Arg0 == 0x21))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = \_SB.PCI0.LPCB.EC0.GPTV /* External reference */
                }

                If ((Arg0 == 0x22))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = \_SB.PCI0.LPCB.EC0.PHTV /* External reference */
                }

                If ((Arg0 == 0x23))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = \_SB.PCI0.LPCB.EC0.FNTV /* External reference */
                }

                If ((Arg0 == 0x24))
                {
                    DerefOf (Local0 [0x02]) [Zero] = One
                    DerefOf (Local0 [0x02]) [One] = \_SB.PCI0.LPCB.EC0.BTTV /* External reference */
                }

                If ((Arg0 == 0xAA))
                {
                    DerefOf (Local0 [0x02]) [Zero] = \_SB.PCI0.LPCB.EC0.RSTV /* External reference */
                }

                Return (Local0)
            }

Note: No FWPM here... Or anywhere else except the DSDT... What is going on?

Overc1ocker avatar Aug 25 '21 06:08 Overc1ocker

Just check if somewhere else use FWPM. The driver should be able to read and write other ones through the WMI interface.

zhen-zen avatar Aug 25 '21 07:08 zhen-zen

Close #167

zhen-zen avatar Aug 12 '22 07:08 zhen-zen