Skip to content

Commit db4344b

Browse files
GTLin08kartben
authored andcommitted
drivers/i2c: ite: Use i2c_bitbang API for bus recovery
Replace the manually implemented GPIO-based I2C recovery logic with Zephyr's i2c_bitbang API. Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
1 parent 6f4b92d commit db4344b

File tree

3 files changed

+78
-74
lines changed

3 files changed

+78
-74
lines changed

drivers/i2c/Kconfig.it8xxx2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ config I2C_ITE_IT8XXX2
66
default y
77
depends on DT_HAS_ITE_IT8XXX2_I2C_ENABLED
88
select PINCTRL
9+
select I2C_BITBANG
910
help
1011
Enable I2C support on it8xxx2_evb.
1112
Supported Speeds: 100kHz, 400kHz and 1MHz.
@@ -32,6 +33,7 @@ config I2C_ITE_ENHANCE
3233
default y
3334
depends on DT_HAS_ITE_ENHANCE_I2C_ENABLED
3435
select PINCTRL
36+
select I2C_BITBANG
3537
help
3638
This option can enable the enhance I2C
3739
of IT8XXX2 and support three channels.

drivers/i2c/i2c_ite_enhance.c

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
#include <zephyr/logging/log.h>
2121
LOG_MODULE_REGISTER(i2c_ite_enhance, CONFIG_I2C_LOG_LEVEL);
22-
22+
#include "i2c_bitbang.h"
2323
#include "i2c-priv.h"
2424

2525
/* Start smbus session from idle state */
@@ -121,6 +121,7 @@ struct i2c_enhance_data {
121121
struct i2c_msg *active_msg;
122122
struct k_mutex mutex;
123123
struct k_sem device_sync_sem;
124+
struct i2c_bitbang bitbang;
124125
/* Index into output data */
125126
size_t widx;
126127
/* Index into input data */
@@ -1263,10 +1264,40 @@ static int i2c_enhance_init(const struct device *dev)
12631264
return 0;
12641265
}
12651266

