i2c学习总结

I2C总线驱动框架详解

i2c的驱动主要分为三个部分:设备驱动层,核心驱动层和总线驱动层

设备驱动层(i2c-dev.c)是用户的接口,主要作用就是定义数据传输的内容,但是不知道传输数据的机制

核心区动层(i2c-core.c)是开发编程的接口,I2C核心提供了I2C总线驱动(适配器)和设备驱动的注册、注销方法,I2C通信方法(”algorithm”)上层的,与具体硬件无关的代码以及探测设备检测设备地址的上层代码等。

总线驱动层(i2c-xxx.c), 他的主要作用就是初始化硬件,同时定义数据传输机制

1、三大组成部分

(1)I2C核心(i2c-core):I2C核心提供了I2C总线驱动(适配器)和设备驱动的注册、注销方法,I2C通信方法(”algorithm”)上层的,与具体硬件无关的代码以及探测设备检测设备地址的上层代码等。。

(2)I2C总线驱动(I2Cadapter):I2C总线驱动是I2C适配器的软件实现,提供I2C适配器与从设备间完成数据通信的能力。I2C总线驱动由i2c_adapter和i2c_algorithm来描述I2C适配器是SoC中内置i2c控制器的软件抽象,可以理解为他所代表的是一个I2C主机。

(3)I2C设备驱动(I2Cclient driver):包括两部分:设备的注册和设备驱动的注册

2、I2C子系统的主要目标是:让驱动开发者可以在内核中方便的添加自己的I2C设备的驱动程序,让内核统一管理I2C设备,从而可以更容易的在linux下驱动自己的I2C接口硬件。
=相关结构体===========

struct i2c_adapter是用来描述一个I2C适配器,在SoC中的指的就是内部外设I2C控制器,当向I2C核心层注册一个I2C适配器时就需要提供这样的一个结构体变量。

1 struct i2c_adapter {
 2     struct module *owner;             // 所有者
 3     unsigned int id;                  
 4     unsigned int class;               // 该适配器支持的从设备的类型
 5     const struct i2c_algorithm *algo; // 该适配器与从设备的通信算法
 6     void *algo_data;                                    
 7 
 8     /* data fields that are valid for all devices    */
 9     struct rt_mutex bus_lock;
10 
11     int timeout;              // 超时时间
12     int retries;
13     struct device dev;        // 该适配器设备对应的device
14 
15     int nr;                   // 适配器的编号
16     char name[48];            // 适配器的名字
17     struct completion dev_released;
18 
19     struct list_head userspace_clients;  // 用来挂接与适配器匹配成功的从设备i2c_client的一个链表头
20 }

;

struct i2c_algorithm结构体代表的是适配器的通信算法,在构建i2c_adapter结构体变量的时候会去填充这个元素。

 1 struct i2c_algorithm {
 2     /* If an adapter algorithm can't do I2C-level access, set master_xfer
 3        to NULL. If an adapter algorithm can do SMBus access, set
 4        smbus_xfer. If set to NULL, the SMBus protocol is simulated
 5        using common I2C messages */
 6     /* master_xfer should return the number of messages successfully
 7        processed, or a negative value on error */
 8     int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
 9                int num);
10     int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,          
11                unsigned short flags, char read_write,
12                u8 command, int size, union i2c_smbus_data *data);
13 
14     /* To determine what the adapter supports */
15     u32 (*functionality) (struct i2c_adapter *);
16 };
1 struct i2c_client {    //  用来描述一个i2c次设备
 2     unsigned short flags;        //  描述i2c次设备特性的标志位  
 3     unsigned short addr;         //  i2c 次设备的地址
 4                     
 5     char name[I2C_NAME_SIZE];    //  i2c次设备的名字
 6     struct i2c_adapter *adapter; //  指向与次设备匹配成功的适配器
 7     struct i2c_driver *driver;   //  指向与次设备匹配成功的设备驱动
 8     struct device dev;           //  该次设备对应的device
 9     int irq;                     //  次设备的中断引脚
10     struct list_head detected;   //  作为一个链表节点挂接到与他匹配成功的i2c_driver 相应的链表头上                
11 };
1 struct i2c_driver {    // 代表一个i2c设备驱动
 2     unsigned int class;      // i2c设备驱动所支持的i2c设备的类型  
 3 
 4     /* Notifies the driver that a new bus has appeared or is about to be
 5      * removed. You should avoid using this if you can, it will probably
 6      * be removed in a near future.
 7      */
 8     int (*attach_adapter)(struct i2c_adapter *);   // 用来匹配适配器的函数 adapter
 9     int (*detach_adapter)(struct i2c_adapter *);                          
10 
11     /* Standard driver model interfaces */
12     int (*probe)(struct i2c_client *, const struct i2c_device_id *); // 设备驱动层的probe函数
13     int (*remove)(struct i2c_client *);                              // 设备驱动层卸载函数
14 
15     /* driver model interfaces that don't relate to enumeration  */
16     void (*shutdown)(struct i2c_client *);
17     int (*suspend)(struct i2c_client *, pm_message_t mesg);
18     int (*resume)(struct i2c_client *);
19 
20     /* Alert callback, for example for the SMBus alert protocol.
21      * The format and meaning of the data value depends on the protocol.
22      * For the SMBus alert protocol, there is a single bit of data passed
23      * as the alert response's low bit ("event flag").
24      */
25     void (*alert)(struct i2c_client *, unsigned int data);
26 
27     /* a ioctl like command that can be used to perform specific functions
28      * with the device.
29      */
30     int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
31 
32     struct device_driver driver;           //  该i2c设备驱动所对应的device_driver
33     const struct i2c_device_id *id_table;  //  设备驱动层用来匹配设备的id_table   
34 
35     /* Device detection callback for automatic device creation */
36     int (*detect)(struct i2c_client *, struct i2c_board_info *);
37     const unsigned short *address_list;    //  该设备驱动支持的所有次设备的地址数组
38     struct list_head clients;              //  用来挂接与该i2c_driver匹配成功的i2c_client (次设备)的一个链表头
39 };
 1 struct i2c_board_info {      //  这个结构体是用来描述板子上的一个i2c设备的信息
 2     char        type[I2C_NAME_SIZE];    //  i2c 设备的名字,用来初始化i2c_client.name
 3     unsigned short    flags;            //  用来初始化i2c_client.flags
 4     unsigned short    addr;             //  用来初始化 i2c_client.addr
 5     void        *platform_data;         //  用来初始化 i2c_client.dev.platform_data
 6     struct dev_archdata    *archdata;   //  用来初始化i2c_client.dev.archdata
 7 #ifdef CONFIG_OF
 8     struct device_node *of_node;
 9 #endif
10     int        irq;                     //  用来初始化i2c_client.irq
11 };
12 
13 
14 
15 struct i2c_devinfo {
16     struct list_head    list;            // 作为一个链表节点挂接到__i2c_board_list 链表上去 
17     int            busnum;               // 适配器的编号
18     struct i2c_board_info    board_info; //  内置的i2c_board_info 结构体
19 };

调用框架:

i2c_add_driver()
           └── i2c_register_driver
                      └── driver_register
                                 ├── driver_find
                                 │   ├── kset_find_obj
                                 │   ├── kobject_put
                                 │   └── to_driver
                                 └── bus_add_driver
                                            └── driver_attach
                                                       └── bus_for_each_dev
                                                                  ├── next_device
                                                                  └── __driver_attach
                                                                             └─ driver_match_device
                                                                                        └── i2c_device_match
                                                                                                   ├── acpi_driver_match_device
                                                                                                   ├── i2c_match_id
                                                                                                   └── of_driver_match_device
                                                                                                   └── of_match_device
                                                                                                              └── of_match_node
                                                                                                                         └── __of_match_node
                                                                                                                                    └── __of_device_is_compatible




i2c_add_driver()
           └── i2c_register_driver
                      └── driver_register
                                 ├── driver_find
                                 │   ├── kset_find_obj
                                 │   ├── kobject_put
                                 │   └── to_driver
                                 └── bus_add_driver
                                            └── driver_attach
                                                       └── bus_for_each_dev
                                                                  ├── next_device
                                                                  └── __driver_attach
                                                                             ├── driver_match_device
                                                                             └── driver_probe_device
                                                                                        └── really_probe
                                                                                                   └── i2c_device_probe
                                                                                                              └── i2c_match_id
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值