- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
PAGE
PAGE 6
手把手教你写
手把手教你写 Linux I2C 设备驱动
Linux I2C 驱动是嵌入式 Linux 驱动开发人员经常需要编写的一种驱动,因为凡是系统中
使用到的 I2C 设备,几乎都需要编写相应的I2C 驱动去配置和控制它,例如 RTC 实时时钟芯片、音视频采集芯片、音视频输出芯片、EEROM 芯片、AD/DA 转换芯片等等。
Linux I2C 驱动涉及的知识点还是挺多的,主要分为Linux I2C 的总线驱动(I2C BUS Driver)和设备驱动(I2C Clients Driver),本文主要关注如何快速地完成一个具体的I2C 设备驱动(I2C Clients Driver)。关于Linux I2C 驱动的整体架构、核心原理等可以在网上
搜索其他相关文章学习。
本文主要参考了 Linux 内核源码目录下的 ./Documentation/i2c/writing-clients 文档。以
手头的一款视频采集芯片 TVP5158 为驱动目标,编写 Linux I2C 设备驱动。
1. i2c_driver 结构体对象
每一个 I2C 设备驱动,必须首先创造一个 i2c_driver 结构体对象,该结构体包含了 I2C
设备探测和注销的一些基本方法和信息,示例如下:
1.2.
1.
2.
3.
4.
5.
6.
7.
8.
static struct i2c_driver tvp5158_i2c_driver = {
.driver = {
.name = tvp5158_i2c_driver,
},
.attach_adapter = tvp5158_attach_adapter,
.detach_client
.command
= tvp5158_detach_client,
= NULL,
};
其中,name 字段标识本驱动的名称(不要超过31 个字符),attach_adapter 和 detac h_client 字段为函数指针,这两个函数在I2C 设备注册的时候会自动调用,需要自己实现这
两个函数,后面将详细讲述。
2. i2c_client 结构体对象
上面定义的 i2c_driver 对象,抽象为一个 i2c 的驱动模型,提供对 i2C 设备的探测和注销
方法,而i2c_client 结构体则是代表着一个具体的 i2c 设备,该结构体有一个data 指针,可以指向任何私有的设备数据,在复杂点的驱动中可能会用到。示例如下:
1.
1.
2.
3.
4.
5.
6.
struct tvp5158_obj{
struct i2c_client client;
int users; // how many users using the driver
};
struct tvp5158_obj* g_tvp5158_obj;
其中,
其中,users 为示例,用户可以自己在 tvp5158_obj 这个结构体里面添加感兴趣的字段,
但是 i2c_client 字段不可少。具体用法后面再详细讲。
3. 设备注册及探测功能
这一步很关键,按照标准的要求来写,则 Linux 系统会自动调用相关的代码去探测你的I
2C 设备,并且添加到系统的 I2C 设备列表中以供后面访问。
我们知道,每一个 I2C 设备芯片,都通过硬件连接设定好了该设备的I2C 设备地址。因
此,I2C 设备的探测一般是靠设备地址来完成的。那么,首先要在驱动代码中声明你要探测的I2C 设备地址列表,以及一个宏。示例如下:
1.2.
1.
2.
3.
4.
5.
6.
static unsigned short normal_i2c[] = {
0xbc 1,
0xbe 1, I2C_CLIENT_END
};
I2C_CLIENT_INSMOD;
normal_i2c 数组包含了你需要探测的 I2C 设备地址列表,并且必须以 I2C_CLIENT_END 作为结尾,注意,上述代码中的 0xbc 和 0xbe 是我在硬件上为我的 tvp5158 分配的地址, 硬件上我支持通过跳线将该地址设置为 0xbc 或者 0xbe,所以把这两个地址均写入到探测列表中,让系统进行探测。如果你的I2C 设备的地址是固定的,那么,这里可以只写你自己
的 I2C 设备地址,注意必须向右移位1。
宏 I2C_CLIENT_INSMOD 的作用网上有许多文章进行了详细的讲解,这里我就不详细
描述了,记得加上就行,我们重点关注实现。
下一步就应该编写第 1 步中的两个回调函数,一个用于注册设备,一个用于注销设备。
探测函数示例如下:
1. static int tvp5158_attach_adapter(struct i2c_adap
原创力文档


文档评论(0)