排查一个触摸屏驱动问题

今天跟同事看一个TP驱动,上电后日志都正常,但是触摸没反应,然后开始排查。

上电后可以正常读到芯片的chip ID,那说明I2C是通讯正常的,也可以说明触摸芯片的供电也是正常的。

基于这个,我搬来示波器,测量中断引脚的信号,发现两个现象

1、从休眠到唤醒状态后,中断脚有波形,而且波形上看不出异常。

2、中断处理函数没有跑进去

—— 触摸屏的dts文件编写如下

 文件:arch/arm/boot/dts/inxxx.dtscap_touch@14 {compatible = "mediatek,cap_touch";reg = <0x14>;interrupt-parent = <&pio>;interrupts = <100 IRQ_TYPE_EDGE_FALLING>;int-gpio = <&pio 100 0>;rst-gpio = <&pio 101 0>;};

compatible 是和驱动里面的name 匹配上的。

reg 是I2C芯片的 地址。

interrupt-parent 对应的是平台的中断控制器,里面应用的 pio对应的是mt8167.dtsi文件里面的中断控制器dts描述

interrupts 的第一个参数对应的是中断号,第二个参数对应的是中断的触发方式。

int-gpio 里面引用的 pio 也是用到了 pio里面的gpio口控制器,第二个参数对应的是gpio 编号,第三个对应的是gpio口的电平。

rst-gpio 和上面同理。

看内核文档对gpiodts的描述

 文件:Documentation/devicetree/binding/pinctrl/pinctrl-mt65xx.txtEg: <&pio 6 0><[phandle of the gpio controller node][line number within the gpio controller][flags]>Values for gpio specifier:- Line number: is a value between 0 to 202.- Flags:  bit field of flags, as defined in <dt-bindings/gpio/gpio.h>. Only the following flags are supported: 0 - GPIO_ACTIVE_HIGH 1 - GPIO_ACTIVE_LOW

看看&pio这个里面都是一些什么东西

pio: pinctrl@10005000 {compatible = "mediatek,mt8167-pinctrl";reg = <0 0x1000b000 0 0x1000>;mediatek,pctl-regmap = <&syscfg_pctl_a>;pins-are-numbered;gpio-controller;#gpio-cells = <2>;interrupt-controller;#interrupt-cells = <2>;interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
};

—— 看看注册上的中断的编号

xxxx:/ # cat proc/interruptsCPU018:      19578       GIC  27 Edge      arch_timer20:          0  MT_SYSIRQ 132 Level     mtk_timer21:         12  MT_SYSIRQ  84 Level     mtk-uart30:          0  MT_SYSIRQ 128 Level     SPM31:          0  MT_SYSIRQ 129 Level     SPM32:          0  MT_SYSIRQ 130 Level     SPM33:          0  MT_SYSIRQ 131 Level     SPM34:          0  MT_SYSIRQ 221 Edge      ATF_irq39:          0  MT_SYSIRQ 194 Level     BTCVSD_ISR_Handle40:          0  MT_SYSIRQ 198 Edge      mtk-wdt42:          0  MT_SYSIRQ 204 Level     mt-pmic-pwrap43:          0  MT_SYSIRQ 149 Edge      mtk-kpd45:          0  MT_SYSIRQ 121 Level     10203000.m4u46:          0  MT_SYSIRQ 218 Level     CIRQ47:          0  MT_SYSIRQ 114 Level     TEE IRQ49:       2942  MT_SYSIRQ 125 Level     mtk_cmdq50:          0  MT_SYSIRQ 126 Level     TEE IRQ53:          0  MT_SYSIRQ  76 Level     mt-pwm54:         30  MT_SYSIRQ  80 Level     i2c-mt65xx55:         16  MT_SYSIRQ  81 Level     i2c-mt65xx56:         64  MT_SYSIRQ  82 Level     i2c-mt65xx57:          0  MT_SYSIRQ  77 Level     mt8167-thermal58:         16  MT_SYSIRQ  83 Level     ptp62:      20967  MT_SYSIRQ  72 Level     musb-hdrc63:          0  MT_SYSIRQ 120 Level     Afe_ISR_Handle64:       2950  MT_SYSIRQ 185 Level     pvrsrvkm65:     113181  MT_SYSIRQ  78 Level     11120000.mmc67:          0  MT_SYSIRQ 210 Level     musbfsh-hdrc.074:        347  MT_SYSIRQ 160 Level     DISPSYS75:      12980  MT_SYSIRQ 162 Level     DISPSYS76:          0  MT_SYSIRQ 163 Level     DISPSYS80:          0  MT_SYSIRQ 167 Level     DISPSYS83:          0  MT_SYSIRQ 171 Level     DISPSYS85:       1466  MT_SYSIRQ 153 Level     DISPSYS88:          0  MT_SYSIRQ 180 Level     ISP
123:          0  mtk-eint  28 Level     mt6397-pmic
136:          0  mtk-eint  41 Level     USB_IDDIG
195:          6  mtk-eint 100 Edge      mtk-tpd
264:          0  mt6397-irq   6 Edge      mt6397-thr_l
265:          0  mt6397-irq   7 Edge      mt6397-thr_h
266:          0  mt6397-irq   5 Edge      mtk-pmic-keys
267:          0  mt6397-irq  17 Edge      mtk-pmic-keys
268:          0  mt6397-irq  18 Edge      mtk-pmic-keys
269:          0  mt6397-irq  19 Edge      mtk-pmic-keys
270:          0  mt6397-irq  20 Edge      mt6397-rtc
IPI0:          0  CPU wakeup interrupts
IPI1:          0  Timer broadcast interrupts
IPI2:      31856  Rescheduling interrupts
IPI3:         35  Function call interrupts
IPI4:        121  Single function call interrupts
IPI5:          0  CPU stop interrupts
IPI6:          0  IRQ work interrupts
IPI7:          0  completion interrupts
Err:          0

