A27系列优化I2C/RTC处理,新增版本A270Y
This commit is contained in:
@ -263,9 +263,9 @@
|
||||
|
||||
#ifdef WIFI_SUPPORT
|
||||
#define CARLINK_EY 0
|
||||
#define CARLINK_EC 0
|
||||
#define CARLINK_CP 1
|
||||
#define CARLINK_AA 1
|
||||
#define CARLINK_EC 1
|
||||
#define CARLINK_CP 0
|
||||
#define CARLINK_AA 0
|
||||
|
||||
#if !DEVICE_MXC_A27
|
||||
#define WIFI_RESET_IO 12
|
||||
|
@ -60,6 +60,7 @@ extern "C" {
|
||||
#define DW_IC_RXFLR 0x78
|
||||
#define DW_IC_SDA_HOLD 0x7c
|
||||
#define DW_IC_TX_ABRT_SOURCE 0x80
|
||||
#define DW_IC_TX_PHASE_DELAY 0x84
|
||||
#define DW_IC_ENABLE_STATUS 0x9c
|
||||
#define DW_IC_CLR_RESTART_DET 0xa8
|
||||
#define DW_IC_COMP_PARAM_1 0xf4
|
||||
|
@ -6,6 +6,10 @@
|
||||
#include "board.h"
|
||||
#include "errno.h"
|
||||
|
||||
#define DW_IC_STATUS_TFNF BIT(1)
|
||||
#define DW_IC_STATUS_RFF BIT(4)
|
||||
#define DW_IC_FIFO_DEPTH 8
|
||||
|
||||
|
||||
#if defined(HW_I2C0_SUPPORT) || defined(HW_I2C1_SUPPORT)
|
||||
static char *abort_sources[] = {
|
||||
@ -453,6 +457,9 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
|
||||
/* Disable the adapter */
|
||||
__i2c_dw_disable(dev);
|
||||
|
||||
/* Clear interrupts */
|
||||
dw_readl(dev, DW_IC_CLR_INTR);
|
||||
|
||||
/* Write standard speed timing parameters */
|
||||
dw_writel(dev, dev->ss_hcnt, DW_IC_SS_SCL_HCNT);
|
||||
dw_writel(dev, dev->ss_lcnt, DW_IC_SS_SCL_LCNT);
|
||||
@ -512,6 +519,8 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
|
||||
/* Enforce disabled interrupts (due to HW issues) */
|
||||
i2c_dw_disable_int(dev);
|
||||
|
||||
dw_writel(dev, 8, DW_IC_TX_PHASE_DELAY);
|
||||
|
||||
/* Enable the adapter */
|
||||
__i2c_dw_enable(dev);
|
||||
|
||||
@ -539,6 +548,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
|
||||
u32 buf_len = dev->tx_buf_len;
|
||||
u8 *buf = dev->tx_buf;
|
||||
int need_restart = 0;
|
||||
u32 status;
|
||||
|
||||
intr_mask = DW_IC_INTR_MASTER_MASK;
|
||||
|
||||
@ -576,8 +586,17 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
|
||||
need_restart = 1;
|
||||
}
|
||||
|
||||
tx_limit = dev->tx_fifo_depth - dw_readl(dev, DW_IC_TXFLR);
|
||||
rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR);
|
||||
status = dw_readl(dev, DW_IC_STATUS);
|
||||
tx_limit = dw_readl(dev, DW_IC_TXFLR);
|
||||
if (tx_limit == 0 && !(status & DW_IC_STATUS_TFNF))
|
||||
tx_limit = 0;
|
||||
else
|
||||
tx_limit = dev->tx_fifo_depth - tx_limit;
|
||||
rx_limit = dw_readl(dev, DW_IC_RXFLR);
|
||||
if (rx_limit == 0 && (status & DW_IC_STATUS_RFF))
|
||||
rx_limit = 0;
|
||||
else
|
||||
rx_limit = dev->rx_fifo_depth - rx_limit;
|
||||
|
||||
while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) {
|
||||
u32 cmd = 0;
|
||||
@ -671,6 +690,7 @@ i2c_dw_read(struct dw_i2c_dev *dev)
|
||||
{
|
||||
struct i2c_msg *msgs = dev->msgs;
|
||||
int rx_valid;
|
||||
u32 status;
|
||||
|
||||
for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) {
|
||||
u32 len;
|
||||
@ -687,7 +707,10 @@ i2c_dw_read(struct dw_i2c_dev *dev)
|
||||
buf = dev->rx_buf;
|
||||
}
|
||||
|
||||
status = dw_readl(dev, DW_IC_STATUS);
|
||||
rx_valid = dw_readl(dev, DW_IC_RXFLR);
|
||||
if (rx_valid == 0 && (status & DW_IC_STATUS_RFF))
|
||||
rx_valid = DW_IC_FIFO_DEPTH;
|
||||
|
||||
for (; len > 0 && rx_valid > 0; len--, rx_valid--) {
|
||||
u32 flags = msgs[dev->msg_read_idx].flags;
|
||||
@ -752,6 +775,14 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!dev->cmd_err && dev->status/* == STATUS_READ_IN_PROGRESS*/) {
|
||||
u32 stick = xTaskGetTickCount();
|
||||
while (dev->status) {
|
||||
if (xTaskGetTickCount() - stick > pdMS_TO_TICKS(500))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We must disable the adapter before returning and signaling the end
|
||||
* of the current transfer. Otherwise the hardware might continue
|
||||
@ -961,8 +992,10 @@ static void i2c_dw_isr(void *dev_id)
|
||||
enabled = dw_readl(dev, DW_IC_ENABLE);
|
||||
stat = dw_readl(dev, DW_IC_RAW_INTR_STAT);
|
||||
TRACE_DEBUG("enabled=%#x stat=%#x\n", enabled, stat);
|
||||
if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY))
|
||||
if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) {
|
||||
dw_readl(dev, DW_IC_CLR_INTR);
|
||||
return;
|
||||
}
|
||||
|
||||
i2c_dw_irq_handler_master(dev);
|
||||
}
|
||||
|
Reference in New Issue
Block a user