summaryrefslogtreecommitdiff
path: root/common/i2c_controller.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/i2c_controller.c')
-rw-r--r--common/i2c_controller.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/common/i2c_controller.c b/common/i2c_controller.c
index f2d1cf4a5f..92234bc600 100644
--- a/common/i2c_controller.c
+++ b/common/i2c_controller.c
@@ -100,13 +100,23 @@ const struct i2c_port_t *get_i2c_port(const int port)
{
int i;
- /* Find the matching port in i2c_ports[] table. */
- for (i = 0; i < i2c_ports_used; i++) {
- if (i2c_ports[i].port == port)
- return &i2c_ports[i];
+ /*
+ * If the EC's I2C driver implementation is task event based and the
+ * I2C is accessed before the task is initialized, it causes the system
+ * panic hence these I2C will fall back to bitbang mode if enabled at
+ * board level and will again switch back to event based I2C upon task
+ * initialization.
+ */
+ if (task_start_called()) {
+ /* Find the matching port in i2c_ports[] table. */
+ for (i = 0; i < i2c_ports_used; i++) {
+ if (i2c_ports[i].port == port)
+ return &i2c_ports[i];
+ }
}
if (IS_ENABLED(CONFIG_I2C_BITBANG)) {
+ /* Find the matching port in i2c_bitbang_ports[] table. */
for (i = 0; i < i2c_bitbang_ports_used; i++) {
if (i2c_bitbang_ports[i].port == port)
return &i2c_bitbang_ports[i];
@@ -137,6 +147,7 @@ __maybe_unused static int chip_i2c_xfer_with_notify(
* remove the flag so it won't confuse chip driver.
*/
no_pec_af &= ~I2C_FLAG_PEC;
+
if (i2c_port->drv)
ret = i2c_port->drv->xfer(i2c_port, no_pec_af,
out, out_size, in, in_size, flags);