#看看驱动文件如何驾驭这些dts配置

先使用函数获取dts里面的内容

  tpd_rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpio", 0);tpd_int_gpio = of_get_named_gpio(dev->of_node, "int-gpio", 0);

然后就是申请

static int gtp_get_gpio_res(void)
{
#if defined(CONFIG_OF) && !defined(CONFIG_GTP_USE_PINCTRL)int ret;/* configure the gpio pins */ret = gpio_request_one(tpd_rst_gpio, GPIOF_OUT_INIT_LOW,"touchp_reset");if (ret < 0) {GTP_ERROR("Unable to request gpio reset_pin\n");return -1;}ret = gpio_request_one(tpd_int_gpio, GPIOF_IN,"tpd_int");if (ret < 0) {GTP_ERROR("Unable to request gpio int_pin\n");gpio_free(tpd_rst_gpio);return -1;}
#endifreturn 0;
}

然后去看中断注册函数的时候,会有点奇怪

static int tpd_irq_registration(void)
{struct device_node *node = NULL;unsigned long irqf_val = 0;int ret = 0;// node = of_find_compatible_node(NULL, NULL, "mediatek,cap_touch");//0704node = of_find_matching_node(NULL, touch_of_match);if (node) {
//  touch_irq = gpio_to_irq(tpd_int_gpio);touch_irq = irq_of_parse_and_map(node, 0);GTP_ERROR("###### touch_irq = %d\n",(int)touch_irq);irqf_val = !int_type ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;irq_enabled = true; //ret = request_irq(touch_irq, (irq_handler_t) tpd_interrupt_handler,irqf_val, TPD_DEVICE, NULL); //jason test hereGTP_ERROR("###### ret = %d\n",(int)ret);if (ret < 0)GTP_ERROR("tpd request_irq IRQ LINE NOT AVAILABLE!.");
}

// touch_irq = gpio_to_irq(tpd_int_gpio); 这行代码被注释掉了,也就是不用 gpio_to_irq来使用中断了。

目前的驱动使用了 irq_of_parse_and_map 函数来解析dts内容给驱动使用。

使用 irq_of_parse_and_map 的原因还是为了让驱动工程师少干活,dts 已经把中断的信息给描述清楚了,包括上面说的 interruptsinterrupt-parent 属性,这个函数会解析这两个属性,并实现对应的映射关系。

—— 看看内核代码对这个函数的解释

/*** irq_of_parse_and_map - Parse and map an interrupt into linux virq space* @dev: Device node of the device whose interrupt is to be mapped* @index: Index of the interrupt to map** This function is a wrapper that chains of_irq_parse_one() and* irq_create_of_mapping() to make things easier to callers*/
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
{struct of_phandle_args oirq;if (of_irq_parse_one(dev, index, &oirq))return 0;return irq_create_of_mapping(&oirq);
}
EXPORT_SYMBOL_GPL(irq_of_parse_and_map);

上面的英文的意思是,这个函数是解析并映射中断到 linux virq 空间,dev对应的就是device指针,index 就是需要映射的中断的索引。

该函数是 of_irq_parse_one() 和 irq_create_of_mapping() 的封装,封装的作用是为了码农写代码更容易一些。

