summaryrefslogtreecommitdiff
path: root/src/ec/system76
diff options
context:
space:
mode:
authorJeremy Soller <jeremy@system76.com>2020-07-20 12:31:07 -0600
committerPhilipp Deppenwiese <zaolin.daisuki@gmail.com>2020-07-23 09:30:22 +0000
commit0de0fe110468cfd609a0aaa42ea9a4c29740e507 (patch)
treed44cc7211e9e44a6fd2712cfaf25b0db761ed6a0 /src/ec/system76
parentb8d6af9569632745966199a21833f0ad426ca140 (diff)
ec/system76_ec: add support for System76 EC
This adds ACPI code for System76 EC and converts system76/lemp9 to use EC_SYSTEM76_EC. Tested on system76/lemp9. Signed-off-by: Jeremy Soller <jeremy@system76.com> Change-Id: I1f693268d94b693b6764e4a3baf4c3180689f3be Reviewed-on: https://review.coreboot.org/c/coreboot/+/43612 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com> Reviewed-by: Michael Niewöhner
Diffstat (limited to 'src/ec/system76')
-rw-r--r--src/ec/system76/ec/Kconfig9
-rw-r--r--src/ec/system76/ec/acpi/ac.asl22
-rw-r--r--src/ec/system76/ec/acpi/battery.asl170
-rw-r--r--src/ec/system76/ec/acpi/buttons.asl13
-rw-r--r--src/ec/system76/ec/acpi/ec.asl230
-rw-r--r--src/ec/system76/ec/acpi/ec_ram.asl175
-rw-r--r--src/ec/system76/ec/acpi/hid.asl50
-rw-r--r--src/ec/system76/ec/acpi/lid.asl23
-rw-r--r--src/ec/system76/ec/acpi/s76.asl114
9 files changed, 806 insertions, 0 deletions
diff --git a/src/ec/system76/ec/Kconfig b/src/ec/system76/ec/Kconfig
new file mode 100644
index 0000000000..fea4743593
--- /dev/null
+++ b/src/ec/system76/ec/Kconfig
@@ -0,0 +1,9 @@
+config EC_SYSTEM76_EC
+ bool
+ help
+ System76 EC
+
+config EC_SYSTEM76_EC_COLOR_KEYBOARD
+ depends on EC_SYSTEM76_EC
+ bool
+ default n
diff --git a/src/ec/system76/ec/acpi/ac.asl b/src/ec/system76/ec/acpi/ac.asl
new file mode 100644
index 0000000000..7326676198
--- /dev/null
+++ b/src/ec/system76/ec/acpi/ac.asl
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Device (AC)
+{
+ Name (_HID, "ACPI0003" /* Power Source Device */) // _HID: Hardware ID
+ Name (_PCL, Package (0x01) // _PCL: Power Consumer List
+ {
+ _SB
+ })
+
+ Name (ACFG, One)
+
+ Method (_PSR, 0, NotSerialized) // _PSR: Power Source
+ {
+ Return (ACFG)
+ }
+
+ Method (_STA, 0, NotSerialized) // _STA: Status
+ {
+ Return (0x0F)
+ }
+}
diff --git a/src/ec/system76/ec/acpi/battery.asl b/src/ec/system76/ec/acpi/battery.asl
new file mode 100644
index 0000000000..bc239dd9c0
--- /dev/null
+++ b/src/ec/system76/ec/acpi/battery.asl
@@ -0,0 +1,170 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Device (BAT0)
+{
+ Name (_HID, EisaId ("PNP0C0A") /* Control Method Battery */) // _HID: Hardware ID
+ Name (_UID, Zero) // _UID: Unique ID
+ Name (_PCL, Package (0x01) // _PCL: Power Consumer List
+ {
+ _SB
+ })
+ Name (BFCC, Zero)
+ Method (_STA, 0, NotSerialized) // _STA: Status
+ {
+ If (^^PCI0.LPCB.EC0.ECOK)
+ {
+ If (^^PCI0.LPCB.EC0.BAT0)
+ {
+ Return (0x1F)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+
+ Name (PBIF, Package (0x0D)
+ {
+ One,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ One,
+ 0x39D0,
+ Zero,
+ Zero,
+ 0x40,
+ 0x40,
+ "BAT",
+ "0001",
+ "LION",
+ "Notebook"
+ })
+ Method (IVBI, 0, NotSerialized)
+ {
+ PBIF [One] = 0xFFFFFFFF
+ PBIF [0x02] = 0xFFFFFFFF
+ PBIF [0x04] = 0xFFFFFFFF
+ PBIF [0x09] = " "
+ PBIF [0x0A] = " "
+ PBIF [0x0B] = " "
+ PBIF [0x0C] = " "
+ BFCC = Zero
+ }
+
+ Method (UPBI, 0, NotSerialized)
+ {
+ If (^^PCI0.LPCB.EC0.BAT0)
+ {
+ Local0 = (^^PCI0.LPCB.EC0.BDC0 & 0xFFFF)
+ PBIF [One] = Local0
+ Local0 = (^^PCI0.LPCB.EC0.BFC0 & 0xFFFF)
+ PBIF [0x02] = Local0
+ BFCC = Local0
+ Local0 = (^^PCI0.LPCB.EC0.BDV0 & 0xFFFF)
+ PBIF [0x04] = Local0
+ Local0 = (^^PCI0.LPCB.EC0.BCW0 & 0xFFFF)
+ PBIF [0x05] = Local0
+ Local0 = (^^PCI0.LPCB.EC0.BCL0 & 0xFFFF)
+ PBIF [0x06] = Local0
+ PBIF [0x09] = "BAT"
+ PBIF [0x0A] = "0001"
+ PBIF [0x0B] = "LION"
+ PBIF [0x0C] = "Notebook"
+ }
+ Else
+ {
+ IVBI ()
+ }
+ }
+
+ Method (_BIF, 0, NotSerialized) // _BIF: Battery Information
+ {
+ If (^^PCI0.LPCB.EC0.ECOK)
+ {
+ UPBI ()
+ }
+ Else
+ {
+ IVBI ()
+ }
+
+ Return (PBIF) /* \_SB_.BAT0.PBIF */
+ }
+
+ Name (PBST, Package (0x04)
+ {
+ Zero,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0x3D90
+ })
+ Method (IVBS, 0, NotSerialized)
+ {
+ PBST [Zero] = Zero
+ PBST [One] = 0xFFFFFFFF
+ PBST [0x02] = 0xFFFFFFFF
+ PBST [0x03] = 0x2710
+ }
+
+ Method (UPBS, 0, NotSerialized)
+ {
+ If (^^PCI0.LPCB.EC0.BAT0)
+ {
+ Local0 = Zero
+ Local1 = Zero
+ If (^^AC.ACFG)
+ {
+ If (((^^PCI0.LPCB.EC0.BST0 & 0x02) == 0x02))
+ {
+ Local0 |= 0x02
+ Local1 = (^^PCI0.LPCB.EC0.BPR0 & 0xFFFF)
+ }
+ }
+ Else
+ {
+ Local0 |= One
+ Local1 = (^^PCI0.LPCB.EC0.BPR0 & 0xFFFF)
+ }
+
+ Local7 = (Local1 & 0x8000)
+ If ((Local7 == 0x8000))
+ {
+ Local1 ^= 0xFFFF
+ }
+
+ Local2 = (^^PCI0.LPCB.EC0.BRC0 & 0xFFFF)
+ Local3 = (^^PCI0.LPCB.EC0.BPV0 & 0xFFFF)
+ PBST [Zero] = Local0
+ PBST [One] = Local1
+ PBST [0x02] = Local2
+ PBST [0x03] = Local3
+ If ((BFCC != ^^PCI0.LPCB.EC0.BFC0))
+ {
+ Notify (BAT0, 0x81) // Information Change
+ }
+ }
+ Else
+ {
+ IVBS ()
+ }
+ }
+
+ Method (_BST, 0, NotSerialized) // _BST: Battery Status
+ {
+ If (^^PCI0.LPCB.EC0.ECOK)
+ {
+ UPBS ()
+ }
+ Else
+ {
+ IVBS ()
+ }
+
+ Return (PBST) /* \_SB_.BAT0.PBST */
+ }
+}
diff --git a/src/ec/system76/ec/acpi/buttons.asl b/src/ec/system76/ec/acpi/buttons.asl
new file mode 100644
index 0000000000..ae85c67ccc
--- /dev/null
+++ b/src/ec/system76/ec/acpi/buttons.asl
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Device (PWRB)
+{
+ Name (_HID, EisaId ("PNP0C0C"))
+ Name (_PRW, Package () { EC_GPE_SWI, 3 })
+}
+
+Device (SLPB)
+{
+ Name (_HID, EisaId ("PNP0C0E"))
+ Name (_PRW, Package () { EC_GPE_SWI, 3 })
+}
diff --git a/src/ec/system76/ec/acpi/ec.asl b/src/ec/system76/ec/acpi/ec.asl
new file mode 100644
index 0000000000..5989f6d285
--- /dev/null
+++ b/src/ec/system76/ec/acpi/ec.asl
@@ -0,0 +1,230 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Scope (\_SB) {
+ #include "ac.asl"
+ #include "battery.asl"
+ #include "buttons.asl"
+ #include "hid.asl"
+ #include "lid.asl"
+ #include "s76.asl"
+}
+
+Device (\_SB.PCI0.LPCB.EC0)
+{
+ Name (_HID, EisaId ("PNP0C09") /* Embedded Controller Device */) // _HID: Hardware ID
+ Name (_GPE, EC_GPE_SCI) // _GPE: General Purpose Events
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
+ {
+ IO (Decode16,
+ 0x0062, // Range Minimum
+ 0x0062, // Range Maximum
+ 0x00, // Alignment
+ 0x01, // Length
+ )
+ IO (Decode16,
+ 0x0066, // Range Minimum
+ 0x0066, // Range Maximum
+ 0x00, // Alignment
+ 0x01, // Length
+ )
+ })
+
+ #include "ec_ram.asl"
+
+ Name (ECOK, Zero)
+ Method (_REG, 2, Serialized) // _REG: Region Availability
+ {
+ Debug = Concatenate("EC: _REG", Concatenate(ToHexString(Arg0), Concatenate(" ", ToHexString(Arg1))))
+ If (((Arg0 == 0x03) && (Arg1 == One))) {
+ // Enable hardware touchpad lock, airplane mode, and keyboard backlight keys
+ ECOS = 1
+
+ // Enable software display brightness keys
+ WINF = 1
+
+ // Set current AC state
+ ^^^^AC.ACFG = ADP
+ // Update battery information and status
+ ^^^^BAT0.UPBI()
+ ^^^^BAT0.UPBS()
+
+ // Notify of changes
+ Notify(^^^^AC, Zero)
+ Notify(^^^^BAT0, Zero)
+
+ PNOT ()
+
+ // EC is now available
+ ECOK = Arg1
+
+ // Reset System76 Device
+ ^^^^S76D.RSET()
+ }
+ }
+
+ Method (PTS, 1, Serialized) {
+ Debug = Concatenate("EC: PTS: ", ToHexString(Arg0))
+ If (ECOK) {
+ // Clear wake cause
+ WFNO = Zero
+ }
+ }
+
+ Method (WAK, 1, Serialized) {
+ Debug = Concatenate("EC: WAK: ", ToHexString(Arg0))
+ If (ECOK) {
+ // Set current AC state
+ ^^^^AC.ACFG = ADP
+
+ // Update battery information and status
+ ^^^^BAT0.UPBI()
+ ^^^^BAT0.UPBS()
+
+ // Notify of changes
+ Notify(^^^^AC, Zero)
+ Notify(^^^^BAT0, Zero)
+
+ // Reset System76 Device
+ ^^^^S76D.RSET()
+ }
+ }
+
+ Method (_Q0A, 0, NotSerialized) // Touchpad Toggle
+ {
+ Debug = "EC: Touchpad Toggle"
+ }
+
+ Method (_Q0B, 0, NotSerialized) // Screen Toggle
+ {
+ Debug = "EC: Screen Toggle"
+ }
+
+ Method (_Q0C, 0, NotSerialized) // Mute
+ {
+ Debug = "EC: Mute"
+ }
+
+ Method (_Q0D, 0, NotSerialized) // Keyboard Backlight
+ {
+ Debug = "EC: Keyboard Backlight"
+ }
+
+ Method (_Q0E, 0, NotSerialized) // Volume Down
+ {
+ Debug = "EC: Volume Down"
+ }
+
+ Method (_Q0F, 0, NotSerialized) // Volume Up
+ {
+ Debug = "EC: Volume Up"
+ }
+
+ Method (_Q10, 0, NotSerialized) // Switch Video Mode
+ {
+ Debug = "EC: Switch Video Mode"
+ }
+
+ Method (_Q11, 0, NotSerialized) // Brightness Down
+ {
+ Debug = "EC: Brightness Down"
+ if (^^^^HIDD.HRDY) {
+ ^^^^HIDD.HPEM (20)
+ }
+ }
+
+ Method (_Q12, 0, NotSerialized) // Brightness Up
+ {
+ Debug = "EC: Brightness Up"
+ if (^^^^HIDD.HRDY) {
+ ^^^^HIDD.HPEM (19)
+ }
+ }
+
+ Method (_Q13, 0, NotSerialized) // Camera Toggle
+ {
+ Debug = "EC: Camera Toggle"
+ }
+
+ Method (_Q14, 0, NotSerialized) // Airplane Mode
+ {
+ Debug = "EC: Airplane Mode"
+ if (^^^^HIDD.HRDY) {
+ ^^^^HIDD.HPEM (8)
+ }
+ // TODO: hardware airplane mode
+ }
+
+ Method (_Q15, 0, NotSerialized) // Suspend Button
+ {
+ Debug = "EC: Suspend Button"
+ Notify (SLPB, 0x80)
+ }
+
+ Method (_Q16, 0, NotSerialized) // AC Detect
+ {
+ Debug = "EC: AC Detect"
+ ^^^^AC.ACFG = ADP
+ Notify (AC, 0x80) // Status Change
+ If (BAT0)
+ {
+ Notify (^^^^BAT0, 0x81) // Information Change
+ Notify (^^^^BAT0, 0x80) // Status Change
+ }
+ }
+
+ Method (_Q17, 0, NotSerialized) // BAT0 Update
+ {
+ Debug = "EC: BAT0 Update (17)"
+ Notify (^^^^BAT0, 0x81) // Information Change
+ }
+
+ Method (_Q19, 0, NotSerialized) // BAT0 Update
+ {
+ Debug = "EC: BAT0 Update (19)"
+ Notify (^^^^BAT0, 0x81) // Information Change
+ }
+
+ Method (_Q1B, 0, NotSerialized) // Lid Close
+ {
+ Debug = "EC: Lid Close"
+ Notify (LID0, 0x80)
+ }
+
+ Method (_Q1C, 0, NotSerialized) // Thermal Trip
+ {
+ Debug = "EC: Thermal Trip"
+ /* TODO
+ Notify (\_TZ.TZ0, 0x81) // Thermal Trip Point Change
+ Notify (\_TZ.TZ0, 0x80) // Thermal Status Change
+ */
+ }
+
+ Method (_Q1D, 0, NotSerialized) // Power Button
+ {
+ Debug = "EC: Power Button"
+ Notify (PWRB, 0x80)
+ }
+
+ Method (_Q50, 0, NotSerialized) // Other Events
+ {
+ Local0 = OEM4
+ If (Local0 == 0x8A) {
+ Debug = "EC: White Keyboard Backlight"
+ Notify (^^^^S76D, 0x80)
+ } ElseIf (Local0 == 0x9F) {
+ Debug = "EC: Color Keyboard Toggle"
+ Notify (^^^^S76D, 0x81)
+ } ElseIf (Local0 == 0x81) {
+ Debug = "EC: Color Keyboard Down"
+ Notify (^^^^S76D, 0x82)
+ } ElseIf (Local0 == 0x82) {
+ Debug = "EC: Color Keyboard Up"
+ Notify (^^^^S76D, 0x83)
+ } ElseIf (Local0 == 0x80) {
+ Debug = "EC: Color Keyboard Color Change"
+ Notify (^^^^S76D, 0x84)
+ } Else {
+ Debug = Concatenate("EC: Other: ", ToHexString(Local0))
+ }
+ }
+}
diff --git a/src/ec/system76/ec/acpi/ec_ram.asl b/src/ec/system76/ec/acpi/ec_ram.asl
new file mode 100644
index 0000000000..d5f97edbd7
--- /dev/null
+++ b/src/ec/system76/ec/acpi/ec_ram.asl
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+OperationRegion (ERAM, EmbeddedControl, Zero, 0xFF)
+Field (ERAM, ByteAcc, Lock, Preserve)
+{
+ NMSG, 8,
+ SLED, 4,
+ Offset (0x02),
+ MODE, 1,
+ FAN0, 1,
+ TME0, 1,
+ TME1, 1,
+ FAN1, 1,
+ , 2,
+ Offset (0x03),
+ LSTE, 1,
+ LSW0, 1,
+ LWKE, 1,
+ WAKF, 1,
+ , 2,
+ PWKE, 1,
+ MWKE, 1,
+ AC0, 8,
+ PSV, 8,
+ CRT, 8,
+ TMP, 8,
+ AC1, 8,
+ BBST, 8,
+ Offset (0x0B),
+ Offset (0x0C),
+ Offset (0x0D),
+ Offset (0x0E),
+ SLPT, 8,
+ SWEJ, 1,
+ SWCH, 1,
+ Offset (0x10),
+ ADP, 1,
+ AFLT, 1,
+ BAT0, 1,
+ BAT1, 1,
+ , 3,
+ PWOF, 1,
+ WFNO, 8,
+ BPU0, 32,
+ BDC0, 32,
+ BFC0, 32,
+ BTC0, 32,
+ BDV0, 32,
+ BST0, 32,
+ BPR0, 32,
+ BRC0, 32,
+ BPV0, 32,
+ BTP0, 16,
+ BRS0, 16,
+ BCW0, 32,
+ BCL0, 32,
+ BCG0, 32,
+ BG20, 32,
+ BMO0, 64,
+ BIF0, 64,
+ BSN0, 32,
+ BTY0, 64,
+ Offset (0x67),
+ Offset (0x68),
+ ECOS, 8,
+ LNXD, 8,
+ ECPS, 8,
+ Offset (0x6C),
+ BTMP, 16,
+ EVTN, 8,
+ Offset (0x72),
+ PRCL, 8,
+ PRC0, 8,
+ PRC1, 8,
+ PRCM, 8,
+ PRIN, 8,
+ PSTE, 8,
+ PCAD, 8,
+ PEWL, 8,
+ PWRL, 8,
+ PECD, 8,
+ PEHI, 8,
+ PECI, 8,
+ PEPL, 8,
+ PEPM, 8,
+ PWFC, 8,
+ PECC, 8,
+ PDT0, 8,
+ PDT1, 8,
+ PDT2, 8,
+ PDT3, 8,
+ PRFC, 8,
+ PRS0, 8,
+ PRS1, 8,
+ PRS2, 8,
+ PRS3, 8,
+ PRS4, 8,
+ PRCS, 8,
+ PEC0, 8,
+ PEC1, 8,
+ PEC2, 8,
+ PEC3, 8,
+ CMDR, 8,
+ CVRT, 8,
+ GTVR, 8,
+ FANT, 8,
+ SKNT, 8,
+ AMBT, 8,
+ MCRT, 8,
+ DIM0, 8,
+ DIM1, 8,
+ PMAX, 8,
+ PPDT, 8,
+ PECH, 8,
+ PMDT, 8,
+ TSD0, 8,
+ TSD1, 8,
+ TSD2, 8,
+ TSD3, 8,
+ CPUP, 16,
+ MCHP, 16,
+ SYSP, 16,
+ CPAP, 16,
+ MCAP, 16,
+ SYAP, 16,
+ CFSP, 16,
+ CPUE, 16,
+ Offset (0xC6),
+ Offset (0xC7),
+ VGAT, 8,
+ OEM1, 8,
+ OEM2, 8,
+ OEM3, 16,
+ OEM4, 8,
+ Offset (0xCE),
+ DUT1, 8,
+ DUT2, 8,
+ RPM1, 16,
+ RPM2, 16,
+ RPM4, 16,
+ Offset (0xD7),
+ DTHL, 8,
+ DTBP, 8,
+ AIRP, 8,
+ WINF, 8,
+ RINF, 8,
+ Offset (0xDD),
+ INF2, 8,
+ MUTE, 1,
+ Offset (0xE0),
+ RPM3, 16,
+ ECKS, 8,
+ Offset (0xE4),
+ , 4,
+ XTUF, 1,
+ EP12, 1,
+ Offset (0xE5),
+ INF3, 8,
+ Offset (0xE7),
+ GFOF, 8,
+ Offset (0xE9),
+ KPCR, 1,
+ Offset (0xEA),
+ Offset (0xF0),
+ PL1T, 16,
+ PL2T, 16,
+ TAUT, 8,
+ Offset (0xF8),
+ FCMD, 8,
+ FDAT, 8,
+ FBUF, 8,
+ FBF1, 8,
+ FBF2, 8,
+ FBF3, 8
+}
diff --git a/src/ec/system76/ec/acpi/hid.asl b/src/ec/system76/ec/acpi/hid.asl
new file mode 100644
index 0000000000..ce8fd3f28b
--- /dev/null
+++ b/src/ec/system76/ec/acpi/hid.asl
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Device (HIDD)
+{
+ Name (_HID, "INT33D5")
+ Name (HBSY, Zero)
+ Name (HIDX, Zero)
+ Name (HRDY, Zero)
+
+ Method (HDEM, 0, Serialized)
+ {
+ HBSY = Zero
+ Return (HIDX)
+ }
+
+ Method (HDMM, 0, Serialized)
+ {
+ Return (Zero)
+ }
+
+ Method (HDSM, 1, Serialized)
+ {
+ HRDY = Arg0
+ }
+
+ Method (HPEM, 1, Serialized)
+ {
+ 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)
+ }
+ }
+}
diff --git a/src/ec/system76/ec/acpi/lid.asl b/src/ec/system76/ec/acpi/lid.asl
new file mode 100644
index 0000000000..45e646acbb
--- /dev/null
+++ b/src/ec/system76/ec/acpi/lid.asl
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+Device (LID0)
+{
+ Name (_HID, EisaId ("PNP0C0D"))
+ Name (_PRW, Package () { EC_GPE_SWI, 3 })
+
+ Method (_LID, 0, NotSerialized) {
+ DEBUG = "LID: _LID"
+ If (^^PCI0.LPCB.EC0.ECOK) {
+ Return (^^PCI0.LPCB.EC0.LSTE)
+ } Else {
+ Return (One)
+ }
+ }
+
+ Method (_PSW, 1, NotSerialized) {
+ DEBUG = Concatenate("LID: _PSW: ", ToHexString(Arg0))
+ If (^^PCI0.LPCB.EC0.ECOK) {
+ ^^PCI0.LPCB.EC0.LWKE = Arg0
+ }
+ }
+}
diff --git a/src/ec/system76/ec/acpi/s76.asl b/src/ec/system76/ec/acpi/s76.asl
new file mode 100644
index 0000000000..7beb50b813
--- /dev/null
+++ b/src/ec/system76/ec/acpi/s76.asl
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+// Notifications:
+// 0x80 - hardware backlight toggle
+// 0x81 - backlight toggle
+// 0x82 - backlight down
+// 0x83 - backlight up
+// 0x84 - backlight color change
+Device (S76D) {
+ Name (_HID, "17761776")
+ Name (_UID, 0)
+
+ Method (RSET, 0, Serialized) {
+ Debug = "S76D: RSET"
+ SAPL(0)
+ SKBL(0)
+#if CONFIG(EC_SYSTEM76_EC_COLOR_KEYBOARD)
+ SKBC(0xFFFFFF)
+#endif // CONFIG(EC_SYSTEM76_EC_COLOR_KEYBOARD)
+ }
+
+ Method (INIT, 0, Serialized) {
+ Debug = "S76D: INIT"
+ RSET()
+ If (^^PCI0.LPCB.EC0.ECOK) {
+ // Set flags to use software control
+ ^^PCI0.LPCB.EC0.ECOS = 2
+ Return (0)
+ } Else {
+ Return (1)
+ }
+ }
+
+ Method (FINI, 0, Serialized) {
+ Debug = "S76D: FINI"
+ RSET()
+ If (^^PCI0.LPCB.EC0.ECOK) {
+ // Set flags to use hardware control
+ ^^PCI0.LPCB.EC0.ECOS = 1
+ Return (0)
+ } Else {
+ Return (1)
+ }
+ }
+
+ // Get Airplane LED
+ Method (GAPL, 0, Serialized) {
+ If (^^PCI0.LPCB.EC0.ECOK) {
+ If (^^PCI0.LPCB.EC0.AIRP & 0x40) {
+ Return (1)
+ }
+ }
+ Return (0)
+ }
+
+ // Set Airplane LED
+ Method (SAPL, 1, Serialized) {
+ If (^^PCI0.LPCB.EC0.ECOK) {
+ If (Arg0) {
+ ^^PCI0.LPCB.EC0.AIRP |= 0x40
+ } Else {
+ ^^PCI0.LPCB.EC0.AIRP &= 0xBF
+ }
+ }
+ }
+
+#if CONFIG(EC_SYSTEM76_EC_COLOR_KEYBOARD)
+ // Set KB LED Brightness
+ Method (SKBL, 1, Serialized) {
+ If (^^PCI0.LPCB.EC0.ECOK) {
+ ^^PCI0.LPCB.EC0.FDAT = 6
+ ^^PCI0.LPCB.EC0.FBUF = Arg0
+ ^^PCI0.LPCB.EC0.FBF1 = 0
+ ^^PCI0.LPCB.EC0.FBF2 = Arg0
+ ^^PCI0.LPCB.EC0.FCMD = 0xCA
+ }
+ }
+
+ // Set Keyboard Color
+ Method (SKBC, 1, Serialized) {
+ If (^^PCI0.LPCB.EC0.ECOK) {
+ ^^PCI0.LPCB.EC0.FDAT = 0x3
+ ^^PCI0.LPCB.EC0.FBUF = (Arg0 & 0xFF)
+ ^^PCI0.LPCB.EC0.FBF1 = ((Arg0 >> 16) & 0xFF)
+ ^^PCI0.LPCB.EC0.FBF2 = ((Arg0 >> 8) & 0xFF)
+ ^^PCI0.LPCB.EC0.FCMD = 0xCA
+ Return (Arg0)
+ } Else {
+ Return (0)
+ }
+ }
+#else // CONFIG(EC_SYSTEM76_EC_COLOR_KEYBOARD)
+ // Get KB LED
+ Method (GKBL, 0, Serialized) {
+ Local0 = 0
+ If (^^PCI0.LPCB.EC0.ECOK) {
+ ^^PCI0.LPCB.EC0.FDAT = One
+ ^^PCI0.LPCB.EC0.FCMD = 0xCA
+ Local0 = ^^PCI0.LPCB.EC0.FBUF
+ ^^PCI0.LPCB.EC0.FCMD = Zero
+ }
+ Return (Local0)
+ }
+
+ // Set KB Led
+ Method (SKBL, 1, Serialized) {
+ If (^^PCI0.LPCB.EC0.ECOK) {
+ ^^PCI0.LPCB.EC0.FDAT = Zero
+ ^^PCI0.LPCB.EC0.FBUF = Arg0
+ ^^PCI0.LPCB.EC0.FCMD = 0xCA
+ }
+ }
+#endif // CONFIG(EC_SYSTEM76_EC_COLOR_KEYBOARD)
+}