summaryrefslogtreecommitdiff
path: root/src/ec/google
diff options
context:
space:
mode:
Diffstat (limited to 'src/ec/google')
-rw-r--r--src/ec/google/Kconfig1
-rw-r--r--src/ec/google/Makefile.inc1
-rw-r--r--src/ec/google/chromeec/Kconfig11
-rw-r--r--src/ec/google/chromeec/Makefile.inc5
-rw-r--r--src/ec/google/chromeec/acpi/ac.asl36
-rw-r--r--src/ec/google/chromeec/acpi/battery.asl230
-rw-r--r--src/ec/google/chromeec/acpi/ec.asl230
-rw-r--r--src/ec/google/chromeec/acpi/superio.asl152
-rw-r--r--src/ec/google/chromeec/chip.h32
-rw-r--r--src/ec/google/chromeec/ec.c519
-rw-r--r--src/ec/google/chromeec/ec.h49
-rw-r--r--src/ec/google/chromeec/ec_commands.h1069
12 files changed, 2335 insertions, 0 deletions
diff --git a/src/ec/google/Kconfig b/src/ec/google/Kconfig
new file mode 100644
index 0000000000..f83741ecc1
--- /dev/null
+++ b/src/ec/google/Kconfig
@@ -0,0 +1 @@
+source src/ec/google/chromeec/Kconfig
diff --git a/src/ec/google/Makefile.inc b/src/ec/google/Makefile.inc
new file mode 100644
index 0000000000..9ca3f0f71a
--- /dev/null
+++ b/src/ec/google/Makefile.inc
@@ -0,0 +1 @@
+subdirs-$(CONFIG_EC_GOOGLE_CHROMEEC) += chromeec
diff --git a/src/ec/google/chromeec/Kconfig b/src/ec/google/chromeec/Kconfig
new file mode 100644
index 0000000000..b8d34443f4
--- /dev/null
+++ b/src/ec/google/chromeec/Kconfig
@@ -0,0 +1,11 @@
+config EC_GOOGLE_CHROMEEC
+ bool
+ help
+ Google's Chrome EC
+
+config EC_GOOGLE_API_ROOT
+ depends on EC_GOOGLE_CHROMEEC
+ string "Path to the EC API include file"
+ default "/usr/include"
+ help
+ Path to the ec API file (ec/ec_commands.h).
diff --git a/src/ec/google/chromeec/Makefile.inc b/src/ec/google/chromeec/Makefile.inc
new file mode 100644
index 0000000000..93ad333bb4
--- /dev/null
+++ b/src/ec/google/chromeec/Makefile.inc
@@ -0,0 +1,5 @@
+ramstage-y += ec.c
+smm-y += ec.c
+romstage-y += ec.c
+
+CFLAGS += -I $(call strip_quotes,$(CONFIG_EC_GOOGLE_API_ROOT))
diff --git a/src/ec/google/chromeec/acpi/ac.asl b/src/ec/google/chromeec/acpi/ac.asl
new file mode 100644
index 0000000000..34b9080fa4
--- /dev/null
+++ b/src/ec/google/chromeec/acpi/ac.asl
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The Chromium OS Authors. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+// Scope (EC0)
+
+Device (AC)
+{
+ Name (_HID, "ACPI0003")
+ Name (_PCL, Package () { \_SB })
+
+ Method (_PSR)
+ {
+ Return (ACEX)
+ }
+
+ Method (_STA)
+ {
+ Return (0x0F)
+ }
+}
diff --git a/src/ec/google/chromeec/acpi/battery.asl b/src/ec/google/chromeec/acpi/battery.asl
new file mode 100644
index 0000000000..341911c372
--- /dev/null
+++ b/src/ec/google/chromeec/acpi/battery.asl
@@ -0,0 +1,230 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+// Scope (EC0)
+
+Device (BAT0)
+{
+ Name (_HID, EISAID ("PNP0C0A"))
+ Name (_UID, 1)
+ Name (_PCL, Package () { \_SB })
+
+ Name (PBIF, Package () {
+ 0x00000001, // 0x00: Power Unit: mAh
+ 0xFFFFFFFF, // 0x01: Design Capacity
+ 0xFFFFFFFF, // 0x02: Last Full Charge Capacity
+ 0x00000001, // 0x03: Battery Technology: Rechargeable
+ 0xFFFFFFFF, // 0x04: Design Voltage
+ 0x00000003, // 0x05: Design Capacity of Warning
+ 0xFFFFFFFF, // 0x06: Design Capacity of Low
+ 0x00000001, // 0x07: Capacity Granularity 1
+ 0x00000001, // 0x08: Capacity Granularity 2
+ "", // 0x09: Model Number
+ "", // 0x0a: Serial Number
+ "LION", // 0x0b: Battery Type
+ "" // 0x0c: OEM Information
+ })
+
+ Name (PBIX, Package () {
+ 0x00000000, // 0x00: Revision
+ 0x00000001, // 0x01: Power Unit: mAh
+ 0xFFFFFFFF, // 0x02: Design Capacity
+ 0xFFFFFFFF, // 0x03: Last Full Charge Capacity
+ 0x00000001, // 0x04: Battery Technology: Rechargeable
+ 0xFFFFFFFF, // 0x05: Design Voltage
+ 0x00000003, // 0x06: Design Capacity of Warning
+ 0xFFFFFFFF, // 0x07: Design Capacity of Low
+ 0x00000000, // 0x08: Cycle Count
+ 0x00018000, // 0x09: Measurement Accuracy (98.3%?)
+ 0x000001F4, // 0x0a: Max Sampling Time (500ms)
+ 0x0000000a, // 0x0b: Min Sampling Time (10ms)
+ 0xFFFFFFFF, // 0x0c: Max Averaging Interval
+ 0xFFFFFFFF, // 0x0d: Min Averaging Interval
+ 0x00000001, // 0x0e: Capacity Granularity 1
+ 0x00000001, // 0x0f: Capacity Granularity 2
+ "", // 0x10 Model Number
+ "", // 0x11: Serial Number
+ "LION", // 0x12: Battery Type
+ "" // 0x13: OEM Information
+ })
+
+ Name (PBST, Package () {
+ 0x00000000, // 0x00: Battery State
+ 0xFFFFFFFF, // 0x01: Battery Present Rate
+ 0xFFFFFFFF, // 0x02: Battery Remaining Capacity
+ 0xFFFFFFFF, // 0x03: Battery Present Voltage
+ })
+ Name (BSTP, Zero)
+
+ // Workaround for full battery status, enabled by default
+ Name (BFWK, One)
+
+ // Method to enable full battery workaround
+ Method (BFWE)
+ {
+ Store (One, BFWK)
+ }
+
+ // Method to disable full battery workaround
+ Method (BFWD)
+ {
+ Store (Zero, BFWK)
+ }
+
+ Method (_STA, 0, Serialized)
+ {
+ If (BTEX) {
+ Return (0x1F)
+ } Else {
+ Return (0x0F)
+ }
+ }
+
+ Method (_BIF, 0, Serialized)
+ {
+ // Last Full Charge Capacity
+ Store (BTDF, Index (PBIF, 2))
+
+ // Design Voltage
+ Store (BTDV, Index (PBIF, 4))
+
+ // Design Capacity
+ Store (BTDA, Local0)
+ Store (Local0, Index (PBIF, 1))
+
+ // Design Capacity of Warning
+ Divide (Multiply (Local0, DWRN), 100, Local1, Local2)
+ Store (Local2, Index (PBIF, 5))
+
+ // Design Capacity of Low
+ Divide (Multiply (Local0, DLOW), 100, Local1, Local2)
+ Store (Local2, Index (PBIF, 6))
+
+ // Get battery info from mainboard
+ Store (ToString(BMOD), Index (PBIF, 9))
+ Store (ToString(BSER), Index (PBIF, 10))
+ Store (ToString(BMFG), Index (PBIF, 12))
+
+ Return (PBIF)
+ }
+
+ // Extended Battery info method is disabled for now due to
+ // a bug in the Linux kernel: http://crosbug.com/28747
+ Method (XBIX, 0, Serialized)
+ {
+ // Last Full Charge Capacity
+ Store (BTDF, Index (PBIX, 3))
+
+ // Design Voltage
+ Store (BTDV, Index (PBIX, 5))
+
+ // Design Capacity
+ Store (BTDA, Local0)
+ Store (Local0, Index (PBIX, 2))
+
+ // Design Capacity of Warning
+ Divide (Multiply (Local0, DWRN), 100, Local1, Local2)
+ Store (Local2, Index (PBIX, 6))
+
+ // Design Capacity of Low
+ Divide (Multiply (Local0, DLOW), 100, Local1, Local2)
+ Store (Local2, Index (PBIX, 7))
+
+ // Cycle Count
+ Store (BTCC, Index (PBIX, 8))
+
+ // Get battery info from mainboard
+ Store (ToString(BMOD), Index (PBIX, 16))
+ Store (ToString(BSER), Index (PBIX, 17))
+ Store (ToString(BMFG), Index (PBIX, 19))
+
+ Return (PBIX)
+ }
+
+ Method (_BST, 0, Serialized)
+ {
+ //
+ // 0: BATTERY STATE
+ //
+ // bit 0 = discharging
+ // bit 1 = charging
+ // bit 2 = critical level
+ //
+ Store (Zero, Local1)
+
+ // Check if AC is present
+ If (ACEX) {
+ If (BFCG) {
+ Store (0x02, Local1)
+ } ElseIf (BFDC) {
+ Store (0x01, Local1)
+ }
+ } Else {
+ // Always discharging when on battery power
+ Store (0x01, Local1)
+ }
+
+ // Check for critical battery level
+ If (BFCR) {
+ Or (Local1, 0x04, Local1)
+ }
+ Store (Local1, Index (PBST, 0))
+
+ // Notify if battery state has changed since last time
+ If (LNotEqual (Local1, BSTP)) {
+ Store (Local1, BSTP)
+ Notify (BAT0, 0x80)
+ }
+
+ //
+ // 1: BATTERY PRESENT RATE
+ //
+ Store (BTPR, Index (PBST, 1))
+
+ //
+ // 2: BATTERY REMAINING CAPACITY
+ //
+ Store (BTRA, Local1)
+ If (LAnd (BFWK, LAnd (ACEX, LNot (LAnd (BFDC, BFCG))))) {
+ // On AC power and battery is neither charging
+ // nor discharging. Linux expects a full battery
+ // to report same capacity as last full charge.
+ // https://bugzilla.kernel.org/show_bug.cgi?id=12632
+ Store (BTDF, Local2)
+
+ // See if within ~3% of full
+ ShiftRight (Local2, 5, Local3)
+ If (LAnd (LGreater (Local1, Subtract (Local2, Local3)),
+ LLess (Local1, Add (Local2, Local3))))
+ {
+ Store (Local2, Local1)
+ }
+ }
+ Store (Local1, Index (PBST, 2))
+
+ //
+ // 3: BATTERY PRESENT VOLTAGE
+ //
+ Store (BTVO, Index (PBST, 3))
+
+ Return (PBST)
+ }
+}
diff --git a/src/ec/google/chromeec/acpi/ec.asl b/src/ec/google/chromeec/acpi/ec.asl
new file mode 100644
index 0000000000..2fb8e7961c
--- /dev/null
+++ b/src/ec/google/chromeec/acpi/ec.asl
@@ -0,0 +1,230 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The Chromium OS Authors. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * The mainboard must define a PNOT method to handle power
+ * state notifications and Notify CPU device objects to
+ * re-evaluate their _PPC and _CST tables.
+ */
+
+Device (EC0)
+{
+ Name (_HID, EISAID ("PNP0C09"))
+ Name (_UID, 1)
+ Name (_GPE, Add(EC_SCI_GPI, 16))
+ Name (TOFS, EC_TEMP_SENSOR_OFFSET)
+ Name (TNOP, 0xFD) // Thermal sensor has no power
+ Name (TBAD, 0xFE) // Thermal sensor bad reading
+ Name (TNPR, 0xFF) // Thermal sensor not present
+ Name (DWRN, 15) // Battery capacity warning at 15%
+ Name (DLOW, 10) // Battery capacity low at 10%
+
+ OperationRegion (ERAM, EmbeddedControl, 0x00, 0xff)
+ Field (ERAM, ByteAcc, Lock, Preserve)
+ {
+ Offset (0x00),
+ RAMV, 8, // EC RAM Version
+ TSTB, 8, // Test Byte
+ TSTC, 8, // Complement of Test Byte
+ KBLV, 8, // Keyboard Backlight
+ }
+
+ OperationRegion (EMEM, SystemIO, EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE)
+ Field (EMEM, ByteAcc, NoLock, Preserve)
+ {
+ Offset (0x00),
+ TIN0, 8, // Temperature 0
+ TIN1, 8, // Temperature 1
+ TIN2, 8, // Temperature 2
+ TIN3, 8, // Temperature 3
+ TIN4, 8, // Temperature 4
+ TIN5, 8, // Temperature 5
+ TIN6, 8, // Temperature 6
+ TIN7, 8, // Temperature 7
+ TIN8, 8, // Temperature 8
+ TIN9, 8, // Temperature 9
+ Offset (0x10),
+ FAN0, 16, // Fan Speed 0
+ Offset (0x30),
+ LIDS, 1, // Lid Switch State
+ PBTN, 1, // Power Button Pressed
+ WPDI, 1, // Write Protect Disabled
+ RECK, 1, // Keyboard Initiated Recovery
+ RECD, 1, // Dedicated Recovery Mode
+ Offset (0x40),
+ BTVO, 32, // Battery Present Voltage
+ BTPR, 32, // Battery Present Rate
+ BTRA, 32, // Battery Remaining Capacity
+ ACEX, 1, // AC Present
+ BTEX, 1, // Battery Present
+ BFDC, 1, // Battery Discharging
+ BFCG, 1, // Battery Charging
+ BFCR, 1, // Battery Level Critical
+ Offset (0x50),
+ BTDA, 32, // Battery Design Capacity
+ BTDV, 32, // Battery Design Voltage
+ BTDF, 32, // Battery Last Full Charge Capacity
+ BTCC, 32, // Battery Cycle Count
+ BMFG, 64, // Battery Manufacturer String
+ BMOD, 64, // Battery Model String
+ BSER, 64, // Battery Serial String
+ BTYP, 64, // Battery Type String
+ }
+
+ Method (TINS, 1, Serialized)
+ {
+ Switch (ToInteger (Arg0))
+ {
+ Case (0) { Return (TIN0) }
+ Case (1) { Return (TIN1) }
+ Case (2) { Return (TIN2) }
+ Case (3) { Return (TIN3) }
+ Case (4) { Return (TIN4) }
+ Case (5) { Return (TIN5) }
+ Case (6) { Return (TIN6) }
+ Case (7) { Return (TIN7) }
+ Case (8) { Return (TIN8) }
+ Case (9) { Return (TIN9) }
+ Default { Return (TIN0) }
+ }
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (ECMD, ResourceTemplate()
+ {
+ IO (Decode16,
+ EC_LPC_ADDR_ACPI_DATA,
+ EC_LPC_ADDR_ACPI_DATA,
+ 0, 1)
+ IO (Decode16,
+ EC_LPC_ADDR_ACPI_CMD,
+ EC_LPC_ADDR_ACPI_CMD,
+ 0, 1)
+ })
+ Return (ECMD)
+ }
+
+ Method (_REG, 2, NotSerialized)
+ {
+ // Initialize AC power state
+ Store (ACEX, \PWRS)
+
+ // Initialize LID switch state
+ Store (LIDS, \LIDS)
+ }
+
+ // Lid Closed Event
+ Method (_Q01, 0, NotSerialized)
+ {
+ Store ("EC: LID CLOSE", Debug)
+ Store (LIDS, \LIDS)
+ Notify (\_SB.LID0, 0x80)
+ }
+
+ // Lid Open Event
+ Method (_Q02, 0, NotSerialized)
+ {
+ Store ("EC: LID OPEN", Debug)
+ Store (LIDS, \LIDS)
+ Notify (\_SB.LID0, 0x80)
+ }
+
+ // Power Button
+ Method (_Q03, 0, NotSerialized)
+ {
+ Store ("EC: POWER BUTTON", Debug)
+ Notify (\_SB.PWRB, 0x80)
+ }
+
+ // AC Connected
+ Method (_Q04, 0, NotSerialized)
+ {
+ Store ("EC: AC CONNECTED", Debug)
+ Store (ACEX, \PWRS)
+ Notify (AC, 0x80)
+ \PNOT ()
+ }
+
+ // AC Disconnected
+ Method (_Q05, 0, NotSerialized)
+ {
+ Store ("EC: AC DISCONNECTED", Debug)
+ Store (ACEX, \PWRS)
+ Notify (AC, 0x80)
+ \PNOT ()
+ }
+
+ // Battery Low Event
+ Method (_Q06, 0, NotSerialized)
+ {
+ Store ("EC: BATTERY LOW", Debug)
+ Notify (BAT0, 0x80)
+ }
+
+ // Battery Critical Event
+ Method (_Q07, 0, NotSerialized)
+ {
+ Store ("EC: BATTERY CRITICAL", Debug)
+ Notify (BAT0, 0x80)
+ }
+
+ // Battery Info Event
+ Method (_Q08, 0, NotSerialized)
+ {
+ Store ("EC: BATTERY INFO", Debug)
+ Notify (BAT0, 0x81)
+ }
+
+ // Thermal Treshold Event
+ Method (_Q09, 0, NotSerialized)
+ {
+ Store ("EC: THERMAL THRESHOLD", Debug)
+ Notify (\_TZ, 0x80)
+ }
+
+ // Thermal Overload Event
+ Method (_Q0A, 0, NotSerialized)
+ {
+ Store ("EC: THERMAL OVERLOAD", Debug)
+ Notify (\_TZ, 0x80)
+ }
+
+ // Thermal Event
+ Method (_Q0B, 0, NotSerialized)
+ {
+ Store ("EC: THERMAL", Debug)
+ Notify (\_TZ, 0x80)
+ }
+
+ // USB Charger
+ Method (_Q0C, 0, NotSerialized)
+ {
+ Store ("EC: USB CHARGER", Debug)
+ }
+
+ // Key Pressed
+ Method (_Q0D, 0, NotSerialized)
+ {
+ Store ("EC: KEY PRESSED", Debug)
+ }
+
+ #include "ac.asl"
+ #include "battery.asl"
+}
diff --git a/src/ec/google/chromeec/acpi/superio.asl b/src/ec/google/chromeec/acpi/superio.asl
new file mode 100644
index 0000000000..56f0f185c6
--- /dev/null
+++ b/src/ec/google/chromeec/acpi/superio.asl
@@ -0,0 +1,152 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Chrome OS Embedded Controller interface
+ *
+ * Constants that should be defined:
+ *
+ * SIO_EC_MEMMAP_ENABLE : Enable EC LPC memory map resources
+ * EC_LPC_ADDR_MEMMAP : Base address of memory map range
+ * EC_MEMMAP_SIZE : Size of memory map range
+ *
+ * SIO_EC_HOST_ENABLE : Enable EC host command interface resources
+ * EC_LPC_ADDR_HOST_DATA : EC host command interface data port
+ * EC_LPC_ADDR_HOST_CMD : EC host command interface command port
+ * EC_LPC_ADDR_OLD_PARAM : EC host command parameter range base (old)
+ * EC_OLD_PARAM_SIZE : Parameter buffer size (old)
+ */
+
+// Scope is \_SB.PCI0.LPCB
+
+Device (SIO) {
+ Name (_UID, 0)
+ Name (_ADR, 0)
+
+#ifdef SIO_EC_MEMMAP_ENABLE
+ Device (ECMM) {
+ Name (_HID, EISAID ("PNP0C02"))
+ Name (_UID, 1)
+ Name (_ADR, 0)
+
+ Method (_STA, 0, NotSerialized) {
+ Return (0x0F)
+ }
+
+ Name (_CRS, ResourceTemplate ()
+ {
+ FixedIO (EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE)
+ })
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ FixedIO (EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE)
+ })
+ }
+#endif
+
+#ifdef SIO_EC_HOST_ENABLE
+ Device (ECUI) {
+ Name (_HID, EISAID ("PNP0C02"))
+ Name (_UID, 3)
+ Name (_ADR, 0)
+
+ Method (_STA, 0, NotSerialized) {
+ Return (0x0F)
+ }
+
+ Name (_CRS, ResourceTemplate ()
+ {
+ FixedIO (EC_LPC_ADDR_HOST_DATA, 1)
+ FixedIO (EC_LPC_ADDR_HOST_CMD, 1)
+ FixedIO (EC_LPC_ADDR_OLD_PARAM,
+ EC_OLD_PARAM_SIZE)
+ })
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ StartDependentFn (0, 0) {
+ FixedIO (EC_LPC_ADDR_HOST_DATA, 1)
+ FixedIO (EC_LPC_ADDR_HOST_CMD, 1)
+ FixedIO (EC_LPC_ADDR_OLD_PARAM,
+ EC_OLD_PARAM_SIZE)
+ }
+ EndDependentFn ()
+ })
+ }
+#endif
+
+#ifdef SIO_EC_ENABLE_COM1
+ Device (COM1) {
+ Name (_HID, EISAID ("PNP0501"))
+ Name (_UID, 1)
+ Name (_ADR, 0)
+
+ Method (_STA, 0, NotSerialized) {
+ Return (0x0F)
+ }
+
+ Name (_CRS, ResourceTemplate ()
+ {
+ FixedIO (0x03F8, 0x08)
+ IRQNoFlags () {4}
+ })
+
+ Name (_PRS, ResourceTemplate ()
+ {
+ StartDependentFn (0, 0) {
+ FixedIO (0x03F8, 0x08)
+ IRQNoFlags () {4}
+ }
+ EndDependentFn ()
+ })
+ }
+#endif
+
+#ifdef SIO_EC_ENABLE_PS2K
+ Device (PS2K) // Keyboard
+ {
+ Name (_UID, 0)
+ Name (_ADR, 0)
+ Name (_HID, EISAID("PNP0303"))
+ Name (_CID, EISAID("PNP030B"))
+
+ Method (_STA, 0, NotSerialized) {
+ Return (0x0F)
+ }
+
+ Name (_CRS, ResourceTemplate()
+ {
+ FixedIO (0x60, 0x01)
+ FixedIO (0x64, 0x01)
+ IRQNoFlags () {1}
+ })
+
+ Name (_PRS, ResourceTemplate()
+ {
+ StartDependentFn (0, 0) {
+ FixedIO (0x60, 0x01)
+ FixedIO (0x64, 0x01)
+ IRQNoFlags () {1}
+ }
+ EndDependentFn ()
+ })
+ }
+#endif
+}
diff --git a/src/ec/google/chromeec/chip.h b/src/ec/google/chromeec/chip.h
new file mode 100644
index 0000000000..0ca2183775
--- /dev/null
+++ b/src/ec/google/chromeec/chip.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The Chromium OS Authors. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef EC_GOOGLE_CHROMEEC_CHIP_H
+#define EC_GOOGLE_CHROMEEC_CHIP_H
+
+#include <device/device.h>
+#include <pc80/keyboard.h>
+
+extern struct chip_operations ec_google_chromeec_ops;
+
+struct ec_google_chromeec_config {
+ struct pc_keyboard keyboard;
+};
+
+#endif
diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c
new file mode 100644
index 0000000000..4057f2a03b
--- /dev/null
+++ b/src/ec/google/chromeec/ec.c
@@ -0,0 +1,519 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The Chromium OS Authors. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <console/console.h>
+#include <arch/io.h>
+#include <delay.h>
+
+#ifdef __PRE_RAM__
+#include <arch/romcc_io.h>
+#else
+#include <device/device.h>
+#include <device/pnp.h>
+#include <elog.h>
+#include <stdlib.h>
+#include <string.h>
+#include <reset.h>
+#include <arch/hlt.h>
+#include "chip.h"
+#endif
+#include "ec.h"
+#include "ec_commands.h"
+#include <vendorcode/google/chromeos/chromeos.h>
+
+/* an internal API to send a command to the EC and wait for response. */
+struct chromeec_command {
+ u8 cmd_code; /* command code in, status out */
+ u8 cmd_version; /* command version */
+ const void* cmd_data_in; /* command data, if any */
+ void* cmd_data_out; /* command response, if any */
+ u16 cmd_size_in; /* size of command data */
+ u16 cmd_size_out; /* expected size of command response in,
+ * actual received size out */
+};
+
+static int google_chromeec_wait_ready(u16 port)
+{
+ u8 ec_status = inb(port);
+ u32 time_count = 0;
+
+ /*
+ * One second is more than plenty for any EC operation to complete
+ * (and the bus accessing/code execution) overhead will make the
+ * timeout even longer.
+ */
+#define MAX_EC_TIMEOUT_US 1000000
+
+ while (ec_status &
+ (EC_LPC_CMDR_PENDING | EC_LPC_CMDR_BUSY)) {
+ udelay(1);
+ if (time_count++ == MAX_EC_TIMEOUT_US)
+ return -1;
+ ec_status = inb(port);
+ }
+ return 0;
+}
+
+static int google_chromeec_cmd_args_supported(void)
+{
+ if (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID) == 'E' &&
+ inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1) == 'C' &&
+ (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_HOST_CMD_FLAGS) &
+ EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED))
+ return 1;
+
+ return 0;
+}
+
+static int google_chromeec_command_old(struct chromeec_command *cec_command)
+{
+ int i;
+
+ if (cec_command->cmd_version) {
+ printk(BIOS_ERR, "Invalid version for command protocol!\n");
+ return 1;
+ }
+
+ if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD)) {
+ printk(BIOS_ERR, "Timeout waiting for EC ready!\n");
+ return 1;
+ }
+
+ /* Copy command data, if any. */
+ for (i = 0; i < cec_command->cmd_size_in; i++)
+ outb(((char*)cec_command->cmd_data_in)[i],
+ EC_LPC_ADDR_OLD_PARAM + i);
+
+ /* Issue the command. */
+ outb(cec_command->cmd_code, EC_LPC_ADDR_HOST_CMD);
+
+ if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD)) {
+ printk(BIOS_ERR, "Timeout waiting for EC process command %d!\n",
+ cec_command->cmd_code);
+ return 1;
+ }
+
+ for (i = 0; i < cec_command->cmd_size_out; i++)
+ ((char*)cec_command->cmd_data_out)[i] =
+ inb(EC_LPC_ADDR_OLD_PARAM + i);
+ cec_command->cmd_code = inb(EC_LPC_ADDR_HOST_DATA);
+ return 0;
+}
+
+static int google_chromeec_command(struct chromeec_command *cec_command)
+{
+ struct ec_lpc_host_args args;
+ const u8 *d;
+ u8 *dout;
+ u8 cmd_code = cec_command->cmd_code;
+ int csum;
+ int i;
+
+ /* Fall back to old command protocol if necessary */
+ if (!google_chromeec_cmd_args_supported())
+ return google_chromeec_command_old(cec_command);
+
+ /* Fill in args */
+ args.flags = EC_HOST_ARGS_FLAG_FROM_HOST;
+ args.command_version = cec_command->cmd_version;
+ args.data_size = cec_command->cmd_size_in;
+
+ /* Initialize checksum */
+ csum = cmd_code + args.flags + args.command_version + args.data_size;
+
+ /* Write data and update checksum */
+ for (i = 0, d = (const u8 *)cec_command->cmd_data_in;
+ i < cec_command->cmd_size_in; i++, d++) {
+ outb(*d, EC_LPC_ADDR_HOST_PARAM + i);
+ csum += *d;
+ }
+
+ /* Finalize checksum and write args */
+ args.checksum = (u8)csum;
+ for (i = 0, d = (const u8 *)&args; i < sizeof(args); i++, d++)
+ outb(*d, EC_LPC_ADDR_HOST_ARGS + i);
+
+
+ /* Issue the command */
+ outb(cmd_code, EC_LPC_ADDR_HOST_CMD);
+
+ if (google_chromeec_wait_ready(EC_LPC_ADDR_HOST_CMD)) {
+ printk(BIOS_ERR, "Timeout waiting for EC process command %d!\n",
+ cec_command->cmd_code);
+ return 1;
+ }
+
+ /* Check result */
+ cec_command->cmd_code = inb(EC_LPC_ADDR_HOST_DATA);
+ if (cec_command->cmd_code)
+ return 1;
+
+ /* Read back args */
+ for (i = 0, dout = (u8 *)&args; i < sizeof(args); i++, dout++)
+ *dout = inb(EC_LPC_ADDR_HOST_ARGS + i);
+
+ /*
+ * If EC didn't modify args flags, then somehow we sent a new-style
+ * command to an old EC, which means it would have read its params
+ * from the wrong place.
+ */
+ if (!(args.flags & EC_HOST_ARGS_FLAG_TO_HOST)) {
+ printk(BIOS_ERR, "EC protocol mismatch\n");
+ return 1;
+ }
+
+ if (args.data_size > cec_command->cmd_size_out) {
+ printk(BIOS_ERR, "EC returned too much data\n");
+ return 1;
+ }
+ cec_command->cmd_size_out = args.data_size;
+
+ /* Start calculating response checksum */
+ csum = cmd_code + args.flags + args.command_version + args.data_size;
+
+ /* Read data, if any */
+ for (i = 0, dout = (u8 *)cec_command->cmd_data_out;
+ i < args.data_size; i++, dout++) {
+ *dout = inb(EC_LPC_ADDR_HOST_PARAM + i);
+ csum += *dout;
+ }
+
+ /* Verify checksum */
+ if (args.checksum != (u8)csum) {
+ printk(BIOS_ERR, "EC response has invalid checksum\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+int google_chromeec_kbbacklight(int percent)
+{
+ struct chromeec_command cec_cmd;
+ struct ec_params_pwm_set_keyboard_backlight cmd_backlight;
+ struct ec_response_pwm_get_keyboard_backlight rsp_backlight;
+ /* if they were dumb, help them out */
+ percent = percent % 101;
+ cec_cmd.cmd_code = EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT;
+ cec_cmd.cmd_version = 0;
+ cmd_backlight.percent = percent;
+ cec_cmd.cmd_data_in = &cmd_backlight;
+ cec_cmd.cmd_data_out = &rsp_backlight;
+ cec_cmd.cmd_size_in = sizeof(cmd_backlight);
+ cec_cmd.cmd_size_out = sizeof(rsp_backlight);
+ google_chromeec_command(&cec_cmd);
+ printk(BIOS_DEBUG, "Google Chrome set keyboard backlight: %x status (%x)\n",
+ rsp_backlight.percent, cec_cmd.cmd_code);
+ return cec_cmd.cmd_code;
+
+}
+
+void google_chromeec_post(u8 postcode)
+{
+ /* backlight is a percent. postcode is a u8.
+ * Convert the u8 to %.
+ */
+ postcode = (postcode/4) + (postcode/8);
+ google_chromeec_kbbacklight(postcode);
+}
+
+/*
+ * Query the EC for specified mask indicating enabled events.
+ * The EC maintains separate event masks for SMI, SCI and WAKE.
+ */
+static u32 google_chromeec_get_mask(u8 type)
+{
+ struct ec_params_host_event_mask req;
+ struct ec_response_host_event_mask rsp;
+ struct chromeec_command cmd;
+
+ cmd.cmd_code = type;
+ cmd.cmd_version = 0;
+ cmd.cmd_data_in = &req;
+ cmd.cmd_size_in = sizeof(req);
+ cmd.cmd_data_out = &rsp;
+ cmd.cmd_size_out = sizeof(rsp);
+
+ if (google_chromeec_command(&cmd) == 0)
+ return rsp.mask;
+ return 0;
+}
+
+u32 google_chromeec_get_events_b(void)
+{
+ return google_chromeec_get_mask(EC_CMD_HOST_EVENT_GET_B);
+}
+
+#ifndef __PRE_RAM__
+
+static int google_chromeec_set_mask(u8 type, u32 mask)
+{
+ struct ec_params_host_event_mask req;
+ struct ec_response_host_event_mask rsp;
+ struct chromeec_command cmd;
+
+ req.mask = mask;
+ cmd.cmd_code = type;
+ cmd.cmd_version = 0;
+ cmd.cmd_data_in = &req;
+ cmd.cmd_size_in = sizeof(req);
+ cmd.cmd_data_out = &rsp;
+ cmd.cmd_size_out = sizeof(rsp);
+
+ return google_chromeec_command(&cmd);
+}
+
+int google_chromeec_set_sci_mask(u32 mask)
+{
+ printk(BIOS_DEBUG, "Chrome EC: Set SCI mask to 0x%08x\n", mask);
+ return google_chromeec_set_mask(
+ EC_CMD_HOST_EVENT_SET_SCI_MASK, mask);
+}
+
+int google_chromeec_set_smi_mask(u32 mask)
+{
+ printk(BIOS_DEBUG, "Chrome EC: Set SMI mask to 0x%08x\n", mask);
+ return google_chromeec_set_mask(
+ EC_CMD_HOST_EVENT_SET_SMI_MASK, mask);
+}
+
+int google_chromeec_set_wake_mask(u32 mask)
+{
+ printk(BIOS_DEBUG, "Chrome EC: Set WAKE mask to 0x%08x\n", mask);
+ return google_chromeec_set_mask(
+ EC_CMD_HOST_EVENT_SET_WAKE_MASK, mask);
+}
+
+u32 google_chromeec_get_wake_mask(void)
+{
+ return google_chromeec_get_mask(
+ EC_CMD_HOST_EVENT_GET_WAKE_MASK);
+}
+
+#if CONFIG_ELOG
+/* Find the last port80 code from the previous boot */
+static u16 google_chromeec_get_port80_last_boot(void)
+{
+ struct ec_response_port80_last_boot rsp;
+ struct chromeec_command cmd = {
+ .cmd_code = EC_CMD_PORT80_LAST_BOOT,
+ .cmd_data_out = &rsp,
+ .cmd_size_out = sizeof(rsp),
+ };
+
+ /* Get last port80 code */
+ if (google_chromeec_command(&cmd) == 0)
+ return rsp.code;
+
+ return 0;
+}
+#endif
+
+void google_chromeec_log_events(u32 mask)
+{
+#if CONFIG_ELOG
+ u8 event;
+ u16 code;
+
+ /* Find the last port80 code */
+ code = google_chromeec_get_port80_last_boot();
+
+ /* Log the last post code only if it is abornmal */
+ if (code > 0 && code != POST_OS_BOOT && code != POST_OS_RESUME)
+ printk(BIOS_DEBUG, "Chrome EC: Last POST code was 0x%02x\n",
+ code);
+
+ while ((event = google_chromeec_get_event()) != 0) {
+ if (EC_HOST_EVENT_MASK(event) & mask)
+ elog_add_event_byte(ELOG_TYPE_EC_EVENT, event);
+ }
+#endif
+}
+
+u8 google_chromeec_get_event(void)
+{
+ if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) {
+ printk(BIOS_ERR, "Timeout waiting for EC ready!\n");
+ return 1;
+ }
+
+ /* Issue the ACPI query-event command */
+ outb(EC_CMD_ACPI_QUERY_EVENT, EC_LPC_ADDR_ACPI_CMD);
+
+ if (google_chromeec_wait_ready(EC_LPC_ADDR_ACPI_CMD)) {
+ printk(BIOS_ERR, "Timeout waiting for EC QUERY_EVENT!\n");
+ return 0;
+ }
+
+ /* Event (or 0 if none) is returned directly in the data byte */
+ return inb(EC_LPC_ADDR_ACPI_DATA);
+}
+
+u16 google_chromeec_get_board_version(void)
+{
+ struct chromeec_command cmd;
+ struct ec_response_board_version board_v;
+
+ cmd.cmd_code = EC_CMD_GET_BOARD_VERSION;
+ cmd.cmd_version = 0;
+ cmd.cmd_size_in = 0;
+ cmd.cmd_size_out = sizeof(board_v);
+ cmd.cmd_data_out = &board_v;
+
+ if (google_chromeec_command(&cmd) != 0)
+ return 0;
+
+ return board_v.board_version;
+}
+
+int google_chromeec_set_usb_charge_mode(u8 port_id, enum usb_charge_mode mode)
+{
+ struct chromeec_command cmd;
+ struct ec_params_usb_charge_set_mode set_mode = {
+ .usb_port_id = port_id,
+ .mode = mode,
+ };
+
+ cmd.cmd_code = EC_CMD_USB_CHARGE_SET_MODE;
+ cmd.cmd_version = 0;
+ cmd.cmd_size_in = sizeof(set_mode);
+ cmd.cmd_data_in = &set_mode;
+ cmd.cmd_size_out = 0;
+ cmd.cmd_data_out = NULL;
+
+ return google_chromeec_command(&cmd);
+}
+
+#ifndef __SMM__
+
+static
+int google_chromeec_hello(void)
+{
+ struct chromeec_command cec_cmd;
+ struct ec_params_hello cmd_hello;
+ struct ec_response_hello rsp_hello;
+ cmd_hello.in_data = 0x10203040;
+ cec_cmd.cmd_code = EC_CMD_HELLO;
+ cec_cmd.cmd_version = 0;
+ cec_cmd.cmd_data_in = &cmd_hello.in_data;
+ cec_cmd.cmd_data_out = &rsp_hello.out_data;
+ cec_cmd.cmd_size_in = sizeof(cmd_hello.in_data);
+ cec_cmd.cmd_size_out = sizeof(rsp_hello.out_data);
+ google_chromeec_command(&cec_cmd);
+ printk(BIOS_DEBUG, "Google Chrome EC: Hello got back %x status (%x)\n",
+ rsp_hello.out_data, cec_cmd.cmd_code);
+ return cec_cmd.cmd_code;
+}
+
+static int ec_image_type; /* Cached EC image type (ro or rw). */
+
+static void google_chromeec_init(device_t dev)
+{
+ struct chromeec_command cec_cmd;
+ struct ec_google_chromeec_config *conf = dev->chip_info;
+ struct ec_response_get_version lpcv_cmd;
+
+ if (!dev->enabled)
+ return;
+
+ printk(BIOS_DEBUG, "Google Chrome EC: Initializing keyboard.\n");
+ pc_keyboard_init(&conf->keyboard);
+
+ google_chromeec_hello();
+
+ memset(&lpcv_cmd, 0, sizeof(lpcv_cmd));
+ cec_cmd.cmd_code = EC_CMD_GET_VERSION;
+ cec_cmd.cmd_version = 0;
+ cec_cmd.cmd_data_out = &lpcv_cmd;
+ cec_cmd.cmd_size_in = 0;
+ cec_cmd.cmd_size_out = sizeof(lpcv_cmd);
+ google_chromeec_command(&cec_cmd);
+
+ if (cec_cmd.cmd_code) {
+ printk(BIOS_DEBUG,
+ "Google Chrome EC: version command failed!\n");
+ } else {
+ printk(BIOS_DEBUG, "Google Chrome EC: version:\n");
+ printk(BIOS_DEBUG, " ro: %s\n", lpcv_cmd.version_string_ro);
+ printk(BIOS_DEBUG, " rw: %s\n", lpcv_cmd.version_string_rw);
+ printk(BIOS_DEBUG, " running image: %d\n",
+ lpcv_cmd.current_image);
+ ec_image_type = lpcv_cmd.current_image;
+ }
+
+ if (cec_cmd.cmd_code ||
+ (recovery_mode_enabled() &&
+ (lpcv_cmd.current_image != EC_IMAGE_RO))) {
+ struct ec_params_reboot_ec reboot_ec;
+ /* Reboot the EC and make it come back in RO mode */
+ reboot_ec.cmd = EC_REBOOT_COLD;
+ reboot_ec.flags = 0;
+ cec_cmd.cmd_code = EC_CMD_REBOOT_EC;
+ cec_cmd.cmd_version = 0;
+ cec_cmd.cmd_data_in = &reboot_ec;
+ cec_cmd.cmd_size_in = sizeof(reboot_ec);
+ cec_cmd.cmd_size_out = 0; /* ignore response, if any */
+ printk(BIOS_DEBUG, "Rebooting with EC in RO mode:\n");
+ google_chromeec_command(&cec_cmd);
+ udelay(1000);
+ hard_reset();
+ hlt();
+ }
+
+}
+
+static void google_chromeec_read_resources(device_t dev)
+{
+ /* Nothing, but this function avoids an error on serial console. */
+}
+
+static void google_chromeec_enable_resources(device_t dev)
+{
+ /* Nothing, but this function avoids an error on serial console. */
+}
+
+static struct device_operations ops = {
+ .init = google_chromeec_init,
+ .read_resources = google_chromeec_read_resources,
+ .enable_resources = google_chromeec_enable_resources
+};
+
+static struct pnp_info pnp_dev_info[] = {
+ { &ops, 0, 0, { 0, 0 }, }
+};
+
+static void enable_dev(device_t dev)
+{
+ pnp_enable_devices(dev, &pnp_ops, ARRAY_SIZE(pnp_dev_info),
+ pnp_dev_info);
+}
+
+struct chip_operations ec_google_chromeec_ops = {
+ CHIP_NAME("Google Chrome EC")
+ .enable_dev = enable_dev,
+};
+
+int google_ec_running_ro(void)
+{
+ return (ec_image_type == EC_IMAGE_RO);
+}
+#endif /* ! __SMM__ */
+
+#endif /* ! __PRE_RAM__ */
diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h
new file mode 100644
index 0000000000..f056d266e6
--- /dev/null
+++ b/src/ec/google/chromeec/ec.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The Chromium OS Authors. All rights reserved.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Mailbox EC communication interface for Google Chrome Embedded Controller.
+ */
+
+#ifndef _EC_GOOGLE_CHROMEEC_EC_H
+#define _EC_GOOGLE_CHROMEEC_EC_H
+
+#ifndef __PRE_RAM__
+u32 google_chromeec_get_wake_mask(void);
+int google_chromeec_set_sci_mask(u32 mask);
+int google_chromeec_set_smi_mask(u32 mask);
+int google_chromeec_set_wake_mask(u32 mask);
+u8 google_chromeec_get_event(void);
+int google_ec_running_ro(void);
+u16 google_chromeec_get_board_version(void);
+#endif
+
+u32 google_chromeec_get_events_b(void);
+int google_chromeec_kbbacklight(int percent);
+void google_chromeec_post(u8 postcode);
+void google_chromeec_log_events(u32 mask);
+
+enum usb_charge_mode {
+ USB_CHARGE_MODE_DISABLED,
+ USB_CHARGE_MODE_CHARGE_AUTO,
+ USB_CHARGE_MODE_CHARGE_BC12,
+ USB_CHARGE_MODE_DOWNSTREAM_500MA,
+ USB_CHARGE_MODE_DOWNSTREAM_1500MA,
+};
+int google_chromeec_set_usb_charge_mode(u8 port_id, enum usb_charge_mode mode);
+
+#endif /* _EC_GOOGLE_CHROMEEC_EC_H */
diff --git a/src/ec/google/chromeec/ec_commands.h b/src/ec/google/chromeec/ec_commands.h
new file mode 100644
index 0000000000..c1b19bcf1a
--- /dev/null
+++ b/src/ec/google/chromeec/ec_commands.h
@@ -0,0 +1,1069 @@
+/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Host communication command constants for Chrome EC */
+
+#ifndef __CROS_EC_COMMANDS_H
+#define __CROS_EC_COMMANDS_H
+
+/*
+ * Protocol overview
+ *
+ * request: CMD [ P0 P1 P2 ... Pn S ]
+ * response: ERR [ P0 P1 P2 ... Pn S ]
+ *
+ * where the bytes are defined as follow :
+ * - CMD is the command code. (defined by EC_CMD_ constants)
+ * - ERR is the error code. (defined by EC_RES_ constants)
+ * - Px is the optional payload.
+ * it is not sent if the error code is not success.
+ * (defined by ec_params_ and ec_response_ structures)
+ * - S is the checksum which is the sum of all payload bytes.
+ *
+ * On LPC, CMD and ERR are sent/received at EC_LPC_ADDR_KERNEL|USER_CMD
+ * and the payloads are sent/received at EC_LPC_ADDR_KERNEL|USER_PARAM.
+ * On I2C, all bytes are sent serially in the same message.
+ */
+
+/* Current version of this protocol */
+#define EC_PROTO_VERSION 0x00000002
+
+/* Command version mask */
+#define EC_VER_MASK(version) (1UL << (version))
+
+/* I/O addresses for ACPI commands */
+#define EC_LPC_ADDR_ACPI_DATA 0x62
+#define EC_LPC_ADDR_ACPI_CMD 0x66
+
+/* I/O addresses for host command */
+#define EC_LPC_ADDR_HOST_DATA 0x200
+#define EC_LPC_ADDR_HOST_CMD 0x204
+
+/* I/O addresses for host command args and params */
+#define EC_LPC_ADDR_HOST_ARGS 0x800
+#define EC_LPC_ADDR_HOST_PARAM 0x804
+#define EC_HOST_PARAM_SIZE 0x0fc /* Size of param area in bytes */
+
+/* I/O addresses for host command params, old interface */
+#define EC_LPC_ADDR_OLD_PARAM 0x880
+#define EC_OLD_PARAM_SIZE 0x080 /* Size of param area in bytes */
+
+/* EC command register bit functions */
+#define EC_LPC_CMDR_DATA (1 << 0) /* Data ready for host to read */
+#define EC_LPC_CMDR_PENDING (1 << 1) /* Write pending to EC */
+#define EC_LPC_CMDR_BUSY (1 << 2) /* EC is busy processing a command */
+#define EC_LPC_CMDR_CMD (1 << 3) /* Last host write was a command */
+#define EC_LPC_CMDR_ACPI_BRST (1 << 4) /* Burst mode (not used) */
+#define EC_LPC_CMDR_SCI (1 << 5) /* SCI event is pending */
+#define EC_LPC_CMDR_SMI (1 << 6) /* SMI event is pending */
+
+#define EC_LPC_ADDR_MEMMAP 0x900
+#define EC_MEMMAP_SIZE 255 /* ACPI IO buffer max is 255 bytes */
+#define EC_MEMMAP_TEXT_MAX 8 /* Size of a string in the memory map */
+
+/* The offset address of each type of data in mapped memory. */
+#define EC_MEMMAP_TEMP_SENSOR 0x00 /* Temp sensors */
+#define EC_MEMMAP_FAN 0x10 /* Fan speeds */
+#define EC_MEMMAP_TEMP_SENSOR_B 0x18 /* Temp sensors (second set) */
+#define EC_MEMMAP_ID 0x20 /* 'E' 'C' */
+#define EC_MEMMAP_ID_VERSION 0x22 /* Version of data in 0x20 - 0x2f */
+#define EC_MEMMAP_THERMAL_VERSION 0x23 /* Version of data in 0x00 - 0x1f */
+#define EC_MEMMAP_BATTERY_VERSION 0x24 /* Version of data in 0x40 - 0x7f */
+#define EC_MEMMAP_SWITCHES_VERSION 0x25 /* Version of data in 0x30 - 0x33 */
+#define EC_MEMMAP_EVENTS_VERSION 0x26 /* Version of data in 0x34 - 0x3f */
+#define EC_MEMMAP_HOST_CMD_FLAGS 0x27 /* Host command interface flags */
+#define EC_MEMMAP_SWITCHES 0x30
+#define EC_MEMMAP_HOST_EVENTS 0x34
+#define EC_MEMMAP_BATT_VOLT 0x40 /* Battery Present Voltage */
+#define EC_MEMMAP_BATT_RATE 0x44 /* Battery Present Rate */
+#define EC_MEMMAP_BATT_CAP 0x48 /* Battery Remaining Capacity */
+#define EC_MEMMAP_BATT_FLAG 0x4c /* Battery State, defined below */
+#define EC_MEMMAP_BATT_DCAP 0x50 /* Battery Design Capacity */
+#define EC_MEMMAP_BATT_DVLT 0x54 /* Battery Design Voltage */
+#define EC_MEMMAP_BATT_LFCC 0x58 /* Battery Last Full Charge Capacity */
+#define EC_MEMMAP_BATT_CCNT 0x5c /* Battery Cycle Count */
+#define EC_MEMMAP_BATT_MFGR 0x60 /* Battery Manufacturer String */
+#define EC_MEMMAP_BATT_MODEL 0x68 /* Battery Model Number String */
+#define EC_MEMMAP_BATT_SERIAL 0x70 /* Battery Serial Number String */
+#define EC_MEMMAP_BATT_TYPE 0x78 /* Battery Type String */
+
+/* Number of temp sensors at EC_MEMMAP_TEMP_SENSOR */
+#define EC_TEMP_SENSOR_ENTRIES 16
+/*
+ * Number of temp sensors at EC_MEMMAP_TEMP_SENSOR_B.
+ *
+ * Valid only if EC_MEMMAP_THERMAL_VERSION returns >= 2.
+ */
+#define EC_TEMP_SENSOR_B_ENTRIES 8
+#define EC_TEMP_SENSOR_NOT_PRESENT 0xff
+#define EC_TEMP_SENSOR_ERROR 0xfe
+#define EC_TEMP_SENSOR_NOT_POWERED 0xfd
+/*
+ * The offset of temperature value stored in mapped memory. This allows
+ * reporting a temperature range of 200K to 454K = -73C to 181C.
+ */
+#define EC_TEMP_SENSOR_OFFSET 200
+
+#define EC_FAN_SPEED_ENTRIES 4 /* Number of fans at EC_MEMMAP_FAN */
+#define EC_FAN_SPEED_NOT_PRESENT 0xffff /* Entry not present */
+#define EC_FAN_SPEED_STALLED 0xfffe /* Fan stalled */
+
+/* Battery bit flags at EC_MEMMAP_BATT_FLAG. */
+#define EC_BATT_FLAG_AC_PRESENT 0x01
+#define EC_BATT_FLAG_BATT_PRESENT 0x02
+#define EC_BATT_FLAG_DISCHARGING 0x04
+#define EC_BATT_FLAG_CHARGING 0x08
+#define EC_BATT_FLAG_LEVEL_CRITICAL 0x10
+
+/* Switch flags at EC_MEMMAP_SWITCHES */
+#define EC_SWITCH_LID_OPEN 0x01
+#define EC_SWITCH_POWER_BUTTON_PRESSED 0x02
+#define EC_SWITCH_WRITE_PROTECT_DISABLED 0x04
+/* Recovery requested via keyboard */
+#define EC_SWITCH_KEYBOARD_RECOVERY 0x08
+/* Recovery requested via dedicated signal (from servo board) */
+#define EC_SWITCH_DEDICATED_RECOVERY 0x10
+/* Was fake developer mode switch; now unused. Remove in next refactor. */
+#define EC_SWITCH_IGNORE0 0x20
+
+/* Host command interface flags */
+/* Host command interface supports LPC args (LPC interface only) */
+#define EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED 0x01
+
+/* Wireless switch flags */
+#define EC_WIRELESS_SWITCH_WLAN 0x01
+#define EC_WIRELESS_SWITCH_BLUETOOTH 0x02
+
+/*
+ * This header file is used in coreboot both in C and ACPI code. The ACPI code
+ * is pre-processed to handle constants but the ASL compiler is unable to
+ * handle actual C code so keep it separate.
+ */
+#ifndef __ACPI__
+
+/*
+ * Define __packed if someone hasn't beat us to it. Linux kernel style
+ * checking prefers __packed over __attribute__((packed)).
+ */
+#ifndef __packed
+#define __packed __attribute__((packed))
+#endif
+
+/* LPC command status byte masks */
+/* EC has written a byte in the data register and host hasn't read it yet */
+#define EC_LPC_STATUS_TO_HOST 0x01
+/* Host has written a command/data byte and the EC hasn't read it yet */
+#define EC_LPC_STATUS_FROM_HOST 0x02
+/* EC is processing a command */
+#define EC_LPC_STATUS_PROCESSING 0x04
+/* Last write to EC was a command, not data */
+#define EC_LPC_STATUS_LAST_CMD 0x08
+/* EC is in burst mode. Unsupported by Chrome EC, so this bit is never set */
+#define EC_LPC_STATUS_BURST_MODE 0x10
+/* SCI event is pending (requesting SCI query) */
+#define EC_LPC_STATUS_SCI_PENDING 0x20
+/* SMI event is pending (requesting SMI query) */
+#define EC_LPC_STATUS_SMI_PENDING 0x40
+/* (reserved) */
+#define EC_LPC_STATUS_RESERVED 0x80
+
+/*
+ * EC is busy. This covers both the EC processing a command, and the host has
+ * written a new command but the EC hasn't picked it up yet.
+ */
+#define EC_LPC_STATUS_BUSY_MASK \
+ (EC_LPC_STATUS_FROM_HOST | EC_LPC_STATUS_PROCESSING)
+
+/* Host command response codes */
+enum ec_status {
+ EC_RES_SUCCESS = 0,
+ EC_RES_INVALID_COMMAND = 1,
+ EC_RES_ERROR = 2,
+ EC_RES_INVALID_PARAM = 3,
+ EC_RES_ACCESS_DENIED = 4,
+ EC_RES_INVALID_RESPONSE = 5,
+ EC_RES_INVALID_VERSION = 6,
+ EC_RES_INVALID_CHECKSUM = 7,
+};
+
+/*
+ * Host event codes. Note these are 1-based, not 0-based, because ACPI query
+ * EC command uses code 0 to mean "no event pending". We explicitly specify
+ * each value in the enum listing so they won't change if we delete/insert an
+ * item or rearrange the list (it needs to be stable across platforms, not
+ * just within a single compiled instance).
+ */
+enum host_event_code {
+ EC_HOST_EVENT_LID_CLOSED = 1,
+ EC_HOST_EVENT_LID_OPEN = 2,
+ EC_HOST_EVENT_POWER_BUTTON = 3,
+ EC_HOST_EVENT_AC_CONNECTED = 4,
+ EC_HOST_EVENT_AC_DISCONNECTED = 5,
+ EC_HOST_EVENT_BATTERY_LOW = 6,
+ EC_HOST_EVENT_BATTERY_CRITICAL = 7,
+ EC_HOST_EVENT_BATTERY = 8,
+ EC_HOST_EVENT_THERMAL_THRESHOLD = 9,
+ EC_HOST_EVENT_THERMAL_OVERLOAD = 10,
+ EC_HOST_EVENT_THERMAL = 11,
+ EC_HOST_EVENT_USB_CHARGER = 12,
+ EC_HOST_EVENT_KEY_PRESSED = 13,
+ /*
+ * EC has finished initializing the host interface. The host can check
+ * for this event following sending a EC_CMD_REBOOT_EC command to
+ * determine when the EC is ready to accept subsequent commands.
+ */
+ EC_HOST_EVENT_INTERFACE_READY = 14,
+ /* Keyboard recovery combo has been pressed */
+ EC_HOST_EVENT_KEYBOARD_RECOVERY = 15,
+
+ /* Shutdown due to thermal overload */
+ EC_HOST_EVENT_THERMAL_SHUTDOWN = 16,
+ /* Shutdown due to battery level too low */
+ EC_HOST_EVENT_BATTERY_SHUTDOWN = 17,
+
+ /*
+ * The high bit of the event mask is not used as a host event code. If
+ * it reads back as set, then the entire event mask should be
+ * considered invalid by the host. This can happen when reading the
+ * raw event status via EC_MEMMAP_HOST_EVENTS but the LPC interface is
+ * not initialized on the EC, or improperly configured on the host.
+ */
+ EC_HOST_EVENT_INVALID = 32
+};
+/* Host event mask */
+#define EC_HOST_EVENT_MASK(event_code) (1UL << ((event_code) - 1))
+
+/* Arguments at EC_LPC_ADDR_HOST_ARGS */
+struct ec_lpc_host_args {
+ uint8_t flags;
+ uint8_t command_version;
+ uint8_t data_size;
+ /*
+ * Checksum; sum of command + flags + command_version + data_size +
+ * all params/response data bytes.
+ */
+ uint8_t checksum;
+} __packed;
+
+/* Flags for ec_lpc_host_args.flags */
+/*
+ * Args are from host. Data area at EC_LPC_ADDR_HOST_PARAM contains command
+ * params.
+ *
+ * If EC gets a command and this flag is not set, this is an old-style command.
+ * Command version is 0 and params from host are at EC_LPC_ADDR_OLD_PARAM with
+ * unknown length. EC must respond with an old-style response (that is,
+ * withouth setting EC_HOST_ARGS_FLAG_TO_HOST).
+ */
+#define EC_HOST_ARGS_FLAG_FROM_HOST 0x01
+/*
+ * Args are from EC. Data area at EC_LPC_ADDR_HOST_PARAM contains response.
+ *
+ * If EC responds to a command and this flag is not set, this is an old-style
+ * response. Command version is 0 and response data from EC is at
+ * EC_LPC_ADDR_OLD_PARAM with unknown length.
+ */
+#define EC_HOST_ARGS_FLAG_TO_HOST 0x02
+
+/*
+ * Notes on commands:
+ *
+ * Each command is an 8-byte command value. Commands which take params or
+ * return response data specify structs for that data. If no struct is
+ * specified, the command does not input or output data, respectively.
+ * Parameter/response length is implicit in the structs. Some underlying
+ * communication protocols (I2C, SPI) may add length or checksum headers, but
+ * those are implementation-dependent and not defined here.
+ */
+
+/*****************************************************************************/
+/* General / test commands */
+
+/*
+ * Get protocol version, used to deal with non-backward compatible protocol
+ * changes.
+ */
+#define EC_CMD_PROTO_VERSION 0x00
+
+struct ec_response_proto_version {
+ uint32_t version;
+} __packed;
+
+/*
+ * Hello. This is a simple command to test the EC is responsive to
+ * commands.
+ */
+#define EC_CMD_HELLO 0x01
+
+struct ec_params_hello {
+ uint32_t in_data; /* Pass anything here */
+} __packed;
+
+struct ec_response_hello {
+ uint32_t out_data; /* Output will be in_data + 0x01020304 */
+} __packed;
+
+/* Get version number */
+#define EC_CMD_GET_VERSION 0x02
+
+enum ec_current_image {
+ EC_IMAGE_UNKNOWN = 0,
+ EC_IMAGE_RO,
+ EC_IMAGE_RW
+};
+
+struct ec_response_get_version {
+ /* Null-terminated version strings for RO, RW */
+ char version_string_ro[32];
+ char version_string_rw[32];
+ char reserved[32]; /* Was previously RW-B string */
+ uint32_t current_image; /* One of ec_current_image */
+} __packed;
+
+/* Read test */
+#define EC_CMD_READ_TEST 0x03
+
+struct ec_params_read_test {
+ uint32_t offset; /* Starting value for read buffer */
+ uint32_t size; /* Size to read in bytes */
+} __packed;
+
+struct ec_response_read_test {
+ uint32_t data[32];
+} __packed;
+
+/*
+ * Get build information
+ *
+ * Response is null-terminated string.
+ */
+#define EC_CMD_GET_BUILD_INFO 0x04
+
+/* Get chip info */
+#define EC_CMD_GET_CHIP_INFO 0x05
+
+struct ec_response_get_chip_info {
+ /* Null-terminated strings */
+ char vendor[32];
+ char name[32];
+ char revision[32]; /* Mask version */
+} __packed;
+
+/* Get board HW version */
+#define EC_CMD_GET_BOARD_VERSION 0x06
+
+struct ec_response_board_version {
+ uint16_t board_version; /* A monotonously incrementing number. */
+} __packed;
+
+/*
+ * Read memory-mapped data.
+ *
+ * This is an alternate interface to memory-mapped data for bus protocols
+ * which don't support direct-mapped memory - I2C, SPI, etc.
+ *
+ * Response is params.size bytes of data.
+ */
+#define EC_CMD_READ_MEMMAP 0x07
+
+struct ec_params_read_memmap {
+ uint8_t offset; /* Offset in memmap (EC_MEMMAP_*) */
+ uint8_t size; /* Size to read in bytes */
+} __packed;
+
+/* Read versions supported for a command */
+#define EC_CMD_GET_CMD_VERSIONS 0x08
+
+struct ec_params_get_cmd_versions {
+ uint8_t cmd; /* Command to check */
+} __packed;
+
+struct ec_response_get_cmd_versions {
+ /*
+ * Mask of supported versions; use EC_VER_MASK() to compare with a
+ * desired version.
+ */
+ uint32_t version_mask;
+} __packed;
+
+/*****************************************************************************/
+/* Flash commands */
+
+/* Get flash info */
+#define EC_CMD_FLASH_INFO 0x10
+
+struct ec_response_flash_info {
+ /* Usable flash size, in bytes */
+ uint32_t flash_size;
+ /*
+ * Write block size. Write offset and size must be a multiple
+ * of this.
+ */
+ uint32_t write_block_size;
+ /*
+ * Erase block size. Erase offset and size must be a multiple
+ * of this.
+ */
+ uint32_t erase_block_size;
+ /*
+ * Protection block size. Protection offset and size must be a
+ * multiple of this.
+ */
+ uint32_t protect_block_size;
+} __packed;
+
+/*
+ * Read flash
+ *
+ * Response is params.size bytes of data.
+ */
+#define EC_CMD_FLASH_READ 0x11
+
+struct ec_params_flash_read {
+ uint32_t offset; /* Byte offset to read */
+ uint32_t size; /* Size to read in bytes */
+} __packed;
+
+/* Write flash */
+#define EC_CMD_FLASH_WRITE 0x12
+
+struct ec_params_flash_write {
+ uint32_t offset; /* Byte offset to write */
+ uint32_t size; /* Size to write in bytes */
+ /*
+ * Data to write. Could really use EC_PARAM_SIZE - 8, but tidiest to
+ * use a power of 2 so writes stay aligned.
+ */
+ uint8_t data[64];
+} __packed;
+
+/* Erase flash */
+#define EC_CMD_FLASH_ERASE 0x13
+
+struct ec_params_flash_erase {
+ uint32_t offset; /* Byte offset to erase */
+ uint32_t size; /* Size to erase in bytes */
+} __packed;
+
+/*
+ * Get/set flash protection.
+ *
+ * If mask!=0, sets/clear the requested bits of flags. Depending on the
+ * firmware write protect GPIO, not all flags will take effect immediately;
+ * some flags require a subsequent hard reset to take effect. Check the
+ * returned flags bits to see what actually happened.
+ *
+ * If mask=0, simply returns the current flags state.
+ */
+#define EC_CMD_FLASH_PROTECT 0x15
+#define EC_VER_FLASH_PROTECT 1 /* Command version 1 */
+
+/* Flags for flash protection */
+/* RO flash code protected when the EC boots */
+#define EC_FLASH_PROTECT_RO_AT_BOOT (1 << 0)
+/*
+ * RO flash code protected now. If this bit is set, at-boot status cannot
+ * be changed.
+ */
+#define EC_FLASH_PROTECT_RO_NOW (1 << 1)
+/* RW flash code protected now, until reboot. */
+#define EC_FLASH_PROTECT_RW_NOW (1 << 2)
+/* Flash write protect GPIO is asserted now */
+#define EC_FLASH_PROTECT_GPIO_ASSERTED (1 << 3)
+/* Error - at least one bank of flash is stuck locked, and cannot be unlocked */
+#define EC_FLASH_PROTECT_ERROR_STUCK (1 << 4)
+/*
+ * Error - flash protection is in inconsistent state. At least one bank of
+ * flash which should be protected is not protected. Usually fixed by
+ * re-requesting the desired flags, or by a hard reset if that fails.
+ */
+#define EC_FLASH_PROTECT_ERROR_INCONSISTENT (1 << 5)
+/* RW flash code protected when the EC boots */
+#define EC_FLASH_PROTECT_RW_AT_BOOT (1 << 6)
+
+struct ec_params_flash_protect {
+ uint32_t mask; /* Bits in flags to apply */
+ uint32_t flags; /* New flags to apply */
+} __packed;
+
+struct ec_response_flash_protect {
+ /* Current value of flash protect flags */
+ uint32_t flags;
+ /*
+ * Flags which are valid on this platform. This allows the caller
+ * to distinguish between flags which aren't set vs. flags which can't
+ * be set on this platform.
+ */
+ uint32_t valid_flags;
+ /* Flags which can be changed given the current protection state */
+ uint32_t writable_flags;
+} __packed;
+
+/*
+ * Note: commands 0x14 - 0x19 version 0 were old commands to get/set flash
+ * write protect. These commands may be reused with version > 0.
+ */
+
+/* Get the region offset/size */
+#define EC_CMD_FLASH_REGION_INFO 0x16
+#define EC_VER_FLASH_REGION_INFO 1
+
+enum ec_flash_region {
+ /* Region which holds read-only EC image */
+ EC_FLASH_REGION_RO,
+ /* Region which holds rewritable EC image */
+ EC_FLASH_REGION_RW,
+ /*
+ * Region which should be write-protected in the factory (a superset of
+ * EC_FLASH_REGION_RO)
+ */
+ EC_FLASH_REGION_WP_RO,
+};
+
+struct ec_params_flash_region_info {
+ uint32_t region; /* enum ec_flash_region */
+} __packed;
+
+struct ec_response_flash_region_info {
+ uint32_t offset;
+ uint32_t size;
+} __packed;
+
+
+/*****************************************************************************/
+/* PWM commands */
+
+/* Get fan target RPM */
+#define EC_CMD_PWM_GET_FAN_TARGET_RPM 0x20
+
+struct ec_response_pwm_get_fan_rpm {
+ uint32_t rpm;
+} __packed;
+
+/* Set target fan RPM */
+#define EC_CMD_PWM_SET_FAN_TARGET_RPM 0x21
+
+struct ec_params_pwm_set_fan_target_rpm {
+ uint32_t rpm;
+} __packed;
+
+/* Get keyboard backlight */
+#define EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT 0x22
+
+struct ec_response_pwm_get_keyboard_backlight {
+ uint8_t percent;
+ uint8_t enabled;
+} __packed;
+
+/* Set keyboard backlight */
+#define EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT 0x23
+
+struct ec_params_pwm_set_keyboard_backlight {
+ uint8_t percent;
+} __packed;
+
+/* Set target fan PWM duty cycle */
+#define EC_CMD_PWM_SET_FAN_DUTY 0x24
+
+struct ec_params_pwm_set_fan_duty {
+ uint32_t percent;
+} __packed;
+
+/*****************************************************************************/
+/*
+ * Lightbar commands. This looks worse than it is. Since we only use one LPC
+ * command to say "talk to the lightbar", we put the "and tell it to do X" part
+ * into a subcommand. We'll make separate structs for subcommands with
+ * different input args, so that we know how much to expect.
+ */
+#define EC_CMD_LIGHTBAR_CMD 0x28
+
+struct ec_params_lightbar_cmd {
+ union {
+ union {
+ uint8_t cmd;
+ struct {
+ uint8_t cmd;
+ } dump, off, on, init, get_seq;
+ struct num {
+ uint8_t cmd;
+ uint8_t num;
+ } brightness, seq;
+
+ struct reg {
+ uint8_t cmd;
+ uint8_t ctrl, reg, value;
+ } reg;
+ struct rgb {
+ uint8_t cmd;
+ uint8_t led, red, green, blue;
+ } rgb;
+ } in;
+ union {
+ struct dump {
+ struct {
+ uint8_t reg;
+ uint8_t ic0;
+ uint8_t ic1;
+ } vals[23];
+ } dump;
+ struct get_seq {
+ uint8_t num;
+ } get_seq;
+ struct {
+ /* no return params */
+ } off, on, init, brightness, seq, reg, rgb;
+ } out;
+ };
+} __packed;
+
+/*****************************************************************************/
+/* Verified boot commands */
+
+/*
+ * Note: command code 0x29 version 0 was VBOOT_CMD in Link EVT; it may be
+ * reused for other purposes with version > 0.
+ */
+
+/* Verified boot hash command */
+#define EC_CMD_VBOOT_HASH 0x2A
+
+struct ec_params_vboot_hash {
+ uint8_t cmd; /* enum ec_vboot_hash_cmd */
+ uint8_t hash_type; /* enum ec_vboot_hash_type */
+ uint8_t nonce_size; /* Nonce size; may be 0 */
+ uint8_t reserved0; /* Reserved; set 0 */
+ uint32_t offset; /* Offset in flash to hash */
+ uint32_t size; /* Number of bytes to hash */
+ uint8_t nonce_data[64]; /* Nonce data; ignored if nonce_size=0 */
+} __packed;
+
+struct ec_response_vboot_hash {
+ uint8_t status; /* enum ec_vboot_hash_status */
+ uint8_t hash_type; /* enum ec_vboot_hash_type */
+ uint8_t digest_size; /* Size of hash digest in bytes */
+ uint8_t reserved0; /* Ignore; will be 0 */
+ uint32_t offset; /* Offset in flash which was hashed */
+ uint32_t size; /* Number of bytes hashed */
+ uint8_t hash_digest[64]; /* Hash digest data */
+} __packed;
+
+enum ec_vboot_hash_cmd {
+ EC_VBOOT_HASH_GET, /* Get current hash status */
+ EC_VBOOT_HASH_ABORT, /* Abort calculating current hash */
+ EC_VBOOT_HASH_START, /* Start computing a new hash */
+ EC_VBOOT_HASH_RECALC, /* Synchronously compute a new hash */
+};
+
+enum ec_vboot_hash_type {
+ EC_VBOOT_HASH_TYPE_SHA256, /* SHA-256 */
+};
+
+enum ec_vboot_hash_status {
+ EC_VBOOT_HASH_STATUS_NONE, /* No hash (not started, or aborted) */
+ EC_VBOOT_HASH_STATUS_DONE, /* Finished computing a hash */
+ EC_VBOOT_HASH_STATUS_BUSY, /* Busy computing a hash */
+};
+
+/*****************************************************************************/
+/* USB charging control commands */
+
+/* Set USB port charging mode */
+#define EC_CMD_USB_CHARGE_SET_MODE 0x30
+
+struct ec_params_usb_charge_set_mode {
+ uint8_t usb_port_id;
+ uint8_t mode;
+} __packed;
+
+/*****************************************************************************/
+/* Persistent storage for host */
+
+/* Maximum bytes that can be read/written in a single command */
+#define EC_PSTORE_SIZE_MAX 64
+
+/* Get persistent storage info */
+#define EC_CMD_PSTORE_INFO 0x40
+
+struct ec_response_pstore_info {
+ /* Persistent storage size, in bytes */
+ uint32_t pstore_size;
+ /* Access size; read/write offset and size must be a multiple of this */
+ uint32_t access_size;
+} __packed;
+
+/*
+ * Read persistent storage
+ *
+ * Response is params.size bytes of data.
+ */
+#define EC_CMD_PSTORE_READ 0x41
+
+struct ec_params_pstore_read {
+ uint32_t offset; /* Byte offset to read */
+ uint32_t size; /* Size to read in bytes */
+} __packed;
+
+/* Write persistent storage */
+#define EC_CMD_PSTORE_WRITE 0x42
+
+struct ec_params_pstore_write {
+ uint32_t offset; /* Byte offset to write */
+ uint32_t size; /* Size to write in bytes */
+ uint8_t data[EC_PSTORE_SIZE_MAX];
+} __packed;
+
+/*****************************************************************************/
+/* Real-time clock */
+
+/* RTC params and response structures */
+struct ec_params_rtc {
+ uint32_t time;
+} __packed;
+
+struct ec_response_rtc {
+ uint32_t time;
+} __packed;
+
+/* These use ec_response_rtc */
+#define EC_CMD_RTC_GET_VALUE 0x44
+#define EC_CMD_RTC_GET_ALARM 0x45
+
+/* These all use ec_params_rtc */
+#define EC_CMD_RTC_SET_VALUE 0x46
+#define EC_CMD_RTC_SET_ALARM 0x47
+
+/*****************************************************************************/
+/* Port80 log access */
+
+/* Get last port80 code from previous boot */
+#define EC_CMD_PORT80_LAST_BOOT 0x48
+
+struct ec_response_port80_last_boot {
+ uint16_t code;
+} __packed;
+
+/*****************************************************************************/
+/* Thermal engine commands */
+
+/* Set thershold value */
+#define EC_CMD_THERMAL_SET_THRESHOLD 0x50
+
+struct ec_params_thermal_set_threshold {
+ uint8_t sensor_type;
+ uint8_t threshold_id;
+ uint16_t value;
+} __packed;
+
+/* Get threshold value */
+#define EC_CMD_THERMAL_GET_THRESHOLD 0x51
+
+struct ec_params_thermal_get_threshold {
+ uint8_t sensor_type;
+ uint8_t threshold_id;
+} __packed;
+
+struct ec_response_thermal_get_threshold {
+ uint16_t value;
+} __packed;
+
+/* Toggle automatic fan control */
+#define EC_CMD_THERMAL_AUTO_FAN_CTRL 0x52
+
+/*****************************************************************************/
+/* MKBP - Matrix KeyBoard Protocol */
+
+/*
+ * Read key state
+ *
+ * Returns raw data for keyboard cols; see ec_response_mkbp_info.cols for
+ * expected response size.
+ */
+#define EC_CMD_MKBP_STATE 0x60
+
+/* Provide information about the matrix : number of rows and columns */
+#define EC_CMD_MKBP_INFO 0x61
+
+struct ec_response_mkbp_info {
+ uint32_t rows;
+ uint32_t cols;
+ uint8_t switches;
+} __packed;
+
+/* Simulate key press */
+#define EC_CMD_MKBP_SIMULATE_KEY 0x62
+
+struct ec_params_mkbp_simulate_key {
+ uint8_t col;
+ uint8_t row;
+ uint8_t pressed;
+} __packed;
+
+/*****************************************************************************/
+/* Temperature sensor commands */
+
+/* Read temperature sensor info */
+#define EC_CMD_TEMP_SENSOR_GET_INFO 0x70
+
+struct ec_params_temp_sensor_get_info {
+ uint8_t id;
+} __packed;
+
+struct ec_response_temp_sensor_get_info {
+ char sensor_name[32];
+ uint8_t sensor_type;
+} __packed;
+
+/*****************************************************************************/
+
+/*
+ * Note: host commands 0x80 - 0x87 are reserved to avoid conflict with ACPI
+ * commands accidentally sent to the wrong interface. See the ACPI section
+ * below.
+ */
+
+/*****************************************************************************/
+/* Host event commands */
+
+/*
+ * Host event mask params and response structures, shared by all of the host
+ * event commands below.
+ */
+struct ec_params_host_event_mask {
+ uint32_t mask;
+} __packed;
+
+struct ec_response_host_event_mask {
+ uint32_t mask;
+} __packed;
+
+/* These all use ec_response_host_event_mask */
+#define EC_CMD_HOST_EVENT_GET_B 0x87
+#define EC_CMD_HOST_EVENT_GET_SMI_MASK 0x88
+#define EC_CMD_HOST_EVENT_GET_SCI_MASK 0x89
+#define EC_CMD_HOST_EVENT_GET_WAKE_MASK 0x8d
+
+/* These all use ec_params_host_event_mask */
+#define EC_CMD_HOST_EVENT_SET_SMI_MASK 0x8a
+#define EC_CMD_HOST_EVENT_SET_SCI_MASK 0x8b
+#define EC_CMD_HOST_EVENT_CLEAR 0x8c
+#define EC_CMD_HOST_EVENT_SET_WAKE_MASK 0x8e
+#define EC_CMD_HOST_EVENT_CLEAR_B 0x8f
+
+/*****************************************************************************/
+/* Switch commands */
+
+/* Enable/disable LCD backlight */
+#define EC_CMD_SWITCH_ENABLE_BKLIGHT 0x90
+
+struct ec_params_switch_enable_backlight {
+ uint8_t enabled;
+} __packed;
+
+/* Enable/disable WLAN/Bluetooth */
+#define EC_CMD_SWITCH_ENABLE_WIRELESS 0x91
+
+struct ec_params_switch_enable_wireless {
+ uint8_t enabled;
+} __packed;
+
+/*****************************************************************************/
+/* GPIO commands. Only available on EC if write protect has been disabled. */
+
+/* Set GPIO output value */
+#define EC_CMD_GPIO_SET 0x92
+
+struct ec_params_gpio_set {
+ char name[32];
+ uint8_t val;
+} __packed;
+
+/* Get GPIO value */
+#define EC_CMD_GPIO_GET 0x93
+
+struct ec_params_gpio_get {
+ char name[32];
+} __packed;
+struct ec_response_gpio_get {
+ uint8_t val;
+} __packed;
+
+/*****************************************************************************/
+/* I2C commands. Only available when flash write protect is unlocked. */
+
+/* Read I2C bus */
+#define EC_CMD_I2C_READ 0x94
+
+struct ec_params_i2c_read {
+ uint16_t addr;
+ uint8_t read_size; /* Either 8 or 16. */
+ uint8_t port;
+ uint8_t offset;
+} __packed;
+struct ec_response_i2c_read {
+ uint16_t data;
+} __packed;
+
+/* Write I2C bus */
+#define EC_CMD_I2C_WRITE 0x95
+
+struct ec_params_i2c_write {
+ uint16_t data;
+ uint16_t addr;
+ uint8_t write_size; /* Either 8 or 16. */
+ uint8_t port;
+ uint8_t offset;
+} __packed;
+
+/*****************************************************************************/
+/* Charge state commands. Only available when flash write protect unlocked. */
+
+/* Force charge state machine to stop in idle mode */
+#define EC_CMD_CHARGE_FORCE_IDLE 0x96
+
+struct ec_params_force_idle {
+ uint8_t enabled;
+} __packed;
+
+/*****************************************************************************/
+/* Console commands. Only available when flash write protect is unlocked. */
+
+/* Snapshot console output buffer for use by EC_CMD_CONSOLE_READ. */
+#define EC_CMD_CONSOLE_SNAPSHOT 0x97
+
+/*
+ * Read next chunk of data from saved snapshot.
+ *
+ * Response is null-terminated string. Empty string, if there is no more
+ * remaining output.
+ */
+#define EC_CMD_CONSOLE_READ 0x98
+
+/*****************************************************************************/
+/* System commands */
+
+/*
+ * TODO: this is a confusing name, since it doesn't necessarily reboot the EC.
+ * Rename to "set image" or something similar.
+ */
+#define EC_CMD_REBOOT_EC 0xd2
+
+/* Command */
+enum ec_reboot_cmd {
+ EC_REBOOT_CANCEL = 0, /* Cancel a pending reboot */
+ EC_REBOOT_JUMP_RO, /* Jump to RO without rebooting */
+ EC_REBOOT_JUMP_RW, /* Jump to RW without rebooting */
+ /* (command 3 was jump to RW-B) */
+ EC_REBOOT_COLD = 4, /* Cold-reboot */
+ EC_REBOOT_DISABLE_JUMP, /* Disable jump until next reboot */
+};
+
+/* Flags for ec_params_reboot_ec.reboot_flags */
+#define EC_REBOOT_FLAG_RESERVED0 (1 << 0) /* Was recovery request */
+#define EC_REBOOT_FLAG_ON_AP_SHUTDOWN (1 << 1)
+#define EC_REBOOT_FLAG_POWER_ON (1 << 2)
+
+struct ec_params_reboot_ec {
+ uint8_t cmd; /* enum ec_reboot_cmd */
+ uint8_t flags; /* See EC_REBOOT_FLAG_* */
+} __packed;
+
+/*****************************************************************************/
+/*
+ * ACPI commands
+ *
+ * These are valid ONLY on the ACPI command/data port.
+ */
+
+/*
+ * ACPI Read Embedded Controller
+ *
+ * This reads from ACPI memory space on the EC (EC_ACPI_MEM_*).
+ *
+ * Use the following sequence:
+ *
+ * - Write EC_CMD_ACPI_READ to EC_LPC_ADDR_ACPI_CMD
+ * - Wait for EC_LPC_CMDR_PENDING bit to clear
+ * - Write address to EC_LPC_ADDR_ACPI_DATA
+ * - Wait for EC_LPC_CMDR_DATA bit to set
+ * - Read value from EC_LPC_ADDR_ACPI_DATA
+ */
+#define EC_CMD_ACPI_READ 0x80
+
+/*
+ * ACPI Write Embedded Controller
+ *
+ * This reads from ACPI memory space on the EC (EC_ACPI_MEM_*).
+ *
+ * Use the following sequence:
+ *
+ * - Write EC_CMD_ACPI_WRITE to EC_LPC_ADDR_ACPI_CMD
+ * - Wait for EC_LPC_CMDR_PENDING bit to clear
+ * - Write address to EC_LPC_ADDR_ACPI_DATA
+ * - Wait for EC_LPC_CMDR_PENDING bit to clear
+ * - Write value to EC_LPC_ADDR_ACPI_DATA
+ */
+#define EC_CMD_ACPI_WRITE 0x81
+
+/*
+ * ACPI Query Embedded Controller
+ *
+ * This clears the lowest-order bit in the currently pending host events, and
+ * sets the result code to the 1-based index of the bit (event 0x00000001 = 1,
+ * event 0x80000000 = 32), or 0 if no event was pending.
+ */
+#define EC_CMD_ACPI_QUERY_EVENT 0x84
+
+/* Valid addresses in ACPI memory space, for read/write commands */
+/* Memory space version; set to EC_ACPI_MEM_VERSION_CURRENT */
+#define EC_ACPI_MEM_VERSION 0x00
+/*
+ * Test location; writing value here updates test compliment byte to (0xff -
+ * value).
+ */
+#define EC_ACPI_MEM_TEST 0x01
+/* Test compliment; writes here are ignored. */
+#define EC_ACPI_MEM_TEST_COMPLIMENT 0x02
+/* Keyboard backlight brightness percent (0 - 100) */
+#define EC_ACPI_MEM_KEYBOARD_BACKLIGHT 0x03
+
+/* Current version of ACPI memory address space */
+#define EC_ACPI_MEM_VERSION_CURRENT 1
+
+
+/*****************************************************************************/
+/*
+ * Special commands
+ *
+ * These do not follow the normal rules for commands. See each command for
+ * details.
+ */
+
+/*
+ * Reboot NOW
+ *
+ * This command will work even when the EC LPC interface is busy, because the
+ * reboot command is processed at interrupt level. Note that when the EC
+ * reboots, the host will reboot too, so there is no response to this command.
+ *
+ * Use EC_CMD_REBOOT_EC to reboot the EC more politely.
+ */
+#define EC_CMD_REBOOT 0xd1 /* Think "die" */
+
+/*
+ * This header byte on a command indicate version 0. Any header byte less
+ * than this means that we are talking to an old EC which doesn't support
+ * versioning. In that case, we assume version 0.
+ *
+ * Header bytes greater than this indicate a later version. For example,
+ * EC_CMD_VERSION0 + 1 means we are using version 1.
+ *
+ * The old EC interface must not use commands 0dc or higher.
+ */
+#define EC_CMD_VERSION0 0xdc
+
+#endif /* !__ACPI__ */
+
+#endif /* __CROS_EC_COMMANDS_H */