1267+
static void i2c_enhance_set_scl(void *io_context, int state)
1268+
{
1269+
const struct i2c_enhance_config *config = io_context;
1270+
1271+
gpio_pin_set_dt(&config->scl_gpios, state);
1272+
}
1273+
1274+
static void i2c_enhance_set_sda(void *io_context, int state)
1275+
{
1276+
const struct i2c_enhance_config *config = io_context;
1277+
1278+
gpio_pin_set_dt(&config->sda_gpios, state);
1279+
}
1280+
1281+
static int i2c_enhance_get_sda(void *io_context)
1282+
{
1283+
const struct i2c_enhance_config *config = io_context;
1284+
int ret = gpio_pin_get_dt(&config->sda_gpios);
1285+
1286+
/* Default high as that would be a NACK */
1287+
return ret != 0;
1288+
}
1289+
1290+
static const struct i2c_bitbang_io i2c_enhance_bitbang_io = {
1291+
.set_scl = i2c_enhance_set_scl,
1292+
.set_sda = i2c_enhance_set_sda,
1293+
.get_sda = i2c_enhance_get_sda,
1294+
};
1295+
12661296
static int i2c_enhance_recover_bus(const struct device *dev)
12671297
{
12681298
const struct i2c_enhance_config *config = dev->config;
1269-
int i, status;
1299+
struct i2c_enhance_data *data = dev->data;
1300+
int status, ret;
12701301

12711302
/* Output type selection */
12721303
gpio_flags_t flags = GPIO_OUTPUT | (config->push_pull_recovery ? 0 : GPIO_OPEN_DRAIN);
@@ -1275,42 +1306,12 @@ static int i2c_enhance_recover_bus(const struct device *dev)
12751306
/* Set SDA of I2C as GPIO pin */
12761307
gpio_pin_configure_dt(&config->sda_gpios, flags);
12771308

1278-
/*
1279-
* In I2C recovery bus, 1ms sleep interval for bitbanging i2c
1280-
* is mainly to ensure that gpio has enough time to go from
1281-
* low to high or high to low.
1282-
*/
1283-
/* Pull SCL and SDA pin to high */
1284-
gpio_pin_set_dt(&config->scl_gpios, 1);
1285-
gpio_pin_set_dt(&config->sda_gpios, 1);
1286-
k_msleep(1);
1287-
1288-
/* Start condition */
1289-
gpio_pin_set_dt(&config->sda_gpios, 0);
1290-
k_msleep(1);
1291-
gpio_pin_set_dt(&config->scl_gpios, 0);
1292-
k_msleep(1);
1293-
1294-
/* 9 cycles of SCL with SDA held high */
1295-
for (i = 0; i < 9; i++) {
1296-
/* SDA */
1297-
gpio_pin_set_dt(&config->sda_gpios, 1);
1298-
/* SCL */
1299-
gpio_pin_set_dt(&config->scl_gpios, 1);
1300-
k_msleep(1);
1301-
/* SCL */
1302-
gpio_pin_set_dt(&config->scl_gpios, 0);
1303-
k_msleep(1);
1309+
i2c_bitbang_init(&data->bitbang, &i2c_enhance_bitbang_io, (void *)config);
1310+
1311+
ret = i2c_bitbang_recover_bus(&data->bitbang);
1312+
if (ret != 0) {
1313+
LOG_ERR("%s: Failed to recover bus (err %d)", dev->name, ret);
13041314
}
1305-
/* SDA */
1306-
gpio_pin_set_dt(&config->sda_gpios, 0);
1307-
k_msleep(1);
1308-
1309-
/* Stop condition */
1310-
gpio_pin_set_dt(&config->scl_gpios, 1);
1311-
k_msleep(1);
1312-
gpio_pin_set_dt(&config->sda_gpios, 1);
1313-
k_msleep(1);
13141315

13151316
/* Set GPIO back to I2C alternate function */
13161317
status = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);

drivers/i2c/i2c_ite_it8xxx2.c

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
#include <zephyr/logging/log.h>
2323
LOG_MODULE_REGISTER(i2c_ite_it8xxx2, CONFIG_I2C_LOG_LEVEL);
24-
24+
#include "i2c_bitbang.h"
2525
#include "i2c-priv.h"
2626

2727
/* Start smbus session from idle state */
@@ -74,6 +74,7 @@ struct i2c_it8xxx2_data {
7474
struct i2c_msg *active_msg;
7575
struct k_mutex mutex;
7676
struct k_sem device_sync_sem;
77+
struct i2c_bitbang bitbang;
7778
#ifdef CONFIG_I2C_IT8XXX2_FIFO_MODE
7879
struct i2c_msg *msgs_list;
7980
/* Read or write byte counts. */
@@ -1186,10 +1187,40 @@ static int i2c_it8xxx2_init(const struct device *dev)
11861187
return 0;
11871188
}
11881189

1190+
static void i2c_it8xxx2_set_scl(void *io_context, int state)
1191+
{
1192+
const struct i2c_it8xxx2_config *config = io_context;
1193+
1194+
gpio_pin_set_dt(&config->scl_gpios, state);
1195+
}
1196+
1197+
static void i2c_it8xxx2_set_sda(void *io_context, int state)
1198+
{
1199+
const struct i2c_it8xxx2_config *config = io_context;
1200+
1201+
gpio_pin_set_dt(&config->sda_gpios, state);
1202+
}
1203+
1204+
static int i2c_it8xxx2_get_sda(void *io_context)
1205+
{
1206+
const struct i2c_it8xxx2_config *config = io_context;
1207+
int ret = gpio_pin_get_dt(&config->sda_gpios);
1208+
1209+
/* Default high as that would be a NACK */
1210+
return ret != 0;
1211+
}
1212+
1213+
static const struct i2c_bitbang_io i2c_it8xxx2_bitbang_io = {
1214+
.set_scl = i2c_it8xxx2_set_scl,
1215+
.set_sda = i2c_it8xxx2_set_sda,
1216+
.get_sda = i2c_it8xxx2_get_sda,
1217+
};
1218+
11891219
static int i2c_it8xxx2_recover_bus(const struct device *dev)
11901220
{
11911221
const struct i2c_it8xxx2_config *config = dev->config;
1192-
int i, status;
1222+
struct i2c_it8xxx2_data *data = dev->data;
1223+
int status, ret;
11931224

11941225
/* Output type selection */
11951226
gpio_flags_t flags = GPIO_OUTPUT | (config->push_pull_recovery ? 0 : GPIO_OPEN_DRAIN);
@@ -1198,42 +1229,12 @@ static int i2c_it8xxx2_recover_bus(const struct device *dev)
11981229
/* Set SDA of I2C as GPIO pin */
11991230
gpio_pin_configure_dt(&config->sda_gpios, flags);
12001231

1201-
/*
1202-
* In I2C recovery bus, 1ms sleep interval for bitbanging i2c
1203-
* is mainly to ensure that gpio has enough time to go from
1204-
* low to high or high to low.
1205-
*/
1206-
/* Pull SCL and SDA pin to high */
1207-
gpio_pin_set_dt(&config->scl_gpios, 1);
1208-
gpio_pin_set_dt(&config->sda_gpios, 1);
1209-
k_msleep(1);
1210-
1211-
/* Start condition */
1212-
gpio_pin_set_dt(&config->sda_gpios, 0);
1213-
k_msleep(1);
1214-
gpio_pin_set_dt(&config->scl_gpios, 0);
1215-
k_msleep(1);
1216-
1217-
/* 9 cycles of SCL with SDA held high */
1218-
for (i = 0; i < 9; i++) {
1219-
/* SDA */
1220-
gpio_pin_set_dt(&config->sda_gpios, 1);
1221-
/* SCL */
1222-
gpio_pin_set_dt(&config->scl_gpios, 1);
1223-
k_msleep(1);
1224-
/* SCL */
1225-
gpio_pin_set_dt(&config->scl_gpios, 0);
1226-
k_msleep(1);
1232+
i2c_bitbang_init(&data->bitbang, &i2c_it8xxx2_bitbang_io, (void *)config);
1233+
1234+
ret = i2c_bitbang_recover_bus(&data->bitbang);
1235+
if (ret != 0) {
1236+
LOG_ERR("%s: Failed to recover bus (err %d)", dev->name, ret);
12271237
}
1228-
/* SDA */
1229-
gpio_pin_set_dt(&config->sda_gpios, 0);
1230-
k_msleep(1);
1231-
1232-
/* Stop condition */
1233-
gpio_pin_set_dt(&config->scl_gpios, 1);
1234-
k_msleep(1);
1235-
gpio_pin_set_dt(&config->sda_gpios, 1);
1236-
k_msleep(1);
12371238

12381239
/* Set GPIO back to I2C alternate function of SCL */
12391240
status = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);

0 commit comments

Comments
 (0)