mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-14 10:28:54 +00:00
V1.0.5
This commit is contained in:
@@ -5,53 +5,394 @@
|
||||
*
|
||||
* Authors: Geo <guojun.dong@artinchip.com>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <sys_freq.h>
|
||||
#include <rtconfig.h>
|
||||
#include <rtdef.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <aic_core.h>
|
||||
#include <aic_soc.h>
|
||||
#include <aic_arch.h>
|
||||
#include <aic_common.h>
|
||||
#include <aic_io.h>
|
||||
#include <aic_errno.h>
|
||||
#include <aic_list.h>
|
||||
#include <aic_osal.h>
|
||||
#include <drivers/i2c.h>
|
||||
#include <aic_hal_gpio.h>
|
||||
#include <hal_i2c.h>
|
||||
|
||||
#ifndef AIC_DEV_I2C0_10BIT
|
||||
#define AIC_DEV_I2C0_10BIT 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C1_10BIT
|
||||
#define AIC_DEV_I2C1_10BIT 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C2_10BIT
|
||||
#define AIC_DEV_I2C2_10BIT 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C3_10BIT
|
||||
#define AIC_DEV_I2C3_10BIT 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C4_10BIT
|
||||
#define AIC_DEV_I2C4_10BIT 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_SP_I2C_10BIT
|
||||
#define AIC_DEV_SP_I2C_10BIT 0
|
||||
#endif
|
||||
|
||||
#ifndef AIC_DEV_I2C0_100K_SPEED
|
||||
#define AIC_DEV_I2C0_100K_SPEED 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C1_100K_SPEED
|
||||
#define AIC_DEV_I2C1_100K_SPEED 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C2_100K_SPEED
|
||||
#define AIC_DEV_I2C2_100K_SPEED 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C3_100K_SPEED
|
||||
#define AIC_DEV_I2C3_100K_SPEED 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C4_100K_SPEED
|
||||
#define AIC_DEV_I2C4_100K_SPEED 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_SP_I2C_100K_SPEED
|
||||
#define AIC_DEV_SP_I2C_100K_SPEED 0
|
||||
#endif
|
||||
|
||||
#ifndef AIC_DEV_I2C0_SLAVE_MODE
|
||||
#define AIC_DEV_I2C0_SLAVE_MODE 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C1_SLAVE_MODE
|
||||
#define AIC_DEV_I2C1_SLAVE_MODE 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C2_SLAVE_MODE
|
||||
#define AIC_DEV_I2C2_SLAVE_MODE 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C3_SLAVE_MODE
|
||||
#define AIC_DEV_I2C3_SLAVE_MODE 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C4_SLAVE_MODE
|
||||
#define AIC_DEV_I2C4_SLAVE_MODE 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_SP_I2C_SLAVE_MODE
|
||||
#define AIC_DEV_SP_I2C_SLAVE_MODE 0
|
||||
#endif
|
||||
|
||||
#ifndef AIC_DEV_I2C0_SLAVE_ADDR
|
||||
#define AIC_DEV_I2C0_SLAVE_ADDR 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C1_SLAVE_ADDR
|
||||
#define AIC_DEV_I2C1_SLAVE_ADDR 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C2_SLAVE_ADDR
|
||||
#define AIC_DEV_I2C2_SLAVE_ADDR 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C3_SLAVE_ADDR
|
||||
#define AIC_DEV_I2C3_SLAVE_ADDR 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_I2C4_SLAVE_ADDR
|
||||
#define AIC_DEV_I2C4_SLAVE_ADDR 0
|
||||
#endif
|
||||
#ifndef AIC_DEV_SP_I2C_SLAVE_ADDR
|
||||
#define AIC_DEV_SP_I2C_SLAVE_ADDR 0
|
||||
#endif
|
||||
|
||||
struct aic_i2c_bus {
|
||||
struct rt_i2c_bus_device bus;
|
||||
uint8_t index;
|
||||
uint32_t reg_base;
|
||||
char *device_name;
|
||||
aic_i2c_ctrl aic_bus;
|
||||
struct rt_completion cmd_complete;
|
||||
};
|
||||
|
||||
static struct aic_i2c_bus g_aic_i2c_dev[AIC_I2C_CH_NUM];
|
||||
|
||||
irqreturn_t aic_i2c_slave_irqhandler(int irq, void * data)
|
||||
{
|
||||
int index = irq - I2C0_IRQn;
|
||||
uint32_t intr_stat;
|
||||
uint8_t val;
|
||||
uint8_t fifo_num;
|
||||
struct slave_param parm;
|
||||
aic_i2c_ctrl *i2c_dev;
|
||||
|
||||
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
|
||||
intr_stat = hal_i2c_get_raw_interrupt_state(i2c_dev);
|
||||
fifo_num = hal_i2c_get_receive_fifo_num(i2c_dev);
|
||||
|
||||
if (!i2c_dev->slave.slave_cb)
|
||||
{
|
||||
/*
|
||||
* if the slave is not registered, we need to read the fifo empty
|
||||
* to avoid interrupts from being triggered continuously
|
||||
*/
|
||||
for (int i = 0; i < fifo_num; i++)
|
||||
hal_i2c_get_receive_data(i2c_dev);
|
||||
|
||||
hal_i2c_clear_all_irq_flags(i2c_dev);
|
||||
pr_debug("slave callback not register!\n");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
|
||||
if (intr_stat & I2C_INTR_START_DET) {
|
||||
parm.cmd = I2C_SLAVE_WRITE_REQUESTED;
|
||||
parm.arg = &val;
|
||||
i2c_dev->slave.slave_cb((void *)&parm);
|
||||
hal_i2c_clear_irq_flags(i2c_dev, I2C_INTR_START_DET);
|
||||
}
|
||||
|
||||
if (intr_stat & I2C_INTR_RX_FULL) {
|
||||
val = hal_i2c_get_receive_data(i2c_dev);
|
||||
parm.cmd = I2C_SLAVE_WRITE_RECEIVED;
|
||||
parm.arg = &val;
|
||||
if (!i2c_dev->slave.slave_cb((void *)&parm)) {
|
||||
pr_debug("Byte 0x%02x acked!\n", val);
|
||||
}
|
||||
hal_i2c_clear_irq_flags(i2c_dev, I2C_INTR_RX_FULL);
|
||||
}
|
||||
|
||||
if (intr_stat & I2C_INTR_RD_REQ) {
|
||||
parm.cmd = I2C_SLAVE_READ_REQUESTED;
|
||||
parm.arg = &val;
|
||||
i2c_dev->slave.slave_cb((void *)&parm);
|
||||
hal_i2c_transmit_data(i2c_dev, *parm.arg);
|
||||
|
||||
parm.cmd = I2C_SLAVE_READ_PROCESSED;
|
||||
parm.arg = &val;
|
||||
i2c_dev->slave.slave_cb((void *)&parm);
|
||||
hal_i2c_clear_irq_flags(i2c_dev, I2C_INTR_RD_REQ);
|
||||
}
|
||||
|
||||
if (intr_stat & I2C_INTR_RX_DONE) {
|
||||
parm.cmd = I2C_SLAVE_STOP;
|
||||
parm.arg = &val;
|
||||
i2c_dev->slave.slave_cb((void *)&parm);
|
||||
hal_i2c_clear_irq_flags(i2c_dev, I2C_INTR_RX_DONE);
|
||||
}
|
||||
|
||||
if (intr_stat & I2C_INTR_RX_UNDER) {
|
||||
hal_i2c_clear_irq_flags(i2c_dev, I2C_INTR_RX_UNDER);
|
||||
}
|
||||
|
||||
if (intr_stat & I2C_INTR_TX_ABRT) {
|
||||
hal_i2c_clear_irq_flags(i2c_dev, I2C_INTR_TX_ABRT);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#ifdef AIC_I2C_INTERRUPT_MODE
|
||||
static void aic_i2c_handle_read(struct aic_i2c_ctrl *i2c_dev)
|
||||
{
|
||||
struct aic_i2c_msg *msg = i2c_dev->msg;
|
||||
int rx_valid;
|
||||
uint32_t idx;
|
||||
|
||||
idx = i2c_dev->index;
|
||||
rx_valid = hal_i2c_get_receive_fifo_num(i2c_dev);
|
||||
|
||||
while (rx_valid--) {
|
||||
msg->buf[i2c_dev->buf_read_idx++] = hal_i2c_get_receive_data(i2c_dev);
|
||||
}
|
||||
|
||||
/* message transfer done if it is a read message */
|
||||
if (i2c_dev->buf_read_idx == msg->len) {
|
||||
hal_i2c_disable_all_irq(i2c_dev);
|
||||
rt_completion_done(&g_aic_i2c_dev[idx].cmd_complete);
|
||||
}
|
||||
}
|
||||
|
||||
static void aic_i2c_handle_write(struct aic_i2c_ctrl *i2c_dev)
|
||||
{
|
||||
struct aic_i2c_msg *msg = i2c_dev->msg;
|
||||
int rx_valid, tx_valid, buf_len;
|
||||
uint32_t intr_mask = I2C_INTR_MASTER_MASK;
|
||||
uint32_t idx;
|
||||
|
||||
idx = i2c_dev->index;
|
||||
|
||||
if ((i2c_dev->msg_status == MSG_IDLE) && (msg->len == 0)
|
||||
&& (i2c_dev->is_first_message) && (i2c_dev->is_last_message)) {
|
||||
uint32_t cmd = 0;
|
||||
|
||||
cmd |= I2C_DATA_CMD_STOP;
|
||||
/* Write operation */
|
||||
hal_i2c_transmit_data_with_cmd(i2c_dev, cmd);
|
||||
hal_i2c_disable_all_irq(i2c_dev);
|
||||
rt_completion_done(&g_aic_i2c_dev[idx].cmd_complete);
|
||||
}
|
||||
|
||||
i2c_dev->msg_status = MSG_IN_PROCESS;
|
||||
rx_valid = I2C_FIFO_DEPTH - hal_i2c_get_receive_fifo_num(i2c_dev);
|
||||
tx_valid = I2C_FIFO_DEPTH - hal_i2c_get_transmit_fifo_num(i2c_dev);
|
||||
buf_len = msg->len - i2c_dev->buf_write_idx;
|
||||
|
||||
while (buf_len > 0 && rx_valid > 0 && tx_valid > 0) {
|
||||
uint32_t cmd = 0;
|
||||
|
||||
if (buf_len == 1 && i2c_dev->is_last_message) {
|
||||
cmd |= I2C_DATA_CMD_STOP;
|
||||
}
|
||||
|
||||
if (!i2c_dev->is_first_message && !i2c_dev->buf_write_idx) {
|
||||
cmd |= I2C_DATA_CMD_RESTART;
|
||||
}
|
||||
|
||||
if (msg->flags & RT_I2C_RD) {
|
||||
cmd |= I2C_DATA_CMD_READ;
|
||||
hal_i2c_transmit_data_with_cmd(i2c_dev, cmd);
|
||||
rx_valid--;
|
||||
} else {
|
||||
hal_i2c_transmit_data_with_cmd(i2c_dev, cmd | msg->buf[i2c_dev->buf_write_idx]);
|
||||
/* ensure the data is sent out */
|
||||
while (hal_i2c_get_transmit_fifo_num(i2c_dev) != 0) {};
|
||||
}
|
||||
|
||||
i2c_dev->buf_write_idx++;
|
||||
tx_valid--;
|
||||
buf_len--;
|
||||
|
||||
if (i2c_dev->buf_write_idx == msg->len) {
|
||||
intr_mask &= ~I2C_INTR_TX_EMPTY;
|
||||
hal_i2c_flags_mask(i2c_dev, intr_mask);
|
||||
/* message transfer done if it is a write message */
|
||||
if (!(msg->flags & RT_I2C_RD)) {
|
||||
hal_i2c_disable_all_irq(i2c_dev);
|
||||
rt_completion_done(&g_aic_i2c_dev[idx].cmd_complete);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
irqreturn_t aic_i2c_irqhandler(int irq, void * data)
|
||||
{
|
||||
int index = irq - I2C0_IRQn;
|
||||
uint32_t status = 0;
|
||||
aic_i2c_ctrl *i2c_dev;
|
||||
|
||||
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
|
||||
status = hal_i2c_get_raw_interrupt_state(i2c_dev);
|
||||
/* clear all interrupt flags */
|
||||
hal_i2c_clear_all_irq_flags(i2c_dev);
|
||||
|
||||
if (status & I2C_INTR_TX_ABRT) {
|
||||
i2c_dev->msg_err = -I2C_INTR_ERROR_ABRT;
|
||||
goto i2c_err;
|
||||
}
|
||||
|
||||
if (status & I2C_INTR_RX_UNDER) {
|
||||
i2c_dev->msg_err = -I2C_INTR_ERROR_RX;
|
||||
goto i2c_err;
|
||||
}
|
||||
|
||||
if (status & I2C_INTR_RX_FULL) {
|
||||
aic_i2c_handle_read(i2c_dev);
|
||||
}
|
||||
|
||||
if (status & I2C_INTR_TX_EMPTY) {
|
||||
aic_i2c_handle_write(i2c_dev);
|
||||
}
|
||||
|
||||
i2c_err:
|
||||
if (status & (I2C_INTR_TX_ABRT | I2C_INTR_RX_UNDER | I2C_INTR_STOP_DET)) {
|
||||
hal_i2c_disable_all_irq(i2c_dev);
|
||||
rt_completion_done(&g_aic_i2c_dev[index].cmd_complete);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void aic_i2c_xfer_msg_init(struct aic_i2c_ctrl *i2c_dev)
|
||||
{
|
||||
i2c_dev->buf_write_idx = 0;
|
||||
i2c_dev->buf_read_idx = 0;
|
||||
i2c_dev->msg_err = 0;
|
||||
i2c_dev->abort_source = 0;
|
||||
i2c_dev->msg_status = MSG_IDLE;
|
||||
|
||||
/* clear and enable interrupts */
|
||||
hal_i2c_clear_all_irq_flags(i2c_dev);
|
||||
hal_i2c_master_enable_irq(i2c_dev);
|
||||
}
|
||||
|
||||
static int aic_i2c_xfer_msg(struct aic_i2c_ctrl *i2c_dev, struct aic_i2c_msg *msg,
|
||||
bool is_first, bool is_last)
|
||||
{
|
||||
int ret = 0;
|
||||
rt_err_t timeout;
|
||||
uint32_t idx;
|
||||
|
||||
i2c_dev->msg = msg;
|
||||
i2c_dev->is_first_message = is_first;
|
||||
i2c_dev->is_last_message = is_last;
|
||||
idx = i2c_dev->index;
|
||||
|
||||
rt_completion_init(&g_aic_i2c_dev[idx].cmd_complete);
|
||||
if (is_first) {
|
||||
/* Set the slave address */
|
||||
hal_i2c_target_addr(i2c_dev, msg->addr);
|
||||
/* Enable i2c dev */
|
||||
hal_i2c_module_enable(i2c_dev);
|
||||
|
||||
ret = hal_i2c_wait_bus_free(i2c_dev, 10);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
aic_i2c_xfer_msg_init(i2c_dev);
|
||||
|
||||
timeout = rt_completion_wait(&g_aic_i2c_dev[idx].cmd_complete, 1000);
|
||||
if (timeout) {
|
||||
pr_err("message xfer timeout\n");
|
||||
ret = I2C_TIMEOUT;
|
||||
}
|
||||
|
||||
if (i2c_dev->msg_err) {
|
||||
ret = I2C_ERR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rt_size_t aic_i2c_master_xfer(struct rt_i2c_bus_device *bus,
|
||||
struct rt_i2c_msg msgs[], rt_uint32_t num)
|
||||
{
|
||||
CHECK_PARAM(bus, -EINVAL);
|
||||
|
||||
aic_i2c_ctrl *i2c_dev;
|
||||
int ret = 0, index;
|
||||
uint8_t idx;
|
||||
|
||||
idx = bus->parent.device_id;
|
||||
i2c_dev = &g_aic_i2c_dev[idx].aic_bus;
|
||||
|
||||
for (index = 0; index < num; index++) {
|
||||
i2c_dev->msg = (struct aic_i2c_msg*)msgs;
|
||||
ret = aic_i2c_xfer_msg(i2c_dev, &i2c_dev->msg[index], index == 0, index == (num-1));
|
||||
}
|
||||
hal_i2c_module_disable(i2c_dev);
|
||||
|
||||
return (ret < 0) ? ret : num;
|
||||
}
|
||||
#else
|
||||
static rt_size_t aic_i2c_master_xfer(struct rt_i2c_bus_device *bus,
|
||||
struct rt_i2c_msg msgs[], rt_uint32_t num)
|
||||
{
|
||||
CHECK_PARAM(bus, -EINVAL);
|
||||
|
||||
struct aic_i2c_bus *i2c_bus = (struct aic_i2c_bus *)bus;
|
||||
struct rt_i2c_msg *msg = NULL;
|
||||
aic_i2c_ctrl *i2c_dev;
|
||||
int ret_msg_len = 0;
|
||||
int32_t bytes_cnt = 0;
|
||||
int8_t is_last_message = 0;
|
||||
uint8_t index;
|
||||
|
||||
for (uint32_t index = 0; index < num; index++) {
|
||||
msg = &msgs[index];
|
||||
if (index == num -1)
|
||||
index = bus->parent.device_id;
|
||||
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
|
||||
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
msg = &msgs[i];
|
||||
if (i == num -1)
|
||||
is_last_message = 1;
|
||||
else
|
||||
is_last_message = 0;
|
||||
|
||||
if ((msg->flags & RT_I2C_RD)) {
|
||||
bytes_cnt = aic_i2c_master_receive_msg(i2c_bus->reg_base, (struct aic_i2c_msg*)msg, is_last_message);
|
||||
bytes_cnt = hal_i2c_master_receive_msg(i2c_dev,
|
||||
(struct aic_i2c_msg*)msg, is_last_message);
|
||||
} else {
|
||||
bytes_cnt = aic_i2c_master_send_msg(i2c_bus->reg_base, (struct aic_i2c_msg*)msg, is_last_message);
|
||||
bytes_cnt = hal_i2c_master_send_msg(i2c_dev,
|
||||
(struct aic_i2c_msg*)msg, is_last_message);
|
||||
}
|
||||
|
||||
if (bytes_cnt == msg->len) {
|
||||
@@ -61,18 +402,40 @@ static rt_size_t aic_i2c_master_xfer(struct rt_i2c_bus_device *bus,
|
||||
|
||||
return ret_msg_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
static rt_err_t aic_i2c_slave_control(struct rt_i2c_bus_device *bus,
|
||||
rt_uint32_t cmd, void *arg)
|
||||
{
|
||||
RT_ASSERT(bus != RT_NULL);
|
||||
|
||||
aic_i2c_ctrl *i2c_dev;
|
||||
|
||||
uint8_t index = bus->parent.device_id;
|
||||
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
|
||||
|
||||
struct aic_i2c_slave_info *slave_info = (struct aic_i2c_slave_info *)arg;
|
||||
|
||||
i2c_dev->slave.slave_cb = slave_info->slave_cb;
|
||||
i2c_dev->slave.callback_param = slave_info->callback_param;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t aic_i2c_bus_control(struct rt_i2c_bus_device *bus,
|
||||
rt_uint32_t cmd, rt_uint32_t value)
|
||||
{
|
||||
RT_ASSERT(bus != RT_NULL);
|
||||
|
||||
struct aic_i2c_bus *i2c_bus = (struct aic_i2c_bus *)bus;
|
||||
aic_i2c_ctrl *i2c_dev;
|
||||
|
||||
uint8_t index = bus->parent.device_id;
|
||||
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case RT_I2C_DEV_CTRL_CLK:
|
||||
aic_i2c_speed_mode_select(i2c_bus->reg_base, I2C_DEFALT_CLOCK, value);
|
||||
hal_i2c_speed_mode_select(i2c_dev, I2C_DEFALT_CLOCK, value);
|
||||
break;
|
||||
default:
|
||||
return -RT_EIO;
|
||||
@@ -83,62 +446,99 @@ static rt_err_t aic_i2c_bus_control(struct rt_i2c_bus_device *bus,
|
||||
|
||||
const struct rt_i2c_bus_device_ops i2c_ops = {
|
||||
aic_i2c_master_xfer,
|
||||
RT_NULL, // slave
|
||||
aic_i2c_bus_control, // bus control
|
||||
RT_NULL,
|
||||
aic_i2c_bus_control,
|
||||
aic_i2c_slave_control,
|
||||
};
|
||||
|
||||
static struct aic_i2c_bus aic_i2c_list[] = {
|
||||
static struct aic_i2c_bus aic_i2c_dev[] = {
|
||||
#ifdef AIC_USING_I2C0
|
||||
{
|
||||
.index = 0,
|
||||
.reg_base = I2C0_BASE,
|
||||
.device_name = "i2c0",
|
||||
.bus.ops = &i2c_ops,
|
||||
.aic_bus = {
|
||||
.index = 0,
|
||||
.reg_base = I2C0_BASE,
|
||||
.device_name = "i2c0",
|
||||
.addr_bit = AIC_DEV_I2C0_10BIT,
|
||||
.speed_mode = AIC_DEV_I2C0_100K_SPEED,
|
||||
.bus_mode = AIC_DEV_I2C0_SLAVE_MODE,
|
||||
.slave_addr = AIC_DEV_I2C0_SLAVE_ADDR,
|
||||
},
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef AIC_USING_I2C1
|
||||
{
|
||||
.index = 1,
|
||||
.reg_base = I2C1_BASE,
|
||||
.device_name = "i2c1",
|
||||
.bus.ops = &i2c_ops,
|
||||
.aic_bus = {
|
||||
.index = 1,
|
||||
.reg_base = I2C1_BASE,
|
||||
.device_name = "i2c1",
|
||||
.addr_bit = AIC_DEV_I2C1_10BIT,
|
||||
.speed_mode = AIC_DEV_I2C1_100K_SPEED,
|
||||
.bus_mode = AIC_DEV_I2C1_SLAVE_MODE,
|
||||
.slave_addr = AIC_DEV_I2C1_SLAVE_ADDR,
|
||||
},
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef AIC_USING_I2C2
|
||||
{
|
||||
.index = 2,
|
||||
.reg_base = I2C2_BASE,
|
||||
.device_name = "i2c2",
|
||||
.bus.ops = &i2c_ops,
|
||||
.aic_bus = {
|
||||
.index = 2,
|
||||
.reg_base = I2C2_BASE,
|
||||
.device_name = "i2c2",
|
||||
.addr_bit = AIC_DEV_I2C2_10BIT,
|
||||
.speed_mode = AIC_DEV_I2C2_100K_SPEED,
|
||||
.bus_mode = AIC_DEV_I2C2_SLAVE_MODE,
|
||||
.slave_addr = AIC_DEV_I2C2_SLAVE_ADDR,
|
||||
},
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef AIC_USING_I2C3
|
||||
{
|
||||
.index = 3,
|
||||
.reg_base = I2C3_BASE,
|
||||
.device_name = "i2c3",
|
||||
.bus.ops = &i2c_ops,
|
||||
.aic_bus = {
|
||||
.index = 3,
|
||||
.reg_base = I2C3_BASE,
|
||||
.device_name = "i2c3",
|
||||
.addr_bit = AIC_DEV_I2C3_10BIT,
|
||||
.speed_mode = AIC_DEV_I2C3_100K_SPEED,
|
||||
.bus_mode = AIC_DEV_I2C3_SLAVE_MODE,
|
||||
.slave_addr = AIC_DEV_I2C3_SLAVE_ADDR,
|
||||
},
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef AIC_USING_I2C4
|
||||
{
|
||||
.index = 4,
|
||||
.reg_base = I2C4_BASE,
|
||||
.device_name = "i2c4",
|
||||
.bus.ops = &i2c_ops,
|
||||
.aic_bus = {
|
||||
.index = 4,
|
||||
.reg_base = I2C4_BASE,
|
||||
.device_name = "i2c4",
|
||||
.addr_bit = AIC_DEV_I2C4_10BIT,
|
||||
.speed_mode = AIC_DEV_I2C4_100K_SPEED,
|
||||
.bus_mode = AIC_DEV_I2C4_SLAVE_MODE,
|
||||
.slave_addr = AIC_DEV_I2C4_SLAVE_ADDR,
|
||||
},
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef AIC_USING_SP_I2C
|
||||
{
|
||||
.index = 5,
|
||||
.reg_base = SP_I2C_BASE,
|
||||
.device_name = "sp_i2c",
|
||||
.bus.ops = &i2c_ops,
|
||||
.aic_bus = {
|
||||
.index = 5,
|
||||
.reg_base = SP_I2C_BASE,
|
||||
.device_name = "sp_i2c",
|
||||
.addr_bit = AIC_DEV_SP_I2C_10BIT,
|
||||
.speed_mode = AIC_DEV_SP_I2C_100K_SPEED,
|
||||
.bus_mode = AIC_DEV_SP_I2C_SLAVE_MODE,
|
||||
.slave_addr = AIC_DEV_SP_I2C_SLAVE_ADDR,
|
||||
},
|
||||
},
|
||||
#endif
|
||||
};
|
||||
@@ -146,29 +546,27 @@ static struct aic_i2c_bus aic_i2c_list[] = {
|
||||
static int aic_hw_i2c_register()
|
||||
{
|
||||
int ret = -1;
|
||||
uint8_t index;
|
||||
|
||||
for (uint8_t i = 0; i < ARRAY_SIZE(aic_i2c_list); i++) {
|
||||
ret = aic_i2c_init(aic_i2c_list[i].index);
|
||||
for (uint8_t i = 0; i < ARRAY_SIZE(aic_i2c_dev); i++) {
|
||||
index = aic_i2c_dev[i].aic_bus.index;
|
||||
aic_i2c_dev[i].bus.parent.device_id = index;
|
||||
g_aic_i2c_dev[index] = aic_i2c_dev[i];
|
||||
|
||||
ret = hal_i2c_init(&aic_i2c_dev[i].aic_bus);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = aic_i2c_set_master_slave_mode(aic_i2c_list[i].reg_base, true);
|
||||
if (ret) {
|
||||
return ret;
|
||||
#ifdef AIC_I2C_INTERRUPT_MODE
|
||||
aicos_request_irq(I2C0_IRQn + index, aic_i2c_irqhandler, 0, "i2c", NULL);
|
||||
#endif
|
||||
if (aic_i2c_dev[i].aic_bus.bus_mode) {
|
||||
aicos_request_irq(I2C0_IRQn + index, aic_i2c_slave_irqhandler, 0, "i2c_slave", NULL);
|
||||
}
|
||||
|
||||
hal_i2c_set_hold(aic_i2c_list[i].reg_base, 10);
|
||||
aic_i2c_master_10bit_addr(aic_i2c_list[i].reg_base, false);
|
||||
aic_i2c_slave_10bit_addr(aic_i2c_list[i].reg_base, false);
|
||||
|
||||
aic_i2c_master_enable_transmit_irq(aic_i2c_list[i].reg_base);
|
||||
aic_i2c_master_enable_receive_irq(aic_i2c_list[i].reg_base);
|
||||
|
||||
aic_i2c_speed_mode_select(aic_i2c_list[i].reg_base, I2C_DEFALT_CLOCK, true);
|
||||
|
||||
ret = rt_i2c_bus_device_register(&aic_i2c_list[i].bus,
|
||||
aic_i2c_list[i].device_name);
|
||||
ret = rt_i2c_bus_device_register(&aic_i2c_dev[i].bus,
|
||||
aic_i2c_dev[i].aic_bus.device_name);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user