目录
一、I2C驱动框架
1、I2C总线驱动
(1) I2C总线驱动重点是 I2C 适配器(i2c_adapter)(也就是 SOC 的 I2C 接口控制器)驱动,i2c_algorithm 就是 I2C 适配器与 IIC 设备进行通信的方法。
(2) I2C总线驱动,或者说 I2C 适配器驱动的主要工作就是初始化 i2c_adapter 结构体变量;然后设置 i2c_algorithm 结构体中的 master_xfer 函数,通过此函数完成总线与I2C设备之间的通信。
(3) 用如下两个函数向系统注册设置好的 i2c_adapter:
int i2c_add_adapter(struct i2c_adapter *adapter); //使用动态的总线号
int i2c_add_numbered_adapter(struct i2c_adapter *adap); //使用静态总线号
(4) 如果要删除 I2C 适配器,使用如下函数:
void i2c_del_adapter(struct i2c_adapter * adap);
2、I2C设备驱动框架
(1) I2C设备驱动重点关注两个数据结构:i2c_client 就是描述设备信息的, i2c_driver 描述驱动内容:
(1.1) 每检测到一个 I2C 设备就会给这个 I2C 设备分配一个i2c_client,定义在 include/linux/i2c.h;
(1.2) i2c_driver的注册驱动(重点):platform框架。
二、I2C设备驱动编写(设备树)
1、设备树的修改:在对应的 i2c 节点添加对应的设备节点:
2、I2C 设备驱动首先要做的就是初始化 i2c_driver 并向 Linux 内核注册:
3、当设备和驱动匹配以后 i2c_driver 里面的 probe 函数就会执行, probe 函数里面所做的就是字符设备驱动那一套了,注意 client 变量的初始化:
4、一般需要在 probe 函数里面初始化 I2C 设备,这就需要对 I2C 设备寄存器进行读写操作,要用到 i2c_transfer 函数了。 i2c_transfer 函数会调用 I2C 适配器中 i2c_algorithm 里面的 master_xfer 函数:
(1)int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
函数参数如下:
adap: 所使用的 I2C 适配器, i2c_client 会保存其对应的 i2c_adapter。
msgs: I2C 要发送的一个或多个消息。
num: 消息数量,也就是 msgs 的数量。
(2) 重点参数:struct i2c_msg *msgs
用法:
5、驱动重要函数:读函数,写函数
读函数:
写函数:
6、其它读写函数
(1)发数据函数:
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 位)类型的数据。
(2) 接收数据函数
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 位)类型的数据。
gitee代码链接:gitee_linux_driver: 个人理解编写的linux驱动 - Gitee.com
github代码链接:Can/21_iic at master · CanvMo/Can · GitHub