summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2015-06-02 18:26:43 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-06-03 21:01:26 +0000
commit904bf6f5758a301103e598a1514a2d9de1577c12 (patch)
treedb8165a2be39e0597c95d315be0779420528bbbb
parentc70fb0f9ebeb175671a0b662048ad3a6531fe91f (diff)
downloadchrome-ec-904bf6f5758a301103e598a1514a2d9de1577c12.tar.gz
mec1322: Implement i2c_set_timeout
Allow timeout to be set at runtime by controller. BUG=chrome-os-partner:40780 TEST=Manual on Glados. Verify PD I2C communication is functional. BRANCH=None Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: I582e47c7bebfed7a639789c90064d86ffe1a5401 Reviewed-on: https://chromium-review.googlesource.com/274967 Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--board/glados/board.c7
-rw-r--r--chip/lm4/i2c.c3
-rw-r--r--chip/mec1322/i2c.c28
-rw-r--r--include/i2c.h3
4 files changed, 26 insertions, 15 deletions
diff --git a/board/glados/board.c b/board/glados/board.c
index 7645929225..7cf45cfa6a 100644
--- a/board/glados/board.c
+++ b/board/glados/board.c
@@ -95,13 +95,6 @@ void board_reset_pd_mcu(void)
gpio_set_level(GPIO_PD_RST_L, 1);
}
-void __board_i2c_set_timeout(int port, uint32_t timeout)
-{
-}
-
-void i2c_set_timeout(int port, uint32_t timeout)
- __attribute__((weak, alias("__board_i2c_set_timeout")));
-
struct motion_sensor_t motion_sensors[] = {
};
diff --git a/chip/lm4/i2c.c b/chip/lm4/i2c.c
index 72d02d2043..9f3db7426f 100644
--- a/chip/lm4/i2c.c
+++ b/chip/lm4/i2c.c
@@ -48,9 +48,6 @@
*/
#define I2C_IDLE_US 500
-/* Default maximum time we allow for an I2C transfer */
-#define I2C_TIMEOUT_DEFAULT_US (100 * MSEC)
-
/* IRQ for each port */
static const uint32_t i2c_irqs[] = {LM4_IRQ_I2C0, LM4_IRQ_I2C1, LM4_IRQ_I2C2,
LM4_IRQ_I2C3, LM4_IRQ_I2C4, LM4_IRQ_I2C5};
diff --git a/chip/mec1322/i2c.c b/chip/mec1322/i2c.c
index b826a3f661..df08479ab0 100644
--- a/chip/mec1322/i2c.c
+++ b/chip/mec1322/i2c.c
@@ -38,7 +38,13 @@
/* Maximum transfer of a SMBUS block transfer */
#define SMBUS_MAX_BLOCK_SIZE 32
-static task_id_t task_waiting_on_controller[I2C_CONTROLLER_COUNT];
+/* I2C controller state data */
+struct {
+ /* Transaction timeout, or 0 to use default. */
+ uint32_t timeout_us;
+ /* Task waiting on port, or TASK_ID_INVALID if none. */
+ task_id_t task_waiting;
+} cdata[I2C_CONTROLLER_COUNT];
static void configure_controller_speed(int controller, int kbps)
{
@@ -111,7 +117,7 @@ static void reset_controller(int controller)
static int wait_for_interrupt(int controller, int *event)
{
- task_waiting_on_controller[controller] = task_get_current();
+ cdata[controller].task_waiting = task_get_current();
task_enable_irq(MEC1322_IRQ_I2C_0 + controller);
/*
* We want to wait here quietly until the I2C interrupt comes
@@ -121,8 +127,9 @@ static int wait_for_interrupt(int controller, int *event)
* the I2C is either completed or timed out. Refer to the
* implementation of usleep() for a similar situation.
*/
- *event |= (task_wait_event(SECOND) & ~TASK_EVENT_I2C_IDLE);
- task_waiting_on_controller[controller] = TASK_ID_INVALID;
+ *event |= (task_wait_event(cdata[controller].timeout_us)
+ & ~TASK_EVENT_I2C_IDLE);
+ cdata[controller].task_waiting = TASK_ID_INVALID;
if (*event & TASK_EVENT_TIMER) {
/* Restore any events that we saw while waiting */
task_set_event(task_get_current(),
@@ -398,6 +405,13 @@ int i2c_port_to_controller(int port)
return (port == MEC1322_I2C0_0) ? 0 : port - 1;
}
+void i2c_set_timeout(int port, uint32_t timeout)
+{
+ /* Param is port, but timeout is stored by-controller. */
+ cdata[i2c_port_to_controller(port)].timeout_us =
+ timeout ? timeout : I2C_TIMEOUT_DEFAULT_US;
+}
+
static void i2c_init(void)
{
int i;
@@ -422,13 +436,17 @@ static void i2c_init(void)
controller0_kbps = i2c_ports[i].kbps;
}
configure_controller(controller, i2c_ports[i].kbps);
+ cdata[controller].task_waiting = TASK_ID_INVALID;
+
+ /* Use default timeout. */
+ i2c_set_timeout(i2c_ports[i].port, 0);
}
}
DECLARE_HOOK(HOOK_INIT, i2c_init, HOOK_PRIO_INIT_I2C);
static void handle_interrupt(int controller)
{
- int id = task_waiting_on_controller[controller];
+ int id = cdata[controller].task_waiting;
/* Clear the interrupt status */
MEC1322_I2C_COMPLETE(controller) |= 1 << 29;
diff --git a/include/i2c.h b/include/i2c.h
index f3495bac41..798c831318 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -145,6 +145,9 @@ int i2c_raw_mode(int port, int enable);
*/
void i2c_lock(int port, int lock);
+/* Default maximum time we allow for an I2C transfer */
+#define I2C_TIMEOUT_DEFAULT_US (100 * MSEC)
+
/**
* Set the timeout for an I2C transaction.
*