[coreboot-gerrit] New patch to review for coreboot: ec: Add support for EC used on Purism Librem laptops

Duncan Laurie (dlaurie@google.com) gerrit at coreboot.org
Sun Jan 17 03:10:42 CET 2016


Duncan Laurie (dlaurie at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13025

-gerrit

commit 7e3d204cfee5b21e771c6c26cf4f85d3c57aea14
Author: Duncan Laurie <dlaurie at google.com>
Date:   Sat Jan 16 17:43:16 2016 -0800

    ec: Add support for EC used on Purism Librem laptops
    
    This adds basic ACPI support for the EC used on Purism Librem laptops.
    The EC firmware appears to use the topstar laptop interface that has
    support in the linux kernel for handling the special keys.
    
    Supported functions:
    - Battery information
    - AC presence
    - Lid switch
    - Special keys (after loading topstar-laptop driver in linux)
    - EC events for turbo enable/disable when on AC power
    
    Things it does not do:
    - EC SMI handling
    - Fan is left under EC control
    
    This was developed and tested on a Librem 13 laptop, and has not
    been directly tested on an Librem 15.
    
    Change-Id: Ib85a24e4cc8ab09b14147060043cff372863c2d1
    Signed-off-by: Duncan Laurie <dlaurie at google.com>
---
 src/ec/purism/librem/Kconfig          |   4 +
 src/ec/purism/librem/acpi/ac.asl      |  30 +++++
 src/ec/purism/librem/acpi/battery.asl | 211 ++++++++++++++++++++++++++++++
 src/ec/purism/librem/acpi/ec.asl      | 233 ++++++++++++++++++++++++++++++++++
 src/ec/purism/librem/chip.h           |  26 ++++
 5 files changed, 504 insertions(+)

diff --git a/src/ec/purism/librem/Kconfig b/src/ec/purism/librem/Kconfig
new file mode 100644
index 0000000..0ea38c6
--- /dev/null
+++ b/src/ec/purism/librem/Kconfig
@@ -0,0 +1,4 @@
+config EC_PURISM_LIBREM
+	bool
+	help
+	  Purism Librem EC
diff --git a/src/ec/purism/librem/acpi/ac.asl b/src/ec/purism/librem/acpi/ac.asl
new file mode 100644
index 0000000..99d17ee
--- /dev/null
+++ b/src/ec/purism/librem/acpi/ac.asl
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Google Inc.
+ *
+ * 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 (AC)
+{
+	Name (_HID, "ACPI0003")
+	Name (_PCL, Package () { \_SB })
+
+	Method (_PSR)
+	{
+		Return (ACEX)
+	}
+
+	Method (_STA)
+	{
+		Return (0x0F)
+	}
+}
diff --git a/src/ec/purism/librem/acpi/battery.asl b/src/ec/purism/librem/acpi/battery.asl
new file mode 100644
index 0000000..a090b7c
--- /dev/null
+++ b/src/ec/purism/librem/acpi/battery.asl
@@ -0,0 +1,211 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Google Inc.
+ *
+ * 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 (BAT)
+{
+	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 */
+		"S10",       /* 0x09: Model Number */
+		"",          /* 0x0a: Serial Number */
+		"LION",      /* 0x0b: Battery Type */
+		"TPS"        /* 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
+		"S10",       // 0x10: Model Number
+		"",          // 0x11: Serial Number
+		"LION",      // 0x12: Battery Type
+		"TPS"        // 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)
+
+	/* Battery Capacity warning at 15% */
+	Name (DWRN, 15)
+
+	/* Battery Capacity low at 10% */
+	Name (DLOW, 10)
+
+	/* 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, , Local2)
+		Store (Local2, Index (PBIF, 5))
+
+		/* Design Capacity of Low */
+		Divide (Multiply (Local0, DLOW), 100, , Local2)
+		Store (Local2, Index (PBIF, 6))
+
+		Return (PBIF)
+	}
+
+	Method (_BIX, 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, , Local2)
+		Store (Local2, Index (PBIX, 6))
+
+		/* Design Capacity of Low */
+		Divide (Multiply (Local0, DLOW), 100, , Local2)
+		Store (Local2, Index (PBIX, 7))
+
+		Return (PBIX)
+	}
+
+	Method (_BST, 0, Serialized)
+	{
+		/*
+		 * 0: BATTERY STATE
+		 *
+		 * bit 0 = discharging
+		 * bit 1 = charging
+		 * bit 2 = critical level
+		 */
+
+		/* Check if AC is present */
+		If (ACEX) {
+			/* Read battery status from EC */
+			Store (BSTS, Local0)
+		} Else {
+			/* Always discharging when on battery power */
+			Store (0x01, Local0)
+		}
+
+		/* Check for critical battery level */
+		If (BFCR) {
+			Or (Local0, 0x04, Local0)
+		}
+		Store (Local0, Index (PBST, 0))
+
+		/* Notify if battery state has changed since last time */
+		If (LNotEqual (Local0, BSTP)) {
+			Store (Local0, BSTP)
+			Notify (BAT, 0x80)
+		}
+
+		/*
+		 * 1: BATTERY PRESENT RATE
+		 */
+		Store (BTPR, Local1)
+		If (And (Local1, 0x8000)) {
+			And (Not (Local1), 0x7FFF, Local0)
+			Increment (Local0)
+		} Else {
+			And (Local1, 0x7FFF, Local0)
+		}
+
+		/*
+		 * 2: BATTERY REMAINING CAPACITY
+		 */
+		Store (BTRA, Local0)
+		If (LAnd (BFWK, LAnd (ACEX, LNot (BSTS)))) {
+			Store (BTDF, Local1)
+
+			/* See if within ~6% of full */
+			ShiftRight (Local1, 4, Local2)
+			If (LAnd (LGreater (Local0, Subtract (Local1, Local2)),
+			          LLess (Local0, Add (Local1, Local2))))
+			{
+				Store (Local1, Local0)
+			}
+		}
+		Store (Local0, Index (PBST, 2))
+
+		/*
+		 * 3: BATTERY PRESENT VOLTAGE
+		 */
+		Store (BTVO, Index (PBST, 3))
+
+		Return (PBST)
+	}
+}
diff --git a/src/ec/purism/librem/acpi/ec.asl b/src/ec/purism/librem/acpi/ec.asl
new file mode 100644
index 0000000..dda9889
--- /dev/null
+++ b/src/ec/purism/librem/acpi/ec.asl
@@ -0,0 +1,233 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Google Inc.
+ *
+ * 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 (TPSD)
+{
+	/*
+	 * TPSACPI01 is not a valid _HID but it is what the linux topstar
+	 * laptop driver expects, use this indirection to let it compile.
+	 */
+	Name (BHID, "TPSACPI01")
+	Method (_HID)
+	{
+		Return (BHID)
+	}
+	Name (_UID, 0)
+
+	Method (FNCX, 1, NotSerialized)
+	{
+		If (LEqual (Arg0, 0x86)) {
+			/* Enable topstar-laptop kernel driver handling */
+			Store (One, ^^EC.TPSE)
+		} ElseIf (LEqual (Arg0, 0x87)) {
+			/* Disable topstar-laptop kernel driver handling */
+			Store (Zero, ^^EC.TPSE)
+		}
+	}
+}
+
+Device (EC)
+{
+	Name (_HID, EisaId ("PNP0C09"))
+	Name (_UID, 0)
+	Name (_GPE, EC_SCI_GPI)
+
+	Name (_CRS, ResourceTemplate () {
+		IO (Decode16, 0x62, 0x62, 0, 1)
+		IO (Decode16, 0x66, 0x66, 0, 1)
+	})
+
+	OperationRegion (ERAM, EmbeddedControl, Zero, 0xFF)
+	Field (ERAM, ByteAcc, Lock, Preserve)
+	{
+		Offset (0x15),
+		BSTS, 2,	/* Battery Status */
+		, 3,
+		BTEX, 1,	/* Battery Present */
+		Offset (0x1D),
+		TPAD, 1,	/* Touchpad Enable/Disable */
+		WIFI, 1,	/* WiFi Enable/Disable */
+		, 2,
+		BTLE, 1,	/* Bluetooth Enable/Disable */
+		Offset (0x25),
+		, 5,
+		TPSE, 1,	/* topstar-laptop driver enable/disable */
+		Offset (0x31),
+		, 6,
+		LIDS, 1,	/* LID Switch */
+		ACEX, 1,	/* AC present */
+		Offset (0x8E),
+		BTDA, 16,	/* Battery Design Capacity */
+		Offset (0x92),
+		BTVO, 16,	/* Battery Present Voltage */
+		Offset (0x98),
+		BTRA, 16,	/* Battery Remaining Capacity */
+		BTDF, 16,	/* Battery Last Full Charge Capacity */
+		Offset (0x9E),
+		, 4,
+		BFCR, 1,	/* Battery Level Critical */
+		Offset (0xA0),
+		BTDV, 16,	/* Battery Design Voltage */
+		Offset (0xA4),
+		BTPR, 16,	/* Battery Present Rate */
+		Offset (0xE6),
+		TURB, 1,	/* EC Requested Turbo Enable/Disable */
+		EDTB, 1,	/* Confirm Turbo Enabled/Disabled */
+	}
+
+	Method (_REG, 2, NotSerialized)
+	{
+		/* Initialize AC power state */
+		Store (ACEX, \PWRS)
+
+		/* Initialize LID switch state */
+		Store (LIDS, \LIDS)
+	}
+
+	/* Notify topstar-laptop kernel driver */
+	Method (TPSN, 1)
+	{
+		If (TPSE) {
+			Notify (^^TPSD, Arg0)
+		}
+	}
+
+	/* KEY_WWW */
+	Method (_Q10)
+	{
+		TPSN (0x8A)
+	}
+
+	/* KEY_MAIL */
+	Method (_Q11)
+	{
+		TPSN (0x8B)
+	}
+
+	/* KEY_MEDIA */
+	Method (_Q12)
+	{
+		TPSN (0x8C)
+	}
+
+	/* AC Status Changed */
+	Method (_Q20)
+	{
+		Store (ACEX, \PWRS)
+		Notify (AC, 0x80)
+		Notify (BAT, 0x80)
+		PNOT ()
+	}
+
+	/* Lid Event */
+	Method (_Q21)
+	{
+		Store (LIDS, \LIDS)
+		Notify (LID0, 0x80)
+	}
+
+	/* Battery Event */
+	Method (_Q22)
+	{
+		Notify (BAT, 0x80)
+	}
+
+	/* KEY_SWITCHVIDEOMODE */
+	Method (_Q25)
+	{
+		TPSN (0x86)
+	}
+
+	/* KEY_BRIGHTNESSUP */
+	Method (_Q28)
+	{
+		TPSN (0x80)
+	}
+
+	/* KEY_BRIGHTNESSDOWN */
+	Method (_Q29)
+	{
+		TPSN (0x81)
+	}
+
+	/* KEY_MUTE */
+	Method (_Q2A)
+	{
+		TPSN (0x85)
+	}
+
+	/* KEY_VOLUMEUP */
+	Method (_Q2B)
+	{
+		TPSN (0x83)
+	}
+
+	/* KEY_VOLUMEDOWN */
+	Method (_Q2C)
+	{
+		TPSN (0x84)
+	}
+
+	/* KEY_SLEEP */
+	Method (_Q2F)
+	{
+		Notify (\_SB.SLPB, 0x80)
+	}
+
+	/* KEY_F13 (Touchpad Enable/Disable)
+	Method (_Q34)
+	{
+		TPSN (0x87)
+		XOr (^TPAD, One, ^TPAD)
+	}
+
+	/* KEY_WLAN */
+	Method (_Q35)
+	{
+		TPSN (0x88)
+		XOr (^WIFI, One, ^WIFI)
+	}
+
+	/* KEY_BLUETOOTH */
+	Method (_Q37)
+	{
+		XOr (^BTLE, One, ^BTLE)
+	}
+
+	/* Turbo Enable/Disable */
+	Method (_Q50)
+	{
+		/*
+		 * Limiting frequency via PPC doesn't do anything if the
+		 * kernel is using intel_pstate instead of ACPI _PPC.
+		 *
+		 * If the state is not updated in EDTB the EC will
+		 * repeatedly send this event several times a second
+		 * when the system is charging.
+		 */
+		If (TURB) {
+			Store (Zero, PPCM)
+			PPCN ()
+			Store (One, EDTB)
+		} Else {
+			Store (One, PPCM)
+			PPCN ()
+			Store (Zero, EDTB)
+		}
+	}
+
+	#include "ac.asl"
+	#include "battery.asl"
+}
diff --git a/src/ec/purism/librem/chip.h b/src/ec/purism/librem/chip.h
new file mode 100644
index 0000000..c8790e2
--- /dev/null
+++ b/src/ec/purism/librem/chip.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Google Inc.
+ *
+ * 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_PURISM_LIBREM_CHIP_H
+#define EC_PURISM_LIBREM_CHIP_H
+
+#include <device/device.h>
+
+extern struct chip_operations ec_purism_librem_ops;
+
+struct ec_purism_librem_config {
+};
+
+#endif /* EC_PURISM_LIBREM_CHIP_H */



More information about the coreboot-gerrit mailing list