我们再看看

touch_irq = irq_of_parse_and_map(node, 0);

后边的这个 0表示的是偏移索引,如果我们在dts里面这样写的话,就可以使用索引来选择我们的配置

interrupts = <0 0 4>, <0 1 4>;

我们在 proc/interrupts下看到的编号「195」就是这里出来的

195:         69          0          0          0  mtk-eint 100 Edge      mtk-tpd

#所以为什么中断函数没有进去?

检查了一轮发现是因为dts描述里面的 interrupts 属性没有写对,interrupts 的第一个参数需要和gpio口编号对应起来,但是我们沿用上个项目的代码,应该修改了这个gpio口,我们软件没有及时修改过来。

当然了,知道问题后就很快解决了。

触摸后可以看到触摸屏可以正常报点是一件非常开心的事情。

#驱动获取dts中断的方式

这部分韦东山老师总结的非常好的,我建议大家看看这篇文章

在Linux驱动中获取dts描述的中断

针对不同的设备,获取的方式不同,比较常见的是在dts里面把中断描述成一个gpio口,然后在驱动中先获取gpio口,然后再转换成中断。

#总结

这部分属于炒旧饭,触摸屏驱动是比较常见的外设,调试的难度也不是很大,正常的调试顺序是

— 先搞定供电
— 再搞定I2C、I2C一般需要上拉,还有I2C的速率,I2C的电平。

— 再看看地址,我们Linux 里面一般是 7bit 地址,需要注意,地址也会跟硬件设计相关。

— 上面都正常了,就可以去排查中断的问题了,有的GPIO可能默认没有中断,也需要软件配置。

— 然后就观察软件是否能进入中断处理函数,有的驱动是支持轮询的,但是代码位置都差不多。

这样都正常后就可以开机测试触摸是否正常了。

推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈


嵌入式Linux

微信扫描二维码,关注我的公众号 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466914.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vmware安装ubuntu

vmware安装Ubuntu 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 &#xff08;1&#xff09; 单击”Power on this virtual machine”开始安装Ubuntu系统 经过一段时间的等待出现如下界面,单击”Install Ubuntu”进行安装 在安装的时候&#xff0…

AWS 免费套餐

https://amazonaws-china.com/cn/free/ 需要的可以看下&#xff0c;我准备搞一个RDS。 转载于:https://www.cnblogs.com/hupo376787/p/8268562.html

C++指针的应用

C指针 文章中我们介绍了指针的基本概念和应用简介。我们有提到指针可以使用在链表、队列和二叉树&#xff0c;等等。但是这些都会比较复查&#xff0c;后面"数据结构” 时&#xff0c;我们会用专门的章节来讲解这些知识。这篇文章&#xff0c;详细的探讨一下指针和其他关联…

Matplotlib——创建散点图

入门&#xff1a; 导入所用到的包 import numpy as np import matplotlib.pyplot as plt as 是对包起一个名字&#xff0c;便于后边程序的编写无颜色差别 figplt.figure() #建立一个画布 axfig.add_subplot(111) #在画布中建立图表&#xff0c;fig.add_subplot(…

vmwaretools安装

vmwaretools安装 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 vmware的作用&#xff1a;windows和linux之间文件拖文件很方便&#xff0c;但是我一般是使用samba服务器&#xff0c;后面介绍samba服务器。 &#xff08;1&#xff09;单击菜单栏上的”…

机器学习——支持向量机主要思想

概念&#xff1a;支持向量运算的分类器&#xff0c;在数据上应用基本形式的SVM分类器就可以得到低错误的结果&#xff0c;能够对训练集以外的数据点做出很好的分类决策。 名词&#xff1a; 支持向量&#xff1a;离分离超平面最近的那些点&#xff0c;需要找到最大化支持向量到分…

哇、、、、C++ 实现单向链表

之前相关的文章 C语言&#xff0c;链表 Linux内核链表 #什么是链表 链表是一种基本的数据结构&#xff0c;之前我在C语言里面写过链表的知识&#xff0c;现在延申到C&#xff0c;不管是什么语言&#xff0c;链表表示的是一种数据结构&#xff0c;跟语言没有强相关性的。 如果我…

vmware与windows共享文件夹

vmware与windows共享文件夹 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 虚拟工具安装好之后&#xff0c;我们就可以在windows和linux设置一个共享目录了,继续看图干活。 设置好共享目录以后&#xff0c;打开终端输入以下命令&#xff0c;就可以再…

asp.net如何取得纯客户端控件的值

