diff --git a/src/ec/starlabs/it8987/Kconfig b/src/ec/starlabs/it8987/Kconfig new file mode 100644 index 0000000000..ba9e908077 --- /dev/null +++ b/src/ec/starlabs/it8987/Kconfig @@ -0,0 +1,7 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config EC_STARLABS_IT8987 + bool + select EC_ACPI + help + Interface to IT8987 embedded controller principally in Star Labs notebooks. diff --git a/src/ec/starlabs/it8987/Makefile.inc b/src/ec/starlabs/it8987/Makefile.inc new file mode 100644 index 0000000000..b021d0ff38 --- /dev/null +++ b/src/ec/starlabs/it8987/Makefile.inc @@ -0,0 +1,26 @@ +## SPDX-License-Identifier: GPL-2.0-only + +PHONY+=add_ite_fw +INTERMEDIATE+=add_ite_fw + +ifeq ($(CONFIG_EC_STARLABS_IT8987),y) +all-y += ec.c +smm-$(CONFIG_DEBUG_SMI) += ec.c +endif + +ifeq ($(CONFIG_EC_STARLABS_IT8987_BIN),y) + +ifeq ($(CONFIG_EC_STARLABS_IT8987_BIN_PATH),) +files_added:: warn_no_ite_fw +endif + +add_ite_fw: $(obj)/coreboot.pre + $(CBFSTOOL) $(obj)/coreboot.pre write -r EC -f $(CONFIG_EC_STARLABS_IT8987_BIN_PATH) -u +endif + +PHONY+=warn_no_ite_fw +warn_no_ite_fw: + printf "\n\t** WARNING **\n" + printf "coreboot has been built without the IT8987 EC Firmware.\n" + printf "Do not flash this image. Your LabTop Mk IV's power button\n" + printf "may not respond when you press it.\n\n" diff --git a/src/ec/starlabs/it8987/acpi/ac.asl b/src/ec/starlabs/it8987/acpi/ac.asl new file mode 100644 index 0000000000..97ae1474a7 --- /dev/null +++ b/src/ec/starlabs/it8987/acpi/ac.asl @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (ADP1) +{ + Name (_HID, "ACPI0003") + Name (_PCL, Package () { \_SB }) + + Method (_STA, 0, NotSerialized) // _STA: Status + { + If (ECON == 1) + { + Local0 = 0x0F + } + Else + { + Local0 = 0 + } + Return (Local0) + } + + Method (_PSR, 0, NotSerialized) // _PSR: Power Source + { + If (ECWR & 0x01) + { + \PWRS = 1 + } + Else + { + \PWRS = 0 + } + Return (\PWRS) + } +} + +Method (_QA0, 0, NotSerialized) // AC Power Connected +{ + If (ECWR & 0x01) + { + \PWRS = 1 + } + Else + { + \PWRS = 0 + } + + // 500ms delay - Not used in coreboot + // Sleep (500) + Notify (BAT0, 0x81) + // Sleep (500) + Notify (ADP1, 0x80) +} + +Method(_Q0B, 0, NotSerialized) // Battery Connected +{ + // 500ms delay - Not used in coreboot + // Sleep (500) + Notify (BAT0, 0x81) + // Sleep (500) + Notify (BAT0, 0x80) +} diff --git a/src/ec/starlabs/it8987/acpi/battery.asl b/src/ec/starlabs/it8987/acpi/battery.asl new file mode 100644 index 0000000000..8936701d1d --- /dev/null +++ b/src/ec/starlabs/it8987/acpi/battery.asl @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (BAT0) +{ + Name (_HID, EISAID ("PNP0C0A")) + Name (_UID, 1) + Name (_PCL, Package () { \_SB }) + + // Battery Slot Status + Method (_STA, 0, Serialized) + { + If (ECWR & 0x02) + { + Return (0x1F) + } + Return (0x0F) + } + + // Default Static Battery Information + Name (BPKG, Package (13) + { + 1, // 0: Power Unit + 0xFFFFFFFF, // 1: Design Capacity + 0xFFFFFFFF, // 2: Last Full Charge Capacity + 1, // 3: Battery Technology(Rechargeable) + 0xFFFFFFFF, // 4: Design Voltage 10.8V + 0, // 5: Design capacity of warning + 0, // 6: Design capacity of low + 0x64, // 7: Battery capacity granularity 1 + 0, // 8: Battery capacity granularity 2 + "CN6613-2S3P", // 9: Model Number + "6UA3", // 10: Serial Number + "Real", // 11: Battery Type + "GDPT" // 12: OEM Information + }) + + Method (_BIF, 0, Serialized) + { + BPKG[1] = B1DC + BPKG[2] = B1FC + BPKG[4] = B1FV + If (B1FC) + { + BPKG[5] = B1FC / 10 + BPKG[6] = B1FC / 25 + BPKG[7] = B1DC / 100 + } + + Return (BPKG) + } + + Name (PKG1, Package (4) + { + 0xFFFFFFFF, // Battery State + 0xFFFFFFFF, // Battery Present Rate + 0xFFFFFFFF, // Battery Remaining Capacity + 0xFFFFFFFF, // Battery Present Voltage + }) + + Method (_BST, 0, Serialized) + { + + + PKG1[0] = B1ST & 0x07 + If (B1ST & 0x01) + { + PKG1[1] = B1CR + } + Else + { + PKG1[1] = B1CR + } + PKG1[2] = B1RC + PKG1[3] = B1VT + Return (PKG1) + } +} diff --git a/src/ec/starlabs/it8987/acpi/cmos.asl b/src/ec/starlabs/it8987/acpi/cmos.asl new file mode 100644 index 0000000000..052094c2ea --- /dev/null +++ b/src/ec/starlabs/it8987/acpi/cmos.asl @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +OperationRegion (CMOS, SystemIO, 0x70, 0x02) +Field (CMOS, ByteAcc, NoLock, Preserve) +{ + NVRI, 8, + NVRD, 8 +} + +IndexField (NVRI, NVRD, ByteAcc, NoLock, Preserve) +{ + Offset (0x40), + KBBL, 8, // Keyboard backlight timeout + FNSW, 8, // Ctrl Fn Reverse (make keyboard Apple-like) + + Offset (0x7D), + FNLC, 8 // Current state of Fn Lock key. +} diff --git a/src/ec/starlabs/it8987/acpi/ec.asl b/src/ec/starlabs/it8987/acpi/ec.asl new file mode 100644 index 0000000000..451cdf125a --- /dev/null +++ b/src/ec/starlabs/it8987/acpi/ec.asl @@ -0,0 +1,379 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define ASL_PVOL_DEFOF_NUM 0xe8 + +Scope(\) +{ + // These fields come from the Global NVS area + Field (GNVS,AnyAcc,Lock,Preserve) + { + Offset(33), + B2SC, 8, // (33) Battery 2 Stored Capacity + Offset(36), + B2SS, 8 // (36) Battery 2 Stored Status + } +} + +Scope (\_SB) +{ + #include "hid.asl" +} + +Scope (\_SB.PCI0) +{ + // Add the entries for the PS/2 keyboard and mouse. + #include +} + +Scope (\_SB.PCI0.LPCB) +{ + // Include the definitions for accessing CMOS. + #include "cmos.asl" + + // Our embedded controller device. + Device (H_EC) + { + Name (_HID, EISAID ("PNP0C09")) // ACPI Embedded Controller + Name (_UID, 1) + Name (_GPE, EC_GPE_SCI) + + // ECDT (Embedded Controller Boot Resources Table) Check to correct + // ECAV flag in the beginning + Name(ECTK, 1) + Name(ECFG, 0) + Name(WIBT, 0) + Name(APST, 0) + + Name(ECON, 1) // AC debug + Name(BNUM, 0) // Number Of Batteries Present + Name(PVOL, ASL_PVOL_DEFOF_NUM) + Name(B1CC, 0) + Name(B2CC, 0) + + Name(B2ST, 0) + Name(CFAN, 0) + Name(CMDR, 0) + Name(DOCK, 0) + Name(EJET, 0) + Name(MCAP, 0) + Name(PLMX, 0) + Name(PECH, 0) + Name(PECL, 0) + Name(PENV, 0) + Name(PINV, 0) + Name(PPSH, 0) + Name(PPSL, 0) + Name(PSTP, 0) + Name(RPWR, 0) + Name(LIDS, 0) + Name(SLPC, 0) + Name(VPWR, 0) + Name(WTMS, 0) + Name(AWT2, 0) + Name(AWT1, 0) + Name(AWT0, 0) + Name(DLED, 0) + Name(IBT1, 0) + Name(ECAV, 1) // Support DPTF feature + Name(SPT2, 0) + Name(PB10, 0) + Name(IWCW, 0) + Name(IWCR, 0) + Name(BTEN, 0) + Mutex(ECMT, 0) + + Method (_CRS, 0, Serialized) + { + Name (BFFR, ResourceTemplate() + { + IO (Decode16, 0x62, 0x62, 0x00, 0x01) + IO (Decode16, 0x66, 0x66, 0x00, 0x01) + }) + Return (BFFR) + } + + Method (_STA, 0, NotSerialized) + { + If ((ECON == 1)) + { + Return (0x0F) + } + + Return (0x00) + } + + Name (ECOK, Zero) + Method(_REG, 2, NotSerialized) + { + If ((Arg0 == 0x03) && (Arg1 == 0x01)) + { + ECOS = 1 + ECAV = 1 + + // Unconditionally fix up the Battery and Power State. + + // Initialize the Number of Present Batteries. + // 1 = Real Battery 1 is present + // 2 = Real Battery 2 is present + // 3 = Real Battery 1 and 2 are present + BNUM = 0 + BNUM |= ((ECRD (RefOf (ECWR)) & 0x02) >> 1) + + // Save the current Power State for later. + // Store (PWRS, Local0) + + // Initialize the Power State. + // BNUM = 0 = Virtual Power State + // BNUM > 0 = Real Power State + If (BNUM == 0x00) + { + \PWRS = ECRD (RefOf (VPWR)) + } + Else + { + \PWRS = (ECRD (RefOf (ECWR)) & 0x01) + } + PNOT() + + /* Initialize LID switch state */ + \LIDS = LIDS + } + + // Flag that the OS supports ACPI. + \_SB.PCI0.LPCB.H_EC.ECOS = 1 + } + + Name (S3OS, Zero) + Method (PTS, 1, Serialized) + { + Debug = Concatenate("EC: PTS: ", ToHexString(Arg0)) + If (ECOK) { + S3OS = ECOS + } + \_SB.PCI0.LPCB.H_EC.ECOS = 0 + } + + Method (WAK, 1, Serialized) + { + Debug = Concatenate("EC: WAK: ", ToHexString(Arg0)) + If (ECOK) { + ECOS = S3OS + } + \_SB.PCI0.LPCB.H_EC.ECOS = 1 + } + + OperationRegion (SIPR, SystemIO, 0xB2, 0x1) + Field (SIPR, ByteAcc, Lock, Preserve) + { + SMB2, 8 + } + + // EC RAM fields + OperationRegion(ECF2, EmbeddedControl, 0, 0xFF) + Field (ECF2, ByteAcc, Lock, Preserve) + { + XXX0, 8, // EC Firmware main- version number. + XXX1, 8, // EC Firmware sub- version number. + XXX2, 8, // EC Firmware test- version number. + + Offset(0x06), + SKID, 8, // SKU ID + + Offset(0x11), + KBCD, 8, // Key / Touch Pad disable/enable bit + ECOS, 8, // Enter OS flag + HDAO, 8, + ECHK, 8, // Hot keys flag + + Offset(0x18), + KLBS, 8, // Keyboard backlight begin. + KLBE, 8, // Keyboard backlight status. + + Offset(0x1A), + KBLT, 8, // Keyboard Backlight Timeout + PWPF, 8, // Power Profile + + Offset(0x1E), + BTHP,8, // Health Battery Percentage + + Offset(0x20), + RCMD, 8, // Same function as IO 66 port to send EC command + RCST, 8, // Report status for the result of command execution + + Offset(0x2C), + FNST, 8, // FN LOCK key status. + + Offset(0x3F), + SFAN, 8, // Set Fan Speed. + BTMP, 16, // Battery Temperature. + BCNT, 16, // Battery Cycle Count. + FRMP, 16, // Fan Current Speed. + + Offset(0x60), + TSR1, 8, // Thermal Sensor Register 1 [CPU VR (IMVP) Temp on RVP] + TSR2, 8, // Thermal Sensor Register 2 [Heat exchanger fan temp on RVP] + TER4, 8, // Thermal Sensor Register 3 (skin temperature) + + Offset(0x63), + TSI,4, // [0..3] 0 = SEN1 - CPU VR temperature sensor + // 1 = SEN2 - Heat Exchanger temperature sensor + // 2 = SEN3 - Skin temperature sensor + // 3 = SEN4 - Ambient temperature sensor + // 4 = SEN5 - DIMM temperature sensor [IR sensor 1 on WSB] + // 5 = SEN6 - not used on RVP + HYST, 4, // [4..7] - Hysteresis in degC. + TSHT, 8, // Thermal Sensor (N) high trip point(set default value =70) + TSLT, 8, // Thermal Sensor (N) low trip point (set default value =70) + TSSR, 8, // TSSR- thermal sensor status register (set bit2 =1) + // BIT0:SEN1 - CPU VR Temp Sensor Trip Flag + // BIT1:SEN2 - Fan Temp Sensor Trip Flag + // BIT2:SEN3 - Skin Temp Sensor Trip Flag + // BIT3:SEN4 - Ambient Temp Sensor Trip Flag + // BIT4:Reserved + // BIT5:Reserved + // BIT6:Reserved + // BIT7:Reserved + CHGR, 16, // Charge Rate + + Offset(0x70), + CPTM, 8, // CPU Temperature + + Offset(0x72), + TER2, 8, // Charger Temperature, Charger thermistor support + + Offset(0x7F), + LSTE, 1, // Lid feature + // BIT0LID GPI + , 7, // Reserved + + Offset(0x80), + ECWR, 8, // AC & Battery status + XX10, 8, // Battery#1 Model Number Code + XX11, 16, // Battery#1 Serial Number + B1DC, 16, // Battery#1 Design Capacity + B1FV, 16, // Battery#1 Design Voltage + B1FC, 16, // Battery#1 Last Full Charge Capacity + XX15, 16, // Battery#1 Trip Point + B1ST, 8, // Battery#1 State + B1CR, 16, // Battery#1 Present Rate + B1RC, 16, // Battery#1 Remaining Capacity + B1VT, 16, // Battery#1 Present Voltage + BPCN, 8, // Battery#1 Remaining percentage + + // USB Type C Mailbox Interface// PPM->OPM Message In + Offset(0xc0), + MGI0, 8, + MGI1, 8, + MGI2, 8, + MGI3, 8, + MGI4, 8, + MGI5, 8, + MGI6, 8, + MGI7, 8, + MGI8, 8, + MGI9, 8, + MGIA, 8, + MGIB, 8, + MGIC, 8, + MGID, 8, + MGIE, 8, + MGIF, 8, + + // USB Type C Mailbox Interface// OPM->PPM Message Out + MGO0, 8, + MGO1, 8, + MGO2, 8, + MGO3, 8, + MGO4, 8, + MGO5, 8, + MGO6, 8, + MGO7, 8, + MGO8, 8, + MGO9, 8, + MGOA, 8, + MGOB, 8, + MGOC, 8, + MGOD, 8, + MGOE, 8, + MGOF, 8, + + // USB Type C UCSI DATA Structure. + VER1, 8, + VER2, 8, + RSV1, 8, + RSV2, 8, + + // PPM->OPM CCI indicator + CCI0, 8, + CCI1, 8, + CCI2, 8, + CCI3, 8, + + // OPM->PPM Control message + CTL0, 8, + CTL1, 8, + CTL2, 8, + CTL3, 8, + CTL4, 8, + CTL5, 8, + CTL6, 8, + CTL7, 8, + + Offset(0xF0), + , 3,// BIT0 .. BIT2 Reserved + TPCC, 1,// BIT3 TypeC connection bit + , 2,// BIT4 .. BIT5 Reserved + DRMD, 1,// Bit6 Dual Role Mode. 0->DFP: Host mode; 1->UFP: Device Mode. + , 1,// BIT7 Reserved + } + + Method (ECMD, 0, Serialized) + { + } + + Method (ECWT, 2, Serialized,,, {IntObj, FieldUnitObj}) + { + Local0 = Acquire (ECMT, 1000) + If (Local0 == 0x00) + { + If (ECAV) + { + // Execute write to Embedded Controller + Arg1 = Arg0 + } + Release (ECMT) + } + } + + Method (ECRD, 1, Serialized, 0, IntObj, FieldUnitObj) + { + Local0 = Acquire (ECMT, 1000) + If (Local0 == 0) + { + If (ECAV) + { + // Execute read from Embedded Controller + Local1 = DerefOf (Arg0) + Release (ECMT) + Return (Local1) + } + Else + { + Release (ECMT) + } + } + Return (Local1) + } + + // Include the other parts of the Embedded Controller ASL. + #include "keyboard.asl" + #include "battery.asl" + #include "ac.asl" + #include "lid.asl" + + // Method(_Q45) // SMM Mode - Not used in coreboot + // { + // SMB2 = 0xC1 + // } + } +} diff --git a/src/ec/starlabs/it8987/acpi/hid.asl b/src/ec/starlabs/it8987/acpi/hid.asl new file mode 100644 index 0000000000..25e3cd2ec9 --- /dev/null +++ b/src/ec/starlabs/it8987/acpi/hid.asl @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (HIDD) +{ + Name (_HID, "INT33D5") + Name (HBSY, Zero) + Name (HIDX, Zero) + Name (HMDE, Zero) + Name (HRDY, Zero) + Name (BTLD, Zero) + Name (BTS1, Zero) + Name (HEB1, 0x3003) + + Method (_STA, 0, Serialized) // _STA: Status + { + If ((OSYS >= 0x07DD)) + { + Return (0x0F) + } + Else + { + Return (Zero) + } + } + + Method (HDDM, 0, Serialized) + { + Store ("-----> HDDM", Debug) + Name (DPKG, Package (0x04) + { + 0x11111111, + 0x22222222, + 0x33333333, + 0x44444444 + }) + Return (DPKG) + } + + Method (HDEM, 0, Serialized) + { + Store ("-----> HDEM", Debug) + HBSY = Zero + If ((HMDE == Zero)) + { + Return (HIDX) + } + Return (HMDE) + } + + Method (HDMM, 0, Serialized) + { + Store ("-----> HDMM", Debug) + Return (HMDE) + } + + Method (HDSM, 1, Serialized) + { + Store ("-----> HDSM", Debug) + HRDY = Arg0 + } + + Method (HPEM, 1, Serialized) + { + Store ("-----> HPEM", Debug) + HBSY = One + HIDX = Arg0 + + Notify (HIDD, 0xC0) + Local0 = Zero + While ((Local0 < 0xFA) && HBSY) + { + Sleep (0x04) + Local0++ + } + + If (HBSY == One) + { + HBSY = Zero + HIDX = Zero + Return (One) + } + Else + { + Return (Zero) + } + } + + Method (BTNL, 0, Serialized) + { + Store ("-----> BTNL", Debug) + If (CondRefOf (\_SB.PWRB.PBST)) + { + \_SB.PWRB.PBST = Zero + Notify (PWRB, One) // Device Check + } + + BTLD = One +// If ((AEAB == One)) +// { + BTS1 = 0x1F + \_SB.PCI0.LPCB.H_EC.ECWT (BTS1, RefOf (\_SB.PCI0.LPCB.H_EC.BTEN)) +// } +// Else +// { +// BTS1 = Zero +// } + } + + Method (BTNE, 1, Serialized) + { + Store ("-----> BTNE", Debug) +// If ((AEAB == One)) +// { + BTS1 = ((Arg0 & 0x1E) | One) + \_SB.PCI0.LPCB.H_EC.ECWT (BTS1, RefOf (\_SB.PCI0.LPCB.H_EC.BTEN)) +// } + } + + Method (BTNS, 0, Serialized) + { + Store ("-----> BTNS", Debug) +// If ((AEAB == One)) +// { + BTS1 = \_SB.PCI0.LPCB.H_EC.ECRD (RefOf (\_SB.PCI0.LPCB.H_EC.BTEN)) +// } + Return (BTS1) + } + + Method (BTNC, 0, Serialized) + { + Store ("-----> BTNC", Debug) +// If ((AEAB == One)) +// { + Return (0x1F) +// } +// Else +// { +// Return (Zero) +// } + } + + Name (HEB2, Zero) + Method (HEBC, 0, Serialized) + { + Store ("-----> HEBC", Debug) +// If ((AHDB == One)) +// { +// Return (\HEB1) +// } +// Else +// { + Return (Zero) +// } + } + + Method (H2BC, 0, Serialized) + { + Store ("-----> H2BC", Debug) +// If ((AHDB == One)) +// { +// Return (\HEB1) +// } +// Else +// { + Return (Zero) +// } + } + + Method (HEEC, 0, Serialized) + { + Store ("-----> HEEC", Debug) +// If ((AHDB == One)) +// { + Return (HEB2) /* \_SB_.HIDD.HEB2 */ +// } +// Else +// { +// Return (Zero) +// } + } + + Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method + { + If ((Arg0 == ToUUID ("eeec56b3-4442-408f-a792-4edd4d758054"))) + { + If ((One == ToInteger (Arg1))) + { + Switch (ToInteger (Arg2)) + { + Case (Zero) + { + Return (Buffer (0x02) + { + 0xFF, 0x03 + }) + } + Case (One) + { + BTNL () + } + Case (0x02) + { + Return (HDMM ()) + } + Case (0x03) + { + HDSM (DerefOf (Arg3 [Zero])) + } + Case (0x04) + { + Return (HDEM ()) + } + Case (0x05) + { + Return (BTNS ()) + } + Case (0x06) + { + BTNE (DerefOf (Arg3 [Zero])) + } + Case (0x07) + { + Return (HEBC ()) + } + Case (0x08) + { + } + Case (0x09) + { + Return (H2BC ()) + } + } + } + } + + Return (Buffer (One) + { + 0x00 + }) + } +} + +Method (PWPR, 0, Serialized) +{ + Notify (HIDD, 0xCE) +} + +Method (PWRR, 0, Serialized) +{ + Notify (HIDD, 0xCF) +} diff --git a/src/ec/starlabs/it8987/acpi/keyboard.asl b/src/ec/starlabs/it8987/acpi/keyboard.asl new file mode 100644 index 0000000000..f5b1d52631 --- /dev/null +++ b/src/ec/starlabs/it8987/acpi/keyboard.asl @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Method(_Q80) // Volume up +{ + Store ("-----> _Q80", Debug) + Notify (\_SB.HIDD, 0xC4) + Notify (\_SB.HIDD, 0xC5) + Store ("<----- _Q80", Debug) +} + +Method(_Q81) // Volume down +{ + Store ("-----> _Q81", Debug) + Notify (\_SB.HIDD, 0xC6) + Notify (\_SB.HIDD, 0xC7) + Store ("<----- _Q81", Debug) +} + +Method(_Q99) // Wireless mode +{ + Store ("-----> _Q99", Debug) + \_SB.HIDD.HPEM(8) + Store ("<----- _Q80", Debug) +} + +Method(_Q06) // Brightness decrease +{ + \_SB.PCI0.GFX0.DECB() +} + +Method(_Q07) // Brightness increase +{ + \_SB.PCI0.GFX0.INCB() +} + +Method(_Q08) // FN lock QEvent +{ + FNLC = FNST +} + +Method(_Q54) // Power Button Event +{ + Store ("-----> _Q54", Debug) + If (CondRefOf (\_SB.PWRB)) + { + Notify(\_SB.PWRB, 0x80) + } + Store ("<----- _Q54", Debug) +} + +Method(_QD5) // 10 second power button press +{ + Store ("-----> _QD5", Debug) + \_SB.PWPR() + Store ("<----- _QD5", Debug) +} + +Method(_QD6) // 10 second power button de-press +{ + Store ("-----> _QD6", Debug) + \_SB.PWRR() + Store ("<----- _QD6", Debug) +} diff --git a/src/ec/starlabs/it8987/acpi/lid.asl b/src/ec/starlabs/it8987/acpi/lid.asl new file mode 100644 index 0000000000..22e8eeb818 --- /dev/null +++ b/src/ec/starlabs/it8987/acpi/lid.asl @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (LID0) +{ + Name (_HID, EisaId ("PNP0C0D")) + + Method (_STA, 0, NotSerialized) + { + DEBUG = "---> IT8987 LID: _STA" + Return (0x0F) + } + + Method (_PSW, 1, NotSerialized) + { + DEBUG = Concatenate ("---> IT8987 LID: _PSW", ToHexString(Arg0)) + } + + Method (_LID, 0, NotSerialized) + { + DEBUG = "---> IT8987 LID: _LID" + If (\_SB.PCI0.LPCB.H_EC.ECRD (RefOf (\_SB.PCI0.LPCB.H_EC.LSTE)) == 0x01) + { + Local0 = 1 + } + else + { + Local0 = 0 + } + Return (Local0) + } +} + +Method (_Q0C, 0, NotSerialized) // Lid close event +{ + DEBUG = "---> IT8987 LID: Q0C (close event)" + LIDS = 0 + \LIDS = LIDS + Notify (LID0, 0x80) +} + +Method (_Q0D, 0, NotSerialized) // Lid open event +{ + DEBUG = "---> IT8987 LID: Q0D (open event)" + LIDS = 1 + \LIDS = LIDS + Notify (LID0, 0x80) +} diff --git a/src/ec/starlabs/it8987/acpi/thermal.asl b/src/ec/starlabs/it8987/acpi/thermal.asl new file mode 100644 index 0000000000..6bf25bf7b6 --- /dev/null +++ b/src/ec/starlabs/it8987/acpi/thermal.asl @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Method(_QF0) // Thermal event. +{ + If (LEqual (DBGS, 0x00)) + { + /* Only handle the numerous thermal events if we are */ + /* NOT doing ACPI Debugging. */ + If (CondRefOf (\_TZ.TZ01)) + { + Notify (\_TZ.TZ01, 0x80) + } + } +} diff --git a/src/ec/starlabs/it8987/chip.h b/src/ec/starlabs/it8987/chip.h new file mode 100644 index 0000000000..a940a46acb --- /dev/null +++ b/src/ec/starlabs/it8987/chip.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _EC_STARLABS_IT8987_CHIP_H +#define _EC_STARLABS_IT8987_CHIP_H + +struct ec_starlabs_it8987_config { + u8 cpuhot_limit; /* temperature in °C which asserts PROCHOT# */ +}; + +#endif /* _EC_STARLABS_IT8987_CHIP_H */ diff --git a/src/ec/starlabs/it8987/ec.c b/src/ec/starlabs/it8987/ec.c new file mode 100644 index 0000000000..b555d28b84 --- /dev/null +++ b/src/ec/starlabs/it8987/ec.c @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include + +#include "ec.h" +#include "chip.h" + +u16 it8987_get_version(void) +{ + return (ec_read(0x00) << 8) | ec_read(0x01); +} + +static void it8987_init(struct device *dev) +{ + if (!dev->enabled) + return; + + /* + * The address/data IO port pair for the IT8987 EC are configurable + * through the EC domain and are fixed by the EC's firmware blob. If + * the value(s) passed through the "dev" structure don't match the + * expected values then output severe warnings. + */ + if (dev->path.pnp.port != IT8987E_FIXED_ADDR) { + printk(BIOS_ERR, "IT8987: Incorrect ports defined in devicetree.cb.\n"); + printk(BIOS_ERR, "IT8987: Serious operational issues will arise.\n"); + return; + } + + u8 chipid1 = pnp_read_index(dev->path.pnp.port, IT8987_CHIPID1); + u8 chipid2 = pnp_read_index(dev->path.pnp.port, IT8987_CHIPID2); + if (chipid1 != IT8987_CHIPID1_VAL || chipid2 != IT8987_CHIPID2_VAL) { + printk(BIOS_DEBUG, "IT8987: Device not found.\n"); + return; + } + + printk(BIOS_DEBUG, "IT8987: Initializing keyboard.\n"); + pc_keyboard_init(NO_AUX_DEVICE); + + /* Enable the keyboard backlight support. */ + ec_write(0x18, 0xaa); + ec_write(0x19, 0xdd); + + /* Set the timeout for the keyboard backlight. */ + ec_write(ECRAM_KBL_TIMEOUT, get_uint_option("kbl_timeout", 0)); + + /* + * Set the correct state for the Ctrl Fn Reverse option. This + * swaps the Ctrl and Fn keys to make it like an Apple keyboard. + */ + ec_write(ECRAM_FN_CTRL_REVERSE, get_uint_option("fn_ctrl_swap", 0)); + /* + * Copy the stored state of the fn_lock_state CMOS variable to the + * corresponding location within the EC RAM. + */ + ec_write(ECRAM_FN_LOCK_STATE, get_uint_option("fn_lock_state", 0)); +} + +static struct device_operations ops = { + .init = it8987_init, + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, +}; + +static struct pnp_info pnp_dev_info[] = { + { NULL, 0, 0, 0, } +}; + +static void enable_dev(struct device *dev) +{ + pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); +} + +struct chip_operations ec_starlabs_it8987_ops = { + CHIP_NAME("ITE IT8987 EC") + .enable_dev = enable_dev +}; diff --git a/src/ec/starlabs/it8987/ec.h b/src/ec/starlabs/it8987/ec.h new file mode 100644 index 0000000000..c6d5a7a28e --- /dev/null +++ b/src/ec/starlabs/it8987/ec.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * EC communication interface for ITE IT8987 Embedded Controller. + */ + +#ifndef _EC_STARLABS_IT8987_H +#define _EC_STARLABS_IT8987_H + +/* + * Define the expected value of the PNP base address that is fixed through + * the BADRSEL register controlled within the EC domain by the binary blob. + */ +#define IT8987E_FIXED_ADDR 0x4e + +/* Logical device number (LDN) assignments. */ +#define IT8987E_SP1 0x01 /* Com1 */ +#define IT8987E_SP2 0x02 /* Com2 */ +#define IT8987E_SWUC 0x04 /* System Wake-Up */ +#define IT8987E_KBCM 0x05 /* PS/2 mouse */ +#define IT8987E_KBCK 0x06 /* PS/2 keyboard */ +#define IT8987E_IR 0x0a /* Consumer IR */ +#define IT8987E_SMFI 0x0f /* Shared Memory/Flash Interface */ +#define IT8987E_RTCT 0x10 /* RTC-like Timer */ +#define IT8987E_PMC1 0x11 /* Power Management Channel 1 */ +#define IT8987E_PMC2 0x12 /* Power Management Channel 2 */ +#define IT8987E_SSPI 0x13 /* Serial Peripheral Interface */ +#define IT8987E_PECI 0x14 /* Platform EC Interface */ +#define IT8987E_PMC3 0x17 /* Power Management Channel 3 */ +#define IT8987E_PMC4 0x18 /* Power Management Channel 4 */ +#define IT8987E_PMC5 0x19 /* Power Management Channel 5 */ + +/* Host domain registers. */ +#define IT8987_CHIPID1 0x20 /* Device ID register 1 */ +#define IT8987_CHIPID2 0x21 /* Device ID register 2 */ + +/* IT8987 chip ID byte values. */ +#define IT8987_CHIPID1_VAL 0x89 +#define IT8987_CHIPID2_VAL 0x87 + +/* EC RAM offsets. */ +#define ECRAM_KBL_TIMEOUT 0x07 +#define ECRAM_FN_CTRL_REVERSE 0x08 +#define ECRAM_FN_LOCK_STATE 0x2C + +u16 it8987_get_version(void); + +#endif