I2C 数据传输主要有三个 API
int i2c_master_send(const struct i2c_client *client,const char *buf,int count)
client:I2C 设备对应的 i2c_client。
buf:要发送的数据。
count:要发送的数据字节数,要小于 64KB,以为 i2c_msg 的 len 成员变量是一个 u16(无符号 16 位)类型的数据。
返回值:负值,失败,其他非负值,发送的字节数。
int i2c_master_recv(const struct i2c_client *client,char *buf,int count)
client:I2C 设备对应的 i2c_client。
buf:要接收的数据。
count:要接收的数据字节数,要小于 64KB,以为 i2c_msg 的 len 成员变量是一个 u16(无符号 16 位)类型的数据。
返回值:负值,失败,其他非负值,发送的字节数。
int i2c_transfer(struct i2c_adapter *adap,struct i2c_msg *msgs,int num)
adap:所使用的 I2C 适配器,i2c_client 会保存其对应的 i2c_adapter。
msgs:I2C 要发送的一个或多个消息。
num:消息数量,也就是 msgs 的数量。
返回值:负值,失败,其他非负值,发送的 msgs 数量。
i2c_master_send 和 i2c_master_recv 都是对 i2c_transfer 的封装。因此我们重点研究 i2c_transfer。
其中,adap->algo->master_xfer 由芯片原厂提供。在 MTK 平台,是 mtk_i2c_transfer 函数,不同平台命名不同。
static int mtk_i2c_transfer(struct i2c_adapter *adap,struct i2c_msg msgs[], int num)
{
int ret;
int left_num = num;
struct mtk_i2c *i2c = i2c_get_adapdata(adap);
//打开时钟
ret = mtk_i2c_clock_enable(i2c);
if (ret)
return ret;
//初始化硬件
mtk_i2c_init_hw(i2c);
i2c- >auto_restart = i2c- >dev_comp- >auto_restart;
if (i2c- >auto_restart && num == 2) {
if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) &&
msgs[0].addr == msgs[1].addr) {
i2c- >auto_restart = 0;
}
}
if (i2c- >auto_restart && num >= 2 && i2c- >speed_hz > MAX_FS_MODE_SPEED)
i2c- >ignore_restart_irq = true;
else
i2c- >ignore_restart_irq = false;
while (left_num--) {
if (!msgs- >buf) {
dev_dbg(i2c- >dev, "data buffer is NULL.n");
ret = -EINVAL;
goto err_exit;
}
if (msgs- >flags & I2C_M_RD)
i2c- >op = I2C_MASTER_RD;
else
i2c- >op = I2C_MASTER_WR;
if (!i2c- >auto_restart) {
if (num > 1) {
/* combined two messages into one transaction */
i2c- >op = I2C_MASTER_WRRD;
left_num--;
}
}
/* always use DMA mode. */
ret = mtk_i2c_do_transfer(i2c, msgs, num, left_num);
if (ret < 0)
goto err_exit;
msgs++;
}
/* the return value is number of executed messages */
ret = num;
err_exit:
mtk_i2c_clock_disable(i2c);
return ret;
}
全部0条评论
快来发表一下你的评论吧 !