I2C驱动之结构体

 在<linux/i2c.h>中定义了i2c驱动中的一些结构体,包含了 i2c_client, i2c_driver, i2c_adapter, i2c_algorithm, i2c_msg, 下面分析一下这些结构体

1. i2c_client 结构体

    该结构体定义了挂载在I2C总线下的slave设备,一个结构体对象代表一个slave设备    

struct i2c_client {
	unsigned int flags;		/* 设备标志		*/
	unsigned int addr;		/* slave地址,7-bit or 10-bit	*/
	struct i2c_adapter *adapter;	/* 适配器	*/
	struct i2c_driver *driver;	/* 该设备驱动	*/
	int usage_count;		/* 访问设备总数  */
	struct device dev;		/* 设备信息	*/
 	struct list_head list;          /* 挂载总线下的设备链表	*/
	char name[I2C_NAME_SIZE];       /* 设备名称    */
	struct completion released;
};


2. i2c_driver 结构体

    该结构体与i2c_client是一对多关系,即一个驱动可以对上多个设备.根据name进行匹配.

struct i2c_driver {
	struct module *owner; /* 模块拥有这,基本上设置成.owner = THIS MODULE */
	char name[32];     /* 驱动名称,用于与设备名称进行匹配  */ 
 	int id;            /* 与设备匹配也可以使用ID,但好像用的不多  */ 
 	unsigned int class;
	unsigned int flags;		/* 		*/
	int (*attach_adapter)(struct i2c_adapter *);   /* 通知总线上出现一个新的驱动程序	 */
        int (*detach_adapter)(struct i2c_adapter *);  /* 总线上移除了一个驱动程序	 */	
	int (*detach_client)(struct i2c_client *);  /* 总线上移除了一个从设备,如果这个设备是动态创建的,这里就必须被释放掉	 */	
	 /*  可以对设备进行命令控制	 */
 	int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
	struct device_driver driver; /* 设备驱动信息 */
	struct list_head list;
};

3. i2c_adapter 结构体

    该结构体定义了一个物理层次的I2C总线    

struct i2c_adapter {
	struct module *owner;
	unsigned int id;      /* == is algo->id | hwdep.struct->id, 		*/
	unsigned int class;
	struct i2c_algorithm *algo;   /* 总线通信的算法	*/
	void *algo_data;
	/* 设备注册和取消 */
	int (*client_register)(struct i2c_client *);
	int (*client_unregister)(struct i2c_client *);
	/* data fields that are valid for all devices	*/
	struct semaphore bus_lock;
	struct semaphore clist_lock;
	int timeout; /* 定义超时时间 */
	int retries;  /* 重试次数 */
	struct device dev;		/*  adapter 设备 */
	struct class_device class_dev;	/*  class 设备 */
#ifdef CONFIG_PROC_FS 
	/* 如果初始化adapter,就不需要设置          */
	int inode;
#endif /* def CONFIG_PROC_FS */

        int nr; /* 总线号 */
	struct list_head clients;
	struct list_head list;
 	char name[I2C_NAME_SIZE];       /* adapter名称 */
 	struct completion dev_released;
	struct completion class_dev_released;
};

4. i2c_algorithm 结构体

     该I2C主设备传输数据的算法.  其中提供了关键的函数master_xfer()用于产生i2c访问周期需要的信号,以i2c_msg为单位

struct i2c_algorithm {
	char name[32];				/* 算法描述,以文本形式 */
	unsigned int id;

	/* 
         *一般都使用 master_xfer() 算法
        */
	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);

	/* 从设备发送/接收数据 */
	int (*slave_send)(struct i2c_adapter *,char*,int);
	int (*slave_recv)(struct i2c_adapter *,char*,int);

	/* 设置参数方法 */
	int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long);

	/*  */
	u32 (*functionality) (struct i2c_adapter *);
};

5. i2c_msg 结构体

   

struct i2c_msg {
	__u16 addr;	/* 从设备地址 */
 	__u16 flags;	/* 设备标示 */	
#define I2C_M_TEN 0x10	 /* 这个使用10-bit地址	*/
#define I2C_M_RD	0x01
#define I2C_M_NOSTART	0x4000
#define I2C_M_REV_DIR_ADDR	0x2000
#define I2C_M_IGNORE_NAK	0x1000
#define I2C_M_NO_RD_ACK		0x0800
 	__u16 len;		/* msg 长度 */
 	__u8 *buf;		/* msg数据指针	*/
};

I2C_M_IGNORE_NAK:
      设置这个标志意味当前i2c_msg忽略I2C器件的ack和nack信号。
I2C_M_NOSTART:      
      设置这个标志意味当前i2c_msg不发送start信号
      1.msgs序列第一个数据必须是地址,同时必须不定义这个标志位
      2.在进行读数据,要从写操作转变为读操作时,会发重复start信号和器件地址时,必须不定义这个标志位
      3.其它情况下一的i2c_msg必须定义这个标志
      以上只是我看完这个函数的理解,不一定正确。同时1和2总结下来就是发器件地址(注意,是器件地址,不是像EEPROM那样的EEPROM地址,这个地址是当数据发的)时会不设置I2C_M_NOSTART, 发数据时就设置I2C_M_NOSTART这个标志。
I2C_M_NO_RD_ACK:
      这个标识表示在正行读操作时不去ACK,我不知道其它芯片如果,如果是AT24C04则一定不能设这个标志位了。
(下面三个标志为均为bit_doAddress函数使用,结合上面的说明,也就是这时I2C_M_NOSTART一定没有设置。)
I2C_M_RD:
      表示这是一个读操作,默认是把相应的位置1
I2C_M_REV_DIR_ADDR:
      表示把读写标志位反转,也就是读是把相应位置0
I2C_M_TEN:
     表示这个器件的器件地址是10Bit的。一定要搞清,这是器件地址,不是指EEPROM的ROM地址。24C02等芯片真正的器件地址只有4位永远有效(0xA),低4位用来放其它东西了(根据容量有可能是器件地址的低3位,或ROM地址的高3位)。也是说,无论什么容量,这类器件的地址只是器件地址我们只选7位模式(内核只区分10位模式和其它模式)

参考 关于i2c_msg的一些标志位




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值