HI3516DV300_19_触摸屏测试及驱动详解2


一、移植并测试触摸屏驱动

1.1 下载正确的触摸屏驱动文件并替换掉原来不对的

1.1.1 电容触摸屏的驱动在下面这个位置:

这个驱动到底是内核自带的,还是之前的板卡商,在移植的时候放进去的,对我们来说,不用去关心

总之,我们拿到的源码,是有的,代码就在这里面呢

这个文件,有相应的.o文件,是被编译了

这个文件,没有.o文件,所以,没有被编译

这个,本来是用make menuconfig来进行配置的,但是这里却被直接注释了

并且,这里只能被编译成为一个module了

如果想编译到zImage里面去,那么这里就要修改成:obj-y

其实只有这两个文件是有用到的

这个pad.c是没有用到的

但问题是这个pad.h是有被用到的

其实,大部分东西,都是在这个pad.h里面的

现在输出的情况不对,就是因为pad.h里面,有些变量的定义是不对的

1.1.2 分析不对的源码

首先,是定义了width与height,也就是定义了分辨率,7inch里面,一般最高分辨率就是1280 X 800

这个是不对的,因为咱们的屏幕是1024 X 600的

这是一个数组,用const修饰,是一个不可更改的常量,这里面写了很多寄存器的配置值

这个寄存器非常大,并且有非常多的数值

这里面还有很多固件(的标志),并且,这里面也全是key和value的,并且是成对的

前面的key应该是寄存器的地址,后面的value,应该是寄存器的值

这些是电容触摸屏里面的那些寄存器

每一款电容触摸屏,其实它里面是有自己的处理器的,它那个处理器,就负责处理电容触摸屏内部的寄存器

每一个电容触摸屏都有多达几百个寄存器,这里面的寄存器,都是用来配置一些特性的,比如配置屏幕的分辨率,配置电容感应的灵敏度这些的。

因为按到的点,中心和边缘的力度,还是有区别的,所以做电容触摸屏这一行,也还是有一点技术含量在里面的。

我们现在,就是这些寄存器里面,配的寄存器的值不对

我们现在要修复这个驱动的话,要找到一个正确的.h文件,把这个错误的.h文件给替换了

先把错误的文件,改个名字

找到正确的文件

这个是根据我们的屏幕给配出来的

这个差异,是来自于触摸屏的差异,因为:

一个触摸屏芯片,是不止配置于,一款触摸屏的;这个芯片能够适配于很多屏幕,有些屏幕大,有些屏幕小,有些分辨率大,有些分辨率小。

触摸屏芯片本身的配置,要和我们的屏幕适配,就要去修改寄存器;这个适配的过程,要懂触摸屏芯片的寄存器怎么写;而且,有时候,还要去调一些效果。

并且,这个过程,有用到专门的人,用专门的软件去调,这个一般是触摸屏芯片厂商去调的

这个要找FAE,以及代理商,帮忙调的,自己没必要去学怎么调试,这种技能只能用于调试这个厂商的

如果公司很小,人家的FAE不理你的话,没有实力调这个,那就不要调这个,直接买过来就行了,如果非要自己调试,那么就是自讨苦吃。

1.1.3 把正确的源码复制到Ubuntu

  • 先把正确的给复制过来

这个就是我们的正确的

  • 然后,编译生成模块

在这里编译生成驱动模块

可以看到,已经被编译了

这里会把所有的配置为-m的那些模块,全部重新编译一遍

Linux里面,如果我们把它集成到内核里面,还不知道能不能编译单个模块,这个是不行的

但是在Android里面,如果想编译单个模块,可以只编译这个模块

如果我们把驱动放在了外面,那我们可以直接在驱动那里去make module

但是,现在我们把驱动是集成到内核里面了,所以,就要编译所有的

  • 编译生成了.ko文件

这个文件,也就是我们所需要的

  • 然后,把这个ko文件拷贝到板子上面去

其中,这个rootfs文件夹,已经被nfs共享出去了

  • 在板子上面找到这个.ko文件

如上图所示

  • 先进到.ko文件夹

如上图所示

  • 先把老版本的.ko文件mv掉

如上图所示

  • 把板子上的.ko文件复制到当前的文件夹

这个ko文件就是我们刚才编译成功的,正确的ko文件了

到这一步,部署就完成了

  • 卸载老驱动
remod gslx680.ko
  • 装载新的驱动
insmod gslx680.ko

如上命令所示

  • 或者简单粗暴地直接重启,重启的话,也会insmod这个驱动的

重启,也就会重新加载驱动了

  • 先看看/dev/input/里面有没有设备

  • 重新挂载nfs文件系统

  • 进入到应用程序文件夹下,并执行应用程序

  • 查看效果

