diff options
author | Randall Spangler <rspangler@chromium.org> | 2013-05-02 10:06:15 -0700 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-05-02 12:05:49 -0700 |
commit | 3e76215df46fbcfb8fa0920b448c2dab7c098914 (patch) | |
tree | 0b19a152471d7efb3c88764c27be9ea5233b5f97 | |
parent | 001fb660bdbe49d3240f20bc67be0ee67ee8b562 (diff) | |
download | chrome-ec-3e76215df46fbcfb8fa0920b448c2dab7c098914.tar.gz |
Fix I2C port configuration on pit
1) Port needs to be open-drain. Missed this when porting from STM32F
because open-drain and alternate function are set in the same register
on STM32F and are different regs on STM32L.
2) Queue a stop condition if a transaction failed, so the clock goes
back high.
BUG=chrome-os-partner:18969
BRANCH=none
TEST=i2cscan finds both the PMU at 0x90 and the battery at 0x16
Change-Id: I708b925e4e30da9d5864b74641b1cbe90c9313fe
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/49898
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r-- | board/pit/board.c | 12 | ||||
-rw-r--r-- | chip/stm32/i2c-stm32l15x.c | 24 |
2 files changed, 20 insertions, 16 deletions
diff --git a/board/pit/board.c b/board/pit/board.c index c7c124df6d..a8bdf5e930 100644 --- a/board/pit/board.c +++ b/board/pit/board.c @@ -56,14 +56,10 @@ const struct gpio_info gpio_list[GPIO_COUNT] = { {"EN_PP3300", GPIO_A, (1<<8), GPIO_OUT_LOW, NULL}, {"EN_PP5000", GPIO_A, (1<<11), GPIO_OUT_LOW, NULL}, {"ENTERING_RW", GPIO_H, (1<<0), GPIO_OUT_LOW, NULL}, - /* - * I2C pins should be configured as inputs until I2C module is - * initialized. This will avoid driving the lines unintentionally. - */ - {"I2C1_SCL", GPIO_B, (1<<6), GPIO_INPUT, NULL}, - {"I2C1_SDA", GPIO_B, (1<<7), GPIO_INPUT, NULL}, - {"I2C2_SCL", GPIO_B, (1<<10), GPIO_INPUT, NULL}, - {"I2C2_SDA", GPIO_B, (1<<11), GPIO_INPUT, NULL}, + {"I2C1_SCL", GPIO_B, (1<<6), GPIO_HI_Z, NULL}, + {"I2C1_SDA", GPIO_B, (1<<7), GPIO_HI_Z, NULL}, + {"I2C2_SCL", GPIO_B, (1<<10), GPIO_HI_Z, NULL}, + {"I2C2_SDA", GPIO_B, (1<<11), GPIO_HI_Z, NULL}, {"LED_POWER_L", GPIO_A, (1<<2), GPIO_OUT_HIGH, NULL}, {"PMIC_PWRON", GPIO_A, (1<<12), GPIO_OUT_LOW, NULL}, {"PMIC_RESET", GPIO_A, (1<<15), GPIO_OUT_LOW, NULL}, diff --git a/chip/stm32/i2c-stm32l15x.c b/chip/stm32/i2c-stm32l15x.c index c96b4e76e1..e3ff2cb0d1 100644 --- a/chip/stm32/i2c-stm32l15x.c +++ b/chip/stm32/i2c-stm32l15x.c @@ -77,8 +77,10 @@ static int wait_sr1(int port, int mask) /* Check for errors */ if (sr1 & (STM32_I2C_SR1_ARLO | STM32_I2C_SR1_BERR | - STM32_I2C_SR1_AF)) + STM32_I2C_SR1_AF)) { + dump_i2c_reg(port, "wait_sr1 failed"); return EC_ERROR_UNKNOWN; + } /* I2C is slow, so let other things run while we wait */ usleep(100); @@ -134,6 +136,8 @@ int i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_bytes, ASSERT(out || !out_bytes); ASSERT(in || !in_bytes); + dump_i2c_reg(port, "xfer start"); + /* Clear status */ /* * TODO: should check for any leftover error status, and reset the @@ -147,13 +151,11 @@ int i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_bytes, /* Clear start and stop bits */ STM32_I2C_CR1(port) &= ~(STM32_I2C_CR1_START | STM32_I2C_CR1_STOP); - dump_i2c_reg(port, "xfer start"); - if (out_bytes) { if (!started) { rv = send_start(port, slave_addr); if (rv) - return rv; + goto xfer_exit; } /* Write data, if any */ @@ -164,7 +166,7 @@ int i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_bytes, rv = wait_sr1(port, STM32_I2C_SR1_BTF); if (rv) - return rv; + goto xfer_exit; } /* Need repeated start condition before reading */ @@ -179,7 +181,7 @@ int i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_bytes, if (!started) { rv = send_start(port, slave_addr | 0x01); if (rv) - return rv; + goto xfer_exit; } /* Read data, if any */ @@ -200,8 +202,14 @@ int i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_bytes, } } - /* Success */ - return EC_SUCCESS; + xfer_exit: + /* On error, queue a stop condition */ + if (rv) { + STM32_I2C_CR1(port) |= STM32_I2C_CR1_STOP; + dump_i2c_reg(port, "stop after error"); + } + + return rv; } int i2c_get_line_levels(int port) |