简单理解下驱动中的i2c,主要是两个方面
一个方面是i2c设备的添加,另一方面是i2c读写数据
一.设备驱动中,i2c设备驱动的注册
i2c_add_driver(&i2c_driver)
i2c_driver //struct i2c_driver
├── .probe
├── .remove
├── .id_table
├── .driver //
├── .name
├── .ownwer
├── .of_match_table
├── .pm = &pm_ops //struct dev_pm_ops 电源管理回调函数
├── .suspend
├── .resume
//dev_pm_ops:
https://blog.csdn.net/zrlean/article/details/7835524
--------------
二.驱动中i2c接口函数的调用,主要就是初始化struct i2c_msg 填充结构体成员,然后调用i2c_transfer函数.
写函数,地址是msg.addr, 写的内容写到msg->buf[]中。读函数,也是读到msg->buf[]中,然后通过memcpy复制到自己的buffer中使用。
s32 i2c_write(register addr,buffer, len);
{
struct i2c_msg msg = {
.flag = 0,
.addr = i2c_client->addr
};
...
msg->buf = data; //alloc
msg->buf[0] = (address >> 8) & 0xFF;
msg->buf[1] = address & 0xFF;
msg->len = transfer_length + _ADDR_LENGTH;
memcpy(&msg->buf[GTP_ADDR_LENGTH], &buffer[pos], transfer_length);
ret = i2c_transfer(gt1x_i2c_client->adapter, msg, 1);
}
s32 i2c_read(register addr, buffer, len)
{
//16位地址,分两个存储
u8 addr_buf[2] = {(addr >> 8) & 0xff, addr & 0xff};
struct i2c_msg msgs[2] = {
.addr = i2c_client->addr,
.flags = 0,
.buf = addr_buf,
.len = 2},
{
.addr = i2c_client->addr,
.flags = I2C_m_RD}
}
};
return _do_i2c_read(msgs, addr, buffer, len);
}
看书上说了很多client, adapter之间的联系,看设备驱动代码,感觉adapter并不需驱动要多操心,linux内核核心层已经做了
很多事情,设备驱动只是在读写i2c时调用i2c_transfer时传入第一个参数是i2c_client->adapter.
-----------------------------------
硬件接口与协议:
https://www.pianshen.com/article/90551353436/