在linux系统中经常会用到i2c的操作,但是i2c寄存器的写在不同系统层面代码有所不同,直接使用应用层的代码到内核中就会常常报找不到函数的错误。
分享一下自己的不同层面i2c写寄存器的代码。针对8位的,16位在研究。
在内核驱动中写操作
static int i2c_write(unsigned char reg_addr,unsigned char value)
{
int ret;
unsigned char buf[2];
struct i2c_msg msg[1];
msg[0].addr = 0x59;
buf[0] = reg_addr;
buf[1] = value;
msg[0].addr = 0x59;
msg[0].buf = buf;
msg[0].len = 2;
msg[0].flags = 0;//读写标准位
ret = i2c_transfer(xx.i2c_client->adapter, msg, 1);
printk("%s:0x%x = 0x%x\n",__func__,buf[0],buf[1]);
return ret;
}
在内核代码中读操作
static int i2c_read(unsigned char reg_addr)
{
int ret;
unsigned char buf[2];
buf[0] = reg_addr;
ret = i2c_smbus_read_byte_data(xx.i2c_client,reg_addr);
printk("%s:0x%x = 0x%x\n",__func__,reg_addr,ret);
return ret;
}
在应用层中
void i2c_rw(unsigned char i2c_addr,unsigned char reg_add,unsigned char reg_val){
int fd = -1;
int ret ;
struct i2c_rdwr_ioctl_data data;
data.msgs = (struct i2c_msg *)malloc(2 * sizeof(struct i2c_msg));
unsigned char sendbuf[sizeof(unsigned char) + 1] = {0};
unsigned char recvbuf[sizeof(unsigned char) + 1] = {0};
fd = open("/dev/i2c-2",O_RDWR);
if(fd < 0) {
printf("Failed to open device /dev/i2c-2\n");
return -1;
}
data.nmsgs = 1;
data.msgs[0].len = 2;
data.msgs[0].addr = i2c_addr;
data.msgs[0].flags = 0;
data.msgs[0].buf = sendbuf;
data.msgs[0].buf[0] = reg_add;
data.msgs[0].buf[1] = reg_val;
ret = ioctl(fd,I2C_RDWR,(unsigned long)&data);
if(ret < 0)
printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);
printf("buf[0] = %x\n",data.msgs[0].buf[0]);
close(fd);
}
最后给大家推荐使用如下工具
i2cdetect 查看i2c挂载的设备地址及使用情况
i2cdetect -f -y 0(查看i2c0下挂载的设备地址),参数0代表i2c0下查找,看到0x1a写着uu代表使用中。
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- 0f
10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
i2cdump -f -y 0 0x0f (查看i2c0下的0x0f设备寄存器值)
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
80: 00 00 00 00 00 00 11 00 00 cf 00 00 e2 65 0c 31 ......?..?..?e?1
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
i2cset -r -y 0 0x0f 0 0x11(向i2c0的0x0f设备中的地址0寄存器写0x11)