summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Reinauer <reinauer@chromium.org>2012-03-30 17:06:43 -0700
committerStefan Reinauer <stefan.reinauer@coreboot.org>2012-04-02 18:42:40 +0200
commit020b22a5c4efd82937706372817fc441c5345d68 (patch)
tree0c076de171bb08ac750ab5dbc45586ba3fee58ce /src
parentb0dd1d91f49eef80016a60bb09e2c1a8cfcc628e (diff)
downloadcoreboot-020b22a5c4efd82937706372817fc441c5345d68.tar.xz
Add EC component for SMSC MEC1308/1310
Change-Id: I92109fb633a1a3090b4b1767dd119b8c8a1b5f81 Signed-off-by: Duncan Laurie <dlaurie@google.com> Signed-off-by: Stefan Reinauer <reinauer@google.com> Reviewed-on: http://review.coreboot.org/828 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/ec/Kconfig1
-rw-r--r--src/ec/Makefile.inc2
-rw-r--r--src/ec/smsc/Kconfig1
-rw-r--r--src/ec/smsc/Makefile.inc1
-rw-r--r--src/ec/smsc/mec1308/Kconfig4
-rw-r--r--src/ec/smsc/mec1308/Makefile.inc2
-rw-r--r--src/ec/smsc/mec1308/acpi/ac.asl38
-rw-r--r--src/ec/smsc/mec1308/acpi/battery.asl196
-rw-r--r--src/ec/smsc/mec1308/acpi/ec.asl272
-rw-r--r--src/ec/smsc/mec1308/chip.h33
-rw-r--r--src/ec/smsc/mec1308/ec.c135
-rw-r--r--src/ec/smsc/mec1308/ec.h41
12 files changed, 725 insertions, 1 deletions
diff --git a/src/ec/Kconfig b/src/ec/Kconfig
index 2a36a328e0..935b40bb05 100644
--- a/src/ec/Kconfig
+++ b/src/ec/Kconfig
@@ -1,2 +1,3 @@
source src/ec/acpi/Kconfig
source src/ec/lenovo/Kconfig
+source src/ec/smsc/Kconfig
diff --git a/src/ec/Makefile.inc b/src/ec/Makefile.inc
index 69d04351a0..b334c1f09d 100644
--- a/src/ec/Makefile.inc
+++ b/src/ec/Makefile.inc
@@ -1,2 +1,2 @@
subdirs-$(CONFIG_EC_ACPI) += acpi
-subdirs-y += lenovo
+subdirs-y += lenovo smsc
diff --git a/src/ec/smsc/Kconfig b/src/ec/smsc/Kconfig
new file mode 100644
index 0000000000..afc6e4b95e
--- /dev/null
+++ b/src/ec/smsc/Kconfig
@@ -0,0 +1 @@
+source src/ec/smsc/mec1308/Kconfig
diff --git a/src/ec/smsc/Makefile.inc b/src/ec/smsc/Makefile.inc
new file mode 100644
index 0000000000..3dd9cce440
--- /dev/null
+++ b/src/ec/smsc/Makefile.inc
@@ -0,0 +1 @@
+subdirs-$(CONFIG_EC_SMSC_MEC1308) += mec1308
diff --git a/src/ec/smsc/mec1308/Kconfig b/src/ec/smsc/mec1308/Kconfig
new file mode 100644
index 0000000000..0a0b04aa39
--- /dev/null
+++ b/src/ec/smsc/mec1308/Kconfig
@@ -0,0 +1,4 @@
+config EC_SMSC_MEC1308
+ bool
+ help
+ Shared memory mailbox interface to SMSC MEC1308 Embedded Controller.
diff --git a/src/ec/smsc/mec1308/Makefile.inc b/src/ec/smsc/mec1308/Makefile.inc
new file mode 100644
index 0000000000..95c6c030d2
--- /dev/null
+++ b/src/ec/smsc/mec1308/Makefile.inc
@@ -0,0 +1,2 @@
+driver-y += ec.c
+smm-y += ec.c
diff --git a/src/ec/smsc/mec1308/acpi/ac.asl b/src/ec/smsc/mec1308/acpi/ac.asl
new file mode 100644
index 0000000000..d14f3a4ae3
--- /dev/null
+++ b/src/ec/smsc/mec1308/acpi/ac.asl
@@ -0,0 +1,38 @@
+/*
+ * 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 (AC)
+{
+ Name (_HID, "ACPI0003")
+ Name (_PCL, Package () { \_SB })
+
+ Method (_PSR)
+ {
+ Return (ACEX)
+ }
+
+ Method (_STA)
+ {
+ Return (0x0F)
+ }
+}
diff --git a/src/ec/smsc/mec1308/acpi/battery.asl b/src/ec/smsc/mec1308/acpi/battery.asl
new file mode 100644
index 0000000000..9b2f93be53
--- /dev/null
+++ b/src/ec/smsc/mec1308/acpi/battery.asl
@@ -0,0 +1,196 @@
+/*
+ * 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
+ */
+
+/*
+ * The mainboard must define strings in the root scope to
+ * report device-specific battery information to the OS.
+ *
+ * BATM: Model
+ * BATS: Serial
+ * BATV: Vendor
+ */
+
+// Scope (EC0)
+
+Device (BAT0)
+{
+ Name (_HID, EISAID ("PNP0C0A"))
+ Name (_UID, 1)
+ Name (_PCL, Package () { \_SB })
+
+ Name (PBIF, Package () {
+ 0x00000001, // Power Unit: mAh
+ 0xFFFFFFFF, // Design Capacity
+ 0xFFFFFFFF, // Last Full Charge Capacity
+ 0x00000001, // Battery Technology: Rechargeable
+ 0xFFFFFFFF, // Design Voltage
+ 0x00000003, // Design Capacity of Warning
+ 0xFFFFFFFF, // Design Capacity of Low
+ 0x00000001, // Capacity Granularity 1
+ 0x00000001, // Capacity Granularity 2
+ "", // Model Number
+ "", // Serial Number
+ "LION", // Battery Type
+ "" // OEM Information
+ })
+
+ Name (PBST, Package () {
+ 0x00000000, // Battery State
+ 0xFFFFFFFF, // Battery Present Rate
+ 0xFFFFFFFF, // Battery Remaining Capacity
+ 0xFFFFFFFF, // 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)
+ }
+
+ // Swap bytes in a word
+ Method (SWAB, 1, NotSerialized)
+ {
+ ShiftRight (Arg0, 8, Local0)
+ ShiftLeft (Arg0, 8, Local1)
+ And (Local1, 0xFF00, Local1)
+ Or (Local0, Local1, Local0)
+ If (LEqual (Local0, 0xFFFF)) {
+ Store (0xFFFFFFFF, Local0)
+ }
+ Return (Local0)
+ }
+
+ Method (_STA, 0, Serialized)
+ {
+ If (BTEX) {
+ Return (0x1F)
+ } Else {
+ Return (0x0F)
+ }
+ }
+
+ Method (_BIF, 0, Serialized)
+ {
+ // Update fields from EC
+ Store (SWAB (BTDA), Index (PBIF, 1))
+ Store (SWAB (BTDF), Index (PBIF, 2))
+ Store (SWAB (BTDV), Index (PBIF, 4))
+ Store (SWAB (BTDL), Index (PBIF, 6))
+
+ // Get battery info from mainboard
+ Store (\BATM, Index (PBIF, 9))
+ Store (\BATS, Index (PBIF, 10))
+ Store (\BATV, Index (PBIF, 12))
+
+ Return (PBIF)
+ }
+
+ Method (_BST, 0, Serialized)
+ {
+ //
+ // 0: BATTERY STATE
+ //
+ // bit 0 = discharging
+ // bit 1 = charging
+ // bit 2 = critical level
+ //
+
+ // Get battery state from EC
+ Store (BTST, Local0)
+ Store (Zero, Local1)
+
+ // Check if AC is present
+ If (ACEX) {
+ // Set only charging/discharging bits
+ And (Local0, 0x03, Local1)
+ } Else {
+ // Always discharging when on battery power
+ Store (0x01, Local1)
+ }
+
+ // Flag if the battery level is critical
+ And (Local0, 0x04, Local4)
+ Or (Local1, Local4, 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 (SWAB (BTPR), Local1)
+ If (LAnd (LNotEqual (Local1, 0xFFFFFFFF),
+ LGreaterEqual (Local1, 0x8000))) {
+ Xor (Local1, 0xFFFF, Local1)
+ Increment (Local1)
+ }
+ Store (Local1, Index (PBST, 1))
+
+ //
+ // 2: BATTERY REMAINING CAPACITY
+ //
+ Store (SWAB (BTRA), Local1)
+ If (LAnd (LNotEqual (Local1, 0xFFFFFFFF),
+ LGreaterEqual (Local1, 0x8000))) {
+ Xor (Local1, 0xFFFF, Local1)
+ Increment (Local1)
+ }
+
+ If (LAnd (BFWK, LAnd (ACEX, LNot (Local0)))) {
+ // 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 (SWAB (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 (SWAB (BTVO), Index (PBST, 3))
+
+ Return (PBST)
+ }
+}
diff --git a/src/ec/smsc/mec1308/acpi/ec.asl b/src/ec/smsc/mec1308/acpi/ec.asl
new file mode 100644
index 0000000000..f0b77c25e5
--- /dev/null
+++ b/src/ec/smsc/mec1308/acpi/ec.asl
@@ -0,0 +1,272 @@
+/*
+ * 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
+ */
+
+/*
+ * 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, EC_GPE) // GPE for Runtime SCI
+
+ OperationRegion (ERAM, EmbeddedControl, 0x00, 0xff)
+ Field (ERAM, ByteAcc, Lock, Preserve)
+ {
+ Offset (0x80),
+ BTEX, 1, // Battery Exists
+ , 1,
+ ACEX, 1, // AC Exists
+ , 5,
+ Offset (0x83),
+ LIDS, 1, // Lid Switch State
+ , 7,
+ BTST, 8, // Battery State
+ Offset (0xA2),
+ BTRA, 16, // Battery Remaining Capacity
+ BTPR, 16, // Battery Present Rate
+ BTVO, 16, // Battery Present Voltage
+ Offset (0xB0),
+ BTDA, 16, // Battery Design Capacity
+ BTDF, 16, // Battery Last Full Charge Capacity
+ BTDV, 16, // Battery Design Voltage
+ BTDL, 16, // Battery Design Low
+ Offset (0xC0),
+ CPUT, 8, // CPU Temperature
+ Offset (0xCA),
+ FSL0, 1, // Fan Speed Level 0
+ FSL1, 1, // Fan Speed Level 1
+ FSL2, 1, // Fan Speed Level 2
+ FSL3, 1, // Fan Speed Level 3
+ FSL4, 1, // Fan Speed Level 4
+ , 2,
+ FCOS, 1, // Fan Speed OS Control
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (ECMD, ResourceTemplate()
+ {
+ IO (Decode16, 0x62, 0x62, 0, 1)
+ IO (Decode16, 0x66, 0x66, 0, 1)
+ })
+ Return (ECMD)
+ }
+
+ Method (_REG, 2, NotSerialized)
+ {
+ // Initialize AC power state
+ Store (ACEX, \PWRS)
+
+ // Initialize LID switch state
+ Store (LIDS, \LIDS)
+
+ // Enable OS control of fan speed
+ Store (One, FCOS)
+
+ // Force a read of CPU temperature
+ Store (CPUT, Local0)
+ }
+
+ PowerResource (FNP0, 0, 0)
+ {
+ Method (_STA) { Return (FSL0) }
+ Method (_ON) {
+ If (FCOS) {
+ Store (One, FSL0)
+ Store (0, \FLVL)
+ Notify (\_TZ.THRM, 0x81)
+ }
+ }
+ Method (_OFF) {
+ If (FCOS) {
+ Store (Zero, FSL0)
+ Store (1, \FLVL)
+ Notify (\_TZ.THRM, 0x81)
+ }
+ }
+ }
+
+ PowerResource (FNP1, 0, 0)
+ {
+ Method (_STA) { Return (FSL1) }
+ Method (_ON) {
+ If (FCOS) {
+ Store (One, FSL1)
+ Store (1, \FLVL)
+ Notify (\_TZ.THRM, 0x81)
+ }
+ }
+ Method (_OFF) {
+ If (FCOS) {
+ Store (Zero, FSL1)
+ Store (2, \FLVL)
+ Notify (\_TZ.THRM, 0x81)
+ }
+ }
+ }
+
+ PowerResource (FNP2, 0, 0)
+ {
+ Method (_STA) { Return (FSL2) }
+ Method (_ON) {
+ If (FCOS) {
+ Store (One, FSL2)
+ Store (2, \FLVL)
+ Notify (\_TZ.THRM, 0x81)
+ }
+ }
+ Method (_OFF) {
+ If (FCOS) {
+ Store (Zero, FSL2)
+ Store (3, \FLVL)
+ Notify (\_TZ.THRM, 0x81)
+ }
+ }
+ }
+
+ PowerResource (FNP3, 0, 0)
+ {
+ Method (_STA) { Return (FSL3) }
+ Method (_ON) {
+ If (FCOS) {
+ Store (One, FSL3)
+ Store (3, \FLVL)
+ Notify (\_TZ.THRM, 0x81)
+ }
+ }
+ Method (_OFF) {
+ If (FCOS) {
+ Store (Zero, FSL3)
+ Store (4, \FLVL)
+ Notify (\_TZ.THRM, 0x81)
+ }
+ }
+ }
+
+ PowerResource (FNP4, 0, 0)
+ {
+ Method (_STA) { Return (FSL4) }
+ Method (_ON) {
+ If (FCOS) {
+ Store (One, FSL4)
+ Store (4, \FLVL)
+ Notify (\_TZ.THRM, 0x81)
+ }
+ }
+ Method (_OFF) {
+ If (FCOS) {
+ Store (Zero, FSL4)
+ Store (5, \FLVL)
+ Notify (\_TZ.THRM, 0x81)
+ }
+ }
+ }
+
+ Device (FAN0)
+ {
+ Name (_HID, EISAID ("PNP0C0B"))
+ Name (_UID, 0)
+ Name (_PR0, Package () { FNP0 })
+ }
+
+ Device (FAN1)
+ {
+ Name (_HID, EISAID ("PNP0C0B"))
+ Name (_UID, 1)
+ Name (_PR0, Package () { FNP1 })
+ }
+
+ Device (FAN2)
+ {
+ Name (_HID, EISAID ("PNP0C0B"))
+ Name (_UID, 2)
+ Name (_PR0, Package () { FNP2 })
+ }
+
+ Device (FAN3)
+ {
+ Name (_HID, EISAID ("PNP0C0B"))
+ Name (_UID, 3)
+ Name (_PR0, Package () { FNP3 })
+ }
+
+ Device (FAN4)
+ {
+ Name (_HID, EISAID ("PNP0C0B"))
+ Name (_UID, 4)
+ Name (_PR0, Package () { FNP4 })
+ }
+
+ // AC Power Connected
+ Method (_Q51, 0, NotSerialized)
+ {
+ Store (One, \PWRS)
+ Notify (AC, 0x80)
+ \PNOT ()
+ }
+
+ // AC Power Removed
+ Method (_Q52, 0, NotSerialized)
+ {
+ Store (Zero, \PWRS)
+ Notify (AC, 0x80)
+ \PNOT ()
+ }
+
+ // Battery State Change
+ Method (_Q53, 0, NotSerialized)
+ {
+ Notify (BAT0, 0x80)
+ Notify (BAT0, 0x81)
+ }
+
+ // Battery State Change
+ Method (_Q54, 0, NotSerialized)
+ {
+ Notify (BAT0, 0x80)
+ Notify (BAT0, 0x81)
+ }
+
+ // Power State Change
+ Method (_Q55, 0, NotSerialized)
+ {
+ \PNOT ()
+ }
+
+ // Lid Switch Event
+ Method (_Q5E, 0, NotSerialized)
+ {
+ Store (LIDS, \LIDS)
+ Notify (\_SB.LID0, 0x80)
+ }
+
+ // Lid Switch Event
+ Method (_Q5F, 0, NotSerialized)
+ {
+ Store (LIDS, \LIDS)
+ Notify (\_SB.LID0, 0x80)
+ }
+
+ #include "ac.asl"
+ #include "battery.asl"
+}
diff --git a/src/ec/smsc/mec1308/chip.h b/src/ec/smsc/mec1308/chip.h
new file mode 100644
index 0000000000..3a8eae8f8a
--- /dev/null
+++ b/src/ec/smsc/mec1308/chip.h
@@ -0,0 +1,33 @@
+/*
+ * 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
+ */
+
+#ifndef _EC_SMSC_MEC1308_CHIP_H
+#define _EC_SMSC_MEC1308_CHIP_H
+
+struct ec_smsc_mec1308_config
+{
+ u16 mailbox_port;
+};
+
+struct chip_operations;
+extern struct chip_operations ec_smsc_mec1308_ops;
+
+#endif /* _EC_SMSC_MEC1308_CHIP_H */
diff --git a/src/ec/smsc/mec1308/ec.c b/src/ec/smsc/mec1308/ec.c
new file mode 100644
index 0000000000..bfd3c14bca
--- /dev/null
+++ b/src/ec/smsc/mec1308/ec.c
@@ -0,0 +1,135 @@
+/*
+ * 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
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "ec.h"
+#include "chip.h"
+
+static u16 ec_cmd_reg = 0;
+static u16 ec_data_reg = 0;
+
+static inline u8 __ec_read(u8 addr)
+{
+ outb(addr, ec_cmd_reg);
+ return inb(ec_data_reg);
+}
+
+static inline void __ec_write(u8 addr, u8 data)
+{
+ outb(addr, ec_cmd_reg);
+ outb(data, ec_data_reg);
+}
+
+static int ec_ready(void)
+{
+ u16 timeout = EC_TIMEOUT;
+
+ if (!ec_cmd_reg || !ec_data_reg) {
+ printk(BIOS_DEBUG, "Invalid ports: cmd=0x%x data=0x%x\n",
+ ec_cmd_reg, ec_data_reg);
+ return -1;
+ }
+
+ while (__ec_read(EC_MAILBOX_COMMAND) != 0 && --timeout) {
+ udelay(10);
+ if ((timeout & 0xff) == 0)
+ printk(BIOS_SPEW, ".");
+ }
+ if (!timeout) {
+ printk(BIOS_DEBUG, "Timeout waiting for EC to be ready.\n");
+ return -1;
+ }
+ return 0;
+}
+
+int send_ec_command(u8 command)
+{
+ if (ec_ready() < 0)
+ return -1;
+ __ec_write(EC_MAILBOX_COMMAND, command);
+ return ec_ready();
+}
+
+int send_ec_command_data(u8 command, u8 data)
+{
+ if (ec_ready() < 0)
+ return -1;
+ __ec_write(EC_MAILBOX_DATA, data);
+ __ec_write(EC_MAILBOX_COMMAND, command);
+ return ec_ready();
+}
+
+u8 read_ec_command_byte(u8 command)
+{
+ send_ec_command(command);
+ return __ec_read(EC_MAILBOX_DATA);
+}
+
+u8 ec_read(u8 addr)
+{
+ if (send_ec_command_data(EC_RAM_READ, addr) < 0)
+ return 0;
+ return __ec_read(EC_MAILBOX_DATA);
+}
+
+int ec_write(u8 addr, u8 data)
+{
+ if (ec_ready() < 0)
+ return -1;
+ __ec_write(EC_MAILBOX_DATA, addr);
+ __ec_write(EC_MAILBOX_DATA_H, data);
+ __ec_write(EC_MAILBOX_COMMAND, EC_RAM_WRITE);
+ return ec_ready();
+}
+
+void ec_set_bit(u8 addr, u8 bit)
+{
+ ec_write(addr, ec_read(addr) | (1 << bit));
+}
+
+void ec_clr_bit(u8 addr, u8 bit)
+{
+ ec_write(addr, ec_read(addr) & ~(1 << bit));
+}
+
+void ec_set_ports(u16 cmd_reg, u16 data_reg)
+{
+ ec_cmd_reg = cmd_reg;
+ ec_data_reg = data_reg;
+}
+
+static void mec1308_enable(device_t dev)
+{
+ struct ec_smsc_mec1308_config *conf = dev->chip_info;
+
+ if (conf->mailbox_port) {
+ ec_cmd_reg = conf->mailbox_port;
+ ec_data_reg = conf->mailbox_port + 1;
+ }
+}
+
+struct chip_operations ec_smsc_mec1308_ops = {
+ CHIP_NAME("SMSC MEC1308 EC Mailbox Interface")
+ .enable_dev = mec1308_enable
+};
diff --git a/src/ec/smsc/mec1308/ec.h b/src/ec/smsc/mec1308/ec.h
new file mode 100644
index 0000000000..07bfc4f786
--- /dev/null
+++ b/src/ec/smsc/mec1308/ec.h
@@ -0,0 +1,41 @@
+/*
+ * 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
+ *
+ * Mailbox EC communication interface for SMSC MEC1308 Embedded Controller.
+ */
+
+#ifndef _EC_SMSC_MEC1308_EC_H
+#define _EC_SMSC_MEC1308_EC_H
+
+#define EC_TIMEOUT 0xfff
+#define EC_MAILBOX_COMMAND 0x82 // Send a command
+#define EC_MAILBOX_DATA 0x84 // Send data with a command
+#define EC_MAILBOX_DATA_H 0x85 // Send data with a command
+#define EC_RAM_READ 0x88 // Read from RAM
+#define EC_RAM_WRITE 0x89 // Write to RAM
+
+int send_ec_command(u8 command);
+int send_ec_command_data(u8 command, u8 data);
+u8 read_ec_command_byte(u8 command);
+u8 ec_read(u8 addr);
+int ec_write(u8 addr, u8 data);
+void ec_set_bit(u8 addr, u8 bit);
+void ec_clr_bit(u8 addr, u8 bit);
+void ec_set_ports(u16 cmd_reg, u16 data_reg);
+
+#endif /* _EC_SMSC_MEC1308_EC_H */