linux之i2c子系统架构---总线驱动
编写i2c设备驱动(从设备)一般有两种方式:
1.用户自己编写独立的从设备驱动,应用程序直接使用即可。
2.linux内核内部已经实现了一个通用的设备驱动,利用通用设备驱动编写一个应用程序(用户态驱动),在应用程序中用到大量设备驱动提供的接口,通过应用程序来控制从设备。
总线驱动
4.1 概述
I2C总线驱动是I2C适配器的软件实现,提供I2C适配器与从设备间完成数据通信的能力,比如起始,停止,应答信号和master_xfer的实现函数。
I2C总线驱动由i2c_adapter和i2c_algorithm来描述
4.2 S3c2440I2C控制器的硬件描述
S3c2440处理器内部集成了一个I2C控制器,通过四个寄存器来进行控制:
IICCON I2C控制寄存器
IICSTAT I2C状态寄存器
IICDS I2C收发数据移位寄存器
IICADD I2C地址寄存器
通过IICCON,IICDS,IICADD寄存器操作,可在I2C总线上产生开始位、停止位、数据和地址,而传输的状态则通过IICSTAT寄存器来获取。
4.3 i2c-s3c2410总线驱动分析(platform_driver)
I2C总线驱动代码在drivers/i2c/busses/i2c-s3c2410.c,这个代码同样支持s3c2410,s3c6410,s5pc110等Samsung 系列的芯片。
初始化模块和卸载模块
- static int __init i2c_adap_s3c_init(void)
- {
- returnplatform_driver_register(&s3c24xx_i2c_driver);
- }
- static void __exit i2c_adap_s3c_exit(void)
- {
- platform_driver_unregister(&s3c24xx_i2c_driver);
- }
总线驱动是基于platform来实现的,很符合设备驱动模型的思想。
- static struct platform_drivers3c24xx_i2c_driver = {
- .probe = s3c24xx_i2c_probe,
- .remove = s3c24xx_i2c_remove,
- .id_table = s3c24xx_driver_ids,
- .driver = {
- .owner = THIS_MODULE,
- .name = "s3c-i2c",
- .pm = S3C24XX_DEV_PM_OPS,
- .of_match_table= s3c24xx_i2c_match,
- },
- };
s3c24xx_i2c_probe函数
当调用platform_driver_register函数注册platform_driver结构体时,如果platformdevice 和 platform driver匹配成功后,会调用probe函数,来初始化适配器硬件。
- static int s3c24xx_i2c_probe(structplatform_device *pdev)
- {
- ……
- /*初始化适配器信息 */
- strlcpy(i2c->adap.name,"s3c2410-i2c", sizeof(i2c->adap.name));
- i2c->adap.owner = THIS_MODULE;
- i2c->adap.algo = &s3c24xx_i2c_algorithm;
- i2c->adap.retries= 2;
- i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- i2c->tx_setup = 50;
- /*初始化自旋锁和等待队列头 */
- spin_lock_init(&i2c->lock);
- init_waitqueue_head(&i2c->wait);
- /*映射寄存器 */
- res= platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->ioarea= request_mem_region(res->start, resource_size(res),
- pdev->name);
- i2c->regs= ioremap(res->start, resource_size(res));
- /*设置I2C核心需要的信息 */
- i2c->adap.algo_data= i2c;
- i2c->adap.dev.parent= &pdev->dev;
- /*初始化I2C控制器 */
- ret= s3c24xx_i2c_init(i2c);
- /*申请中断 */
- i2c->irq= ret = platform_get_irq(pdev, 0);
- ret= request_irq(i2c->irq, s3c24xx_i2c_irq, 0,
- dev_name(&pdev->dev), i2c);
- /* 注册I2C适配器 */
- ret= i2c_add_numbered_adapter(&i2c->adap);
- ……
- }
Probe主要工作是时能硬件并申请I2C适配器使用的IO地址,中断号等,然后向I2C核心添加这个适配器。I2c_adapter注册过程i2c_add_numbered_adapter->i2c_register_adapter
I2C总线通信方法
- static const struct i2c_algorithms3c24xx_i2c_algorithm = {
- .master_xfer = s3c24xx_i2c_xfer,
- .functionality = s3c24xx_i2c_func,
- };
s3c24xx_i2c_xfer函数是总线通信方式的具体实现,依赖于s3c24xx_i2c_doxfer和s3c24xx_i2c_message_start两个函数;
- static int s3c24xx_i2c_doxfer(structs3c24xx_i2c *i2c,
- struct i2c_msg *msgs, int num)
- {
- ret =s3c24xx_i2c_set_master(i2c);
- i2c->msg = msgs;
- i2c->msg_num= num;
- i2c->msg_ptr= 0;
- i2c->msg_idx= 0;
- i2c->state = STATE_START;
- s3c24xx_i2c_message_start(i2c,msgs);
- }
首先设置s3c I2C设备器为主设备,然后调用s3c24xx_i2c_message_start函数启动I2C消息传输。
s3c24xx_i2c_func函数返回适配器所支持的通信功能。
4.4 适配器的设备资源(platform_device)
S3c2440的I2C总线驱动是基于platform来实现,前面我们分析了platformdriver部分,再来看下platform device部分。
在arch/arm/plat-samsung/dev-i2c0.c文件中定义了platform_device结构体以及I2C控制器的资源信息:
- static struct resource s3c_i2c_resource[] ={
- [0]= {
- .start= S3C_PA_IIC,
- .end = S3C_PA_IIC + SZ_4K - 1,
- .flags= IORESOURCE_MEM,
- },
- [1]= {
- .start= IRQ_IIC,
- .end = IRQ_IIC,
- .flags= IORESOURCE_IRQ,
- },
- };
- struct platform_device s3c_device_i2c0 = {
- .name = "s3c2410-i2c", /* 设备名 */
- #ifdef CONFIG_S3C_DEV_I2C1
- .id = 0,
- #else
- .id = -1,
- #endif
- .num_resources =ARRAY_SIZE(s3c_i2c_resource),
- .resource =s3c_i2c_resource,
- };
- struct s3c2410_platform_i2cdefault_i2c_data __initdata = {
- .flags = 0,
- .slave_addr = 0x10, /* I2C适配器的地址 */
- .frequency = 100*1000, /* 总线频率 */
- .sda_delay = 100, /* SDA边沿延迟时间ns */
- };
- void __init s3c_i2c0_set_platdata(structs3c2410_platform_i2c *pd)
- {
- structs3c2410_platform_i2c *npd;
- if(!pd)
- pd= &default_i2c_data;
- npd= s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
- &s3c_device_i2c0);
- if(!npd->cfg_gpio)
- npd->cfg_gpio= s3c_i2c0_cfg_gpio;
- }
在板文件中把platform_device注册进内核:
- static struct platform_device*mini2440_devices[] __initdata = {
- ……
- &s3c_device_i2c0,
- ……
- };
调用s3c_i2c0_set_platdata 函数把适配器具体的数据赋值给dev.platform_data:
- static void __init mini2440_init(void)
- {
- ……
- s3c_i2c0_set_platdata(NULL);
- }
I2C总线驱动就分析到这里。
linux之i2c子系统架构---总线驱动的更多相关文章
- 嵌入式Linux内核I2C子系统详解
1.1 I2C总线知识 1.1.1 I2C总线物理拓扑结构 I2C总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成.通信原理是通过对SCL和SDA线高 ...
- Linux下smi/mdio总线驱动
Linux下smi/mdio总线驱动 韩大卫@吉林师范大学 MII(媒体独立接口), 是IEEE802.3定义的以太网行业标准接口, smi是mii中的标准管理接口, 有两跟管脚, mdio 和mdc ...
- linux内核I2C子系统学习(三)
写设备驱动: 四部曲: 构建i2c_driver 注册i2c_driver 构建i2c_client ( 第一种方法:注册字符设备驱动.第二种方法:通过板文件的i2c_board_info填充,然后注 ...
- linux之i2c子系统维护者源码仓库地址
仓库地址: git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
- Linux驱动编程--基于I2C子系统的I2C驱动
代码中,我添加了很多注释,应该不难理解,有错误大家可以指出来,我再改正 #include <linux/kernel.h> #include <linux/module.h> ...
- linux input输入子系统应用分析
输入设备(如按键.键盘.触摸屏.鼠标等)是典型的字符设备,其一般的工作机理是底层在按键.触摸等动作发送时产生一个中断(或驱动通过timer定时查询),然后CPU通过SPI.I2 C或外部存储器总线读取 ...
- LinuxI2C核心、总线驱动与设备驱动
I2C体系结构分为三个部分:I2C核心.总线驱动.设备驱动 I2C核心: I2C核心提供了一组不依赖硬件的接口函数,I2C总线驱动和设备驱动之间依赖于I2C核心作为纽带 (1)增加/删除i2c_ada ...
- 【驱动】linux下I2C驱动架构全面分析
I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线. ...
- linux下I2C驱动架构全面分析【转】
本文转载自:http://blog.csdn.net/wangpengqi/article/details/17711165 I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一 ...
随机推荐
- X60的BIOS白名单-黑苹果之路
一时兴起装起了黑苹果,用了最古老的thinkpad X60.装完了才发现无线网卡是硬伤,无法驱动,只有淘了个博通的无线网卡,但商家告诉我需要搞定白名单. 于是在商家的帮助下折腾半天,终于搞定. 1.在 ...
- (Loadrunner)Abnormal termination, caused by mdrv process termination.(转)
Load generator跑了太多用户导致CPU和内存爆满,进程无法处理请求 确认自定义的代码是否释放内存 合理调整或增加思考时间 关闭extended log 尽量避免使用Load generat ...
- 软件测试入门——测试模型(V型 W型 H型)
软件测试工程师称为“QA”,质量保证者——这是入门的第一点要学习的. 首先看基本的测试模型 1.“V”型 特点:[活动串行]这是一种古老的瀑布模型,反映了实际和测试之间的关系. 局限:仅仅把测试过程作 ...
- 用github pages展示你的静态网页,多项目支持
我看到有分享用github pages来做博客的,不过我并不想挂博客在上面,我只是想将我的一些作品挂上去,然后链接到我的简历里,这样HR可以直接看到. 首先是最基本的操作,在github上创建一个新的 ...
- Oracle 存储过程包
create or replace package body cuttoship_lots is procedure prod_run(p_w_day date) as begin delete cu ...
- mongodb分组,的两种方式,先记一下
using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.Builders; using NationalUnion.AdGalle ...
- Digest [information value filtering]
http://oak.cs.ucla.edu/~cho/papers/cho-filter.pdf 最近对评估方法进行研究,这篇paper是一种对IR方法进行总结,不错的角度,也比较全面
- Ov
- 【Linux】基于Bind_DLZ和MySQL数据的DNS搭建
参考:http://www.linuxfromscratch.org/blfs/view/cvs/server/bind.html 参考:http://bind-dlz.sourceforge.net ...
- java jdbc 封装。。
JDBC工具类...package it.cast.jdbcutils; import java.io.InputStream; import java.sql.Connection; import ...