aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2017-03-26 10:25:00 +0800
committerMartin Roth <martinroth@google.com>2017-08-11 16:10:52 +0000
commit44d399c394f0cd5d38dffe551742badc100573d3 (patch)
tree23084902b39de3b72963bfc8bf8d24ebce979951
parentae1548621acae99b7f7ac4a722607af0a4a0c825 (diff)
ec: add support for KBC1126 in HP laptops
- let the coreboot build system insert the two blobs to the coreboot image - EC and Super I/O initialization - ACPI support Tested on 2760p, 8460p, 2570p, 8470p. Issue: Kernel gives the following error: ACPI Error: No handler for Region [ECRM] (...) [EmbeddedControl] ACPI Error: Region EmbeddedControl (ID=3) has no handler TODO: - consider moving the Super I/O initialization code to ramstage, or reuse the existing sio/smsc/kbc1100 code (if so, how to add the additional kbc1126 specific functions to sio/kbc1100) - sort out the ACPI code which is mostly from the ACPI dump of vendor firmware - find out why the digitizer in hp/2760p doesn't work - GRUB payload freezing on all HP Elitebooks may be related to EC Change-Id: I6b16eb7e26303eda740f52d667dedb7cc04b4ef0 Signed-off-by: Iru Cai <mytbk920423@gmail.com> Reviewed-on: https://review.coreboot.org/19072 Reviewed-by: Arthur Heymans <arthur@aheymans.xyz> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/ec/hp/kbc1126/Kconfig61
-rw-r--r--src/ec/hp/kbc1126/Makefile.inc58
-rw-r--r--src/ec/hp/kbc1126/acpi/ac.asl89
-rw-r--r--src/ec/hp/kbc1126/acpi/battery.asl520
-rw-r--r--src/ec/hp/kbc1126/acpi/ec.asl241
-rw-r--r--src/ec/hp/kbc1126/acpi/lid.asl30
-rw-r--r--src/ec/hp/kbc1126/chip.h28
-rw-r--r--src/ec/hp/kbc1126/early_init.c108
-rw-r--r--src/ec/hp/kbc1126/ec.c140
-rw-r--r--src/ec/hp/kbc1126/ec.h42
10 files changed, 1317 insertions, 0 deletions
diff --git a/src/ec/hp/kbc1126/Kconfig b/src/ec/hp/kbc1126/Kconfig
new file mode 100644
index 0000000000..edd4202813
--- /dev/null
+++ b/src/ec/hp/kbc1126/Kconfig
@@ -0,0 +1,61 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2017 Iru Cai
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+
+config EC_HP_KBC1126
+ bool
+ help
+ Interface to SMSC KBC1126 embedded controller in HP laptops.
+
+if EC_HP_KBC1126
+
+comment "Please select the following otherwise your laptop cannot be powered on."
+
+config KBC1126_FIRMWARE
+ bool "Add firmware images for KBC1126 EC"
+ depends on EC_HP_KBC1126
+ default n
+ help
+ Select this option to add the two firmware blobs for KBC1126.
+ You need these two blobs to power on your machine.
+
+config KBC1126_FW1
+ string "KBC1126 firmware #1 path and filename"
+ depends on KBC1126_FIRMWARE
+ default "fw1.bin"
+ help
+ The path and filename of the file to use as KBC1126 firmware #1.
+ You can use util/kbc1126/kbc1126_ec_dump to dump it from the
+ vendor firmware.
+
+config KBC1126_FW1_OFFSET
+ string
+ depends on KBC1126_FIRMWARE
+ default "0xffffe800"
+
+config KBC1126_FW2
+ string "KBC1126 filename #2 path and filename"
+ depends on KBC1126_FIRMWARE
+ default "fw2.bin"
+ help
+ The path and filename of the file to use as KBC1126 firmware #2.
+ You can use util/kbc1126/kbc1126_ec_dump to dump it from the
+ vendor firmware.
+
+config KBC1126_FW2_OFFSET
+ string
+ depends on KBC1126_FIRMWARE
+ default "0xfffee000"
+
+endif
diff --git a/src/ec/hp/kbc1126/Makefile.inc b/src/ec/hp/kbc1126/Makefile.inc
new file mode 100644
index 0000000000..83b78f0112
--- /dev/null
+++ b/src/ec/hp/kbc1126/Makefile.inc
@@ -0,0 +1,58 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2017 Iru Cai
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+
+ifeq ($(CONFIG_EC_HP_KBC1126),y)
+KBC1126_EC_INSERT:=$(top)/util/kbc1126/kbc1126_ec_insert
+INTERMEDIATE+=kbc1126_ec_insert
+
+ifeq ($(CONFIG_KBC1126_FIRMWARE),y)
+cbfs-files-y += ecfw1.bin
+cbfs-files-y += ecfw2.bin
+
+ecfw1.bin-file := $(call strip_quotes,$(CONFIG_KBC1126_FW1))
+ecfw1.bin-position := $(CONFIG_KBC1126_FW1_OFFSET)
+ecfw1.bin-type := raw
+
+ecfw2.bin-file := $(call strip_quotes,$(CONFIG_KBC1126_FW2))
+ecfw2.bin-position := $(CONFIG_KBC1126_FW2_OFFSET)
+ecfw2.bin-type := raw
+endif
+
+kbc1126_ec_insert: $(obj)/coreboot.pre
+ifeq ($(CONFIG_KBC1126_FIRMWARE),y)
+ printf " Building kbc1126_ec_insert.\n"
+ $(MAKE) -C util/kbc1126
+ printf " KBC1126 Inserting KBC1126 firmware blobs.\n"
+ $(KBC1126_EC_INSERT) $(obj)/coreboot.pre \
+ $(CONFIG_KBC1126_FW1_OFFSET) $(CONFIG_KBC1126_FW2_OFFSET)
+endif
+
+PHONY+=kbc1126_ec_insert
+
+build_complete::
+ifeq ($(CONFIG_KBC1126_FIRMWARE),)
+ printf "\n** WARNING **\n"
+ printf "You haven't added the firmware blobs for KBC1126 EC.\n"
+ printf "You may be unable to power on your laptop without these blobs.\n"
+ printf "Please select the following option to add them:\n\n"
+ printf " Chipset --->\n"
+ printf " [*] Add firmware images for KBC1126 EC\n\n"
+ printf "You can read util/kbc1126/README.md for details.\n\n"
+endif
+
+ramstage-y += ec.c
+romstage-y += early_init.c
+
+endif
diff --git a/src/ec/hp/kbc1126/acpi/ac.asl b/src/ec/hp/kbc1126/acpi/ac.asl
new file mode 100644
index 0000000000..3a80f8dedb
--- /dev/null
+++ b/src/ec/hp/kbc1126/acpi/ac.asl
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Iru Cai <mytbk920423@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Name (ACST, 0x01)
+Name (SMAR, 0x00)
+
+Field (ECRM, ByteAcc, NoLock, Preserve)
+{
+ Offset (0x84),
+ ADP, 1,
+ ADID, 2
+}
+
+Method (UPAD, 0, Serialized)
+{
+ Acquire (BTMX, 0xFFFF)
+ If ((GACP & 0x01))
+ {
+ GACP &= 0x06
+ Release (BTMX)
+ Acquire (ECMX, 0xFFFF)
+ Local0 = ADP
+ Local1 = ADID
+ Release (ECMX)
+ ACST = Local0
+ SMAR = Local1
+ }
+ Else
+ {
+ Release (BTMX)
+ }
+}
+
+Method (GPID, 0, Serialized)
+{
+ UPAD ()
+ Return (SMAR)
+}
+
+Method (GACS, 0, Serialized) /* get AC status */
+{
+ UPAD ()
+ Return (ACST)
+}
+
+Device (AC)
+{
+ Name (_HID, "ACPI0003")
+ Name (_PCL, Package () { \_SB })
+
+ Method (_STA)
+ {
+ Return (0x0F)
+ }
+
+ Method (_PSR, 0, NotSerialized)
+ {
+ Local0 = GACS ()
+ PWRS = Local0 /* GNVS.PWRS */
+ Local1 = GPID ()
+ ACST = Local0
+ SMAR = Local1
+ Return (Local0)
+ }
+}
+
+Method (_Q06, 0, NotSerialized)
+{
+ Store ("EC: AC STATUS", Debug)
+ PWUP (0x05, (0x02 | 0x01))
+ If (BTDR (0x02))
+ {
+ Notify (AC, 0x80)
+ PNOT ()
+ }
+}
diff --git a/src/ec/hp/kbc1126/acpi/battery.asl b/src/ec/hp/kbc1126/acpi/battery.asl
new file mode 100644
index 0000000000..a659cfaa73
--- /dev/null
+++ b/src/ec/hp/kbc1126/acpi/battery.asl
@@ -0,0 +1,520 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Iru Cai <mytbk920423@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Field (ECRM, ByteAcc, NoLock, Preserve)
+{
+ Offset (0x84),
+ , 3,
+ LCTV, 1,
+ BATP, 4,
+ BPU, 1,
+ Offset (0x86),
+ BSEL, 4, /* battery select */
+ Offset (0x87),
+ LB1, 8,
+ LB2, 8,
+ BDC, 16,
+ Offset (0x8D),
+ BFC, 16, /* battery full capacity */
+ BRTE, 16,
+ BTC, 1,
+ Offset (0x92),
+ BME, 16,
+ BDN, 8,
+ BDV, 16, /* battery design voltage */
+ BCV1, 16,
+ BST, 4,
+ Offset (0xC9),
+ BSN, 16, /* battery serial number */
+ BDAT, 16, /* battery date */
+ BMF, 8,
+}
+
+Name (NGBF, 0xFF)
+Name (NGBT, 0xFF)
+Name (GACP, 0x07)
+Name (NBAP, 0x00)
+Name (NNBO, 0x01)
+Name (NDCB, 0x00)
+Mutex (BTMX, 0x00)
+
+#define NLB1 0xC8 /* design capacity of warning */
+#define NLB2 0x64 /* design capacity of low */
+
+Method (ITLB, 0, NotSerialized)
+{
+ Divide ((NLB1 + 0x09), 0x0A, Local0, Local1)
+ Divide ((0x96 + 0x09), 0x0A, Local0, Local2)
+ Local0 = Local0
+ LB1 = Local1
+ LB2 = Local2
+}
+
+Method (PWUP, 2, Serialized)
+{
+ Local0 = 0x00
+ Acquire (BTMX, 0xFFFF)
+ Local1 = (Arg0 | GACP)
+ GACP = (Local1 & 0x07)
+ If ((GACP & 0x02))
+ {
+ NGBF |= Arg1
+ }
+
+ If ((GACP & 0x04))
+ {
+ If ((NGBT != 0xFF))
+ {
+ Local0 = 0x01
+ }
+
+ NGBT |= Arg1
+ }
+
+ Release (BTMX)
+ Return (Local0)
+}
+
+Method (GBAP, 0, Serialized)
+{
+ Acquire (BTMX, 0xFFFF)
+ If ((GACP & 0x02))
+ {
+ GACP &= 0x05
+ Release (BTMX)
+ Acquire (ECMX, 0xFFFF)
+ NBAP = BATP
+ Release (ECMX)
+ }
+ Else
+ {
+ Release (BTMX)
+ }
+ Return (NBAP)
+}
+
+Method (BTDR, 1, Serialized)
+{
+ If ((Arg0 == 0x01))
+ {
+ NNBO = 0x01
+ }
+ ElseIf ((Arg0 == 0x00))
+ {
+ NNBO = 0x00
+ }
+
+ Return (NNBO)
+}
+
+Method (BSTA, 1, Serialized)
+{
+ BTDR (0x01)
+ Local0 = GBAP ()
+ Local1 = 0x0F
+ If ((Local0 & Arg0))
+ {
+ Local1 = 0x1F
+ }
+ Return (Local1)
+}
+
+Device (BAT0)
+{
+ Name (_HID, EisaId ("PNP0C0A"))
+ Name (_UID, 0x01)
+
+ Method (_STA, 0, NotSerialized)
+ {
+ Return (BSTA (0x01))
+ }
+
+ Method (_BIF, 0, NotSerialized)
+ {
+ Return (BTIF (0x00))
+ }
+
+ Method (_BST, 0, NotSerialized)
+ {
+ Return (BTSZ (0x00))
+ }
+
+ Name (_PCL, Package (0x01)
+ {
+ \_SB
+ })
+}
+
+Device (BAT1)
+{
+ Name (_HID, EisaId ("PNP0C0A"))
+ Name (_UID, 0x02)
+
+ Method (_STA, 0, NotSerialized)
+ {
+ Return (BSTA (0x02))
+ }
+
+ Method (_BIF, 0, NotSerialized)
+ {
+ Return (BTIF (0x01))
+ }
+
+ Method (_BST, 0, NotSerialized)
+ {
+ Return (BTSZ (0x01))
+ }
+
+ Name (_PCL, Package (0x01)
+ {
+ \_SB
+ })
+}
+
+Name (NBTI, Package (0x02)
+{
+ Package (0x0D)
+ {
+ 0x01, /* power unit: mA */
+ 0xFFFFFFFF, /* design capacity */
+ 0xFFFFFFFF, /* last full charge capacity */
+ 0x01, /* battery technology */
+ 0xFFFFFFFF, /* design voltage */
+ 0x00, /* design capacity of warning */
+ 0x00, /* design capacity of low */
+ 0x64, /* battery capacity granularity 1 */
+ 0x64, /* battery capacity granularity 2 */
+ "Primary", /* model number */
+ "100000", /* serial number */
+ "LIon", /* battery type */
+ "Hewlett-Packard" /* OEM information */
+ },
+
+ Package (0x0D)
+ {
+ 0x01,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0x01,
+ 0xFFFFFFFF,
+ 0x00,
+ 0x00,
+ 0x64,
+ 0x64,
+ "Travel",
+ "100000",
+ "LIon",
+ "Hewlett-Packard"
+ }
+})
+
+Name (NBST, Package (0x02)
+{
+ Package (0x04) {0x00, 0x00, 0x0FA0, 0x04B0},
+ Package (0x04) {0x00, 0x00, 0x0FA0, 0x04B0}
+})
+
+Name (NDBS, Package (0x04)
+{
+ 0x00,
+ 0x00,
+ 0x0FA0,
+ 0x04B0
+})
+
+Method (\ISTR, 2, NotSerialized)
+{
+ Name (NUMB, Buffer (6) { " " })
+ Local0 = Arg0
+ Local1 = Arg1
+ While (Local1)
+ {
+ Local1--
+ Divide (Local0, 10, Local2, Local0)
+ Add (Local2, 48, Index (NUMB, Local1))
+ }
+ ToString (NUMB, Arg1, Local3)
+ Return (Local3)
+}
+
+Method (GBSS, 2, Serialized)
+{
+ Local3 = \ISTR (Arg0, 0x05)
+ Concatenate (Local3, " ", Local4)
+ Local0 = (Arg1 >> 0x09)
+ Local1 = (Local0 + 1980)
+ Local2 = \ISTR (Local1, 0x04)
+ Concatenate (Local4, Local2, Local3)
+ Concatenate (Local3, "/", Local4)
+ Local0 = (Arg1 >> 0x05)
+ Local1 = (Local0 & 0x0F)
+ Local2 = \ISTR (Local1, 0x02)
+ Concatenate (Local4, Local2, Local3)
+ Concatenate (Local3, "/", Local4)
+ Local1 = (Arg1 & 0x1F)
+ Local2 = \ISTR (Local1, 0x02)
+ Concatenate (Local4, Local2, Local3)
+ Return (Local3)
+}
+
+Method (BTIG, 1, Serialized) /* in vendor DSDT is EC0.BTIF */
+{
+ Local7 = (0x01 << Arg0)
+ BTDR (0x01)
+ If ((BSTA (Local7) == 0x0F))
+ {
+ Return (0xFF)
+ }
+
+ Acquire (BTMX, 0xFFFF)
+ Local0 = NGBF
+ Release (BTMX)
+ If (((Local0 & Local7) == 0x00))
+ {
+ Return (0x00)
+ }
+
+ NBST [Arg0] = NDBS
+ Acquire (BTMX, 0xFFFF)
+ NGBT |= Local7
+ Release (BTMX)
+
+ /* fill battery information */
+ Acquire (ECMX, 0xFFFF)
+ BSEL = Arg0
+ Local0 = BFC
+ DerefOf (NBTI [Arg0]) [0x01] = Local0
+ DerefOf (NBTI [Arg0]) [0x02] = Local0
+ DerefOf (NBTI [Arg0]) [0x04] = BDV
+ DerefOf (NBTI [Arg0]) [0x05] = NLB1
+ DerefOf (NBTI [Arg0]) [0x06] = NLB2
+ Local0 = BSN
+ Local1 = BDAT
+ Release (ECMX)
+
+ /* serial number */
+ Local2 = GBSS (Local0, Local1)
+ DerefOf (NBTI [Arg0]) [0x0A] = Local2
+
+ Acquire (BTMX, 0xFFFF)
+ NGBF &= ~Local7
+ Release (BTMX)
+ Return (0x00)
+}
+
+Method (BTIF, 1, Serialized) /* in vendor DSDT is SB.BTIF */
+{
+ Local0 = BTIG (Arg0)
+ If ((Local0 == 0xFF))
+ {
+ Return (Package (0x0D)
+ {
+ 0x00,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0x01,
+ 0xFFFFFFFF,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ "",
+ "",
+ "",
+ 0x00
+ })
+ }
+ Else
+ {
+ Return (DerefOf (NBTI [Arg0]))
+ }
+}
+
+Name (NFBS, 0x01)
+Method (BTSZ, 1, Serialized) /* in vendor DSDT is EC.BTST */
+{
+ Local1 = NFBS
+ If (NFBS)
+ {
+ NFBS = 0x00
+ }
+ BTST (Arg0, Local1)
+ Return (DerefOf (NBST [Arg0]))
+}
+
+Method (BTST, 2, Serialized)
+{
+ Local7 = (0x01 << Arg0)
+ BTDR (0x01)
+ If ((BSTA (Local7) == 0x0F))
+ {
+ NBST [Arg0] = Package (0x04)
+ {
+ 0x00,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF
+ }
+ Return (0xFF)
+ }
+
+ Acquire (BTMX, 0xFFFF)
+ If (Arg1)
+ {
+ NGBT = 0xFF
+ }
+
+ Local0 = NGBT /* \_SB_.PCI0.LPCB.EC0_.NGBT */
+ Release (BTMX)
+ If (((Local0 & Local7) == 0x00))
+ {
+ Return (0x00)
+ }
+
+ Acquire (ECMX, 0xFFFF)
+ BSEL = Arg0
+ Local0 = BST
+ Local3 = BPR
+ DerefOf (NBST [Arg0]) [0x02] = BRC
+ DerefOf (NBST [Arg0]) [0x03] = BPV
+ Release (ECMX)
+
+ If ((GACS () == 0x01))
+ {
+ Local0 &= ~0x01
+ }
+ Else
+ {
+ Local0 &= ~0x02
+ }
+
+ If ((Local0 & 0x01))
+ {
+ Acquire (BTMX, 0xFFFF)
+ NDCB = Local7
+ Release (BTMX)
+ }
+
+ DerefOf (NBST [Arg0]) [0x00] = Local0
+ If ((Local0 & 0x01))
+ {
+ If (((Local3 < 0x0190) || (Local3 > 0x1964)))
+ {
+ Local5 = DerefOf (DerefOf (NBST [Arg0]) [0x01])
+ If (((Local5 < 0x0190) || (Local5 > 0x1964)))
+ {
+ Local3 = (0x1AF4 / 0x02)
+ }
+ Else
+ {
+ Local3 = Local5
+ }
+ }
+ }
+ ElseIf (((Local0 & 0x02) == 0x00))
+ {
+ Local3 = 0x00
+ }
+
+ DerefOf (NBST [Arg0]) [0x01] = Local3
+ Acquire (BTMX, 0xFFFF)
+ NGBT &= ~Local7
+ Release (BTMX)
+ Return (0x00)
+}
+
+Method (SBTN, 2, Serialized)
+{
+ If ((Arg0 & 0x01))
+ {
+ Notify (BAT0, Arg1)
+ }
+
+ If ((Arg0 & 0x02))
+ {
+ Notify (BAT1, Arg1)
+ }
+}
+
+Method (_Q03, 0, NotSerialized)
+{
+ Store ("EC: _Q03", Debug)
+ Acquire (BTMX, 0xFFFF)
+ Local0 = NDCB
+ Release (BTMX)
+ PWUP (0x04, Local0)
+ SBTN (Local0, 0x80)
+}
+
+Method (_Q08, 0, NotSerialized)
+{
+ Store ("EC: PRIMARY BATTERY ATTACHED/DETACHED", Debug)
+ PWUP (0x06, 0x01)
+ Local0 = GBAP ()
+ If ((Local0 != 0x02))
+ {
+ PWUP (0x04, 0x02)
+ If (BTDR (0x02))
+ {
+ Notify (BAT1, 0x80)
+ }
+ }
+
+ If (BTDR (0x02))
+ {
+ Notify (BAT0, 0x81)
+ }
+}
+
+Method (_Q09, 0, NotSerialized)
+{
+ Store ("EC: PRIMARY BATTERY STATUS", Debug)
+ PWUP (0x04, 0x01)
+ If (BTDR (0x02))
+ {
+ Notify (BAT0, 0x80)
+ }
+}
+
+Method (_Q18, 0, NotSerialized)
+{
+ Store("EC: SECONDARY BATTERY ATTACHED/DETACHED", Debug)
+ PWUP (0x06, 0x02)
+ Local0 = GBAP ()
+ If ((Local0 != 0x01))
+ {
+ PWUP (0x04, 0x01)
+ If (BTDR (0x02))
+ {
+ Notify (BAT0, 0x80)
+ }
+ }
+
+ If (BTDR (0x02))
+ {
+ Notify (BAT1, 0x81) // Information Change
+ }
+}
+
+Method (_Q19, 0, NotSerialized)
+{
+ Store ("EC: SECONDARY BATTERY STATUS", Debug)
+ PWUP (0x04, 0x02)
+ If (BTDR (0x02))
+ {
+ Notify (BAT1, 0x80)
+ }
+}
diff --git a/src/ec/hp/kbc1126/acpi/ec.asl b/src/ec/hp/kbc1126/acpi/ec.asl
new file mode 100644
index 0000000000..6e636ed3ff
--- /dev/null
+++ b/src/ec/hp/kbc1126/acpi/ec.asl
@@ -0,0 +1,241 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Iru Cai <mytbk920423@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Device (EC0)
+{
+ Name (_HID, EISAID("PNP0C09"))
+ Name (_UID, 0)
+ Name (_GPE, 0x16)
+
+ Name (_CRS, ResourceTemplate ()
+ {
+ IO (Decode16, 0x62, 0x62, 1, 1)
+ IO (Decode16, 0x66, 0x66, 1, 1)
+ })
+
+ Method (_STA, 0, NotSerialized)
+ {
+ Return (0x0F)
+ }
+
+ OperationRegion (ECRM, EmbeddedControl, 0x00, 0xFF)
+ Field (ECRM, ByteAcc, NoLock, Preserve)
+ {
+ PMCD, 32,
+ S0FL, 8,
+ SXF0, 8,
+ SXF1, 8,
+ CPWR, 16,
+ CVLT, 16,
+ CCUR, 16,
+ DIDX, 8,
+ CIDX, 8,
+ PMCC, 8,
+ PMEP, 8,
+ Offset (0x22),
+ CRZN, 8,
+ THTA, 8,
+ HYST, 8,
+ CRIT, 8,
+ TEMP, 8,
+ TENA, 8,
+ Offset (0x29),
+ TOAD, 8,
+ PHTP, 8,
+ THEM, 8,
+ TMPO, 8,
+ Offset (0x2E),
+ FRDC, 8,
+ FTGC, 8,
+ PLTP, 8,
+ Offset (0x32),
+ DTMP, 8,
+ Offset (0x35),
+ PL1, 8,
+ PL2, 8,
+ BCVD, 8,
+ Offset (0x40),
+ ABDI, 8,
+ ABAD, 8,
+ ABIX, 8,
+ ABDA, 8,
+ ABST, 8,
+ PORI, 8,
+ Offset (0x4C),
+ PSSB, 8,
+ Offset (0x80),
+ Offset (0x81),
+ , 4,
+ SLPT, 4,
+ FNSW, 1,
+ SFNC, 1,
+ ACPI, 1,
+ , 1,
+ , 1,
+ , 1,
+ , 1,
+ DETF, 1,
+ LIDS, 1,
+ TBLT, 1,
+ , 1,
+ , 1,
+ , 1,
+ COMM, 1,
+ PME, 1,
+ SBVD, 1,
+
+ /* 0x84 to 0x9A is in battery.asl */
+
+ Offset (0x9B),
+ BATE, 16,
+ BPR, 16,
+ BCR, 16,
+ BRC, 16,
+ BCC, 16,
+ BPV, 16,
+ BCV2, 16,
+ BCV3, 16,
+ BCV4, 16,
+ BCW, 16,
+ BATF, 16,
+ BCL, 16,
+ MAXC, 16,
+ BCG1, 8,
+ BT1I, 1,
+ BT2I, 1,
+ , 2,
+ BATN, 4,
+ BSTS, 16,
+ BCG2, 8,
+ Offset (0xBD),
+ BMO, 8,
+ Offset (0xBF),
+ BRCV, 8,
+ Offset (0xC1),
+ BIF, 8,
+ BRCC, 8,
+
+ /* 0xC9 to 0xCD in battery.asl */
+
+ Offset (0xCF),
+ CTLB, 8,
+ Offset (0xD1),
+ BTY, 8,
+ Offset (0xD5),
+ MFAC, 8,
+ CFAN, 8,
+ PFAN, 8,
+ OCPS, 8,
+ OCPR, 8,
+ OCPE, 8,
+ TMP1, 8,
+ TMP2, 8,
+ NABT, 4,
+ BCM, 4,
+ CCBQ, 16,
+ CBT, 16,
+ Offset (0xE3),
+ OST, 4,
+ Offset (0xE4),
+ Offset (0xE5),
+ TPTE, 1,
+ TBBN, 1,
+ , 3,
+ TP, 1,
+ Offset (0xE6),
+ SHK, 8,
+ AUDS, 1,
+ SPKR, 1,
+ Offset (0xE8),
+ HSEN, 4,
+ HSST, 4,
+ Offset (0xEA),
+ , 2,
+ WWP, 1,
+ WLP, 1,
+ Offset (0xEF),
+ INCH, 2,
+ IDIS, 2,
+ INAC, 1
+ }
+
+ Method (ECRI, 0, Serialized)
+ {
+ OST = 0x7 /* FIXME: OS specific, in Linux is 7 */
+ PWUP (0x07, 0xFF)
+ Local0 = GBAP ()
+ ITLB ()
+ SBTN (Local0, 0x81)
+ }
+
+ Method (_REG, 2, NotSerialized)
+ {
+ ACPI = 1
+ ECRI ()
+ }
+
+ /* mailbox: port 0x200 and 0x201 */
+ OperationRegion (MAIO, SystemIO, 0x0200, 0x02)
+ Field (MAIO, ByteAcc, NoLock, Preserve)
+ {
+ MAIN, 8,
+ MADT, 8
+ }
+ IndexField (MAIN, MADT, ByteAcc, NoLock, Preserve)
+ {
+ Offset (0x8C),
+ , 7,
+ CLID, 1,
+ Offset (0x95),
+ PWM0, 8,
+ Offset (0x9D),
+ PWMC, 8
+ }
+
+ Mutex (ECMX, 0x00)
+
+#include "ac.asl"
+#include "battery.asl"
+#include "lid.asl"
+
+ /* The following are _Qxx methods in vendor DSDT whose function
+ is unknown. Just leave a debug message here. */
+
+ Method (_Q04, 0, NotSerialized)
+ {
+ Store ("EC: _Q04", Debug)
+ PNOT()
+ }
+
+ Method (_Q05, 0, NotSerialized)
+ {
+ Store ("EC: _Q05", Debug)
+ }
+
+ Method (_Q0B, 0, NotSerialized)
+ {
+ Store ("EC: _Q0B", Debug)
+ }
+
+ Method (_Q0C, 0, NotSerialized)
+ {
+ Store ("EC: _Q0C", Debug)
+ }
+
+ Method (_Q0D, 0, NotSerialized)
+ {
+ Store ("EC: _Q0D", Debug)
+ }
+}
diff --git a/src/ec/hp/kbc1126/acpi/lid.asl b/src/ec/hp/kbc1126/acpi/lid.asl
new file mode 100644
index 0000000000..c123c4c1f1
--- /dev/null
+++ b/src/ec/hp/kbc1126/acpi/lid.asl
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Iru Cai <mytbk920423@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Device (LID)
+{
+ Name (_HID, EisaId ("PNP0C0D"))
+ Method (_LID, 0, NotSerialized)
+ {
+ Local0 = CLID
+ Return (Local0)
+ }
+}
+
+Method (_Q0A, 0, NotSerialized)
+{
+ Store ("EC: LID STATUS", Debug)
+ Notify (LID, 0x80)
+}
diff --git a/src/ec/hp/kbc1126/chip.h b/src/ec/hp/kbc1126/chip.h
new file mode 100644
index 0000000000..009aa6bd06
--- /dev/null
+++ b/src/ec/hp/kbc1126/chip.h
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Iru Cai <mytbk920423@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _EC_HP_KBC1126_CHIP_H
+#define _EC_HP_KBC1126_CHIP_H
+
+struct ec_hp_kbc1126_config
+{
+ u16 ec_data_port;
+ u16 ec_cmd_port;
+ u8 ec_ctrl_reg;
+ u8 ec_fan_ctrl_value;
+};
+
+#endif /* _EC_HP_KBC1126_CHIP_H */
diff --git a/src/ec/hp/kbc1126/early_init.c b/src/ec/hp/kbc1126/early_init.c
new file mode 100644
index 0000000000..2a74a93a1a
--- /dev/null
+++ b/src/ec/hp/kbc1126/early_init.c
@@ -0,0 +1,108 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Iru Cai <mytbk920423@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <device/pnp.h>
+#include "ec.h"
+
+void kbc1126_enter_conf(void)
+{
+ outb(0x55, 0x2e);
+ outb(0x22, 0x2e);
+ outb(0x00, 0x2f);
+ outb(0x23, 0x2e);
+ outb(0x00, 0x2f);
+ outb(0x24, 0x2e);
+ outb(0x84, 0x2f);
+}
+
+void kbc1126_exit_conf(void)
+{
+ outb(0xaa, 0x2e);
+ /* one more time in PlatformStage1 of vendor firmware */
+ outb(0xaa, 0x2e);
+
+ outb(0x83, 0x200);
+ outb(0x00, 0x201);
+ inb(0x201);
+}
+
+void kbc1126_mailbox_init(void)
+{
+ pnp_devfn_t dev = PNP_DEV(0x2e, KBC1100_MAILBOX);
+ pnp_set_logical_device(dev);
+ pnp_set_iobase(dev, PNP_IDX_IO0, 0x200);
+ pnp_set_enable(dev, 1);
+}
+
+void kbc1126_kbc_init(void)
+{
+ pnp_devfn_t dev = PNP_DEV(0x2e, KBC1100_KBC);
+ pnp_set_logical_device(dev);
+ pnp_set_irq(dev, PNP_IDX_IRQ0, 0x1);
+ pnp_set_irq(dev, PNP_IDX_IRQ1, 0xc);
+ pnp_set_enable(dev, 1);
+}
+
+void kbc1126_ec_init(void)
+{
+ pnp_devfn_t dev = PNP_DEV(0x2e, KBC1100_EC0);
+ pnp_set_logical_device(dev);
+ pnp_set_iobase(dev, PNP_IDX_IO0, 0x62);
+ pnp_set_enable(dev, 1);
+}
+
+void kbc1126_com1_init(void)
+{
+ pnp_devfn_t dev = PNP_DEV(0x2e, SMSCSUPERIO_SP1);
+ pnp_set_logical_device(dev);
+ pnp_set_iobase(dev, PNP_IDX_IO0, 0x280);
+ pnp_set_irq(dev, PNP_IDX_IRQ0, 0x6);
+ pnp_set_enable(dev, 1);
+}
+
+void kbc1126_pm1_init(void)
+{
+ pnp_devfn_t dev = PNP_DEV(0x2e, KBC1100_PM1);
+ pnp_set_logical_device(dev);
+ pnp_set_iobase(dev, PNP_IDX_IO0, 0x220);
+ pnp_set_enable(dev, 1);
+}
+
+/*
+ * This code is found in PEI module F65354B9-1FF0-46D7-A5F7-0926CB238048
+ * of the OEM firmware.
+ *
+ * For mainboards without a Super I/O at 0x4e, without this code, superiotool
+ * will detect an Infineon Super I/O at 0x4e.
+ */
+
+void kbc1126_disable4e(void)
+{
+ outb(0x55, 0x4e);
+
+ outb(0x26, 0x4e);
+ outb(0x00, 0x4f);
+ outb(0x27, 0x4e);
+ outb(0xfe, 0x4f);
+ outb(0x60, 0x4e);
+ outb(0xfe, 0x4f);
+ outb(0x61, 0x4e);
+ outb(0x80, 0x4f);
+ outb(0x30, 0x4e);
+ outb(0x01, 0x4f);
+
+ outb(0xaa, 0x4e);
+}
diff --git a/src/ec/hp/kbc1126/ec.c b/src/ec/hp/kbc1126/ec.c
new file mode 100644
index 0000000000..a3e6e9c69c
--- /dev/null
+++ b/src/ec/hp/kbc1126/ec.c
@@ -0,0 +1,140 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ * Copyright (C) 2017 Iru Cai
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <delay.h>
+
+#include "ec.h"
+#include "chip.h"
+
+static u16 ec_data_port;
+static u16 ec_cmd_port;
+
+#define KBD_IBF (1 << 1) /* 1: input buffer full (data ready for ec) */
+#define KBD_OBF (1 << 0) /* 1: output buffer full (data ready for host) */
+
+static void ec_setports(u16 data, u16 cmd)
+{
+ ec_data_port = data;
+ ec_cmd_port = cmd;
+}
+
+static int send_kbd_command(u8 command)
+{
+ int timeout;
+
+ timeout = 0x7ff;
+ while ((inb(ec_cmd_port) & KBD_IBF) && --timeout) {
+ udelay(10);
+ if ((timeout & 0xff) == 0)
+ printk(BIOS_SPEW, ".");
+ }
+ if (!timeout) {
+ printk(BIOS_DEBUG, "Timeout while sending command 0x%02x to EC!\n",
+ command);
+ return -1;
+ }
+
+ outb(command, ec_cmd_port);
+ return 0;
+}
+
+static int send_kbd_data(u8 data)
+{
+ int timeout;
+
+ timeout = 0x7ff;
+ while ((inb(ec_cmd_port) & KBD_IBF) && --timeout) { /* wait for IBF = 0 */
+ udelay(10);
+ if ((timeout & 0xff) == 0)
+ printk(BIOS_SPEW, ".");
+ }
+ if (!timeout) {
+ printk(BIOS_DEBUG, "Timeout while sending data 0x%02x to EC!\n",
+ data);
+ return -1;
+ }
+
+ outb(data, ec_data_port);
+ return 0;
+}
+
+/*
+ * kbc1126_thermalinit: initialize fan control
+ * The code is found in EcThermalInit of the vendor firmware.
+ */
+static int kbc1126_thermalinit(u8 cmd, u8 value)
+{
+ printk(BIOS_DEBUG, "KBC1126: initialize fan control.");
+
+ if (send_kbd_command(cmd) < 0)
+ return -1;
+
+ if (send_kbd_data(0x27) < 0)
+ return -1;
+
+ if (send_kbd_data(0x01) < 0)
+ return -1;
+
+ /*
+ * The following code is needed for fan control when AC is plugged in.
+ */
+
+ if (send_kbd_command(cmd) < 0)
+ return -1;
+
+ if (send_kbd_data(0xd5) < 0)
+ return -1;
+
+ if (send_kbd_data(value) < 0)
+ return -1;
+
+ printk(BIOS_DEBUG, "KBC1126: fan control initialized.\n");
+ return 0;
+}
+
+/*
+ * kbc1126_kbdled: set CapsLock and NumLock LEDs
+ * This is used in MemoryErrorReport of the vendor firmware.
+ */
+static void kbc1126_kbdled(u8 cmd, u8 val)
+{
+ if (send_kbd_command(cmd) < 0)
+ return;
+
+ if (send_kbd_data(0xf0) < 0)
+ return;
+
+ if (send_kbd_data(val) < 0)
+ return;
+}
+
+static void kbc1126_enable(struct device *dev)
+{
+ struct ec_hp_kbc1126_config *conf = dev->chip_info;
+ ec_setports(conf->ec_data_port, conf->ec_cmd_port);
+ kbc1126_kbdled(conf->ec_ctrl_reg, 0);
+ if (kbc1126_thermalinit(conf->ec_ctrl_reg, conf->ec_fan_ctrl_value) < 0)
+ printk(BIOS_DEBUG, "KBC1126: error when initializing fan control.\n");
+}
+
+struct chip_operations ec_hp_kbc1126_ops = {
+ CHIP_NAME("SMSC KBC1126 for HP laptops")
+ .enable_dev = kbc1126_enable
+};
diff --git a/src/ec/hp/kbc1126/ec.h b/src/ec/hp/kbc1126/ec.h
new file mode 100644
index 0000000000..372f2a13e9
--- /dev/null
+++ b/src/ec/hp/kbc1126/ec.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Iru Cai
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _EC_HP_KBC1126_EC_H
+#define _EC_HP_KBC1126_EC_H
+
+#define KBC1100_PM1 1 /* PM1 */
+#define SMSCSUPERIO_SP1 4 /* Com1 */
+#define SMSCSUPERIO_SP2 5 /* Com2 */
+#define KBC1100_KBC 7 /* Keyboard */
+#define KBC1100_EC0 8 /* EC Channel 0 */
+#define KBC1100_MAILBOX 9 /* Mail Box */
+#define KBC1100_GPIO 0x0A /* GPIO */
+#define KBC1100_SPI 0x0B /* Share flash interface */
+
+#define KBC1100_EC1 0x0D /* EC Channel 1 */
+#define KBC1100_EC2 0x0E /* EC Channel 2 */
+
+/* early init */
+void kbc1126_enter_conf(void);
+void kbc1126_exit_conf(void);
+void kbc1126_mailbox_init(void);
+void kbc1126_kbc_init(void);
+void kbc1126_ec_init(void);
+void kbc1126_com1_init(void);
+void kbc1126_pm1_init(void);
+void kbc1126_disable4e(void);
+
+#endif /* _EC_HP_KBC1126_EC_H */