summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-05-02 10:06:15 -0700
committerChromeBot <chrome-bot@google.com>2013-05-02 12:05:49 -0700
commit3e76215df46fbcfb8fa0920b448c2dab7c098914 (patch)
tree0b19a152471d7efb3c88764c27be9ea5233b5f97
parent001fb660bdbe49d3240f20bc67be0ee67ee8b562 (diff)
downloadchrome-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.c12
-rw-r--r--chip/stm32/i2c-stm32l15x.c24
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)