可以看到,效果是对的了

但是,调试触摸屏芯片寄存器的过程,应当是触摸屏芯片厂商自己专门做的,而不是我们自己去做

二、触摸屏驱动源码简单分析

2.1 找到并确认实际工作的源码

  • 先找到源码在哪

pad_touch_back.c

pad.c:这个没有被调用

touch_id:只包含少量内容

  • 分析源码

源码中,最核心的两个源码,就是在这里的

  • 来分析:gsl_ts_init

  • 有两个分支

一个是Linux里面的驱动

一个是Android里面的驱动

这两个驱动是不太一样的

区别就是:Linux里面只支持单点,Android里面呢支持多点,但是这个芯片本身是支持多点的

Android里面,大部分时候,都是支持多点触控的

Linux里面,大部分时候,都会 使用Qtcreator这样一些GUI,这个时候就不需要多点触控

大部分驱动,也都是一样的

  • gsl_ts_init函数分析

在这个函数里面,做的事情主要是这个

  • 分析

I2C Device呢,一个触摸屏驱动对我们主机来说,其实就是I2C的从设备

所以:这里就是一个I2C Device,一个I2C Driver

那么I2C Device在什么地方添加了呢?就是在设备树解析的那个地方添加了,给你做了I2C add device了

然后,在这个地方执行了i2c_add_driver了

再然后,driver和device在I2C总线上一match

match之后呢,就probe了

probe之后,就执行我们的驱动了

所以,下一步,其实就到了驱动这里了

  • 找到驱动

进入到驱动这里

这里主要是一个probe函数

I2C总线driver和device那边一match,就会调用这个probe

所以,所有的驱动入口函数,就在probe函数这里

这都是非常经典的驱动函数框架

进入到probe函数里面

可以看到,probe函数,其实是先在定义变量

然后,这里先做相关的check

然后将ts进行相关的实例化,分配内存

然后进行填充

然后,在这里面,把各种数据,把Device和Driver里面的那个硬件数据进行挂接

irq_pin:就是我们中断对应的引脚

也就是说,我们的I2C设备,有一个引脚是专门来处理中断的,这是一个硬件信息,是硬件要告诉软件的

也就是Device要告诉Driver的,Driver这边操作irq的时候,只会直接基于irq的pin来直接进行处理,这个是纯软件的,这个只负责直接具体的操作,而不知道是哪个Pin,这个是要device告诉它的,怎么告诉它呢?三种方法:

第一种方法:简单粗暴,这就是直接硬编程,直接编译进去了;缺点就是,如果你要移植,那就必须要修改源码,如果不修改源码,如果不修改源码,这个是完不成的;所以一般正式的代码都不可能这样写的。

第二种方法:老式的做法是:通过I2C Device那里来,进行配置,也就是直接使用数据结构,在代码里面定义数据结构,但是,在数据结构那个地方就需要改;也就是说,还需要改源码。

第三种方法:新式的做法:改设备树,设备树的代码,就在下面:

这里,就是通过设备树来获取具体的Pin

获取touch-gpio的节点,那个节点里面有这样一个属性,属性就是:touch-gpio
获取reset-gpio的节点,那个节点里面有这样一个属性,属性就是:reset-gpio

那么,这个函数在哪里呢?

这就是goodix这家的触摸屏的

这就是gsl680这家的触摸屏的对应的

这里是对应的i2c从地址,对应的0x40

compatible,这个属性是为了让它能够匹配上的

所以可以看到,其实人家在这里,都配好了

但是,在源码里面,是没有用设备树传参的

但是,SDK在做这个的时候,已经基本把这个做好了

看设备树里面的相关属性

这里应该不是800 x 1280,应该是600 x 1024
这里没有修改,没有修改是很正常的,因为都是写死的,因为没有用到设备树,在这里改了,其实也不影响

这两个节点的数值,本来就被配置为4和3

如果在代码里面用这两行,读出来也是4和3

再往下走,这个驱动,其实是和原来的驱动,没啥区别了

但是,这个驱动和以前的相比,差别就在这里

在核心课程一期里面,是没有看到这些寄存器配置值的,因为当时用的是.bin文件,当年,触摸屏厂商为了保持竞争力,是不愿意把这个寄存器的设置值开源的,核心课程一期是15年讲的。

寄存器配置值是不是以文本的方式给客户,这个对我们是没有影响的

用没用到设备树,也是一个比较大的不同

别的驱动,也与这个触摸屏的驱动类似


Author: Ruimin Huang
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Ruimin Huang !
  TOC