I2C 设备驱动重点关注两个数据结构:i2c_client 和 i2c_driver。i2c_client 就是描述设备信息的,i2c_driver 描述驱动内容。
一个设备对应一个 i2c_client,每检测到一个 I2C 设备就会给这个 I2C 设备分配一个 i2c_client。
i2c_driver 中包含 probe 函数和 device_driver 结构体。如果使用设备树的话,需要设置 device_driver 的 of_match_table 成员变量,也就是驱动的兼容(compatible)属性。
当 I2C 设备和驱动匹配以后,probe 函数就会执行。
因此,对于 Linux 来讲,不区分 I2C 控制器和 I2C 从机设备,用的都是同一套东西,即【总线、设备、驱动】框架,都有 probe 函数。
设备树
注意,I2C 设备在设备树中必须挂到对应的总线下,如图是在 &i2c0 下。
驱动
当驱动和设备匹配时,probe 函数开始执行,重要的地方博主都写了注释
static int goodix_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
struct goodix_ts_device *ts_device = NULL;
struct goodix_ts_board_data *ts_bdata = NULL;
int r = 0;
//检查 I2C 控制器支持是否支持标准 I2C 协议
r = i2c_check_functionality(client- >adapter,I2C_FUNC_I2C);
/* 板级信息分配内存 */
ts_bdata = devm_kzalloc(&client- >dev,sizeof(struct goodix_ts_board_data), GFP_KERNEL);
ts_device = devm_kzalloc(&client- >dev,sizeof(struct goodix_ts_device), GFP_KERNEL);
//填充结构体元素
/* use pinctrl in core.c */
ts_bdata- >pinctrl_dev = client- >adapter- >dev.parent;
ts_device- >name = "GT9886 TouchDevcie";
ts_device- >dev = &client- >dev;
ts_device- >board_data = ts_bdata;
ts_device- >hw_ops = &hw_i2c_ops;
touch_filter_bdata = ts_bdata;
/* ts core device */
goodix_pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
//填充结构体元素
goodix_pdev- >name = GOODIX_CORE_DRIVER_NAME;
goodix_pdev- >id = 0;
goodix_pdev- >num_resources = 0;
goodix_pdev- >dev.platform_data = ts_device;
goodix_pdev- >dev.release = goodix_pdev_release;
r = platform_device_register(goodix_pdev);
/* register platform driver*/
r = goodix_ts_core_init();
......
}
I2C 从机设备驱动中的 probe 函数和器件强相关,各家撰写方式不一样。
在 I2C 设备驱动中,除了 init、exit、probe、remove 函数外,还要实现 read、write 函数才行。
全部0条评论
快来发表一下你的评论吧 !