ITE: drivers/i2c: Enable I2C interrupt after completing configuration
Fix the flow of I2C enable interrupt. We should enable the interrupt after I2C configuration is completed to avoid pending interrupts and cause errors irq. Test port: i2c_ite_it8xxx2: i2c0 i2c_ite_enhance: i2c4 Test: tests\drivers\i2c\i2c_api --> pass Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
This commit is contained in:
parent
64af112d30
commit
19724ba002
2 changed files with 32 additions and 15 deletions
|
@ -382,8 +382,6 @@ static int enhanced_i2c_tran_read(const struct device *dev)
|
||||||
i2c_pio_trans_data(dev, RX_DIRECT,
|
i2c_pio_trans_data(dev, RX_DIRECT,
|
||||||
data->addr_16bit << 1, 1);
|
data->addr_16bit << 1, 1);
|
||||||
}
|
}
|
||||||
/* Turn on irq before next direct read */
|
|
||||||
irq_enable(config->i2c_irq_base);
|
|
||||||
} else {
|
} else {
|
||||||
if (data->ridx < data->msgs->len) {
|
if (data->ridx < data->msgs->len) {
|
||||||
/* read data */
|
/* read data */
|
||||||
|
@ -434,7 +432,6 @@ static int enhanced_i2c_tran_write(const struct device *dev)
|
||||||
i2c_pio_trans_data(dev, TX_DIRECT, out_data, 0);
|
i2c_pio_trans_data(dev, TX_DIRECT, out_data, 0);
|
||||||
if (data->i2ccs == I2C_CH_WAIT_NEXT_XFER) {
|
if (data->i2ccs == I2C_CH_WAIT_NEXT_XFER) {
|
||||||
data->i2ccs = I2C_CH_NORMAL;
|
data->i2ccs = I2C_CH_NORMAL;
|
||||||
irq_enable(config->i2c_irq_base);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* done */
|
/* done */
|
||||||
|
@ -462,10 +459,14 @@ static int i2c_transaction(const struct device *dev)
|
||||||
/* no error */
|
/* no error */
|
||||||
if (!(enhanced_i2c_error(dev))) {
|
if (!(enhanced_i2c_error(dev))) {
|
||||||
if (!data->stop) {
|
if (!data->stop) {
|
||||||
/* i2c read */
|
/*
|
||||||
|
* The return value indicates if there is more data
|
||||||
|
* to be read or written. If the return value = 1,
|
||||||
|
* it means that the interrupt cannot be disable and
|
||||||
|
* continue to transmit data.
|
||||||
|
*/
|
||||||
if (data->msgs->flags & I2C_MSG_READ) {
|
if (data->msgs->flags & I2C_MSG_READ) {
|
||||||
return enhanced_i2c_tran_read(dev);
|
return enhanced_i2c_tran_read(dev);
|
||||||
/* i2c write */
|
|
||||||
} else {
|
} else {
|
||||||
return enhanced_i2c_tran_write(dev);
|
return enhanced_i2c_tran_write(dev);
|
||||||
}
|
}
|
||||||
|
@ -523,11 +524,17 @@ static int i2c_enhance_transfer(const struct device *dev, struct i2c_msg *msgs,
|
||||||
|
|
||||||
if (msgs->flags & I2C_MSG_START) {
|
if (msgs->flags & I2C_MSG_START) {
|
||||||
data->i2ccs = I2C_CH_NORMAL;
|
data->i2ccs = I2C_CH_NORMAL;
|
||||||
/* enable i2c interrupt */
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start transaction.
|
||||||
|
* The return value indicates if the initial configuration
|
||||||
|
* of I2C transaction for read or write has been completed.
|
||||||
|
*/
|
||||||
|
if (i2c_transaction(dev)) {
|
||||||
|
/* Enable I2C interrupt. */
|
||||||
irq_enable(config->i2c_irq_base);
|
irq_enable(config->i2c_irq_base);
|
||||||
}
|
}
|
||||||
/* Start transaction */
|
|
||||||
i2c_transaction(dev);
|
|
||||||
/* Wait for the transfer to complete */
|
/* Wait for the transfer to complete */
|
||||||
/* TODO: the timeout should be adjustable */
|
/* TODO: the timeout should be adjustable */
|
||||||
res = k_sem_take(&data->device_sync_sem, K_MSEC(100));
|
res = k_sem_take(&data->device_sync_sem, K_MSEC(100));
|
||||||
|
@ -575,8 +582,8 @@ static void i2c_enhance_isr(void *arg)
|
||||||
|
|
||||||
/* If done doing work, wake up the task waiting for the transfer */
|
/* If done doing work, wake up the task waiting for the transfer */
|
||||||
if (!i2c_transaction(dev)) {
|
if (!i2c_transaction(dev)) {
|
||||||
k_sem_give(&data->device_sync_sem);
|
|
||||||
irq_disable(config->i2c_irq_base);
|
irq_disable(config->i2c_irq_base);
|
||||||
|
k_sem_give(&data->device_sync_sem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -359,7 +359,6 @@ static int i2c_tran_read(const struct device *dev)
|
||||||
IT8XXX2_SMB_HOSTA(base) = HOSTA_NEXT_BYTE;
|
IT8XXX2_SMB_HOSTA(base) = HOSTA_NEXT_BYTE;
|
||||||
}
|
}
|
||||||
data->i2ccs = I2C_CH_NORMAL;
|
data->i2ccs = I2C_CH_NORMAL;
|
||||||
irq_enable(config->i2c_irq_base);
|
|
||||||
} else if (IT8XXX2_SMB_HOSTA(base) & HOSTA_BDS) {
|
} else if (IT8XXX2_SMB_HOSTA(base) & HOSTA_BDS) {
|
||||||
if (data->ridx < data->msgs->len) {
|
if (data->ridx < data->msgs->len) {
|
||||||
/* To get received data. */
|
/* To get received data. */
|
||||||
|
@ -435,7 +434,6 @@ static int i2c_tran_write(const struct device *dev)
|
||||||
|
|
||||||
if (data->i2ccs == I2C_CH_REPEAT_START) {
|
if (data->i2ccs == I2C_CH_REPEAT_START) {
|
||||||
data->i2ccs = I2C_CH_NORMAL;
|
data->i2ccs = I2C_CH_NORMAL;
|
||||||
irq_enable(config->i2c_irq_base);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* done */
|
/* done */
|
||||||
|
@ -470,6 +468,12 @@ static int i2c_transaction(const struct device *dev)
|
||||||
data->err = (IT8XXX2_SMB_HOSTA(base) & HOSTA_ANY_ERROR);
|
data->err = (IT8XXX2_SMB_HOSTA(base) & HOSTA_ANY_ERROR);
|
||||||
} else {
|
} else {
|
||||||
if (!data->stop) {
|
if (!data->stop) {
|
||||||
|
/*
|
||||||
|
* The return value indicates if there is more data
|
||||||
|
* to be read or written. If the return value = 1,
|
||||||
|
* it means that the interrupt cannot be disable and
|
||||||
|
* continue to transmit data.
|
||||||
|
*/
|
||||||
if (data->msgs->flags & I2C_MSG_READ) {
|
if (data->msgs->flags & I2C_MSG_READ) {
|
||||||
return i2c_tran_read(dev);
|
return i2c_tran_read(dev);
|
||||||
} else {
|
} else {
|
||||||
|
@ -534,11 +538,17 @@ static int i2c_it8xxx2_transfer(const struct device *dev, struct i2c_msg *msgs,
|
||||||
|
|
||||||
if (msgs->flags & I2C_MSG_START) {
|
if (msgs->flags & I2C_MSG_START) {
|
||||||
data->i2ccs = I2C_CH_NORMAL;
|
data->i2ccs = I2C_CH_NORMAL;
|
||||||
/* enable i2c interrupt */
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start transaction.
|
||||||
|
* The return value indicates if the initial configuration
|
||||||
|
* of I2C transaction for read or write has been completed.
|
||||||
|
*/
|
||||||
|
if (i2c_transaction(dev)) {
|
||||||
|
/* Enable I2C interrupt. */
|
||||||
irq_enable(config->i2c_irq_base);
|
irq_enable(config->i2c_irq_base);
|
||||||
}
|
}
|
||||||
/* Start transaction */
|
|
||||||
i2c_transaction(dev);
|
|
||||||
/* Wait for the transfer to complete */
|
/* Wait for the transfer to complete */
|
||||||
/* TODO: the timeout should be adjustable */
|
/* TODO: the timeout should be adjustable */
|
||||||
res = k_sem_take(&data->device_sync_sem, K_MSEC(100));
|
res = k_sem_take(&data->device_sync_sem, K_MSEC(100));
|
||||||
|
@ -585,8 +595,8 @@ static void i2c_it8xxx2_isr(const struct device *dev)
|
||||||
|
|
||||||
/* If done doing work, wake up the task waiting for the transfer */
|
/* If done doing work, wake up the task waiting for the transfer */
|
||||||
if (!i2c_transaction(dev)) {
|
if (!i2c_transaction(dev)) {
|
||||||
k_sem_give(&data->device_sync_sem);
|
|
||||||
irq_disable(config->i2c_irq_base);
|
irq_disable(config->i2c_irq_base);
|
||||||
|
k_sem_give(&data->device_sync_sem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue