参考:http://blog.csdn.net/fanqipin/article/details/7940061
I2C(Inter-Intergratedcircuit)及子集smbus(system management Bus)接口是嵌入式系统中比较常见的接口。I2C设备主要有EEPROM,HWMON,RTC等。
I2C为两线接口,SDA和SCL。
I2C设备通常为7位地址,但也有10位地址。
在kernel加载时,会加载dts,遍历到dts文件中的i2c设备;
dts中至少包含设备名称和设备地址;
当设备驱动insmod时,driver中的name与dts中的name一致时,probe函数被调用,并将client传递给driver,如此设备与driver建立联系。
在probe中创建设备节点,供用户空间访问设备。
i2cdev->dev = device_create(i2c_dev_class, NULL, MKDEV(I2C_MAJOR, client->adapter->nr),
NULL,"i2c-%d",client->adapter->nr);
struct module *owner;
unsigned int class; /* classes to allow probing for */
const struct i2c_algorithm *algo; /* the algorithm to access the bus */
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;/* the adapter device */
int nr;
char name[48];
struct completion dev_released;
struct mutex userspace_clients_lock;
struct list_head userspace_clients;
};
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg*msgs, int num);
// 更加强大并通用的传输函数, 可以由多个struct i2c_msg拼凑出复杂的传输. 其中的i2c_msg定义如下:
struct i2c_msg {
__u16 addr; /*slave address */
__u16 flags;
#defineI2C_M_TEN 0x0010 /* this is a ten bit chip address */
#defineI2C_M_RD 0x0001 /* read data, from slave to master */
#defineI2C_M_NOSTART 0x4000 /* ifI2C_FUNC_PROTOCOL_MANGLING */
#defineI2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#defineI2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#defineI2C_M_NO_RD_ACK 0x0800 /* ifI2C_FUNC_PROTOCOL_MANGLING */
#defineI2C_M_RECV_LEN 0x0400 /* length will befirst received byte */
__u16 len; /* msg length */
__u8 *buf; /* pointer to msg data */
};
i2c_transfer顺序处理*msgs指向的所有的i2c_msg,每个i2c_msg执行前都会发START状态
当最后一个i2c_msg执行完成后会发STOP状态。
s32 i2c_smbus_read_byte(const struct i2c_client *client);
s32 i2c_smbus_write_byte(const struct i2c_client *client, u8value);
s32 i2c_smbus_read_byte_data(const struct i2c_client*client, u8 command);
s32 i2c_smbus_write_byte_data(const struct i2c_client*client, u8 command, u8 value);
s32 i2c_smbus_read_word_data(const struct i2c_client*client, u8 command);
s32 i2c_smbus_write_word_data(const struct i2c_client*client, u8 command, u16 value);
s32 i2c_smbus_read_word_swapped(const struct i2c_client*client, u8 command);
s32 i2c_smbus_write_word_swapped(const struct i2c_client*client, u8 command, u16 value);
s32 i2c_smbus_read_block_data(const struct i2c_client*client, u8 command, u8 *values);
s32 i2c_smbus_write_block_data(const struct i2c_client*client, u8 command, u8 length, const u8 *values);
s32 i2c_smbus_read_i2c_block_data(const struct i2c_client*client, u8 command, u8 length, u8 *values);
s32 i2c_smbus_write_i2c_block_data(const struct i2c_client*client, u8 command, u8 length, const u8 *values);
// 这些是smbus协议的常用函数, 方便兼容smbus协议的client使用.
// smbus协议是i2c协议的一个子集, 常见的i2cslave器件的寄存器读写都符合smbus协议,
// 这样的话直接使用这些函数会比使用i2c_transfer方便很多.
// smbus协议请参考内核文档android/kernel/Documentation/i2c/smbus-protocol
关于I2C框架的使用, 内核有相关的文档:
android/kernel/Documentation/i2c (文档)