• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

i2c驱动程序全面分析,从adapter驱动程序到设备驱动程序

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
开发板    :mini2440
内核版本:linux2.6.32.2
驱动程序参考:韦东山老师毕业班i2c


内容概括:

   1、adapter client 简介
   2、adapter 驱动框架

      2.1 设备侧
      2.2 驱动侧
         2.2.1 probe 函数
         2.2.1.1 注册adapter
            new_device del_device
            board_info
            i2c_detect
            i2c_new_device

   3、i2c 设备驱动框架
      3.1 i2c_bus_type
      3.2 i2c_driver
      3.3 i2c_device

   4、写设备驱动程序

   5、写adapter驱动程序


1、adapter client 简介
  在内核里,i2c 驱动框架大概分为两层,adapter 驱动 和 设备驱动,adapter 英文翻译过来为 “适配器”,适配器并不恰当,根据我的理解,adapter 指的是我们 mcu 里的 i2c 控制模块,就是那堆寄存器,因为一个 mcu 里的i2c控制模块是固定的(寄存器参数、以及收发数据的方法),因此大多数情况下,它们都有芯片厂商写好了,然而我们学习的过程中自己动手写一写也并不困难。对于s3c2440仅仅有一个i2c_adapter,但是别的Mcu可能有多个。至于Client,它对应于muc外围的I2c设备,每一个i2c设备都由一个唯一的client来描述。


[cpp] view plain copy
  1. struct i2c_adapter {  
  2.     struct module *owner;  
  3.     unsigned int id;  
  4.     unsigned int class;       /* classes to allow probing for */  
  5.     const struct i2c_algorithm *algo; /* the algorithm to access the bus */  
  6.     void *algo_data;  
  7.   
  8.     /* data fields that are valid for all devices   */  
  9.     u8 level;           /* nesting level for lockdep */  
  10.     struct mutex bus_lock;  
  11.   
  12.     int timeout;            /* in jiffies */  
  13.     int retries;  
  14.     struct device dev;      /* the adapter device */  
  15.   
  16.     int nr;  
  17.     char name[48];  
  18.     struct completion dev_released;  
  19. };  
    简单扫一眼,i2c_adapter 封装了 struct device ,因此它是作为一个设备注册到内核中去的(稍后我们会知道,它是注册到i2c_bus_type里),此外非常重要的一个成员struct i2c_algorithm *algo ,这就是我们上边提到的 i2c 控制器收发数据的方法。
[cpp] view plain copy
  1. struct i2c_algorithm {  
  2.   
  3.     int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,  
  4.                int num);  
  5.     int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,  
  6.                unsigned short flags, char read_write,  
  7.                u8 command, int size, union i2c_smbus_data *data);  
  8.   
  9.     /* To determine what the adapter supports */  
  10.     u32 (*functionality) (struct i2c_adapter *);  
  11. };  

    master_xfer 对应于i2c协议子集 smbus ,有些设备只支持这个协议

    smbus_xfer 对应于普通的 i2c 传输协议

    functionality 用来描述,adapter 所具有的功能,比如是否支持 smbus

[cpp] view plain copy
  1. struct i2c_client {  
  2.     unsigned short flags;       /* div., see below      */  
  3.     unsigned short addr;        /* chip address - NOTE: 7bit    */  
  4.                     /* addresses are stored in the  */  
  5.                     /* _LOWER_ 7 bits       */  
  6.     char name[I2C_NAME_SIZE];  
  7.     struct i2c_adapter *adapter;    /* the adapter we sit on    */  
  8.     struct i2c_driver *driver;  /* and our access routines  */  
  9.     struct device dev;      /* the device structure     */  
  10.     int irq;            /* irq issued by device     */  
  11.     struct list_head detected;  
  12. };  
    i2c_client 本质上是一个 i2c_"dev", 它包含了与它配对的 driver ,以及它所在的 adapter(i2c设备在物理连接上,连接到了哪个adapter),后面分析时会看到,它也是作为设备注册到i2c_bus_type


2、adapter 驱动框架
    在我所使用的这个内核里,2440的i2c_adapter框架是基于 platform_bus_type 的,关于 platform_bus_type 别的文章已经分析过了,这里不做赘述,只简单提一下,当设备或驱动注册到 platform_bus_type 时,首先会查找驱动是否有id_table,如果有根据id_table进行匹配(就是看id_table里有无设备的名字),否则匹配设备名字和驱动名字。匹配成功则调用驱动里的probe函数。
    2.1 设备侧
        根据设备总线驱动模型的分层思想,将一个驱动程序分为 device 和 driver 两层,那么 device 里提供底层的硬件资源,在 driver 中取出这些资源进行使用。那么我们就可以猜测到 i2c_adapter 驱动的设备侧 至少应该含有哪些资源?

        1、存器地址必须有吧,因为我们要使用这些寄存器,不然怎么传输。
        2、中断必须有吧,i2c传输过程中可是离不开中断的。
        下面,我们就开详细的看一看,i2c_adapter 驱动的设备侧提供了哪些设备资源。
        mach-smdk2410.c (arch\arm\mach-s3c2410) 中定义了个指针数组,这里面有我们想要的 s3c_device_i2c0

[cpp] view plain copy
  1. static struct platform_device *smdk2410_devices[] __initdata = {  
  2.     &s3c_device_usb,  
  3.     &s3c_device_lcd,  
  4.     &s3c_device_wdt,  
  5.     &s3c_device_i2c0,  
  6.     &s3c_device_iis,  
  7. };  
  8. dev-i2c0.c (arch\arm\plat-s3c)  
  9. struct platform_device s3c_device_i2c0 = {  
  10.     .name         = "s3c2410-i2c",  
  11. #ifdef CONFIG_S3C_DEV_I2C1  
  12.     .id       = 0,  
  13. #else  
  14.     .id       = -1,  
  15. #endif  
  16.     .num_resources    = ARRAY_SIZE(s3c_i2c_resource),  
  17.     .resource     = s3c_i2c_resource,  
  18. };  
  19. static struct resource s3c_i2c_resource[] = {  
  20.     [0] = {  
  21.         .start = S3C_PA_IIC1,  
  22.         .end   = S3C_PA_IIC1 + SZ_4K - 1,  
  23.         .flags = IORESOURCE_MEM,  
  24.     },  

  25. 鲜花

    握手

    雷人

    路过

    鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
c#vs2010连接access数据库(转)发布时间:2022-07-13
下一篇:
C#与.NET程序员面试宝典2.1.7面试题7:C#中的非托管代码是什么发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap