I2C-子系统

I2C-子系统

I2C系统框架

1.框架介绍:

应用程序层(app层)
------------------------------------------------------------------------------------------------------------
i2c driver层: i2c_client driver
设备驱动,对I2C从设备的软件实现,一个具体的I2C客户驱动包括两部分:一部分是i2c_driver,用于将设备挂接于i2c总线;另一部分是设备本身的驱动。
I2C客户驱动程序由i2c_driver和i2c_client来描述。
------------------------------------------------------------------------------------------------------------
i2c core:i2c核心层
提供了I2C总线驱动(适配器)和设备驱动的注册、注销方法,I2C通信方法(”algorithm”)上层的,与具体硬件无关的代码以及探测设备检测设备地址的上层代码等。
------------------------------------------------------------------------------------------------------------
i2c adapter层: 总线驱动,i2c控制器层,初始化i2c控制器,实现i2c时序。
I2C总线驱动是I2C适配器的软件实现, 提供I2C适配器与从设备间完成数据通信的能力。I2C总线驱动由i2c_adapter和i2c_algorithm来描述。
I2C适配器是SoC中内置i2c控制器的软件抽象,可以理解为他所代表的是一个I2C主机。
------------------------------------------------------------------------------------------------------------
居中的图片: 框架图框架图

2. I2c工具

i2c-get i2c-set i2cdetect i2cdump i2cget i2cset
总线扫描
/ # i2cdetect -l
i2c-0 i2c rk3x-i2c I2C adapter
i2c-2 i2c rk3x-i2c I2C adapter

3. 相关重要结构体和函数:

3.1 i2c_client:

每一个i2c从设备都需要用一个i2c_client结构体来描述,i2c_client对应真实的i2c物理设备device。
i2c_client不是我们自己写程序去创建的,而是通过以下常用的方式自动创建的:
方法一: 分配、设置、注册i2c_board_info
方法二: 获取adapter调用i2c_new_device
方法三: 通过设备树(devicetree)创建
方法1和方法2通过platform创建,这两种方法在内核3.0版本以前使用所以在这不详细介绍;**方法3是最新的方法,**3.0版本之后的内核都是通过这种方式创建
I2c_client 代表i2c从设备

struct i2c_client {		 //  用来描述一个i2c次设备
    unsigned short flags;       // 描述i2c次设备特性的标志位 
    unsigned short addr;        // i2c 次设备的地址    
                    // _LOWER_ 7 bits       
char name[I2C_NAME_SIZE];	 //	i2c次设备的名字	   
 struct i2c_adapter *adapter;    // 指向与次设备匹配成功的适配器  
    struct device dev;      // 该次设备对应的device    
int irq;            //  次设备的中断引脚       
struct list_head detected;	 //  作为一个链表节点挂接到与他匹配成功的i2c_driver 相应的链表头上
};
3.2 i2c_driver:

用于管理I2C的驱动程序和i2c设备(client)的匹配探测,实现与应用层交互的文件操作集合fops、cdev等
I2c_driver代表I2C从设备驱动

struct i2c_driver {	// 代表从设备驱动
    unsigned int class;	 // i2c设备驱动所支持的i2c设备的类型  
    /* Notifies the driver that a new bus has appeared. You should avoid
     * using this, it will be removed in a near future.
     */
    int (*attach_adapter)(struct i2c_adapter *) __deprecated; 
    /* Standard driver model interfaces */
    int (*probe)(struct i2c_client *, const struct i2c_device_id *);
    int (*remove)(struct i2c_client *);
    /* driver model interfaces that don't relate to enumeration  */
    void (*shutdown)(struct i2c_client *);
    /* Alert callback, for example for the SMBus alert protocol.
     * The format and meaning of the data value depends on the protocol.
     * For the SMBus alert protocol, there is a single bit of data passed
     * as the alert response's low bit ("event flag").
     */
    void (*alert)(struct i2c_client *, unsigned int data);

    /* a ioctl like command that can be used to perform specific functions
     * with the device.
     */
    int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
    struct device_driver driver; //  该i2c设备驱动所对应的device_driver
    const struct i2c_device_id *id_table; //  设备驱动层用来匹配设备的id_table   
    /* Device detection callback for automatic device creation */
    int (*detect)(struct i2c_client *, struct i2c_board_info *);
    const unsigned short *address_list; //  该设备驱动支持的所有次设备的地址数组
    struct list_head clients; //  用来挂接与该i2c_driver匹配成功的i2c_client (次设备)的一个链表头
};
3.3 i2c_adapter:

i2c总线适配器其实就是一个i2c总线控制器,本质上是一个物理设备,主要用来完成i2c总线控制器相关的数据通信,当向I2C核心层注册一个I2C适配器时就需要提供这样的一个结构体变量。

struct i2c_adapter {
    struct module *owner;	  /*所有者*/
    unsigned int class;       /*该适配器支持的从设备的类型*/
    const struct i2c_algorithm *algo; /* 该适配器与从设备的通信算法*/
    void *algo_data;
    /* data fields that are valid for all devices   */
    struct rt_mutex bus_lock;
    int timeout;            /* in jiffies */
    int retries;
    struct device dev;      /* 该适配器设备对应的device */
    int nr;				// 适配器的编号
    char name[48];			// 适配器的名字
    struct completion dev_released;
    struct mutex userspace_clients_lock;
    struct list_head userspace_clients;	// 用来挂接与适配器匹配成功的从设备i2c_client的一个链表头
    struct i2c_bus_recovery_info *bus_recovery_info;
    const struct i2c_adapter_quirks *quirks;
};
3.4 i2c_algorithm:

代表的是适配器的通信算法,在构建i2c_adapter结构体变量的时候会去填充这个元素。
I2C总线数据通信算法,通过管理I2C总线控制器,实现对I2C总线上数据的发送和接收等操作。亦可以理解为I2C总线控制器(适配器adapter)对应的驱动程序,每一个适配器对应一个驱动程序,用来描述适配器和设备之间的通信方法

struct i2c_algorithm {
    /* If an adapter algorithm can't do I2C-level access, set master_xfer
       to NULL. If an adapter algorithm can do SMBus access, set
       smbus_xfer. If set to NULL, the SMBus protocol is simulated
       using common I2C messages */
    /* master_xfer should return the number of messages successfully
       processed, or a negative value on error */
    int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
               int num);
    int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,          
               unsigned short flags, char read_write,
               u8 command, int size, union i2c_smbus_data *data);

    /* To determine what the adapter supports */
    u32 (*functionality) (struct i2c_adapter *);
};
3.5 代码目录:

/drivers/i2c 目录下:
I2c-core.c 实现I2C核心的功能
I2c-dev.c 通用的从设备驱动
Busses I2C适配器的驱动
Algos 实现了一些I2C总线适配器的algorithm

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值