LinuxI2C总线详解.doc

上传人:鲁** 文档编号:550352810 上传时间:2023-03-26 格式:DOC 页数:9 大小:470KB
返回 下载 相关 举报
LinuxI2C总线详解.doc_第1页
第1页 / 共9页
LinuxI2C总线详解.doc_第2页
第2页 / 共9页
LinuxI2C总线详解.doc_第3页
第3页 / 共9页
LinuxI2C总线详解.doc_第4页
第4页 / 共9页
LinuxI2C总线详解.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《LinuxI2C总线详解.doc》由会员分享,可在线阅读,更多相关《LinuxI2C总线详解.doc(9页珍藏版)》请在金锄头文库上搜索。

1、Linux I2C 总线详解 OverviewLinux的I2C体系结构分为3个组成部分:I2C核心:I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法(即“algorithm”)上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等。这部分是与平台无关的。I2C总线驱动:I2C总线驱动是对I2C硬件体系结构中适配器端的实现。I2C总线驱动主要包含了I2C适配器数据结构i2c_adapter、I2C适配器的algorithm数据结构i2c_algorithm和控制I2C适配器产生通信信号的函数。经由I2C总线驱动的代码,我们可以控制I2C适配器以主控方式产生

2、开始位、停止位、读写周期,以及以从设备方式被读写、产生ACK等。不同的CPU平台对应着不同的I2C总线驱动。总线驱动的职责,是为系统中每个I2C总线增加相应的读写方法。但是总线驱动本身并不会进行任何的通讯,它只是存在在那里,等待设备驱动调用其函数。这部分在MTK 6516中是由MTK已经帮我们实现了的,不需要我们更改。 I2C设备驱动:I2C设备驱动是对I2C硬件体系结构中设备端的实现。设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。I2C设备驱动主要包含了数据结构i2c_driver和i2c_client,我们需要根据具体设备实现其中的成员函数。在Linux内核

3、源代码中的drivers目录下的i2c_dev.c文件,实现了I2C适配器设备文件的功能,应用程序通过“i2c-%d”文件名并使用文件操作接口open()、write()、read()、ioctl()和close()等来访问这个设备。应用层可以借用这些接口访问挂接在适配器上的I2C设备的存储空间或寄存器并控制I2C设备的工作方式。设备驱动则是与挂在I2C总线上的具体的设备通讯的驱动。通过I2C总线驱动提供的函数,设备驱动可以忽略不同总线控制器的差异,不考虑其实现细节地与硬件设备通讯。这部分在MTK 6516中是由具体的设备实现的。(比如camera)struct i2c_client:代表一个

4、挂载到i2c总线上的i2c从设备,该设备所需要的数据结构,其中包括该i2c从设备所依附的i2c主设备 struct i2c_adapter *adapter 该i2c从设备的驱动程序struct i2c_driver *driver 作为i2c从设备所通用的成员变量,比如addr, name等 该i2c从设备驱动所特有的数据,依附于dev-driver_data下struct i2c_adapter:代表主芯片所支持的一个i2c主设备。struct i2c_algorithm *algo:是该i2c主设备传输数据的一种算法,或者说是在i2c总线上完成主从设备间数据通信的一种能力。Linux的i

5、2c子系统新、旧架构并存。主要分为旧架构(Legacy)也有人称之为adapter方式,和新的架构new-style的方式。这俩者的区别主要在于设备注册和驱动注册的不同。对于Legacy的设备注册是在驱动运行的时候动态的创建,而新式的new-style则是采用静态定义的方式。注:MTK在Android2.1版上用的是Legacy的架构,而在Android2.2版上用的是new-style的架构。(在这里我就只说明Android2.2的new-style的实现方法)要完成I2C设备的驱动,我们可以分三步走:第一步:完成适配器的注册(总线);第二步:完成I2C client的设备注册(设备);第三

6、步:完成I2C client驱动的注册(驱动);我们分别给予介绍:(I2C-mt6516.c)就总线而言,其本质只需要我们填充俩个结构体就可以了:i2c_adapter;i2c_algorithm;i2c_add_adapter(i2c-adap); 往总线上添加对应的适配器;struct i2c_adapter struct module *owner; unsigned int id; unsigned int class; /* classes to allow probing for */ const struct i2c_algorithm *algo; /* the algorit

7、hm to access the bus */ void *algo_data; /* - administration stuff. */ int (*client_register)(struct i2c_client *); int (*client_unregister)(struct i2c_client *); /* data fields that are valid for all devices */ u8 level; /* nesting level for lockdep */ struct mutex bus_lock; struct mutex clist_lock

8、; int timeout; /* in jiffies */ int retries; struct device dev; /* the adapter device */ int nr; /*该成员描述了总线号*/ struct list_head clients; /* i2c_client结构链表,该结构包含device,driver和 adapter结构*/ char name48; struct completion dev_released; ;static struct i2c_algorithm mt6516_i2c_algorithm = .master_xfer = m

9、t6516_i2c_transfer,.smbus_xfer = NULL,.functionality = mt6516_i2c_functionality,;2、设备注册第一步:记得以前的i2c设备驱动,设备部分喜欢驱动运行的时候动态创建,新式的驱动倾向于向传统的linux下设备驱动看齐,采用静态定义的方式来注册设备,使用接口为:int _init i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len) int status; mutex_lock(&_i2c_board_lo

10、ck); /* dynamic bus numbers will be assigned after the last static one */ if (busnum = _i2c_first_dynamic_bus_num) _i2c_first_dynamic_bus_num = busnum + 1; for (status = 0; len; len-, info+) struct i2c_devinfo *devinfo; devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);/申请表示i2c设备的结构体空间 if (!devinfo) p

11、r_debug(i2c-core: cant register boardinfo!n); status = -ENOMEM; break; /* 填写i2c设备描述结构 */ devinfo-busnum = busnum; devinfo-board_info = *info; list_add_tail(&devinfo-list, &_i2c_board_list);/添加到全局链表_i2c_board_list中 mutex_unlock(&_i2c_board_lock); return status;在系统初始化的过程中,我们可以通过 i2c_register_board_inf

12、o,将所需要的I2C从设备加入一个名为_i2c_board_list双向循环链表,系统在成功加载I2C主设备adapt后,就会对这张链表里所有I2C从设备逐一地完成 i2c_client的注册。第二步: 系统初始化的时候,会根据板级i2c设备配置信息,创建i2c客户端设备(i2c_client),添加到i2c子系统中:static void i2c_scan_static_board_info (struct i2c_adapter *adapter) struct i2c_devinfo *devinfo; mutex_lock(&_i2c_board_lock); list_for_eac

13、h_entry(devinfo, &_i2c_board_list, list) /遍历全局链表_i2c_board_list if (devinfo-busnum = adapter-nr & !i2c_new_device(adapter, &devinfo-board_info) printk(KERN_ERR i2c-core: cant create i2c%d-%04xn, i2c_adapter_id(adapter), devinfo-board_info.addr); mutex_unlock(&_i2c_board_lock);struct i2c_client *i2c_

14、new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)struct i2c_client*client;intstatus;client = kzalloc(sizeof *client, GFP_KERNEL);if (!client)return NULL;client-adapter = adap;client-dev.platform_data = info-platform_data;if (info-archdata)client-dev.archdata = *info-archdata;client-flags = info-flags;client-addr = info-addr;client-irq = info-irq;strlcpy(client-name, info-t

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号