Linux下I2C驱动框架:I2C 设备驱动

一. 简介

前面一篇文章学习了 Linux下 I2C 驱动框架与 I2C总线驱动(即I2C控制器驱动),文章如下:

Linux下I2C驱动实验: I2C驱动框架与I2C总线驱动-CSDN博客

Linux 内核也将 I2C 驱动分为两部分:
(1) I2C 总线驱动, I2C 总线驱动就是 SOC 的 I2C 控制器驱动,也叫做 I2C 适配器驱动。
(2) I2C 设备驱动, I2C 设备驱动就是针对具体的 I2C 设备而编写的驱动。

本文来学习一下 I2C 设备驱动。

二. Linux下I2C驱动实验:I2C设备驱动

I2C 设备驱动重点关注两个数据结构:i2c_client 和 i2c_driver,i2c_client 就是描述设备信息的,i2c_driver 描述驱动内容,类似于 platform_driver。

1. I2C 设备驱动涉及的结构体

(1)i2c_client 结构体

i2c_client 结构体定义在 include/linux/i2c.h 文件中,内容如下:

复制代码
struct i2c_client {
    unsigned short flags; /* 标志 */
    unsigned short addr; /* 芯片地址,7 位,存在低 7 位*/
......
    char name[I2C_NAME_SIZE]; /* 名字 */
    struct i2c_adapter *adapter; /* 对应的 I2C 适配器 */
    struct device dev; /* 设备结构体 */
    int irq; /* 中断 */
    struct list_head detected;
......
};

一个设备对应一个 i2c_client ,每检测到一个 I2C 设备就会给这个 I2C 设备分配一个 i2c_client 。

(2)i2c_driver结构体

i2c_driver 类似 platform_driver,是我们编写 I2C 设备驱动重点要处理的内容,i2c_driver 结构体定义在 include/linux/i2c.h 文件中,内容如下:

复制代码
struct i2c_driver {
	unsigned int class;

	/* Notifies the driver that a new bus has appeared. You should avoid
	 * using this, it will be removed in a near future.
	 */
	int (*attach_adapter)(struct i2c_adapter *) __deprecated;

	/* Standard driver model interfaces */
	int (*probe)(struct i2c_client *, const struct i2c_device_id *);
	int (*remove)(struct i2c_client *);

	/* driver model interfaces that don't relate to enumeration  */
	void (*shutdown)(struct i2c_client *);

	/* Alert callback, for example for the SMBus alert protocol.
	 * The format and meaning of the data value depends on the protocol.
	 * For the SMBus alert protocol, there is a single bit of data passed
	 * as the alert response's low bit ("event flag").
	 */
	void (*alert)(struct i2c_client *, unsigned int data);

	/* a ioctl like command that can be used to perform specific functions
	 * with the device.
	 */
	int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);

	struct device_driver driver;
	const struct i2c_device_id *id_table;

	/* Device detection callback for automatic device creation */
	int (*detect)(struct i2c_client *, struct i2c_board_info *);
	const unsigned short *address_list;
	struct list_head clients;
};

第 10 行,当 I2C 设备和驱动匹配成功以后, probe 函数就会执行,和 platform 驱动一样。
第 28 行,device_driver 驱动结构体,如果使用设备树的话,需要设置 device_driver 的
of_match_table 成员变量,也就是驱动的兼容(compatible)属性。
第 29 行,id_table 是传统的、未使用设备树的设备匹配 ID 表。

对于我们 I2C 设备驱动编写人来说,重点工作就是构建 i2c_driver。

2. I2C 设备驱动注册与删除

构建完成 i2c_driver 结构体 以后,需要向Linux 内核注册这个 i2c_driver 。 i2c_driver 注册函数为 i2c_register_driver函数 ,此函数原型如下:

复制代码
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)

函数参数和返回值含义如下:
owner 一般为 THIS_MODULE 。
driver :要注册的 i2c_driver 。
返回值: 0 ,成功;负值,失败。

i2c_add_driver 也常常用于注册 i2c_driver , i2c_add_driver 是一个宏,定义如下:

复制代码
#define i2c_add_driver(driver) \
	i2c_register_driver(THIS_MODULE, driver)

i2c_add_driver 就是对 i2c_register_driver 做了一个简单的封装,只有一个参数,就是要注册的 i2c_driver 。

注销 I2C 设备驱动的时候需要将前面注册的 i2c_driver 从 Linux 内核中注销掉,需要用到
i2c_del_driver 函数,此函数原型如下:

复制代码
void i2c_del_driver(struct i2c_driver *driver)

函数参数和返回值含义如下:
driver :要注销的 i2c_driver 。
返回值: 无。

三. 总结

**i2c_client结构体:**表示I2C设备,不需要我们自己创建 i2c_client,我们一般在设备树里面添加具体的I2C芯片,比如 fxls8471,系统在解析设备树的时候,就会知道有这个I2C设备,然后会创建对应的i2c_client。

**i2c设备驱动框架:**i2c_driver初始化与注册,需要II2C设备驱动编写人员编写的,IIC驱动程序就是初始化i2c_driver,然后向系统注册。注册使用i2c_register_driver、i2c_add_driver,如果注销i2c_driver使用i2c_del_driver。

相关推荐
jimy14 小时前
安卓里运行Linux
linux·运维·服务器
爱凤的小光5 小时前
Linux清理磁盘技巧---个人笔记
linux·运维
耗同学一米八6 小时前
2026年河北省职业院校技能大赛中职组“网络建设与运维”赛项答案解析 1.系统安装
linux·服务器·centos
知星小度S7 小时前
系统核心解析:深入文件系统底层机制——Ext系列探秘:从磁盘结构到挂载链接的全链路解析
linux
2401_890443027 小时前
Linux 基础IO
linux·c语言
智慧地球(AI·Earth)8 小时前
在Linux上使用Claude Code 并使用本地VS Code SSH远程访问的完整指南
linux·ssh·ai编程
老王熬夜敲代码9 小时前
解决IP不够用的问题
linux·网络·笔记
zly35009 小时前
linux查看正在运行的nginx的当前工作目录(webroot)
linux·运维·nginx
QT 小鲜肉9 小时前
【Linux命令大全】001.文件管理之file命令(实操篇)
linux·运维·前端·网络·chrome·笔记
问道飞鱼10 小时前
【Linux知识】Linux 虚拟机磁盘扩缩容操作指南(按文件系统分类)
linux·运维·服务器·磁盘扩缩容