例一&#xff1a;纯客户端控件 <input name"edisundong"type"text">在服务器端取得的方法 stringstrvalueRequest.Form.Get("edisundong");例二&#xff1a;纯客户端控件 <input type"radio"name"sex"value"…

C++ const限定符和auto类型说明符

const限定符# 1.限定常量有时我们希望定义这样的变量&#xff1a;它的值不能被改变。为了满足这一要求&#xff0c;我们使用const对变量的类型加以限定&#xff1a;const int bufSize 512;这样就把bufSize定义成了一个常量&#xff0c;它的值不能再发生变化。所以这也就意味着…

Flume框架基础

* Flume框架基础 框架简介&#xff1a; ** Flume提供一个分布式的&#xff0c;可靠的&#xff0c;对大数据量的日志进行高效收集、聚集、移动的服务&#xff0c;Flume只能在Unix环境下运行。 ** Flume基于流式架构&#xff0c;容错性强&#xff0c;也很灵活简单&#xff0c;主要…

tensorflow的安装

安装好adaconda软件&#xff0c;打开 adaconda prompt anaconda search -t conda tensorflow 查看conda create -n tensorflow python3.5 配置python3.5环境选择 yes 进行安装activate tensorflow 激活tensorflowpip install tensorflow 安装 然后打开adaco…

昨晚三巨头聚餐,顺便聊了这三个问题

今天老何找我们吃饭&#xff0c;我和老何还有老墨是邻居&#xff0c;三年前我们就认识了&#xff0c;而且关系还不错&#xff0c;但是今年疫情的原因我们都没聚过&#xff0c;上周六本来说好要聚一下&#xff0c;但又因为周末带娃的原因又没聚成&#xff0c;今天我在微信群上说…

决策树 算法原理及代码

决策树可以使用不熟悉的数据集合&#xff0c;并从中提取出一系列的规则&#xff0c;这是机器根据数据集创建规则的过程&#xff0c;就是机器学习的过程。用一个小案例分析&#xff1a;通过No surfacing 和 flippers判断该生物是否是鱼&#xff0c;No surfacing 是离开水面是否…

深度好文|面试官:进程和线程,我只问这19个问题

# 干了这碗鸡汤&#xff01;我急切地盼望着可以经历一场放纵的快乐&#xff0c;纵使巨大的悲哀将接踵而至&#xff0c;我也在所不惜。-- 太宰治 《人间失格》大家好&#xff0c;这里是周日凌晨4点&#xff0c;仍在笔耕不辍的程序喵大人。下面隆重推出我呕心沥血&#xff0c;耗时…

终于有人将进程间通信讲明白了

使用多进程协作来实现应用和系统是一种被广泛使用的开发方法。多进程协作主要有以下三点优势。将功能模块化&#xff0c;避免重复造轮子。增强模块间的隔离&#xff0c;提供更强的安全保障。提高应用的容错能力。进程间通信&#xff08;Inter-Process Communication&#xff0c…

神舟本本放心率

总得票8520 可以放心购买 22.0% 1942票 不太放心 64.0% 5510票 看情况 12.0% 1068票投票起止时间&#xff1a;2007-11-15 至2008-11-22转载于:https://www.cnblogs.com/badapple126/archive/2007/11/16/962020.html

梯度下降算法

在学习逻辑回归时&#xff0c;对梯度上升算法进行了应用&#xff0c;看到其他的博客讲解&#xff0c;梯度上升算法适合求最大值&#xff0c;梯度下降算法适合求最小值&#xff0c;这里有一个分析&#xff1a;梯度上升算法公式是学习率&#xff0c;是一个常数。这个是根据逻辑回…

花了一个深夜,才用C语言写了一个2048游戏雏形

12年我毕业的第二个月工资&#xff0c;我就买了一个IPAD&#xff0c;然后在IPAD上下了一个2048游戏&#xff0c;玩起来非常爽。然后这几天看到好几个公众号都发了自己写这个游戏的代码&#xff0c;然后我自己也想试试&#xff0c;所以就有了这篇文章&#xff0c;写代码还是很有…

向银行贷款20万, 分期三年买50万的车,个人借款40万, 贷款10年买200万的房子,再贷款120万分创业...

向银行贷款20万按1年期贷款利率为&#xff1a;6%&#xff0c;若按年还贷款&#xff0c;银行贷款利息为&#xff1a;200&#xff0c;000*6%12&#xff0c;000。连本带息&#xff1a;20*106%21.2万分期三年买50万的车 贷款总额30万 年利率按10%算&#xff0c;分三年还清&#xff…