【IMX6ULL驱动开发学习】09.Linux之I2C驱动框架简介和驱动程序模板( 二 )


当 I2C 设备和驱动匹配成功以后 probe 函数就会执行 。驱动结构体,如果使用设备树,需要设置的 成员变量,即驱动的兼容()性 。未使用设备树的设备需要设置 设备匹配 ID 表 。
构造结构体,里面会表明支持那些设备,入口函数里注册结构体,如果发现能够支持的的话,probe函数就被调用,在probe函数里记录信息、注册字符设备、注册、自动创建设备节点
I2C驱动程序与普通的字符设备驱动程序没有本质差别,唯一差别:发起数据传输时用到,该函数需要用到适配器(i2c控制器),probe函数被调用时内核会传入,里含有i2c控制器 。
二、I2C总线-设备-驱动模型

【IMX6ULL驱动开发学习】09.Linux之I2C驱动框架简介和驱动程序模板

文章插图
2.
表明能支持哪些设备:
.name跟某个[i].值相同,则匹配成功
使用来判断
跟匹配成功后,就调用.probe函数 。
/* 传统匹配方式 ID 列表 */static const struct i2c_device_id xxx_id[] = {{"xxx", 0},{}};/* 设备树匹配列表 */static const struct of_device_id xxx_of_match[] = {{ .compatible = "xxx" },{ /* Sentinel */ }};/* i2c 驱动结构体 */static struct i2c_driver xxx_driver = {.probe = xxx_probe,.remove = xxx_remove,.driver = {.owner = THIS_MODULE,.name = "xxx",.of_match_table = xxx_of_match,//使用设备树},.id_table = xxx_id,//未使用设备树};
2.2
表示一个I2C设备,创建的方法有4种:
(1)方法1:通过设备树来创建(常用)
i2c1: i2c@400a0000 {/* ... master properties skipped ... */clock-frequency = <100000>;flash@50 {compatible = "atmel,24c256";reg = <0x50>;};pca9532: gpio@60 {compatible = "nxp,pca9532";gpio-controller;#gpio-cells = <2>;reg = <0x60>;};};
向 i2c1 添加 flash 子节点,flash@50是子节点名字,@后面的50是I2C 器件地址 。属性值为atmel, 。reg属性也是设置I2C的器件地址的 。I2C 设备节点的创建主要是属性和 reg属性的设置,一个用于匹配驱动,一个用于设置器件地址 。
(2)方法2:
有时候无法知道该设备挂载哪个I2C bus下,无法知道它对应的I2C bus。但是可以通过其他方法知道对应的结构体 。可以使用下面两个函数来创建:
static struct i2c_board_info sfe4001_hwmon_info = {I2C_BOARD_INFO("max6647", 0x4e),};int sfe4001_init(struct efx_nic *efx){(...)efx->board_info.hwmon_client =i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);(...)}
e
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };static int usb_hcd_nxp_probe(struct platform_device *pdev){(...)struct i2c_adapter *i2c_adap;struct i2c_board_info i2c_info;(...)i2c_adap = i2c_get_adapter(2);memset(&i2c_info, 0, sizeof(struct i2c_board_info));strscpy(i2c_info.type, "isp1301_nxp", sizeof(i2c_info.type));isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,normal_i2c, NULL);i2c_put_adapter(i2c_adap);(...)}
差别:
(3)方法3(不推荐):由.函数来判断是否有对应的I2C设备并生成
(4)方法4:通过用户空间(user-space)生成 调试时、或者不方便通过代码明确地生成时,可以通过用户空间来生成 。
// 创建一个i2c_client, .name = "eeprom", .addr=0x50, .adapter是i2c-3# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device// 删除一个i2c_client# echo 0x50 > /sys/bus/i2c/devices/i2c-3/delete_device
2.3I2C 设备数据收发和处理
在 I2C 设备驱动中首先要完成结构体的创建、 初始化和注册,当设备和驱动匹配成功后,就会执行 probe 函数,probe 函数中就是执行字符设备驱动的一套流程 。