Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3042932
  • 博文数量: 396
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4209
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-04 13:04
文章分类

全部博文(396)

文章存档

2022年(1)

2021年(2)

2020年(8)

2019年(24)

2018年(135)

2017年(158)

2016年(68)

我的朋友

分类: 嵌入式

2016-09-20 22:06:01

I2C驱动源码主要在linux内核/drivers/i2c下。
其中主要涉及到的结构有:
------i2c适配器------
struct i2c_adapter {
    struct module *owner; //所属模块
    unsigned int id; //algorithm的类型,定义于i2c-id.h,以I2C_ALGO_开始
    unsigned int class;
    struct i2c_algorithm *algo; //总线通信方法结构体指针,一个i2c适配器上的i2c总线通信方法由其驱动程序提供的i2c_algorithm数据结构描述,由algo指针指向
    void *algo_data; // algorithm数据
    int (*client_register)(struct i2c_client *); //client注册时调用
    int (*client_unregister)(struct i2c_client *); //client注销时调用
    struct semaphore bus_lock; //控制并发访问的自旋锁
    struct semaphore clist_lock;
    int timeout;
    int retries; //重试次数
    struct device dev; //适配器设备
    struct class_device class_dev; //类设备
    int nr;
    struct list_head clients; //client链表头,总线上每个设备的 i2c_client数据结构挂载在这里
    struct list_head list;
    char name[I2C_NAME_SIZE]; //适配器名称
    struct completion dev_released; //用于同步
    struct completion class_dev_released;
};

------i2c算法------
struct i2c_algorithm {
    int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,int num); //I2C传输函数指针
    int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,unsigned short flags, char read_write,u8 command, int size, union i2c_smbus_data *data); //SMbus传输函数指针
    u32 (*functionality) (struct i2c_adapter *); //返回适配器支持的功能
};

------i2c设备驱动------
struct i2c_driver {
    unsigned int class;
    int (*attach_adapter)(struct i2c_adapter *); //这两个接口已经被probe和remove取代 
    int (*detach_adapter)(struct i2c_adapter *); //
    int (*probe)(struct i2c_client *, const struct i2c_device_id *);
    int (*remove)(struct i2c_client *);    
    void (*shutdown)(struct i2c_client *);
    int (*suspend)(struct i2c_client *, pm_message_t mesg);
    int (*resume)(struct i2c_client *);
    void (*alert)(struct i2c_client *, unsigned int data);
    int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
    struct device_driver driver; //设备驱动结构体
    const struct i2c_device_id *id_table; //该驱动所支持的设备ID表
    int (*detect)(struct i2c_client *, struct i2c_board_info *);
    const unsigned short *address_list;
    struct list_head clients;
};

------i2c设备------
struct i2c_client {
    unsigned int flags; //标志
    //需要说明的是,i2c设备的7位地址是就当前i2c总线而言的,是“相对地址”。不同的i2c总线上的设备可以使用相同的7位地址,但是它们所在的i2c总线不同。所以在系统中一个i2c设备的“绝对地址”由二元组(i2c适配器的ID和设备在该总线上的7位地址)表示。
    unsigned short addr; //低7位为芯片地址 
    struct i2c_adapter *adapter; //依附的i2c_adapter
    struct i2c_driver *driver; //依附的i2c_driver 
    int usage_count; //访问计数 
    struct device dev; //设备结构体 
    struct list_head list; //链表头 
    char name[I2C_NAME_SIZE]; //设备名称 
    struct completion released; //用于同步 
};

单从结构体声明可以看出。
一个i2c_adapter内绑定一个i2c_algorithm。
i2c_client结构则是在struct device的基础上额外依附一个driver和一个adapter形成了一个i2c设备。
还是上图比较容易理解。
I2C驱动之主要结构体介绍
图中的Client则是i2c_client,也是提供给应用层的唯一接口,Driver、Algorithm、Adapter则分别对应其他结构,i2c-core、i2c-dev都在最上面提到的内核源码路径中可以找到。而i2c的驱动则是要把所有这些资源整合起来完成通过i2c总线读写设备的任务。
阅读(1642) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~