最近在rk3399平臺上更換調試了錄音小板,原rk3399的es7243 修改新的adc小板,一開始硬件就有問題,但因爲對硬件不熟悉,導致做了汗多無用功,
言歸正傳,換adc錄音小板,首先應該用i2ctools 檢測寄存器
硬件i2c ok的情況下能使用i2cdetect 能檢測到設備,驅動裏配置了地址就顯示爲UU,沒有配置地址顯示具體值,比如10
一般寄存器都是8位地址的,i2ctools 裏的i2cdump i2cget i2cset,也是設置讀取8位的地址,但這次調試的寄存器是16位地址,i2cdump i2cget i2cset 都用不了,這時候就要用到i2ctransfer 了,I2C-Tools 4.0增加了i2ctransfer命令,可以對i2c設備指定定長度進行讀寫操作
比如在這個16位的寄存器裏我們要看 0x0020 開始的寄存器值,向後讀取16個字節
i2ctransfer -y -f 1 w2@0x1d 0x00 0x20 r16
讀取了16個字節數據
w是寫,2是寫入2個字節,@0x1d 是寄存器地址,0x00 0x20 是寄存器要設置的地址的高低位,r是讀取,16 是讀取16個字節
如果我們想修改0x0020 的值可以如下指令
i2ctransfer -y -f 1 w4@0x1d 0x00 0x20 0x77 0x77
可以看到設置成功了
w是寫,4是寫入4個字節,@0x1d 是寄存器地址,0x00 0x20 是寄存器要設置的地址的高低位,0x77 0x77是要設置的值
加上代碼寫16位寄存器方法
static int i2c_write(struct i2c_client *client, u16 reg, u16 value)
{
u8 data[4];
data[0] = (reg& 0xFF00)>>8 ;
data[1] = reg& 0x00FF;
data[2] = (value& 0xFF00)>>8;
data[3] = value& 0x00FF;
if (i2c_master_send(client, data, 4) == 4){
printk("send ok\n");
return 0;
}
else{
printk("send failed");
return -EIO;
}
}
int i2c_master_send(struct i2c_client *client,const char *buf ,int count)
{
int ret;
struct i2c_adapter *adap=client->adapter; // 獲取adapter信息
struct i2c_msg msg; // 定義一個臨時的數據包
msg.addr = client->addr; // 將從機地址寫入數據包
msg.flags = client->flags & I2C_M_TEN; // 將從機標誌併入數據包
msg.len = count; // 將此次發送的數據字節數寫入數據包
msg.buf = (char *)buf; // 將發送數據指針寫入數據包
ret = i2c_transfer(adap, &msg, 1); // 調用平臺接口發送數據
return (ret == 1) ? count : ret; // 如果發送成功就返回字節數
}
讀取16位
static u16 i2c_read(struct i2c_client *client, u16 reg)
{
struct i2c_msg xfer[2];
u8 data[2];
int ret;
u16 result = -1;
u8 reg_buf[2];
reg_buf[0]= (reg& 0xFF00)>>8;
reg_buf[1]= reg& 0x00FF;
/* Write register */
xfer[0].addr = client->addr;
xfer[0].flags = 0;
xfer[0].len = 2;
xfer[0].buf = reg_buf;
/* Read data */
xfer[1].addr = client->addr;
xfer[1].flags = I2C_M_RD;
xfer[1].len = 2;
xfer[1].buf = data;
ret = i2c_transfer(client->adapter, xfer, 2);
if (ret != 2) {
dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
return 0;
}
result = *(u16 *)data;
printk("read ok data[0] = 0x%0x , data[1] = 0x%0x\n",data[0],data[1]);
//printk("***0x%x***\n",xfer[1].buf[0]);
return result;
}