Method (_GPE._L0C, 0, NotSerialized) // _Lxx: Level-Triggered GPE, xx=0x00-0xFF { Notify (\_TZ.THRM, 0x80) // Thermal Status Change } Scope (_TZ) { ThermalZone (THRM) { Method (_TMP, 0, NotSerialized) // _TMP: Temperature { Return (RTMP ()) } Method (_CRT, 0, NotSerialized) // _CRT: Critical Temperature { Return (CTMP ()) } } } Name (SSBS, 0x0A35) // isa ioport for the hardware monitor // "senp" = "sensor package"? OperationRegion (SENP, SystemIO, SSBS, 0x02) Field (SENP, ByteAcc, NoLock, Preserve) { INDX, 8, // register selector DAT0, 8 // data for that register } // write byte into hw monitor // params: register, value Method (SBYT, 2, NotSerialized) { INDX = Arg0 DAT0 = Arg1 } // read byte from hardware monitor. // params: register Method (GBYT, 1, NotSerialized) { INDX = Arg0 Local0 = DAT0 /* \DAT0 */ Return (Local0) } Name (RMTR, 0x29) // register for temperature sensor 0 Name (RTTR, 0x2B) // register for temperature sensor 2 (for this board this is cpu temp) Name (MHTL, 0x5A) // = 90 decimal Name (MLTL, 0x55) // = 85 decimal Name (EIMB, 0x03) Name (PPGS, 0xB1) Name (PPGB, 0x02) // called by thermal zone (see above) Method (RTMP, 0, NotSerialized) { Local0 = GBYT (0x03) // read from hw monitor register 3 (interrupt status?) Local0 = GBYT (RMTR) // read temp sensor 0 // if temp is higher than 90 deg? If ((Local0 >= MHTL)) { // select ldn 7 (gpio stuff?) ENFG (0x07) // set bit 2 in gpio unit's register 0xB1 of the super io chip. // 0xB1 could be "pin polarity" // no idea... depends on whats connected to that pin... RWIO (PPGS, ~(One << PPGB), (One << PPGB)) // 0x0C on the hw monitor is probably "fan tacho 16 counter enable" // EIMB = 3. bit 3 in that register is probably "generate interrupt when temp0 is higher then hi-limit or lower then low limit" // side note: CTMP below (critical temp) is for temp2 ie the cpu sensor! SBYT (0x0C, ((GBYT (0x0C) & ~(One << EIMB)) | (One << EIMB))) } // if temp is lower than 85 deg? If ((Local0 <= MLTL)) { // select ldn 7 (gpio stuff?) ENFG (0x07) // clear bit 2 in super io register 0xB1 RWIO (PPGS, ~(One << PPGB), Zero) // same as above: generate interrupt if temp0 < lowlimit or temp0 > hilimit SBYT (0x0C, ((GBYT (0x0C) & ~(One << EIMB)) | (One << EIMB))) } Local0 = GBYT (RTTR) // read cpu temp from hw monitor FindSetLeftBit (Local0, Local1) // is negative celsius? If ((Local1 == 0x08)) { // convert to deci-kelvin. Local0 &= 0x7F Local0 *= 0x0A Local0 = (0x0AAC - Local0) } Else { // conversion from celsius to deci-kelvin, ie units of 0.1 K Local0 *= 0x0A Local0 += 0x0AAC // 0x0AAC = 2732 = 10*273.2 } Return (Local0) } Name (CSTR, 0x44) // hw monitor register for temp2 high limit Method (CTMP, 0, NotSerialized) { Local0 = GBYT (CSTR) // read high limit register for cpu temp, likely 127 deg // celsius to deci-kelvin conversion. FindSetLeftBit (Local0, Local1) If ((Local1 == 0x08)) { Local0 &= 0x7F Local0 *= 0x0A Local0 = (0x0AAC - Local0) } Else { Local0 *= 0x0A Local0 += 0x0AAC } Return (Local0) } Name (SP1O, 0x2E) // super io address // super io activation sequence. // write these to 0x2E (SP1O above) to allow access to the chip. Name (IPSW, Package (0x02) { Package (0x04) { 0x87, One, 0x55, 0x55 }, Package (0x04) // not used in my case { 0x87, One, 0x55, 0xAA } }) OperationRegion (IOOR, SystemIO, SP1O, 0x02) Field (IOOR, ByteAcc, NoLock, Preserve) { IOID, 8, // super io register selector, "io index"? IODT, 8 // super io data register, "io data"? } Method (ENFG, 1, NotSerialized) { Local1 = Zero // which activation sequence to use, see IPSW above // which super io address? 0x2E for my board. If ((SP1O == 0x2E)) { Local1 = Zero } If ((SP1O == 0x4E)) { Local1 = One } // write activation sequence into super io chip. Local0 = Zero While ((Local0 != 0x04)) { IOID = DerefOf (DerefOf (IPSW [Local1]) [Local0]) Local0++ } // 0x07 is the register for ldn selection // select the ldn given in arg0 WSIO (0x07, Arg0) } // write to super io chip. // params: register, value. Method (WSIO, 2, NotSerialized) { IOID = Arg0 IODT = Arg1 } // read-modify-write super io register. // params: register, bits to clear, bits to set Method (RWIO, 3, NotSerialized) { WSIO (Arg0, ((RSIO (Arg0) & Arg1) | Arg2)) } // read super io register. // params: register Method (RSIO, 1, NotSerialized) { IOID = Arg0 Return (IODT) /* \IODT */ }