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>
This commit is contained in:
Iru Cai 2017-03-26 10:25:00 +08:00 committed by Martin Roth
parent ae1548621a
commit 44d399c394
10 changed files with 1317 additions and 0 deletions

61
src/ec/hp/kbc1126/Kconfig Normal file
View File

@ -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

View File

@ -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

View File

@ -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 ()
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}

28
src/ec/hp/kbc1126/chip.h Normal file
View File

@ -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 */

View File

@ -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);
}

140
src/ec/hp/kbc1126/ec.c Normal file
View File

@ -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
};

42
src/ec/hp/kbc1126/ec.h Normal file
View File

@ -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 */