1.小序
TP驱动程序,是指带屏幕设备的触屏功能调用的驱动程序。TP外设与主板之间的关系如下框图:
产品常用的屏幕单元为液晶显示屏幕,TP的触摸功能也是一同集成到一起的,通过控制芯片以及外围电路、i2c总线与主板进行通信。
TP驱动的功能逻辑:
- 当有触点发生时,TP芯片向主板传递中断信号
- 驱动在收到中断后,调用驱动的中断处理函数
- 中断处理函数中,唤醒触点处理线程
- 处理线程通过 i2c 读取TP-IC内寄存器里的数据并处理
2.module_init之后的流程
此处在添加TP-I2C驱动,通过driver来匹配device中的 compatible 来识别dts 设备树中的节点。
我们通过一段地址跟踪来看TP-I2C driver的添加过程。
通过 i2c_add_driver() 函数调用到 i2c 驱动中 i2c_register_driver() ,使用的是TP外设中定义的tpd_i2c_driver->driver,在添加 i2c 驱动过程中match对应的device
static struct i2c_driver tpd_i2c_driver = {
.driver = {
.name = "gt9xx",
#ifdef CONFIG_OF
.of_match_table = of_match_ptr(gt9xx_dt_match),
#endif
},
.probe = tpd_i2c_probe,
.remove = tpd_i2c_remove,
.detect = tpd_i2c_detect,
.id_table = tpd_i2c_id,
.address_list = (const unsigned short *) forces,
};
tpd_i2c_driver->driver中的 “.of_match_table = of_match_ptr(gt9xx_dt_match), ” 这一行根据驱动中的定义
static const struct of_device_id gt9xx_dt_match[] = { {.compatible = “mediatek,goodix_touch”}, {},};
对应dts中i2c节点内子节点的 compatiable 信息。
3 获取对应pin信息
devm_pinctrl_get() 是Linux内获取对应节点内pin信息的函数,通过打印日志可以看到,在添加外设的 i2c_driver 时,触发此函数获取dits中的pin信息。调用函数如日志中一般,详细过程可跟Linux源码分析,此处详细说一下与dts有关的设置。
首先看一下dts中的内容,以下是
第
一
种
情
况
\color{#FF3030}{第一种情况}
第一种情况。
&i2c0 {
status = "okay";
goodix_touch@5d {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c0_pins>;
pinctrl-1 = <&i2c0_pins_sleep>;
compatible = "mediatek,goodix_touch";
reg = <0x5d>;
status = "okay" ;
interrupt-parent = <&pio>;
interrupts = <0 IRQ_TYPE_EDGE_FALLING 0 0>;
int-gpio = <&pio 0 0>;
rst-gpio = <&pio 174 0>;
};
};
这些pin信息
pinctrl-names = “default”, “sleep”;
pinctrl-0 = <&i2c0_pins>;
pinctrl-1 = <&i2c0_pins_sleep>;
是定义在对应外设TP节点内部,因此在外设添加 i2c_driver 时,匹配到对应 device 后,打印出 dev_name 信息为 0-005d。
内核的 i2c 驱动加载时,i2c0总线打印的dev_name 则为11007000@i2c0
以下是 第 二 种 情 况 \color{#FF3030}{第二种情况} 第二种情况。
&i2c0 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c0_pins>;
pinctrl-1 = <&i2c0_pins_sleep>;
status = "okay";
goodix_touch@5d {
compatible = "mediatek,goodix_touch";
reg = <0x5d>;
status = "okay" ;
interrupt-parent = <&pio>;
interrupts = <0 IRQ_TYPE_EDGE_FALLING 0 0>;
int-gpio = <&pio 0 0>;
rst-gpio = <&pio 174 0>;
};
};
pinctrl-names = “default”, “sleep”;
pinctrl-0 = <&i2c0_pins>;
pinctrl-1 = <&i2c0_pins_sleep>;
这些pin信息的定义是在 i2c0节点下的,因此在 i2c 驱动加载时,匹配i2c的compatible信息获取此处的pinctrl信息。打印的log如下
1、是i2c驱动的入口处;
2、是i2c驱动的driver地址,对照6处,i2c-0和i2c-1是先后加载到内核中的,他们在dts中有一样的compatible;
3、依次匹配的device节点,dev_name是设备树节点的name;
4、把dts中,i2c0节点下的 pinctrl 信息绑定到此处,此处可以用作对i2c0总线的操作;如果某外设要自身操作,参考上面第一种情况。
5、由于绑定的是总线driver,直接调用drv->probe。如果是外设添加driver,则首先调用总线probe,再调用drv->probe。文章来源:https://www.toymoban.com/news/detail-442127.html
3.1 小注
Q:通过dts添加的pinctrl信息,将i2c的SDA和SCL两根线上下电
A:在dts中添加pinctrl信息后,如果采用第二种情况,对i2c总线整体操作,效果不生效,可能是probe中没有将pinctrl信息获取。是否欠缺此处代码。
文章来源地址https://www.toymoban.com/news/detail-442127.html
到了这里,关于TP驱动——I2C驱动,细节分析——dts设备树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!