排查一个触摸屏驱动问题
今天跟同事看一个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 已经把中断的信息给描述清楚了,包括上面说的 interrupts
和 interrupt-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
微信扫描二维码,关注我的公众号
排查一个触摸屏驱动问题相关推荐
- linux内核关闭触摸屏校准,linux内核usb触摸屏驱动bug调试- selected device is not a touchscreen I understand...
近期给客户调试一块数控板,今天客户带过来一个屏,并且有一个usb的触摸屏芯片接在屏上.屏很快就弄好正常显示. 触摸屏在内核下找到usb 触摸屏驱动,内核启动后这个usb转的触摸屏也正常找到,注册为ev ...
- 触摸屏驱动分析(eeti源码为例)
module_init(egalax_i2c_ts_init)–>表示驱动加载时首先执行的函数是egalax_i2c_ts_init,下面看egalax_i2c_ts_init函数源码: sta ...
- WINCE6.0+S3C6410的触摸屏驱动
********************************LoongEmbedded******************************** 作者:LoongEmbedded(kandi ...
- 移植基于linux-2.6.26.5内核s3c2410触摸屏驱动移植
移植基于linux-2.6.26.5内核s3c2410触摸屏驱动移植的过程记录下来: (1)首先打一个补丁:s3c2410_touchscreen.patch, 在内核解压的根目录下 patch -N ...
- wince7 屏幕控制_技术干货:WinCE 7.0下的触摸屏驱动
在嵌入式系统中较为常用的是四线电阻式触摸屏,通过检测x轴和y轴的电压,来确定触点的位置.一般触摸屏系统结构为:触摸屏->触摸屏控制器->处理器. wince7下触摸屏的驱动分为PDD层(位 ...
- linux触摸屏代码解析,Linux触摸屏驱动解析
Linux下开发触摸屏驱动,最好的范例莫过于mc68328digi.c的实现.在没有看到原文之前,我把其中用到的结构解析一下. 1,struct ts_pen_info 该结构是触摸屏的核心数据结构. ...
- usb触摸屏驱动移植
最近公司产品在原有基础上增加一个触摸功能,因电路已经定型,只有usb接口引出来,所以只能选用市面上usb接口的触摸屏,联系了多家触摸屏代理商,移植时都存在问题. 公司产品用的平台是: PXA270 + ...
- GT9xx触摸屏驱动总结
GT9xx触摸屏驱动总结 一:GT9xx触摸屏驱动移植过程出现的问题 1:GT9xx触摸屏驱动的模块加载函数没有执行到. 具体情况: 现象:.ko文件已经是最新的,烧进去之后,或者使用adb工具pus ...
- focaltech(敦泰)触摸屏驱动Ft5306.c学习记录
最近正在做安卓系统的驱动开发工作,学习了focaltech(敦泰)触摸屏驱动Ft5306.c,简单总结如下(未完,待续).因为刚接触驱动开发,许多知识没有彻底理解,如有错误请指正. 1 概述 linu ...
最新文章
- TeraTerm设定(窗体大小,字体字号)保存为默认值
- MTK 驱动开发(48)---ARM 看门狗机制
- C++ 整形转换为字符串的方式总结
- xampp的mysql和phpnow的mysql,xampp的apache和visualsvn的apache和phpnow的apache
- MySQL 性能优化的19个要点
- [BZOJ 1212][HNOI2004]L语言(AC自动机)
- 使用Power Query从Web页面获取图像到Power BI报告中
- 一个440MHz的 VGA电路设计与仿真
- 星星之火-58:CPRI协议缺点,eCPRI协议是如何克服CPRI协议的不足?
- Matplotlib系列(三):坐标轴变换及注释
- 科研必备 | 谷歌学术高级搜索详解
- Keras实现小数量集图片分类——6类别Birds数据集分类
- 峰会•沙龙•招聘 | 记零数科技多线并进的一天
- 程序员们逢年过节初一十五都应该祭拜哪些神仙?
- docker容器内开启22 ssh_细述docker容器中创建SSH服务镜像
- 炸了!3年图片都没了!
- Matlab解决脚本中中文乱码问题
- hbase集群的搭建(完全分布式)
- python3爬虫系列之使用requests爬取LOL英雄图片
- python判断一个字符串是不是ip地址
热门文章
- Lync Server 2010迁移至Lync Server 2013故障排错 Part3 :内外网共享PPT提示证书问
- Android应用开发——onStop的调用时机
- java 栈 先进后出_数据结构: 先进后出——堆栈
- web服务器文件管理,web文件管理服务器
- ip68级防水可以泡多久_iPhone8防水级别升级至IP68:能在1.5米深水中坚持30分钟
- 铁路售票系统_铁路资讯:复兴号动车、智能京张高铁…中国最高端铁路装备看这里...
- Golang语言基础课件
- 【深度学习】TensorFlow之卷积神经网络
- Flask中的 url_for() 函数
- Django中的核心思想ORM---元类实现ORM