diff options
-rw-r--r-- | board/glados/board.c | 7 | ||||
-rw-r--r-- | chip/lm4/i2c.c | 3 | ||||
-rw-r--r-- | chip/mec1322/i2c.c | 28 | ||||
-rw-r--r-- | include/i2c.h | 3 |
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. * |