ap3216c.c i2c probe函数始终无法执行,最后发现是传统匹配方式ID列表需要修改

编译官方例程源码中的I2C驱动例程,发现i2c的probe函数始终无法执行,没有在dev下面生成设备节点。

多方求助,原来是i2c需要传统匹配方式,设备树匹配方式要同时匹配,ap3216c中的probe函数才能执行。

例程如下:

【正点原子】阿尔法Linux开发板(A盘)-基础资料\01、例程源码\02、Linux驱动例程\21_iic\ap3216c.c中

/* 传统匹配方式ID列表 */

static const struct i2c_device_id ap3216c_id\[\] = {

复制代码
**{"alientek,ap3216c", 0},**  

{}

};

/* 设备树匹配列表 */

static const struct of_device_id ap3216c_of_match\[\] = {

复制代码
{ .compatible = "Liteon,ap3216c" },

{ /* Sentinel */ }

};

修改为:

/* 传统匹配方式ID列表 */

static const struct i2c_device_id ap3216c_id\[\] = {

复制代码
**{"ap3216c", 0},**  

{}

};

/* 设备树匹配列表 */

static const struct of_device_id ap3216c_of_match\[\] = {

复制代码
{ .compatible = "Liteon,ap3216c" },

{ /* Sentinel */ }

};

修改后从新编译,/dev的设备节点终于生成了:

root@ATK-IMX6U:/mnt# ls /dev

ap3216c

root@ATK-IMX6U:/mnt# ./ap3216cApp /dev/ap3216c

ir = 0, als = 0, ps = 0

ir = 0, als = 265, ps = 3

ir = 0, als = 265, ps = 3

我使用的设备树定义如下

F:\【正点原子】阿尔法Linux开发板(A盘)-基础资料\01、例程源码\03、正点原子Uboot和Linux出厂源码\linux-imx-4.1.15-2.1.0-g3dc0a4b-v2.7\arch\arm\boot\dts\imx6ull-alientek-emmc.dts

&i2c1 {

复制代码
clock-frequency = <100000>;

pinctrl-names = "default";

pinctrl-0 = <&pinctrl_i2c1>;

status = "okay";



mag3110@0e {

	compatible = "fsl,mag3110";

	reg = <0x0e>;

	position = <2>;

};



ap3216c@1e {

	compatible = "ap3216c";

	reg = <0x1e>;

};

};

内核中的匹配代码分析:

内核代码中 i2c_device_probe 函数中存在

static int i2c_device_probe(struct device *dev)

{

复制代码
struct i2c_client    *client = i2c_verify_client(dev);

struct i2c_driver    *driver;

int status;



if (!client)

    return 0;



... ...



driver = to_i2c_driver(dev->driver);

if (!driver->probe || !driver->id_table)

    return -ENODEV;



... ...



status = driver->probe(client, i2c_match_id(driver->id_table, client));



... ...

}

if (!driver->probe || !driver->id_table)

return -ENODEV

其中|| 逻辑或 判断规则:一真则真,两假才假,即

如果driver->id_table为空或者driver->probe为空则无法实现probe函数

所以,在新内核的dts设备树表述设备时,注册i2c_driver时,一定要将i2c_driver中的id_table实现!!!

其实也是根据设备树匹配成功的,只不过传统匹配表(i2c_device_id)也必须实现。如果只使用传统匹配表匹配应该是不需要设备树匹配表的。

相关推荐
Ruiery2 小时前
Linux 6.6内核内存管理深度解析(十六):mmap — 用户态“申请内存“的真相
linux·运维·服务器
第九序言T2 小时前
Python 数据处理进阶(十八)批量处理同结构文件:一个文件夹一次跑完
开发语言·python·自动化·pandas·数据处理
欧米欧2 小时前
Linux系统篇(七),环境变量的底层溯源,核心获取机制与安全应用
linux·运维·服务器
Ruiery2 小时前
Linux 6.6内核内存管理深度解析(十八):KASLR 内核地址空间随机化
linux·运维·服务器·安全
qetfw3 小时前
UOS MariaDB 数据库:安装、最小权限与备份验证
linux·数据库·mariadb·uos
龙亘川3 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
程序喵大人3 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
Raas1004 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
专注仿真5 小时前
线性回归和逻辑回归算法详解
开发语言·人工智能·python·大模型训练·控制算法
逆风的蚂蚁5 小时前
linux服务器性能调整怎么落地?我把 CPU 调度、I/O 优先级和内核参数这几个旋钮都拧了一遍
linux·运维·服务器