mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-01 21:02:27 +00:00
npcx: Add 1.8V IO support for some GPIOs and I2C pins.
Add 1.8V IO support for some GPIOs and I2C pins. We use a array (gpio_lvol_table) to confine which IO pins can switch to 1.8V. Before setting it to support low voltage level, FW should set IO pin's type to open-drain and disable internal pulling up or down. We also add examples in gpio.inc of npcx_evb and npcx_evb_arm to indicate how to set GPIO & I2C pins to 1.8V if user adds CONFIG_TEST_1P8V definition in board.h. In i2c.c driver, this version removes the internal pull-up feature of i2c ports since the driving force is too weak. (about 30K ohm) Modified sources: 1. gpio.c: Add 1.8V IO support for some GPIOs and I2C pins. 2. i2c.c: Remove internal pull-ups feature for i2c pins and move 1.8V support to gpio.c. 3. register.h: Modified NPCX_LV_GPIO_CTL register & bits definitions. 4. npcx_evb\gpio.inc: Add examples of 1.8V IO. 5. npcx_evb_arm\gpio.inc: Add examples of 1.8V IO. BUG=chrome-os-partner:34346 TEST=make buildall -j; test nuvoton IC specific drivers BRANCH=none Change-Id: I73a840ae321820212e50d609dab17576117a7d64 Signed-off-by: Mulin Chao <mlchao@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/330037 Reviewed-by: Shawn N <shawnn@chromium.org>
This commit is contained in:
@@ -19,7 +19,11 @@ GPIO_INT(POWER_BUTTON_L, PIN(0, 2), GPIO_PULL_UP | GPIO_INT_BOTH, power_butt
|
||||
GPIO_INT(LID_OPEN, PIN(3, 3), GPIO_PULL_DOWN | GPIO_INT_BOTH, lid_interrupt) /* Lid switch */
|
||||
|
||||
/**************************** Need a empty line between GPIO_INT and GPIO ****************************/
|
||||
GPIO(ENTERING_RW, PIN(3, 6), GPIO_OUT_LOW) /* Indicate when EC is entering RW code */
|
||||
#ifdef CONFIG_TEST_1P8V
|
||||
GPIO(ENTERING_RW, PIN(3, 6), GPIO_ODR_LOW | GPIO_SEL_1P8V) /* Indicate when EC is entering RW code */
|
||||
#else
|
||||
GPIO(ENTERING_RW, PIN(3, 6), GPIO_OUT_LOW ) /* Indicate when EC is entering RW code */
|
||||
#endif
|
||||
GPIO(PCH_WAKE_L, PIN(5, 0), GPIO_OUT_HIGH) /* Wake signal output to PCH */
|
||||
|
||||
/* Used for module testing */
|
||||
@@ -30,8 +34,13 @@ GPIO(SPI_CS_L, PIN(A, 5), GPIO_OUT_HIGH)
|
||||
* I2C pins should be configured as inputs until I2C module is
|
||||
* initialized. This will avoid driving the lines unintentionally.
|
||||
*/
|
||||
#ifdef CONFIG_TEST_1P8V
|
||||
GPIO(I2C0_SCL0, PIN(B, 5), GPIO_ODR_HIGH | GPIO_SEL_1P8V)
|
||||
GPIO(I2C0_SDA0, PIN(B, 4), GPIO_ODR_HIGH | GPIO_SEL_1P8V)
|
||||
#else
|
||||
GPIO(I2C0_SCL0, PIN(B, 5), GPIO_ODR_HIGH)
|
||||
GPIO(I2C0_SDA0, PIN(B, 4), GPIO_ODR_HIGH)
|
||||
#endif
|
||||
GPIO(I2C0_SCL1, PIN(B, 3), GPIO_ODR_HIGH)
|
||||
GPIO(I2C0_SDA1, PIN(B, 2), GPIO_ODR_HIGH)
|
||||
GPIO(I2C1_SCL, PIN(9, 0), GPIO_ODR_HIGH)
|
||||
|
||||
@@ -20,7 +20,11 @@ GPIO_INT(POWER_BUTTON_L, PIN(0, 2), GPIO_PULL_UP | GPIO_INT_BOTH, power_butt
|
||||
GPIO_INT(LID_OPEN, PIN(3, 3), GPIO_PULL_DOWN | GPIO_INT_BOTH, lid_interrupt) /* Lid switch */
|
||||
|
||||
/**************************** Need a empty line between GPIO_INT and GPIO ****************************/
|
||||
GPIO(ENTERING_RW, PIN(3, 6), GPIO_OUT_LOW) /* Indicate when EC is entering RW code */
|
||||
#ifdef CONFIG_TEST_1P8V
|
||||
GPIO(ENTERING_RW, PIN(3, 6), GPIO_ODR_LOW | GPIO_SEL_1P8V) /* Indicate when EC is entering RW code */
|
||||
#else
|
||||
GPIO(ENTERING_RW, PIN(3, 6), GPIO_OUT_LOW ) /* Indicate when EC is entering RW code */
|
||||
#endif
|
||||
GPIO(PCH_WAKE_L, PIN(5, 0), GPIO_OUT_HIGH) /* Wake signal output to PCH */
|
||||
/* For testing keyboard mkbp */
|
||||
GPIO(EC_INT_L, PIN(7, 4), GPIO_ODR_HIGH) /* Interrupt pin for keyboard mkbp */
|
||||
@@ -31,8 +35,13 @@ GPIO(PGOOD_FAN, PIN(C, 7), GPIO_PULL_UP | GPIO_INPUT) /* Power Goo
|
||||
* I2C pins should be configured as inputs until I2C module is
|
||||
* initialized. This will avoid driving the lines unintentionally.
|
||||
*/
|
||||
#ifdef CONFIG_TEST_1P8V
|
||||
GPIO(I2C0_SCL0, PIN(B, 5), GPIO_ODR_HIGH | GPIO_SEL_1P8V)
|
||||
GPIO(I2C0_SDA0, PIN(B, 4), GPIO_ODR_HIGH | GPIO_SEL_1P8V)
|
||||
#else
|
||||
GPIO(I2C0_SCL0, PIN(B, 5), GPIO_ODR_HIGH)
|
||||
GPIO(I2C0_SDA0, PIN(B, 4), GPIO_ODR_HIGH)
|
||||
#endif
|
||||
GPIO(I2C0_SCL1, PIN(B, 3), GPIO_ODR_HIGH)
|
||||
GPIO(I2C0_SDA1, PIN(B, 2), GPIO_ODR_HIGH)
|
||||
GPIO(I2C1_SCL, PIN(9, 0), GPIO_ODR_HIGH)
|
||||
|
||||
@@ -308,6 +308,49 @@ const struct gpio_alt_map gpio_alt_table[] = {
|
||||
{ NPCX_GPIO(B, 1), NPCX_ALT_INV(A, NO_KSO17_SL)},/* KSO17 */
|
||||
};
|
||||
|
||||
struct gpio_lvol_item {
|
||||
struct npcx_gpio lvol_gpio[8];
|
||||
};
|
||||
|
||||
const struct gpio_lvol_item gpio_lvol_table[] = {
|
||||
/* Low-Voltage GPIO Control 0 */
|
||||
{ { NPCX_GPIO(B, 5),
|
||||
NPCX_GPIO(B, 4),
|
||||
NPCX_GPIO(B, 3),
|
||||
NPCX_GPIO(B, 2),
|
||||
NPCX_GPIO(9, 0),
|
||||
NPCX_GPIO(8, 7),
|
||||
NPCX_GPIO(0, 0),
|
||||
NPCX_GPIO(3, 3), }, },
|
||||
/* Low-Voltage GPIO Control 1 */
|
||||
{ { NPCX_GPIO(9, 2),
|
||||
NPCX_GPIO(9, 1),
|
||||
NPCX_GPIO(D, 1),
|
||||
NPCX_GPIO(D, 0),
|
||||
NPCX_GPIO(3, 6),
|
||||
NPCX_GPIO(6, 4),
|
||||
NPCX_GPIO(6, 5),
|
||||
NPCX_GPIO_NONE , }, },
|
||||
/* Low-Voltage GPIO Control 2 */
|
||||
{ { NPCX_GPIO(7, 4),
|
||||
NPCX_GPIO(8, 4),
|
||||
NPCX_GPIO(8, 5),
|
||||
NPCX_GPIO(7, 3),
|
||||
NPCX_GPIO(C, 1),
|
||||
NPCX_GPIO(C, 7),
|
||||
NPCX_GPIO(E, 7),
|
||||
NPCX_GPIO(3, 4), }, },
|
||||
/* Low-Voltage GPIO Control 3 */
|
||||
{ { NPCX_GPIO(C, 6),
|
||||
NPCX_GPIO(3, 7),
|
||||
NPCX_GPIO(4, 0),
|
||||
NPCX_GPIO(7, 1),
|
||||
NPCX_GPIO(8, 2),
|
||||
NPCX_GPIO(7, 5),
|
||||
NPCX_GPIO(8, 0),
|
||||
NPCX_GPIO(C, 5), }, },
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Internal functions */
|
||||
|
||||
@@ -484,6 +527,32 @@ static void gpio_interrupt_type_sel(uint8_t port, uint8_t mask, uint32_t flags)
|
||||
/* No support analog mode */
|
||||
}
|
||||
|
||||
/* Select low voltage detection level */
|
||||
void gpio_low_voltage_level_sel(uint8_t port, uint8_t mask, uint8_t low_voltage)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(gpio_lvol_table); i++) {
|
||||
const struct npcx_gpio *gpio = gpio_lvol_table[i].lvol_gpio;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(gpio_lvol_table[0].lvol_gpio); j++)
|
||||
if (gpio_match(port, mask, gpio[j])) {
|
||||
if (low_voltage)
|
||||
/* Select vol-detect level for 1.8V */
|
||||
SET_BIT(NPCX_LV_GPIO_CTL(i), j);
|
||||
else
|
||||
/* Select vol-detect level for 3.3V */
|
||||
CLEAR_BIT(NPCX_LV_GPIO_CTL(i), j);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Make sure the bit depth of low voltage register.
|
||||
*/
|
||||
BUILD_ASSERT(ARRAY_SIZE(gpio_lvol_table[0].lvol_gpio) == 8);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* IC specific low-level driver */
|
||||
|
||||
@@ -540,6 +609,18 @@ void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags)
|
||||
NPCX_PPULL(port) &= ~mask; /* disable pull down/up */
|
||||
}
|
||||
|
||||
/* 1.8V low voltage select */
|
||||
if (flags & GPIO_SEL_1P8V) {
|
||||
/*
|
||||
* Set IO type to open-drain & disable internal pulling
|
||||
* before selecting low-voltage level
|
||||
*/
|
||||
NPCX_PTYPE(port) |= mask;
|
||||
NPCX_PPULL(port) &= ~mask;
|
||||
gpio_low_voltage_level_sel(port, mask, 1);
|
||||
} else
|
||||
gpio_low_voltage_level_sel(port, mask, 0);
|
||||
|
||||
/* Set up interrupt type */
|
||||
if (flags & GPIO_INPUT)
|
||||
gpio_interrupt_type_sel(port, mask, flags);
|
||||
|
||||
@@ -786,46 +786,6 @@ static void i2c_init(void)
|
||||
int ctrl = i2c_port_to_controller(port);
|
||||
volatile struct i2c_status *p_status = i2c_stsobjs + ctrl;
|
||||
|
||||
/* Configure pull-up for SMB interface pins */
|
||||
|
||||
/* Enable 3.3V pull-up or turn to 1.8V support */
|
||||
if (port == NPCX_I2C_PORT0_0) {
|
||||
#ifdef NPCX_I2C0_0_1P8V
|
||||
SET_BIT(NPCX_LV_GPIO_CTL0, NPCX_LV_GPIO_CTL0_SC0_0_LV);
|
||||
SET_BIT(NPCX_LV_GPIO_CTL0, NPCX_LV_GPIO_CTL0_SD0_0_LV);
|
||||
#else
|
||||
SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(ctrl, 0));
|
||||
#endif
|
||||
} else if (port == NPCX_I2C_PORT0_1) {
|
||||
#ifdef NPCX_I2C0_1_1P8V
|
||||
SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL0_SC0_1_LV);
|
||||
SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL0_SD0_1_LV);
|
||||
#else
|
||||
SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(ctrl, 1));
|
||||
#endif
|
||||
} else if (port == NPCX_I2C_PORT1) {
|
||||
#ifdef NPCX_I2C1_1P8V
|
||||
SET_BIT(NPCX_LV_GPIO_CTL0, NPCX_LV_GPIO_CTL0_SC1_0_LV);
|
||||
SET_BIT(NPCX_LV_GPIO_CTL0, NPCX_LV_GPIO_CTL0_SD1_0_LV);
|
||||
#else
|
||||
SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(ctrl, 0));
|
||||
#endif
|
||||
} else if (port == NPCX_I2C_PORT2) {
|
||||
#ifdef NPCX_I2C2_1P8V
|
||||
SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SC2_0_LV);
|
||||
SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SD2_0_LV);
|
||||
#else
|
||||
SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(ctrl, 0));
|
||||
#endif
|
||||
} else if (port == NPCX_I2C_PORT3) {
|
||||
#ifdef NPCX_I2C3_1P8V
|
||||
SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SC3_0_LV);
|
||||
SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SD3_0_LV);
|
||||
#else
|
||||
SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(ctrl, 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* status init */
|
||||
p_status->oper_state = SMB_IDLE;
|
||||
|
||||
|
||||
@@ -432,12 +432,9 @@ enum {
|
||||
#define NPCX_DEV_CTL4 REG8(NPCX_SCFG_BASE_ADDR + 0x006)
|
||||
#define NPCX_DEVALT(n) REG8(NPCX_SCFG_BASE_ADDR + 0x010 + n)
|
||||
#define NPCX_LFCGCALCNT REG8(NPCX_SCFG_BASE_ADDR + 0x021)
|
||||
#define NPCX_DEVPU0 REG8(NPCX_SCFG_BASE_ADDR + 0x028)
|
||||
#define NPCX_DEVPU1 REG8(NPCX_SCFG_BASE_ADDR + 0x029)
|
||||
#define NPCX_LV_GPIO_CTL0 REG8(NPCX_SCFG_BASE_ADDR + 0x02A)
|
||||
#define NPCX_LV_GPIO_CTL1 REG8(NPCX_SCFG_BASE_ADDR + 0x02B)
|
||||
#define NPCX_LV_GPIO_CTL2 REG8(NPCX_SCFG_BASE_ADDR + 0x02C)
|
||||
#define NPCX_LV_GPIO_CTL3 REG8(NPCX_SCFG_BASE_ADDR + 0x02D)
|
||||
#define NPCX_PUPD_EN0 REG8(NPCX_SCFG_BASE_ADDR + 0x028)
|
||||
#define NPCX_PUPD_EN1 REG8(NPCX_SCFG_BASE_ADDR + 0x029)
|
||||
#define NPCX_LV_GPIO_CTL(n) REG8(NPCX_SCFG_BASE_ADDR + 0x02A + n)
|
||||
#define NPCX_SCFG_VER REG8(NPCX_SCFG_BASE_ADDR + 0x02F)
|
||||
|
||||
#define TEST_BKSL REG8(NPCX_SCFG_BASE_ADDR + 0x037)
|
||||
@@ -588,18 +585,6 @@ enum {
|
||||
/* Others bit definitions */
|
||||
#define NPCX_LFCGCALCNT_LPREG_CTL_EN 1
|
||||
|
||||
#define NPCX_LV_GPIO_CTL0_SC0_0_LV 0
|
||||
#define NPCX_LV_GPIO_CTL0_SD0_0_LV 1
|
||||
#define NPCX_LV_GPIO_CTL0_SC0_1_LV 2
|
||||
#define NPCX_LV_GPIO_CTL0_SD0_1_LV 3
|
||||
#define NPCX_LV_GPIO_CTL0_SC1_0_LV 4
|
||||
#define NPCX_LV_GPIO_CTL0_SD1_0_LV 5
|
||||
|
||||
#define NPCX_LV_GPIO_CTL1_SC2_0_LV 0
|
||||
#define NPCX_LV_GPIO_CTL1_SD2_0_LV 1
|
||||
#define NPCX_LV_GPIO_CTL1_SC3_0_LV 2
|
||||
#define NPCX_LV_GPIO_CTL1_SD3_0_LV 3
|
||||
|
||||
/******************************************************************************/
|
||||
/* Development and Debug Support (DBG) Registers */
|
||||
#define NPCX_DBGCTRL REG8(NPCX_SCFG_BASE_ADDR + 0x074)
|
||||
|
||||
Reference in New Issue
Block a user