4 OMAP3630 I2C device驱动在Linux内核中,I2C device驱动位于drivers/i2c/chips目录下,可以看到该目录下有很多相关的device驱动,这里以xxxx项目的mma7455为例介绍device驱动的注册过程,对应的device驱动程序为mma7455.c。

既然有device驱动,那么必定有相应的device,I2C的device是什么呢?其实就是我们在1.3节中提到的i2c_client,所以在device驱动注册之前先来了解下i2c_client的注册过程。4.1 Mma7455 device注册    Mma7455 device即i2c_client的创建以及注册分为两步。4.1.1 将mma7455设备信息加入到设备链表    在板级初始化时将I2C device的名称,地址和相关的信息加入到链表__i2c_board_list中,该链表记录了具体开发板上的I2C设备信息。

在board-xxxx.c中,定义了mma7455的设备信息定义如下:

staticstructi2c_board_info __initdata xxxx_i2c_bus3_info[] = {

……

#ifdef CONFIG_SENSORS_MMA7455

{

I2C_BOARD_INFO("mma7455", 0x1D),

.platform_data = &xxxx_mma7455_platform_data,

},

#endif

};

Mma7455加入到设备链表__i2c_board_list的流程图如下图:

图4.1 mma7455加入到I2C设备链表的过程

i2c_register_board_info()函数的定义如下:

int__init i2c_register_board_info(intbusnum,

structi2c_board_infoconst*info, unsigned len)

{

……

for(status = 0; len; len--, info++) {

structi2c_devinfo  *devinfo;

devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);

……

devinfo->busnum = busnum;

devinfo->board_info = *info;

list_add_tail(&devinfo->list, &__i2c_board_list);

}

……

}

4.1.2 创建并注册i2c_client    i2c_client的创建和注册在I2C adapter驱动注册过程中完成,I2C adapter驱动的注册可以参考3.2.2节,i2c_add_numbered_adapter()函数在注册I2C adapter驱动的同时会扫描4.1.1中提到的I2C设备链表__i2c_board_list,如果该总线上有对应的I2C设备,则创建相应的i2c_client,并将其注册到I2C core中。流程图如下所示:

图4.2创建并注册i2c_client

相应的代码位于i2c-core.c如下:

staticvoidi2c_scan_static_board_info(structi2c_adapter *adapter)

{

……

list_for_each_entry(devinfo, &__i2c_board_list, list) {

if(devinfo->busnum == adapter->nr

&& !i2c_new_device(adapter,

&devinfo->board_info))

……

}

……

}

在i2c_scan_static_board_info()函数中遍历I2C设备链表__i2c_board_list,设备的总线号和adapter的总线号相等,则使用函数i2c_new_device()创建该设备。

structi2c_client *

i2c_new_device(structi2c_adapter *adap,structi2c_board_infoconst*info)

{

……

client = kzalloc(sizeof*client, GFP_KERNEL);

if(!client)

returnNULL;

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->type,sizeof(client->name));

……

status = i2c_attach_client(client);

……

}

在函数i2c_new_device()中创建一个i2c_client,初始化该结构体的adapter,addr,name等变量,这里的client->name被初始化为info->type,在4.1.1中,info->type初始化为“mma7455”, client->name后面会用于I2C device和I2C driver匹配时使用,最后调用i2c_attach_client()将该client注册到I2C core。

inti2c_attach_client(structi2c_client *client)

{

structi2c_adapter *adapter = client->adapter;

……

client->dev.parent = &client->adapter->dev;

client->dev.bus = &i2c_bus_type;

……

res = device_register(&client->dev);

……

}

函数i2c_attach_client()进一步初始化i2c_client结构体,将该设备的总线初始化为i2c_bus_type,说明该设备被放在I2C总线上,用于后面跟I2C driver匹配时使用,最后使用device_register(&client->dev)注册该i2c_client设备。4.2 Mma7455 device驱动注册    在mma7455.c中,定义了mma7455的device驱动,代码如下:

staticstructi2c_driver mma7455_driver = {

.driver     = {

.name ="mma7455",

},

.class= I2C_CLASS_HWMON,

.probe      = mma7455_probe,

.remove     = mma7455_remove,

.id_table   = mma7455_id,

……

};

注册的简要示意图如下:

图4.3 device驱动的注册

相应的代码位于mma7455.c和i2c-core.c。

staticint__init init_mma7455(void)

{

……

res = i2c_add_driver(&mma7455_driver);

……

return(res);

}

在模块加载的时候首先调用init_mma7455(),然后init_mma7455()调用函数i2c_add_driver()注册mma7455_driver结构体。

inti2c_register_driver(structmodule *owner,structi2c_driver *driver)

{

…….

/* add the driver to the list of i2c drivers in the driver core */

driver->driver.owner = owner;

driver->driver.bus = &i2c_bus_type;

……

res = driver_register(&driver->driver);

if(res)

returnres;

……

}

函数i2c_register_driver()初始化该驱动的总线为i2c_bus_type,然后使用函数driver_register(&driver->driver)注册该驱动,因此内核会在I2C总线上遍历所有I2C设备,由于该mma7455 device驱动的匹配因子name变量为“mma7455”,因此正好和在4.1.2里创建的name也为“mma7455”的i2c client匹配。因此总线的probe函数将会被调用,I2C总线的probe函数为i2c_device_probe(),具体代码如下:

staticinti2c_device_probe(structdevice *dev)

