Files
luban-lite-t3e-pro/bsp/artinchip/drv/i2c/drv_i2c.c

646 lines
17 KiB
C
Raw Normal View History

2023-08-30 16:21:18 +08:00
/*
2024-09-30 17:06:01 +08:00
* Copyright (c) 2022-2024, ArtInChip Technology Co., Ltd
2023-08-30 16:21:18 +08:00
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: Geo <guojun.dong@artinchip.com>
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <aic_core.h>
#include <drivers/i2c.h>
#include <hal_i2c.h>
2024-06-04 19:00:30 +08:00
#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
2024-09-30 17:06:01 +08:00
#ifndef AIC_DEV_R_I2C0_10BIT
#define AIC_DEV_R_I2C0_10BIT 0
#endif
#ifndef AIC_DEV_R_I2C1_10BIT
#define AIC_DEV_R_I2C1_10BIT 0
#endif
2024-06-04 19:00:30 +08:00
2024-09-30 17:06:01 +08:00
#ifndef AIC_DEV_I2C0_SPEED
#define AIC_DEV_I2C0_SPEED 400000
#endif
#ifndef AIC_DEV_I2C1_SPEED
#define AIC_DEV_I2C1_SPEED 400000
2024-06-04 19:00:30 +08:00
#endif
2024-09-30 17:06:01 +08:00
#ifndef AIC_DEV_I2C2_SPEED
#define AIC_DEV_I2C2_SPEED 400000
2024-06-04 19:00:30 +08:00
#endif
2024-09-30 17:06:01 +08:00
#ifndef AIC_DEV_I2C3_SPEED
#define AIC_DEV_I2C3_SPEED 400000
2024-06-04 19:00:30 +08:00
#endif
2024-09-30 17:06:01 +08:00
#ifndef AIC_DEV_I2C4_SPEED
#define AIC_DEV_I2C4_SPEED 400000
2024-06-04 19:00:30 +08:00
#endif
2024-09-30 17:06:01 +08:00
#ifndef AIC_DEV_SP_I2C_SPEED
#define AIC_DEV_SP_I2C_SPEED 400000
2024-06-04 19:00:30 +08:00
#endif
2024-09-30 17:06:01 +08:00
#ifndef AIC_DEV_R_I2C0_SPEED
#define AIC_DEV_R_I2C0_SPEED 400000
#endif
#ifndef AIC_DEV_R_I2C1_SPEED
#define AIC_DEV_R_I2C1_SPEED 400000
2024-06-04 19:00:30 +08:00
#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
2024-09-30 17:06:01 +08:00
#ifndef AIC_DEV_R_I2C0_SLAVE_MODE
#define AIC_DEV_R_I2C0_SLAVE_MODE 0
#endif
#ifndef AIC_DEV_R_I2C1_SLAVE_MODE
#define AIC_DEV_R_I2C1_SLAVE_MODE 0
#endif
2024-06-04 19:00:30 +08:00
#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
2024-09-30 17:06:01 +08:00
#ifndef AIC_DEV_R_I2C0_SLAVE_ADDR
#define AIC_DEV_R_I2C0_SLAVE_ADDR 0
#endif
#ifndef AIC_DEV_R_I2C1_SLAVE_ADDR
#define AIC_DEV_R_I2C1_SLAVE_ADDR 0
#endif
2024-06-04 19:00:30 +08:00
2023-08-30 16:21:18 +08:00
struct aic_i2c_bus {
struct rt_i2c_bus_device bus;
2024-06-04 19:00:30 +08:00
aic_i2c_ctrl aic_bus;
struct rt_completion cmd_complete;
2023-08-30 16:21:18 +08:00
};
2024-06-04 19:00:30 +08:00
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
2023-08-30 16:21:18 +08:00
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 rt_i2c_msg *msg = NULL;
2024-06-04 19:00:30 +08:00
aic_i2c_ctrl *i2c_dev;
2023-08-30 16:21:18 +08:00
int ret_msg_len = 0;
int32_t bytes_cnt = 0;
2024-04-03 16:40:57 +08:00
int8_t is_last_message = 0;
2024-06-04 19:00:30 +08:00
uint8_t index;
index = bus->parent.device_id;
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
2023-08-30 16:21:18 +08:00
2024-06-04 19:00:30 +08:00
for (uint32_t i = 0; i < num; i++) {
msg = &msgs[i];
if (i == num -1)
2024-04-03 16:40:57 +08:00
is_last_message = 1;
else
is_last_message = 0;
2023-08-30 16:21:18 +08:00
if ((msg->flags & RT_I2C_RD)) {
2024-06-04 19:00:30 +08:00
bytes_cnt = hal_i2c_master_receive_msg(i2c_dev,
(struct aic_i2c_msg*)msg, is_last_message);
2023-08-30 16:21:18 +08:00
} else {
2024-06-04 19:00:30 +08:00
bytes_cnt = hal_i2c_master_send_msg(i2c_dev,
(struct aic_i2c_msg*)msg, is_last_message);
2023-08-30 16:21:18 +08:00
}
if (bytes_cnt == msg->len) {
ret_msg_len++;
}
}
return ret_msg_len;
}
2024-06-04 19:00:30 +08:00
#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;
}
2023-08-30 16:21:18 +08:00
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);
2024-06-04 19:00:30 +08:00
aic_i2c_ctrl *i2c_dev;
uint8_t index = bus->parent.device_id;
i2c_dev = &g_aic_i2c_dev[index].aic_bus;
2023-08-30 16:21:18 +08:00
switch(cmd)
{
case RT_I2C_DEV_CTRL_CLK:
2024-09-30 17:06:01 +08:00
i2c_dev->target_rate = value;
hal_i2c_set_speed(i2c_dev);
2023-08-30 16:21:18 +08:00
break;
default:
return -RT_EIO;
}
return RT_EOK;
}
2024-01-27 08:47:24 +08:00
const struct rt_i2c_bus_device_ops i2c_ops = {
2023-08-30 16:21:18 +08:00
aic_i2c_master_xfer,
2024-06-04 19:00:30 +08:00
RT_NULL,
aic_i2c_bus_control,
aic_i2c_slave_control,
2023-08-30 16:21:18 +08:00
};
2024-06-04 19:00:30 +08:00
static struct aic_i2c_bus aic_i2c_dev[] = {
2023-08-30 16:21:18 +08:00
#ifdef AIC_USING_I2C0
{
.bus.ops = &i2c_ops,
2024-06-04 19:00:30 +08:00
.aic_bus = {
.index = 0,
.reg_base = I2C0_BASE,
.device_name = "i2c0",
.addr_bit = AIC_DEV_I2C0_10BIT,
2024-09-30 17:06:01 +08:00
.target_rate = AIC_DEV_I2C0_SPEED,
2024-06-04 19:00:30 +08:00
.bus_mode = AIC_DEV_I2C0_SLAVE_MODE,
.slave_addr = AIC_DEV_I2C0_SLAVE_ADDR,
2024-09-30 17:06:01 +08:00
.irq_index = I2C0_IRQn,
.clk_id = CLK_I2C0,
2024-06-04 19:00:30 +08:00
},
2023-08-30 16:21:18 +08:00
},
#endif
#ifdef AIC_USING_I2C1
{
.bus.ops = &i2c_ops,
2024-06-04 19:00:30 +08:00
.aic_bus = {
.index = 1,
.reg_base = I2C1_BASE,
.device_name = "i2c1",
.addr_bit = AIC_DEV_I2C1_10BIT,
2024-09-30 17:06:01 +08:00
.target_rate = AIC_DEV_I2C1_SPEED,
2024-06-04 19:00:30 +08:00
.bus_mode = AIC_DEV_I2C1_SLAVE_MODE,
.slave_addr = AIC_DEV_I2C1_SLAVE_ADDR,
2024-09-30 17:06:01 +08:00
.irq_index = I2C1_IRQn,
.clk_id = CLK_I2C1,
2024-06-04 19:00:30 +08:00
},
2023-08-30 16:21:18 +08:00
},
#endif
#ifdef AIC_USING_I2C2
{
.bus.ops = &i2c_ops,
2024-06-04 19:00:30 +08:00
.aic_bus = {
.index = 2,
.reg_base = I2C2_BASE,
.device_name = "i2c2",
.addr_bit = AIC_DEV_I2C2_10BIT,
2024-09-30 17:06:01 +08:00
.target_rate = AIC_DEV_I2C2_SPEED,
2024-06-04 19:00:30 +08:00
.bus_mode = AIC_DEV_I2C2_SLAVE_MODE,
.slave_addr = AIC_DEV_I2C2_SLAVE_ADDR,
2024-09-30 17:06:01 +08:00
.irq_index = I2C2_IRQn,
.clk_id = CLK_I2C2,
2024-06-04 19:00:30 +08:00
},
2023-08-30 16:21:18 +08:00
},
#endif
#ifdef AIC_USING_I2C3
{
.bus.ops = &i2c_ops,
2024-06-04 19:00:30 +08:00
.aic_bus = {
.index = 3,
.reg_base = I2C3_BASE,
.device_name = "i2c3",
.addr_bit = AIC_DEV_I2C3_10BIT,
2024-09-30 17:06:01 +08:00
.target_rate = AIC_DEV_I2C3_SPEED,
2024-06-04 19:00:30 +08:00
.bus_mode = AIC_DEV_I2C3_SLAVE_MODE,
.slave_addr = AIC_DEV_I2C3_SLAVE_ADDR,
2024-09-30 17:06:01 +08:00
.irq_index = I2C3_IRQn,
.clk_id = CLK_I2C3,
2024-06-04 19:00:30 +08:00
},
2023-08-30 16:21:18 +08:00
},
#endif
2023-11-09 20:19:51 +08:00
#ifdef AIC_USING_I2C4
{
.bus.ops = &i2c_ops,
2024-06-04 19:00:30 +08:00
.aic_bus = {
.index = 4,
.reg_base = I2C4_BASE,
.device_name = "i2c4",
.addr_bit = AIC_DEV_I2C4_10BIT,
2024-09-30 17:06:01 +08:00
.target_rate = AIC_DEV_I2C4_SPEED,
2024-06-04 19:00:30 +08:00
.bus_mode = AIC_DEV_I2C4_SLAVE_MODE,
.slave_addr = AIC_DEV_I2C4_SLAVE_ADDR,
2024-09-30 17:06:01 +08:00
.irq_index = I2C4_IRQn,
.clk_id = CLK_I2C4,
2024-06-04 19:00:30 +08:00
},
2023-11-09 20:19:51 +08:00
},
#endif
#ifdef AIC_USING_SP_I2C
{
.bus.ops = &i2c_ops,
2024-06-04 19:00:30 +08:00
.aic_bus = {
.index = 5,
.reg_base = SP_I2C_BASE,
.device_name = "sp_i2c",
.addr_bit = AIC_DEV_SP_I2C_10BIT,
2024-09-30 17:06:01 +08:00
.target_rate = AIC_DEV_SP_I2C_SPEED,
2024-06-04 19:00:30 +08:00
.bus_mode = AIC_DEV_SP_I2C_SLAVE_MODE,
.slave_addr = AIC_DEV_SP_I2C_SLAVE_ADDR,
2024-09-30 17:06:01 +08:00
.irq_index = SP_I2C_IRQn,
.clk_id = CLK_SP_I2C,
},
},
#endif
#ifdef AIC_USING_R_I2C0
{
.bus.ops = &i2c_ops,
.aic_bus = {
.index = 6,
.reg_base = R_I2C0_BASE,
.device_name = "r_i2c0",
.addr_bit = AIC_DEV_R_I2C0_10BIT,
.target_rate = AIC_DEV_R_I2C0_SPEED,
.bus_mode = AIC_DEV_R_I2C0_SLAVE_MODE,
.slave_addr = AIC_DEV_R_I2C0_SLAVE_ADDR,
.irq_index = R_I2C0_IRQn,
.clk_id = CLK_R_I2C0,
},
},
#endif
#ifdef AIC_USING_R_I2C1
{
.bus.ops = &i2c_ops,
.aic_bus = {
.index = 7,
.reg_base = R_I2C1_BASE,
.device_name = "r_i2c1",
.addr_bit = AIC_DEV_R_I2C1_10BIT,
.target_rate = AIC_DEV_R_I2C1_SPEED,
.bus_mode = AIC_DEV_R_I2C1_SLAVE_MODE,
.slave_addr = AIC_DEV_R_I2C1_SLAVE_ADDR,
.irq_index = R_I2C1_IRQn,
.clk_id = CLK_R_I2C1,
2024-06-04 19:00:30 +08:00
},
2023-11-09 20:19:51 +08:00
},
#endif
2023-08-30 16:21:18 +08:00
};
static int aic_hw_i2c_register()
{
int ret = -1;
2024-06-04 19:00:30 +08:00
uint8_t index;
2023-08-30 16:21:18 +08:00
2024-06-04 19:00:30 +08:00
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;
2023-08-30 16:21:18 +08:00
2024-06-04 19:00:30 +08:00
ret = hal_i2c_init(&aic_i2c_dev[i].aic_bus);
2023-08-30 16:21:18 +08:00
if (ret) {
return ret;
}
2024-09-30 17:06:01 +08:00
g_aic_i2c_dev[index] = aic_i2c_dev[i];
2023-08-30 16:21:18 +08:00
2024-06-04 19:00:30 +08:00
#ifdef AIC_I2C_INTERRUPT_MODE
2024-09-30 17:06:01 +08:00
aicos_request_irq(aic_i2c_dev[i].aic_bus.irq_index, aic_i2c_irqhandler, 0, "i2c", NULL);
2024-06-04 19:00:30 +08:00
#endif
if (aic_i2c_dev[i].aic_bus.bus_mode) {
2024-09-30 17:06:01 +08:00
aicos_request_irq(aic_i2c_dev[i].aic_bus.irq_index, aic_i2c_slave_irqhandler, 0, "i2c_slave", NULL);
2024-06-04 19:00:30 +08:00
}
2023-08-30 16:21:18 +08:00
2024-06-04 19:00:30 +08:00
ret = rt_i2c_bus_device_register(&aic_i2c_dev[i].bus,
aic_i2c_dev[i].aic_bus.device_name);
2023-08-30 16:21:18 +08:00
if (ret) {
return ret;
}
}
return 0;
}
INIT_BOARD_EXPORT(aic_hw_i2c_register);