summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ec/dell/mec5035/Kconfig4
-rw-r--r--src/ec/dell/mec5035/Makefile.inc9
-rw-r--r--src/ec/dell/mec5035/mec5035.c122
-rw-r--r--src/ec/dell/mec5035/mec5035.h23
4 files changed, 158 insertions, 0 deletions
diff --git a/src/ec/dell/mec5035/Kconfig b/src/ec/dell/mec5035/Kconfig
new file mode 100644
index 0000000000..220714371d
--- /dev/null
+++ b/src/ec/dell/mec5035/Kconfig
@@ -0,0 +1,4 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+config EC_DELL_MEC5035
+ bool
diff --git a/src/ec/dell/mec5035/Makefile.inc b/src/ec/dell/mec5035/Makefile.inc
new file mode 100644
index 0000000000..4ebdd811f9
--- /dev/null
+++ b/src/ec/dell/mec5035/Makefile.inc
@@ -0,0 +1,9 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+ifeq ($(CONFIG_EC_DELL_MEC5035),y)
+
+bootblock-y += mec5035.c
+romstage-y += mec5035.c
+ramstage-y += mec5035.c
+
+endif
diff --git a/src/ec/dell/mec5035/mec5035.c b/src/ec/dell/mec5035/mec5035.c
new file mode 100644
index 0000000000..8da11e5b1c
--- /dev/null
+++ b/src/ec/dell/mec5035/mec5035.c
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pnp.h>
+#include <pc80/keyboard.h>
+#include <stdint.h>
+#include "mec5035.h"
+
+static const u16 MAILBOX_INDEX = 0x910;
+static const u16 MAILBOX_DATA = MAILBOX_INDEX + 1;
+
+static inline u8 __get_mailbox_register(u8 index)
+{
+ outb(index + 0x10, MAILBOX_INDEX);
+ return inb(MAILBOX_DATA);
+}
+
+static inline void __set_mailbox_register(u8 index, u8 data)
+{
+ outb(index + 0x10, MAILBOX_INDEX);
+ outb(data, MAILBOX_DATA);
+}
+
+static void wait_ec(void)
+{
+ u8 busy;
+ do {
+ outb(0, MAILBOX_INDEX);
+ busy = inb(MAILBOX_DATA);
+ } while (busy);
+}
+
+
+static enum cb_err read_mailbox_regs(u8 *data, u8 start, u8 count)
+{
+ if (start + count >= NUM_REGISTERS) {
+ printk(BIOS_ERR, "%s: Invalid start or count argument.\n", __func__);
+ return CB_ERR_ARG;
+ }
+
+ while (count--) {
+ *data = __get_mailbox_register(start);
+ data++;
+ start++;
+ }
+
+ return CB_SUCCESS;
+}
+
+static enum cb_err write_mailbox_regs(const u8 *data, u8 start, u8 count)
+{
+ if (start + count >= NUM_REGISTERS) {
+ printk(BIOS_ERR, "%s: Invalid start or count argument.\n", __func__);
+ return CB_ERR_ARG;
+ }
+
+ while (count--) {
+ __set_mailbox_register(start, *data);
+ data++;
+ start++;
+ }
+
+ return CB_SUCCESS;
+}
+
+static void ec_command(u8 cmd)
+{
+ outb(0, MAILBOX_INDEX);
+ outb(cmd, MAILBOX_DATA);
+ wait_ec();
+}
+
+u8 mec5035_mouse_touchpad(u8 setting)
+{
+ u8 buf[15] = {0};
+ write_mailbox_regs(&setting, 2, 1);
+ ec_command(CMD_MOUSE_TP);
+ /* The vendor firmware reads 15 bytes starting at index 1, presumably
+ to get some sort of return code. Though I don't know for sure if
+ this is the case. Assume the first byte is the return code. */
+ read_mailbox_regs(buf, 1, 15);
+ return buf[0];
+}
+
+void mec5035_early_init(void)
+{
+ /* If this isn't sent the EC shuts down the system after about 15
+ seconds, flashing a pattern on the keyboard LEDs corresponding
+ to "processor failure" according to Dell service manuals. */
+ ec_command(CMD_CPU_OK);
+}
+
+static void mec5035_init(struct device *dev)
+{
+ /* Unconditionally use this argument for now as this setting
+ is probably the most sensible default out of the 3 choices. */
+ mec5035_mouse_touchpad(TP_PS2_MOUSE);
+
+ pc_keyboard_init(NO_AUX_DEVICE);
+}
+
+static struct device_operations ops = {
+ .init = mec5035_init,
+ .read_resources = noop_read_resources,
+ .set_resources = noop_set_resources
+};
+
+static struct pnp_info pnp_dev_info[] = {
+ { NULL, 0, 0, 0, }
+};
+
+static void mec5035_enable(struct device *dev)
+{
+ pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
+}
+
+struct chip_operations ec_dell_mec5035_ops = {
+ CHIP_NAME("MEC5035 EC")
+ .enable_dev = mec5035_enable,
+};
diff --git a/src/ec/dell/mec5035/mec5035.h b/src/ec/dell/mec5035/mec5035.h
new file mode 100644
index 0000000000..e7a05b64d4
--- /dev/null
+++ b/src/ec/dell/mec5035/mec5035.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _EC_DELL_MEC5035_H_
+#define _EC_DELL_MEC5035_H_
+
+#include <stdint.h>
+
+#define NUM_REGISTERS 32
+
+/* Touchpad (TP) and mouse related. The EC seems to
+ default to 0 which results in the TP not working. */
+#define CMD_MOUSE_TP 0x1a
+#define SERIAL_MOUSE 0 /* Disable TP, force use of a serial mouse */
+#define PS2_MOUSE 1 /* Disable TP when using a PS/2 mouse */
+#define TP_PS2_MOUSE 2 /* Leave TP enabled when using a PS/2 mouse */
+
+#define CMD_CPU_OK 0xc2
+
+u8 mec5035_mouse_touchpad(u8 setting);
+void mec5035_cpu_ok(void);
+void mec5035_early_init(void);
+
+#endif /* _EC_DELL_MEC5035_H_ */