summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/it8380dev/board.c26
-rw-r--r--board/it8380dev/board.h15
-rw-r--r--chip/it83xx/build.mk1
-rw-r--r--chip/it83xx/config_chip.h1
-rw-r--r--chip/it83xx/ec2i.c157
-rw-r--r--chip/it83xx/ec2i_chip.h126
-rw-r--r--chip/it83xx/registers.h16
7 files changed, 340 insertions, 2 deletions
diff --git a/board/it8380dev/board.c b/board/it8380dev/board.c
index 201a6c20c0..c18aa58d41 100644
--- a/board/it8380dev/board.c
+++ b/board/it8380dev/board.c
@@ -15,6 +15,7 @@
#include "pwm_chip.h"
#include "adc.h"
#include "adc_chip.h"
+#include "ec2i_chip.h"
/* Test GPIO interrupt function that toggles one LED. */
void test_interrupt(enum gpio_signal signal)
@@ -42,6 +43,31 @@ const struct pwm_t pwm_channels[] = {
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
+/* PNPCFG settings */
+const struct ec2i_t pnpcfg_settings[] = {
+ /* Select logical device 06h(keyboard) */
+ {HOST_INDEX_LDN, LDN_KBC_KEYBOARD},
+ /* Set IRQ=01h for logical device */
+ {HOST_INDEX_IRQNUMX, 0x01},
+ /* Enable logical device */
+ {HOST_INDEX_LDA, 0x01},
+
+ /* Select logical device 05h(mouse) */
+ {HOST_INDEX_LDN, LDN_KBC_MOUSE},
+ /* Set IRQ=0Ch for logical device */
+ {HOST_INDEX_IRQNUMX, 0x0C},
+ /* Enable logical device */
+ {HOST_INDEX_LDA, 0x01},
+
+ /* Select logical device 11h(PM1 ACPI) */
+ {HOST_INDEX_LDN, LDN_PMC1},
+ /* Set IRQ=00h for logical device */
+ {HOST_INDEX_IRQNUMX, 0x00},
+ /* Enable logical device */
+ {HOST_INDEX_LDA, 0x01},
+};
+BUILD_ASSERT(ARRAY_SIZE(pnpcfg_settings) == EC2I_SETTING_COUNT);
+
/* Initialize board. */
static void board_init(void)
{
diff --git a/board/it8380dev/board.h b/board/it8380dev/board.h
index afadc3c40b..a1852d46a6 100644
--- a/board/it8380dev/board.h
+++ b/board/it8380dev/board.h
@@ -43,5 +43,20 @@ enum adc_channel {
ADC_CH_COUNT
};
+enum ec2i_setting {
+ EC2I_SET_KB_LDN,
+ EC2I_SET_KB_IRQ,
+ EC2I_SET_KB_ENABLE,
+ EC2I_SET_MOUSE_LDN,
+ EC2I_SET_MOUSE_IRQ,
+ EC2I_SET_MOUSE_ENABLE,
+ EC2I_SET_PMC1_LDN,
+ EC2I_SET_PMC1_IRQ,
+ EC2I_SET_PMC1_ENABLE,
+
+ /* Number of EC2I settings */
+ EC2I_SETTING_COUNT
+};
+
#endif /* !__ASSEMBLER__ */
#endif /* __BOARD_H */
diff --git a/chip/it83xx/build.mk b/chip/it83xx/build.mk
index 6029ee4b30..615e7832f9 100644
--- a/chip/it83xx/build.mk
+++ b/chip/it83xx/build.mk
@@ -16,3 +16,4 @@ chip-y=hwtimer.o uart.o gpio.o system.o jtag.o clock.o irq.o
chip-$(CONFIG_WATCHDOG)+=watchdog.o
chip-$(CONFIG_PWM)+=pwm.o
chip-$(CONFIG_ADC)+=adc.o
+chip-$(CONFIG_EC2I)+=ec2i.o
diff --git a/chip/it83xx/config_chip.h b/chip/it83xx/config_chip.h
index 6032ce5e83..55e41763b4 100644
--- a/chip/it83xx/config_chip.h
+++ b/chip/it83xx/config_chip.h
@@ -105,5 +105,6 @@
#undef CONFIG_WATCHDOG
#define CONFIG_PWM
#define CONFIG_ADC
+#define CONFIG_EC2I
#endif /* __CROS_EC_CONFIG_CHIP_H */
diff --git a/chip/it83xx/ec2i.c b/chip/it83xx/ec2i.c
new file mode 100644
index 0000000000..210aad7d25
--- /dev/null
+++ b/chip/it83xx/ec2i.c
@@ -0,0 +1,157 @@
+/* Copyright (c) 2014 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.
+ */
+
+/* EC2I control module for IT83xx. */
+
+#include "hooks.h"
+#include "ec2i_chip.h"
+#include "registers.h"
+#include "timer.h"
+
+#define EC2I_ACCESS_TIME_USEC 15
+
+static int ec2i_check_status_bit(uint8_t status_bit)
+{
+ int num;
+
+ for (num = 0; num < 10; num++) {
+ udelay(EC2I_ACCESS_TIME_USEC);
+
+ if (!(IT83XX_EC2I_IBCTL & status_bit))
+ return 0;
+ }
+
+ /* Timeout */
+ return -1;
+}
+
+static void ec2i_ec_access_enable(void)
+{
+ /*
+ * bit0: Host access to the PNPCFG registers is disabled.
+ * bit1: Host access to the BRAM registers is disabled.
+ */
+ IT83XX_EC2I_LSIOHA |= 0x03;
+
+ /* bit0: EC to I-Bus access enabled. */
+ IT83XX_EC2I_IBCTL |= 0x01;
+
+ /*
+ * Make sure that both CRIB and CWIB bits in IBCTL register
+ * are cleared.
+ * bit1: CRIB
+ * bit2: CWIB
+ */
+ if (ec2i_check_status_bit(0x06))
+ IT83XX_EC2I_IBCTL &= ~0x02;
+
+ /* Enable EC access to the PNPCFG registers */
+ IT83XX_EC2I_IBMAE |= 0x01;
+}
+
+static void ec2i_ec_access_disable(void)
+{
+ /* Disable EC access to the PNPCFG registers. */
+ IT83XX_EC2I_IBMAE &= ~0x01;
+
+ /* Diable EC to I-Bus access. */
+ IT83XX_EC2I_IBCTL &= ~0x01;
+
+ /* Enable host access */
+ IT83XX_EC2I_LSIOHA &= ~0x03;
+}
+
+/* EC2I write */
+enum ec2i_message ec2i_write(enum host_pnpcfg_index index, uint8_t data)
+{
+ /* bit1 : VCC power on */
+ if (IT83XX_SWUC_SWCTL1 & 0x02) {
+ /* Enable EC2I EC access */
+ ec2i_ec_access_enable();
+
+ /* Set indirect host I/O offset. (index port) */
+ IT83XX_EC2I_IHIOA = 0;
+ IT83XX_EC2I_IHD = index;
+
+ /* Read the CWIB bit in IBCTL until it returns 0. */
+ if (ec2i_check_status_bit(0x04)) {
+ ec2i_ec_access_disable();
+ return EC2I_WRITE_ERROR;
+ }
+
+ /* Set indirect host I/O offset. (data port) */
+ IT83XX_EC2I_IHIOA = 1;
+ IT83XX_EC2I_IHD = data;
+
+ /* Read the CWIB bit in IBCTL until it returns 0. */
+ if (ec2i_check_status_bit(0x04)) {
+ ec2i_ec_access_disable();
+ return EC2I_WRITE_ERROR;
+ }
+
+ /* Disable EC2I EC access */
+ ec2i_ec_access_disable();
+
+ return EC2I_WRITE_SUCCESS;
+ } else {
+ return EC2I_WRITE_ERROR;
+ }
+}
+
+/* EC2I read */
+enum ec2i_message ec2i_read(enum host_pnpcfg_index index)
+{
+ uint8_t data;
+
+ /* bit1 : VCC power on */
+ if (IT83XX_SWUC_SWCTL1 & 0x02) {
+ /* Enable EC2I EC access */
+ ec2i_ec_access_enable();
+
+ /* Set indirect host I/O offset. (index port) */
+ IT83XX_EC2I_IHIOA = 0;
+ IT83XX_EC2I_IHD = index;
+
+ /* Read the CWIB bit in IBCTL until it returns 0. */
+ if (ec2i_check_status_bit(0x04)) {
+ ec2i_ec_access_disable();
+ return EC2I_READ_ERROR;
+ }
+
+ /* Set indirect host I/O offset. (data port) */
+ IT83XX_EC2I_IHIOA = 1;
+
+ /* This access is a read-action */
+ IT83XX_EC2I_IBCTL |= 0x02;
+
+ /* Read the CRIB bit in IBCTL until it returns 0. */
+ if (ec2i_check_status_bit(0x02)) {
+ ec2i_ec_access_disable();
+ return EC2I_READ_ERROR;
+ }
+
+ /* Read the data from IHD register */
+ data = IT83XX_EC2I_IHD;
+
+ /* Disable EC2I EC access */
+ ec2i_ec_access_disable();
+
+ return EC2I_READ_SUCCESS + data;
+ } else {
+ return EC2I_READ_ERROR;
+ }
+}
+
+static void pnpcfg_init(void)
+{
+ int table;
+
+ for (table = 0x00; table < EC2I_SETTING_COUNT; table++) {
+ if (ec2i_write(pnpcfg_settings[table].index_port,
+ pnpcfg_settings[table].data_port) == EC2I_WRITE_ERROR)
+ break;
+ }
+}
+DECLARE_HOOK(HOOK_INIT, pnpcfg_init, HOOK_PRIO_DEFAULT);
diff --git a/chip/it83xx/ec2i_chip.h b/chip/it83xx/ec2i_chip.h
new file mode 100644
index 0000000000..d584973ef7
--- /dev/null
+++ b/chip/it83xx/ec2i_chip.h
@@ -0,0 +1,126 @@
+/* Copyright (c) 2014 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.
+ */
+
+/* EC2I control module for IT83xx. */
+
+#ifndef __CROS_EC_IT83XX_EC2I_H
+#define __CROS_EC_IT83XX_EC2I_H
+
+/* Index list of the host interface registers of PNPCFG */
+enum host_pnpcfg_index {
+ /* Logical Device Number */
+ HOST_INDEX_LDN = 0x07,
+ /* Chip ID Byte 1 */
+ HOST_INDEX_CHIPID1 = 0x20,
+ /* Chip ID Byte 2 */
+ HOST_INDEX_CHIPID2 = 0x21,
+ /* Chip Version */
+ HOST_INDEX_CHIPVER = 0x22,
+ /* Super I/O Control */
+ HOST_INDEX_SIOCTRL = 0x23,
+ /* Super I/O IRQ Configuration */
+ HOST_INDEX_SIOIRQ = 0x25,
+ /* Super I/O General Purpose */
+ HOST_INDEX_SIOGP = 0x26,
+ /* Super I/O Power Mode */
+ HOST_INDEX_SIOPWR = 0x2D,
+ /* Depth 2 I/O Address */
+ HOST_INDEX_D2ADR = 0x2E,
+ /* Depth 2 I/O Data */
+ HOST_INDEX_D2DAT = 0x2F,
+ /* Logical Device Activate Register */
+ HOST_INDEX_LDA = 0x30,
+ /* I/O Port Base Address Bits [15:8] for Descriptor 0 */
+ HOST_INDEX_IOBAD0_MSB = 0x60,
+ /* I/O Port Base Address Bits [7:0] for Descriptor 0 */
+ HOST_INDEX_IOBAD0_LSB = 0x61,
+ /* I/O Port Base Address Bits [15:8] for Descriptor 1 */
+ HOST_INDEX_IOBAD1_MSB = 0x62,
+ /* I/O Port Base Address Bits [7:0] for Descriptor 1 */
+ HOST_INDEX_IOBAD1_LSB = 0x63,
+ /* Interrupt Request Number and Wake-Up on IRQ Enabled */
+ HOST_INDEX_IRQNUMX = 0x70,
+ /* Interrupt Request Type Select */
+ HOST_INDEX_IRQTP = 0x71,
+ /* DMA Channel Select 0 */
+ HOST_INDEX_DMAS0 = 0x74,
+ /* DMA Channel Select 1 */
+ HOST_INDEX_DMAS1 = 0x75,
+ /* Device Specific Logical Device Configuration 1 to 10 */
+ HOST_INDEX_DSLDC1 = 0xF0,
+ HOST_INDEX_DSLDC2 = 0xF1,
+ HOST_INDEX_DSLDC3 = 0xF2,
+ HOST_INDEX_DSLDC4 = 0xF3,
+ HOST_INDEX_DSLDC5 = 0xF4,
+ HOST_INDEX_DSLDC6 = 0xF5,
+ HOST_INDEX_DSLDC7 = 0xF6,
+ HOST_INDEX_DSLDC8 = 0xF7,
+ HOST_INDEX_DSLDC9 = 0xF8,
+ HOST_INDEX_DSLDC10 = 0xF9,
+};
+
+/* List of logical device number (LDN) assignments */
+enum logical_device_number {
+ /* Serial Port 1 */
+ LDN_UART1 = 0x01,
+ /* Serial Port 2 */
+ LDN_UART2 = 0x02,
+ /* System Wake-Up Control */
+ LDN_SWUC = 0x04,
+ /* KBC/Mouse Interface */
+ LDN_KBC_MOUSE = 0x05,
+ /* KBC/Keyboard Interface */
+ LDN_KBC_KEYBOARD = 0x06,
+ /* Consumer IR */
+ LDN_CIR = 0x0A,
+ /* Shared Memory/Flash Interface */
+ LDN_SMFI = 0x0F,
+ /* RTC-like Timer */
+ LDN_RTCT = 0x10,
+ /* Power Management I/F Channel 1 */
+ LDN_PMC1 = 0x11,
+ /* Power Management I/F Channel 2 */
+ LDN_PMC2 = 0x12,
+ /* Serial Peripheral Interface */
+ LDN_SSPI = 0x13,
+ /* Platform Environment Control Interface */
+ LDN_PECI = 0x14,
+ /* Power Management I/F Channel 3 */
+ LDN_PMC3 = 0x17,
+ /* Power Management I/F Channel 4 */
+ LDN_PMC4 = 0x18,
+ /* Power Management I/F Channel 5 */
+ LDN_PMC5 = 0x19,
+};
+
+/* EC2I read/write message */
+enum ec2i_message {
+ /* EC2I write success */
+ EC2I_WRITE_SUCCESS = 0x00,
+ /* EC2I write error */
+ EC2I_WRITE_ERROR = 0x01,
+ /* EC2I read success */
+ EC2I_READ_SUCCESS = 0x8000,
+ /* EC2I read error */
+ EC2I_READ_ERROR = 0x8100,
+};
+
+/* Data structure for initializing PNPCFG via ec2i. */
+struct ec2i_t {
+ /* index port */
+ enum host_pnpcfg_index index_port;
+ /* data port */
+ uint8_t data_port;
+};
+
+extern const struct ec2i_t pnpcfg_settings[];
+
+/* EC2I write */
+enum ec2i_message ec2i_write(enum host_pnpcfg_index index, uint8_t data);
+
+/* EC2I read */
+enum ec2i_message ec2i_read(enum host_pnpcfg_index index);
+
+#endif /* __CROS_EC_IT83XX_EC2I_H */
diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h
index 08a3aab150..473f696a6c 100644
--- a/chip/it83xx/registers.h
+++ b/chip/it83xx/registers.h
@@ -383,6 +383,20 @@
#define IT83XX_INTC_IVCT14 REG8(IT83XX_INTC_BASE+0x8E)
#define IT83XX_INTC_IVCT15 REG8(IT83XX_INTC_BASE+0x8F)
+/* --- EC Access to the Host Controlled Modules (EC2I Bridge) --- */
+#define IT83XX_EC2I_BASE 0x00F01200
+
+#define IT83XX_EC2I_IHIOA REG8(IT83XX_EC2I_BASE+0x00)
+#define IT83XX_EC2I_IHD REG8(IT83XX_EC2I_BASE+0x01)
+#define IT83XX_EC2I_LSIOHA REG8(IT83XX_EC2I_BASE+0x02)
+#define IT83XX_EC2I_SIOLV REG8(IT83XX_EC2I_BASE+0x03)
+#define IT83XX_EC2I_IBMAE REG8(IT83XX_EC2I_BASE+0x04)
+#define IT83XX_EC2I_IBCTL REG8(IT83XX_EC2I_BASE+0x05)
+
+/* --- System Wake-UP Control (SWUC) --- */
+#define IT83XX_SWUC_BASE 0x00F01400
+#define IT83XX_SWUC_SWCTL1 REG8(IT83XX_SWUC_BASE+0x00)
+
/* --- Wake-Up Control (WUC) --- */
#define IT83XX_WUC_BASE 0x00F01B00
@@ -644,9 +658,7 @@ enum clock_gate_offsets {
/* --- MISC (not implemented yet) --- */
#define IT83XX_SMFI_BASE 0x00F01000
-#define IT83XX_EC2I_BASE 0x00F01200
#define IT83XX_KBC_BASE 0x00F01300
-#define IT83XX_SWUC_BASE 0x00F01400
#define IT83XX_PMC_BASE 0x00F01500
#define IT83XX_PS2_BASE 0x00F01700
#define IT83XX_DAC_BASE 0x00F01A00