{

structi2c_client   *client = to_i2c_client(dev);

structi2c_driver   *driver = to_i2c_driver(dev->driver);

intstatus;

if(!driver->probe || !driver->id_table)

return-ENODEV;

client->driver = driver;

…….

status = driver->probe(client, i2c_match_id(driver->id_table, client));

……

returnstatus;

}

在i2c_device_probe()函数中,语句client->driver = driver将I2C device和I2C driver绑定,然后直接调用具体设备的probe函数,这里即mma7455的probe函数mma7455_probe()。

在mma7455_probe()函数会完成一些具体I2C设备相关的初始化等操作,这边就不再详述。

omap3630 linux i2c总线驱动分析,OMAP3630 Linux I2C总线驱动分析相关推荐

  1. linux i2c核心,总线与设备驱动,Linux2.6.37 I2C驱动框架分析(一)

    最近工作中又使用到了I2C,所以借S3C2440开发板GT2440为硬件平台温习一遍I2C驱动体系. linux内核中IIC驱动的体系框架 linux内核中IIC部分驱动代码位于:/drivers/i ...

  2. i.MX6ULL终结者Linux I2C驱动实验IMX6ULL的I2C总线驱动分析

    在上一节中我们了解了I2C框架分为I2C核心.I2C总线驱动和I2C设备驱动三部分.其中I2C总线驱动就是SOC的I2C控制器驱动,一般来说都是SOC厂家实现好的.而I2C设备驱动是用户根据自己不同的 ...

  3. linux下I2C驱动发送IO时序,I2C驱动情景分析——怎样控制I2C时序

    内核版本:linux-3.4.2 源程序:    linux-3.4.2\drivers\i2c\busses\I2c-s3c2410.c 这次要解决的问题是:如何配置soc的I2C模块,输出想要的时 ...

  4. linux用户空间flash驱动,全面掌握Linux驱动框架——字符设备驱动、I2C驱动、总线设备驱动、NAND FLASH驱动...

    原标题:全面掌握Linux驱动框架--字符设备驱动.I2C驱动.总线设备驱动.NAND FLASH驱动 字符设备驱动 哈~ 这几天都在发图,通过这种方式,我们希望能帮大家梳理学过的知识,全局的掌握Li ...

  5. Linux设备驱动程序架构分析之一个I2C驱动实例

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 内核版本:3.10.1 编写一个I2C设备驱动程序的工作可分为两部分,一是定义和注册I2C设备,即i2c_clien ...

  6. LINUX SPI设备驱动模型分析之二 SPI总线模块分析

    上一篇文章我们简要介绍了SPI驱动模块,本章我们详细说明一下spi总线.设备.驱动模块的注册.注销以及这几个模块之间的关联. SPI总线的注册 spi模块也是基于LINUX设备-总线-驱动模型进行开发 ...

  7. platform框架--Linux MISC杂项框架--Linux INPUT子系统框架--串行集成电路总线I2C设备驱动框架--串行外设接口SPI 设备驱动框架---通用异步收发器UART驱动框架

    platform框架 input. pinctrl. gpio 子系统都是 Linux 内核针对某一类设备而创建的框架, input子系统是管理输入的子系统 pinctrl 子系统重点是设置 PIN( ...

  8. Linux下的USB总线驱动(三) u盘驱动分析

    版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127 4.U盘驱动分析 USB Mass Storage是一类USB存储设备,这些设备包括USB磁盘.USB硬盘 ...

  9. Linux设备驱动模型之platform(平台)总线详解

    /********************************************************/ 内核版本:2.6.35.7 运行平台:三星s5pv210 /*********** ...

最新文章

  1. MVC3+EF4.1学习系列(一)-------创建EF4.1 code first的第一个实例(强转)
  2. 函数 php_PHP回调函数及匿名函数概念与用法详解
  3. 深度学习——02、深度学习入门 1-7
  4. 关于pipelineDB调用GetLocalStreamReaders的BUG
  5. BP神经网络python简单实现
  6. ado execute open区别_二极管IN4148和IN4007的应用区别
  7. ASP.NET MVC 分部视图
  8. java人员工作建议_给JAVA设计开发新手的一些建议和意见(1)
  9. Java计算两点坐标之间的距离
  10. 51单片机学习——1天学完普中基本实验例程,走马观花式学习,大家切勿效仿。
  11. SQL连接查询总结和练习
  12. iOS转前端之仿写宠物网(适配不同尺寸)
  13. c++ 的interface
  14. 想不想修真鸿蒙秘术,想不想修真鸿蒙秘诀怎么得 揭开想不想修真秘诀真面目...
  15. 计算机学渣和你说说从毕业到工作
  16. 根据起始日期、起始时间、终止日期、终止时间计算天数
  17. c语言与多字节编码,什么是单字节,双字节和多字节编码
  18. 谈谈HTTP协议中的短轮询、长轮询、长连接和短连接
  19. 纪念日或者悼念日 网站改为灰白模式
  20. 在Ubuntu安装完成后更改默认的语言LANG,出现Cannot set LC_CTYPE to default locale: No such file or directory错误的解决办法

热门文章

  1. linux服务器监控
  2. 将同一文件夹下的图片转化为视频
  3. 让单个单元格显示两个数据
  4. 使用YOLOX进行物体检测
  5. 业务消息中心系统设计与实现(一)
  6. ajax传递数组怎么办?
  7. Java后端学习路线图
  8. 效率神器Apifox_API 文档、API 调试、API Mock、API 自动化测试工具推荐
  9. BP神经网络的Java实现
  10. JSF与JSTL TAG的互用问题