Edward O'Callaghan submitted this change.
Add MEC1308 EC programmer
Initial support of Microchip MEC1308 Embedded Controller.
BUG=b:156144893
BRANCH=none
Signed-off-by: Victor Ding <victording@google.com>
Change-Id: I2d51b4bdc0b38b6e488e71b9e774eb6232a2069e
Reviewed-on: https://review.coreboot.org/c/flashrom/+/44541
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
---
M Makefile
M flashrom.c
A mec1308.c
M meson.build
M meson_options.txt
M programmer.h
6 files changed, 572 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
index 85b4850..f3f7717 100644
--- a/Makefile
+++ b/Makefile
@@ -180,6 +180,11 @@
else
override CONFIG_FT2232_SPI = no
endif
+ifeq ($(CONFIG_MEC1308), yes)
+UNSUPPORTED_FEATURES += CONFIG_MEC1308=yes
+else
+override CONFIG_MEC1308 = no
+endif
ifeq ($(CONFIG_USBBLASTER_SPI), yes)
UNSUPPORTED_FEATURES += CONFIG_USBBLASTER_SPI=yes
else
@@ -291,6 +296,11 @@
else
override CONFIG_DRKAISER = no
endif
+ifeq ($(CONFIG_MEC1308), yes)
+UNSUPPORTED_FEATURES += CONFIG_MEC1308=yes
+else
+override CONFIG_MEC1308 = no
+endif
ifeq ($(CONFIG_NICREALTEK), yes)
UNSUPPORTED_FEATURES += CONFIG_NICREALTEK=yes
else
@@ -401,6 +411,11 @@
else
override CONFIG_FT2232_SPI = no
endif
+ifeq ($(CONFIG_MEC1308), yes)
+UNSUPPORTED_FEATURES += CONFIG_MEC1308=yes
+else
+override CONFIG_MEC1308 = no
+endif
ifeq ($(CONFIG_USBBLASTER_SPI), yes)
UNSUPPORTED_FEATURES += CONFIG_USBBLASTER_SPI=yes
else
@@ -692,6 +707,9 @@
# Always enable FT2232 SPI dongles for now.
CONFIG_FT2232_SPI ?= yes
+# Microchip MEC1308 Embedded Controller
+CONFIG_MEC1308 ?= yes
+
# Always enable Altera USB-Blaster dongles for now.
CONFIG_USBBLASTER_SPI ?= yes
@@ -878,6 +896,11 @@
PROGRAMMER_OBJS += ene_lpc.o
endif
+ifeq ($(CONFIG_MEC1308), yes)
+FEATURE_CFLAGS += -D'CONFIG_MEC1308=1'
+PROGRAMMER_OBJS += mec1308.o
+endif
+
ifeq ($(CONFIG_SERPROG), yes)
FEATURE_CFLAGS += -D'CONFIG_SERPROG=1'
PROGRAMMER_OBJS += serprog.o
diff --git a/flashrom.c b/flashrom.c
index 35ac6f5..c18a04f 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -84,6 +84,18 @@
},
#endif
+#if CONFIG_MEC1308 == 1
+ {
+ .name = "mec1308",
+ .type = OTHER,
+ .devs.note = "Microchip MEC1308 Embedded Controller.\n",
+ .init = mec1308_init,
+ .map_flash_region = fallback_map,
+ .unmap_flash_region = fallback_unmap,
+ .delay = internal_delay,
+ },
+#endif
+
#if CONFIG_NIC3COM == 1
{
.name = "nic3com",
diff --git a/mec1308.c b/mec1308.c
new file mode 100644
index 0000000..c4b34f5
--- /dev/null
+++ b/mec1308.c
@@ -0,0 +1,523 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2010-2020, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+#if defined(__i386__) || defined(__x86_64__)
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "flash.h"
+#include "hwaccess.h"
+#include "chipdrivers.h"
+#include "programmer.h"
+#include "spi.h"
+
+#define MEC1308_SIO_PORT1 0x2e
+#define MEC1308_SIO_PORT2 0x4e
+#define MEC1308_SIO_ENTRY_KEY 0x55
+#define MEC1308_SIO_EXIT_KEY 0xaa
+
+#define MEC1308_SIOCFG_LDN 0x07 /* LDN Bank Selector */
+#define MEC1308_DEVICE_ID_REG 0x20 /* Device ID Register */
+#define MEC1308_DEVICE_ID_VAL 0x4d /* Device ID Value for MEC1308 */
+#define MEC1310_DEVICE_ID_VAL 0x04 /* Device ID Value for MEC1310 */
+#define MEC1308_DEVICE_REV 0x21 /* Device Revision ID Register */
+
+#define MEC1308_MBX_CMD 0x82 /* mailbox command register offset */
+#define MEC1308_MBX_EXT_CMD 0x83 /* mailbox ext. command reg offset */
+#define MEC1308_MBX_DATA_START 0x84 /* first mailbox data register offset */
+#define MEC1308_MBX_DATA_END 0x91 /* last mailbox data register offset */
+
+static unsigned int mbx_data; /* Mailbox register interface data address*/
+
+/*
+ * These command codes depend on EC firmware. The ones listed below are input
+ * using the mailbox interface, though others may be input using the ACPI
+ * interface. Some commands also have an output value (ie pass/failure code)
+ * which EC writes to the mailbox command register after completion.
+ */
+#define MEC1308_CMD_SMI_ENABLE 0x84
+#define MEC1308_CMD_SMI_DISABLE 0x85
+#define MEC1308_CMD_ACPI_ENABLE 0x86
+#define MEC1308_CMD_ACPI_DISABLE 0x87
+
+/*
+ * Passthru commands are also input using the mailbox interface. Passthru mode
+ * enter/start/end commands are special since they require a command word to
+ * be written to the data registers. Other passthru commands are performed
+ * after passthru mode has been started.
+ *
+ * Multiple passthru mode commands may be issued before ending passthru mode.
+ * You do not need to enter, start, and end passthru mode for each SPI
+ * command. However, other mailbox commands might not work when passthru mode
+ * is enabled. For example, you may read all SPI chip content while in passthru
+ * mode, but you should exit passthru mode before performing other EC commands
+ * such as reading fan speed.
+ */
+#define MEC1308_CMD_PASSTHRU 0x55 /* force EC to process word */
+#define MEC1308_CMD_PASSTHRU_SUCCESS 0xaa /* success code for passthru */
+#define MEC1308_CMD_PASSTHRU_FAIL 0xfe /* failure code for passthru */
+#define MEC1308_CMD_PASSTHRU_ENTER "PathThruMode" /* not a typo... */
+#define MEC1308_CMD_PASSTHRU_START "Start"
+#define MEC1308_CMD_PASSTHRU_EXIT "End_Mode"
+#define MEC1308_CMD_PASSTHRU_CS_EN 0xf0 /* chip-select enable */
+#define MEC1308_CMD_PASSTHRU_CS_DIS 0xf1 /* chip-select disable */
+#define MEC1308_CMD_PASSTHRU_SEND 0xf2 /* send byte from data0 */
+#define MEC1308_CMD_PASSTHRU_READ 0xf3 /* read byte, place in data0 */
+
+typedef struct
+{
+ unsigned int in_sio_cfgmode;
+ unsigned int mbx_idx; /* Mailbox register interface index address */
+ unsigned int mbx_data; /* Mailbox register interface data address*/
+} mec1308_data_t;
+
+static void mec1308_sio_enter(mec1308_data_t *ctx_data, uint16_t port)
+{
+ if (ctx_data->in_sio_cfgmode)
+ return;
+
+ OUTB(MEC1308_SIO_ENTRY_KEY, port);
+ ctx_data->in_sio_cfgmode = 1;
+}
+
+static void mec1308_sio_exit(mec1308_data_t *ctx_data, uint16_t port)
+{
+ if (!ctx_data->in_sio_cfgmode)
+ return;
+
+ OUTB(MEC1308_SIO_EXIT_KEY, port);
+ ctx_data->in_sio_cfgmode = 0;
+}
+
+/** probe for super i/o index
+ * @port: allocated buffer to store port
+ *
+ * returns 0 to indicate success, <0 to indicate error
+ */
+static int mec1308_get_sio_index(mec1308_data_t *ctx_data, uint16_t *port)
+{
+ uint16_t ports[] = { MEC1308_SIO_PORT1,
+ MEC1308_SIO_PORT2,
+ };
+ size_t i;
+ static uint16_t port_internal, port_found = 0;
+
+ if (port_found) {
+ *port = port_internal;
+ return 0;
+ }
+
+ if (rget_io_perms())
+ return -1;
+
+ for (i = 0; i < ARRAY_SIZE(ports); i++) {
+ uint8_t tmp8;
+
+ /*
+ * Only after config mode has been successfully entered will the
+ * index port will read back the last value written to it.
+ * So we will attempt to enter config mode, set the index
+ * register, and see if the index register retains the value.
+ *
+ * Note: It seems to work "best" when using a device ID register
+ * as the index and reading from the data port before reading
+ * the index port.
+ */
+ mec1308_sio_enter(ctx_data, ports[i]);
+ OUTB(MEC1308_DEVICE_ID_REG, ports[i]);
+ tmp8 = INB(ports[i] + 1);
+ tmp8 = INB(ports[i]);
+ if ((tmp8 != MEC1308_DEVICE_ID_REG)) {
+ ctx_data->in_sio_cfgmode = 0;
+ continue;
+ }
+
+ port_internal = ports[i];
+ port_found = 1;
+ break;
+ }
+
+ if (!port_found) {
+ msg_cdbg("\nfailed to obtain super i/o index\n");
+ return -1;
+ }
+
+ msg_cdbg("\nsuper i/o index = 0x%04x\n", port_internal);
+ *port = port_internal;
+ return 0;
+}
+
+static uint8_t mbx_read(mec1308_data_t *ctx_data, uint8_t idx)
+{
+ OUTB(idx, ctx_data->mbx_idx);
+ return INB(mbx_data);
+}
+
+static int mbx_wait(mec1308_data_t *ctx_data)
+{
+ int i;
+ int max_attempts = 10000;
+ int rc = 0;
+
+ for (i = 0; mbx_read(ctx_data, MEC1308_MBX_CMD); i++) {
+ if (i == max_attempts) {
+ rc = 1;
+ break;
+ }
+ /* FIXME: This delay adds determinism to the delay period. It
+ was chosen arbitrarily thru some experiments. */
+ programmer_delay(2);
+ }
+
+ return rc;
+}
+
+static int mbx_write(mec1308_data_t *ctx_data, uint8_t idx, uint8_t data)
+{
+ int rc = 0;
+
+ if (idx == MEC1308_MBX_CMD && mbx_wait(ctx_data)) {
+ msg_perr("%s: command register not clear\n", __func__);
+ return 1;
+ }
+
+ OUTB(idx, ctx_data->mbx_idx);
+ OUTB(data, mbx_data);
+
+ if (idx == MEC1308_MBX_CMD)
+ rc = mbx_wait(ctx_data);
+
+ return rc;
+}
+
+static void mbx_clear(mec1308_data_t *ctx_data)
+{
+ int reg;
+
+ for (reg = MEC1308_MBX_DATA_START; reg < MEC1308_MBX_DATA_END; reg++)
+ mbx_write(ctx_data, reg, 0x00);
+ mbx_write(ctx_data, MEC1308_MBX_CMD, 0x00);
+}
+
+static int mec1308_exit_passthru_mode(mec1308_data_t *ctx_data)
+{
+ uint8_t tmp8;
+ size_t i;
+
+ /* exit passthru mode */
+ for (i = 0; i < strlen(MEC1308_CMD_PASSTHRU_EXIT); i++) {
+ mbx_write(ctx_data, MEC1308_MBX_DATA_START + i,
+ MEC1308_CMD_PASSTHRU_EXIT[i]);
+ }
+
+ if (mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU)) {
+ msg_pdbg("%s(): exit passthru command timed out\n", __func__);
+ return 1;
+ }
+
+ tmp8 = mbx_read(ctx_data, MEC1308_MBX_DATA_START);
+ msg_pdbg("%s: result: 0x%02x ", __func__, tmp8);
+ if (tmp8 == MEC1308_CMD_PASSTHRU_SUCCESS) {
+ msg_pdbg("(exited passthru mode)\n");
+ } else if (tmp8 == MEC1308_CMD_PASSTHRU_FAIL) {
+ msg_pdbg("(failed to exit passthru mode)\n");
+ }
+
+ return 0;
+}
+
+static int enter_passthru_mode(mec1308_data_t *ctx_data)
+{
+ uint8_t tmp8;
+ size_t i;
+
+ /*
+ * Enter passthru mode. If the EC does not successfully enter passthru
+ * mode the first time, we'll clear the mailbox and issue the "exit
+ * passthru mode" command sequence up to 3 times or until it arrives in
+ * a known state.
+ *
+ * Note: This workaround was developed experimentally.
+ */
+ for (i = 0; i < 3; i++) {
+ size_t j;
+
+ msg_pdbg("%s(): entering passthru mode, attempt %d out of 3\n",
+ __func__, (int)(i + 1));
+ for (j = 0; j < strlen(MEC1308_CMD_PASSTHRU_ENTER); j++) {
+ mbx_write(ctx_data, MEC1308_MBX_DATA_START + j,
+ MEC1308_CMD_PASSTHRU_ENTER[j]);
+ }
+
+ if (mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU))
+ msg_pdbg("%s(): enter passthru command timed out\n",
+ __func__);
+
+ tmp8 = mbx_read(ctx_data, MEC1308_MBX_DATA_START);
+ if (tmp8 == MEC1308_CMD_PASSTHRU_SUCCESS)
+ break;
+
+ msg_pdbg("%s(): command failed, clearing data registers and "
+ "issuing full exit passthru command...\n", __func__);
+ mbx_clear(ctx_data);
+ mec1308_exit_passthru_mode(ctx_data);
+ }
+
+ if (tmp8 != MEC1308_CMD_PASSTHRU_SUCCESS) {
+ msg_perr("%s(): failed to enter passthru mode, result=0x%02x\n",
+ __func__, tmp8);
+ return 1;
+ }
+
+ msg_pdbg("%s(): enter passthru mode return code: 0x%02x\n",
+ __func__, tmp8);
+
+ /* start passthru mode */
+ for (i = 0; i < strlen(MEC1308_CMD_PASSTHRU_START); i++)
+ mbx_write(ctx_data, MEC1308_MBX_DATA_START + i,
+ MEC1308_CMD_PASSTHRU_START[i]);
+ if (mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU)) {
+ msg_pdbg("%s(): start passthru command timed out\n", __func__);
+ return 1;
+ }
+ tmp8 = mbx_read(ctx_data, MEC1308_MBX_DATA_START);
+ if (tmp8 != MEC1308_CMD_PASSTHRU_SUCCESS) {
+ msg_perr("%s(): failed to enter passthru mode, result=%02x\n",
+ __func__, tmp8);
+ return 1;
+ }
+ msg_pdbg("%s(): start passthru mode return code: 0x%02x\n",
+ __func__, tmp8);
+
+ return 0;
+}
+
+static int mec1308_shutdown(void *data)
+{
+ mec1308_data_t *ctx_data = (mec1308_data_t *)data;
+
+ /* Exit passthru mode before performing commands which do not affect
+ the SPI ROM */
+ mec1308_exit_passthru_mode(ctx_data);
+
+ /* Re-enable SMI and ACPI.
+ FIXME: is there an ordering dependency? */
+ if (mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_SMI_ENABLE))
+ msg_pdbg("%s: unable to re-enable SMI\n", __func__);
+ if (mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_ACPI_ENABLE))
+ msg_pdbg("%s: unable to re-enable ACPI\n", __func__);
+
+ free(data);
+ return 0;
+}
+
+static int mec1308_chip_select(mec1308_data_t *ctx_data)
+{
+ return mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU_CS_EN);
+}
+
+static int mec1308_chip_deselect(mec1308_data_t *ctx_data)
+{
+ return mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU_CS_DIS);
+}
+
+/*
+ * MEC1308 will not allow direct access to SPI chip from host if EC is
+ * connected to LPC bus. This function will forward commands issued thru
+ * mailbox interface to the SPI flash chip.
+ */
+static int mec1308_spi_send_command(const struct flashctx *flash, unsigned int writecnt,
+ unsigned int readcnt,
+ const unsigned char *writearr,
+ unsigned char *readarr)
+{
+ int rc = 0;
+ size_t i;
+ mec1308_data_t *ctx_data = (mec1308_data_t *)flash->mst->spi.data;
+
+ if (mec1308_chip_select(ctx_data))
+ return 1;
+
+ for (i = 0; i < writecnt; i++) {
+ if (mbx_write(ctx_data, MEC1308_MBX_DATA_START, writearr[i]) ||
+ mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU_SEND)) {
+ msg_pdbg("%s: failed to issue send command\n",__func__);
+ rc = 1;
+ goto mec1308_spi_send_command_exit;
+ }
+ }
+
+ for (i = 0; i < readcnt; i++) {
+ if (mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_PASSTHRU_READ)) {
+ msg_pdbg("%s: failed to issue read command\n",__func__);
+ rc = 1;
+ goto mec1308_spi_send_command_exit;
+ }
+ readarr[i] = mbx_read(ctx_data, MEC1308_MBX_DATA_START);
+ }
+
+mec1308_spi_send_command_exit:
+ rc |= mec1308_chip_deselect(ctx_data);
+ return rc;
+}
+
+static struct spi_master spi_master_mec1308 = {
+ .max_data_read = 256, /* FIXME: should be MAX_DATA_READ_UNLIMITED? */
+ .max_data_write = 256, /* FIXME: should be MAX_DATA_WRITE_UNLIMITED? */
+ .command = mec1308_spi_send_command,
+ .multicommand = default_spi_send_multicommand,
+ .read = default_spi_read,
+ .write_256 = default_spi_write_256,
+};
+
+int mec1308_init(void)
+{
+ uint16_t sio_port;
+ uint8_t device_id;
+ uint8_t tmp8;
+ int ret = 0;
+ char *p = NULL;
+ mec1308_data_t *ctx_data = NULL;
+
+ msg_pdbg("%s(): entered\n", __func__);
+
+ ctx_data = calloc(1, sizeof(mec1308_data_t));
+ if (!ctx_data) {
+ msg_perr("Unable to allocate space for extra context data.\n");
+ return 1;
+ }
+
+ p = extract_programmer_param("type");
+ if (p && strcmp(p, "ec")) {
+ msg_pdbg("mec1308 only supports \"ec\" type devices\n");
+ ret = 1;
+ goto mec1308_init_exit;
+ }
+
+ if (mec1308_get_sio_index(ctx_data, &sio_port) < 0) {
+ msg_pdbg("MEC1308 not found (probe failed).\n");
+ ret = 1;
+ goto mec1308_init_exit;
+ }
+ device_id = sio_read(sio_port, MEC1308_DEVICE_ID_REG);
+ switch(device_id) {
+ case MEC1308_DEVICE_ID_VAL:
+ msg_pdbg("Found EC: MEC1308 (ID:0x%02x,Rev:0x%02x) on "
+ "sio_port:0x%x.\n", device_id,
+ sio_read(sio_port, MEC1308_DEVICE_REV), sio_port);
+ break;
+ case MEC1310_DEVICE_ID_VAL:
+ msg_pdbg("Found EC: MEC1310 (ID:0x%02x,Rev:0x%02x) on "
+ "sio_port:0x%x.\n", device_id,
+ sio_read(sio_port, MEC1308_DEVICE_REV), sio_port);
+ break;
+ default:
+ msg_pdbg("MEC1308 not found\n");
+ ret = 1;
+ goto mec1308_init_exit;
+ }
+
+ /*
+ * setup mailbox interface at LDN 9
+ */
+ sio_write(sio_port, MEC1308_SIOCFG_LDN, 0x09);
+ tmp8 = sio_read(sio_port, 0x30);
+ tmp8 |= 1;
+ sio_write(sio_port, 0x30, tmp8); /* activate logical device */
+
+ ctx_data->mbx_idx = (unsigned int)sio_read(sio_port, 0x60) << 8 |
+ sio_read(sio_port, 0x61);
+ mbx_data = ctx_data->mbx_idx + 1;
+ msg_pdbg("%s: mbx_idx: 0x%04x, mbx_data: 0x%04x\n",
+ __func__, ctx_data->mbx_idx, mbx_data);
+
+ /* Exit Super I/O config mode */
+ mec1308_sio_exit(ctx_data, sio_port);
+
+ /* Now that we can read the mailbox, we will wait for any remaining
+ * command to finish.*/
+ if (mbx_wait(ctx_data) != 0) {
+ msg_perr("%s: mailbox is not available\n", __func__);
+ ret = 1;
+ goto mec1308_init_exit;
+ }
+
+ /* Further setup -- disable SMI and ACPI.
+ FIXME: is there an ordering dependency? */
+ if (mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_ACPI_DISABLE)) {
+ msg_pdbg("%s: unable to disable ACPI\n", __func__);
+ ret = 1;
+ goto mec1308_init_exit;
+ }
+
+ if (mbx_write(ctx_data, MEC1308_MBX_CMD, MEC1308_CMD_SMI_DISABLE)) {
+ msg_pdbg("%s: unable to disable SMI\n", __func__);
+ ret = 1;
+ goto mec1308_init_exit;
+ }
+
+ if (register_shutdown(mec1308_shutdown, ctx_data)) {
+ ret = 1;
+ goto mec1308_init_exit;
+ }
+
+ /*
+ * Enter SPI Pass-Thru Mode after commands which do not require access
+ * to SPI ROM are complete. We'll start by doing the exit_passthru_mode
+ * sequence, which is benign if the EC is already in passthru mode.
+ */
+ mec1308_exit_passthru_mode(ctx_data);
+
+ if (enter_passthru_mode(ctx_data)) {
+ ret = 1;
+ goto mec1308_init_exit;
+ }
+
+ internal_buses_supported |= BUS_LPC; /* for LPC <--> SPI bridging */
+ spi_master_mec1308.data = ctx_data;
+ register_spi_master(&spi_master_mec1308);
+ msg_pdbg("%s(): successfully initialized mec1308\n", __func__);
+
+mec1308_init_exit:
+ free(p);
+ if (ret)
+ free(ctx_data);
+ return ret;
+}
+#endif
diff --git a/meson.build b/meson.build
index 180b5dd..9836194 100644
--- a/meson.build
+++ b/meson.build
@@ -48,6 +48,7 @@
config_it8212 = get_option('config_it8212')
config_linux_mtd = get_option('config_linux_mtd')
config_linux_spi = get_option('config_linux_spi')
+config_mec1308 = get_option('config_mec1308')
config_mstarddc_spi = get_option('config_mstarddc_spi')
config_nic3com = get_option('config_nic3com')
config_nicintel_eeprom = get_option('config_nicintel_eeprom')
@@ -219,6 +220,10 @@
srcs += 'linux_spi.c'
cargs += '-DCONFIG_LINUX_SPI=1'
endif
+if config_mec1308
+ srcs += 'mec1308.c'
+ cargs += '-DCONFIG_MEC1308=1'
+endif
if config_mstarddc_spi
srcs += 'mstarddc_spi.c'
cargs += '-DCONFIG_MSTARDDC_SPI=1'
diff --git a/meson_options.txt b/meson_options.txt
index ba5130b..9c0a798 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -20,6 +20,7 @@
option('config_it8212', type : 'boolean', value : true, description : 'ITE IT8212F PATA')
option('config_linux_mtd', type : 'boolean', value : true, description : 'Linux MTD interfaces')
option('config_linux_spi', type : 'boolean', value : true, description : 'Linux spidev interfaces')
+option('config_mec1308', type : 'boolean', value : true, description : 'Microchip MEC1308 Embedded Controller')
option('config_mstarddc_spi', type : 'boolean', value : false, description : 'MSTAR DDC support')
option('config_nic3com', type : 'boolean', value : true, description : '3Com NICs')
option('config_nicintel_eeprom', type : 'boolean', value : true, description : 'EEPROM on Intel NICs')
diff --git a/programmer.h b/programmer.h
index b3bc700..73d37f8 100644
--- a/programmer.h
+++ b/programmer.h
@@ -112,6 +112,9 @@
#if CONFIG_USBBLASTER_SPI == 1
PROGRAMMER_USBBLASTER_SPI,
#endif
+#if CONFIG_MEC1308 == 1
+ PROGRAMMER_MEC1308,
+#endif
#if CONFIG_MSTARDDC_SPI == 1
PROGRAMMER_MSTARDDC_SPI,
#endif
@@ -697,6 +700,11 @@
/* mcp6x_spi.c */
int mcp6x_spi_init(int want_spi);
+/* mec1308.c */
+#if CONFIG_MEC1308 == 1
+int mec1308_init(void);
+#endif
+
/* sb600spi.c */
int sb600_probe_spi(struct pci_dev *dev);
To view, visit change 44541. To unsubscribe, or for help writing mail filters, visit settings.