简介
kernel 4.9.88
imx6ull Arm-v7 内核
移植思路
- LCD 以及 触摸屏 ``` LCD 的驱动Linux 以及相当完善了,我们只需要修改时序等东西就可以了。以及修改背光引脚等引脚参数就可以。
触摸屏的驱动在内核中一般也有了,各厂家用的触摸屏IC可能不同。需要配置内核把它加进去,同时修改设备树:指定触摸IC的信息(比如I2C地址),指定中断引脚
我们拥有这一块板子在其他板子上面的源码,就可以知道他的LCD参数,触摸IC参数。以及使用到的GPIO找出来
<a name="9u73h"></a>
## 移植LCD驱动
**<br />**![image.png](https://cdn.nlark.com/yuque/0/2020/png/980070/1592371368913-302b1248-e8e6-4f3d-bcdd-1d7f13c43e39.png#align=left&display=inline&height=163&margin=%5Bobject%20Object%5D&name=image.png&originHeight=163&originWidth=670&size=11359&status=done&style=none&width=670)**<br />**<br />IMX6ULL内部有LCD控制器,厂家一般都会在内核中做好LCD控制器的驱动程序。<br />而IMX6ULL可以接各种LCD,这些LCD参数各有不同。LCD控制器的驱动程序会去设备树中获得这些参数,并根据这些参数来设置LCD控制器。<br />所以,我们要做的事情从理论上讲很简单:根据LCD参数修改设备树。<br />我们要做的事有3项:<br />- **确定LCD参数**<br />- **修改设备树**<br />- **完善驱动**。
<a name="suaYS"></a>
## **确定LCD参数**
- 分辨率 800*480
这个东西没什么好讲的。
- 确定LCD的详细时序
同样是查看LCD的芯片手册,不过更快的办法是可以查看设备树文件,
```bash
# 确定对应大小的设备树文件
$ cd arch/arm/boot/dts/
$ ls *imx6ull*.dts
修改我们自己的设备树
打开我们自己的设备树,将timing0的属性全部复制过去。替换原有的内容,重新编译设备树即可。
完善驱动
移植成功以后,发现LCD有时候显示,有时候没有。不断的重新启动。
在技术交流群里问了大佬,说是LCD的复位问题。查看硬件原理图,确定LCD的复位引脚是GPIO3_IO04。既然是GPIO那么我们就可以使用GPIO子系统来手动复位测试一下。
使用GPIO子系统复位LCD
GPIO3_IO04在GPIO子系统中编号为:(3-1)*32+4=68,它是第68号GPIO。
fb-test 是一个简单的demo。用作点亮使用。
$ fb-test // LCD上应该红绿蓝色块
$ echo 68 > /sys/class/gpio/export // 导出68号GPIO
$ echo out > /sys/class/gpio/gpio68/direction // 设置为输出引脚
$ echo 0 > /sys/class/gpio/gpio68/value // 让它输出0
$ echo 1 > /sys/class/gpio/gpio68/value // 让它输出1
$ echo 68 > /sys/class/gpio/unexport // unexport
我发现一旦执行上述命令,LCD立刻就有显示了。所以,LCD驱动不完善,应该加上复位信号。
修改设备树:指定复位引脚
修改设备树lcd控制的复位引脚。
reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>;
修改驱动mxsfb_probe函数
确定驱动的源码
$ ls drivers/video/fbdev/*.o
drivers/video/fbdev/built-in.o drivers/video/fbdev/mx3fb.o drivers/video/fbdev/mxsfb.o
通过一些关键字的匹配,确定我们使用的是 mxsfb.c文件.修改mxsfb_probe函数,
# 下面都是我们增加的代码。
rst_gpio = of_get_named_gpio(pdev->dev.of_node, "reset-gpios", 0); # 注意这个, 这里就是我们设备树中的复位引脚名称。
if (gpio_is_valid(rst_gpio)) {
ret = gpio_request(rst_gpio, "lcdif_rst");
if (ret < 0) {
dev_err(&pdev->dev,
"Failed to request GPIO:%d, ERRNO:%d\n",
(s32)rst_gpio, ret);
} else {
gpio_direction_output(rst_gpio, 0); # 输出0
msleep(2); # 睡眠
gpio_direction_output(rst_gpio, 1); # 输出1
dev_info(&pdev->dev, "Success seset LCDIF\n");
}
}
移植触摸屏驱动
确定触摸屏型号
如果有触摸屏数据手册,看手册就。
- 没有手册
触摸屏的主控芯片一般都是I2C接口的,那么我们可以把屏接到板子上,用i2cdetect检测出I2C设备的地址,根据地址就可以知道它的型号。
i2cdetect -y 1
上图中,
“—”表示没有这个地址对应的I2C设备;
“UU”表示这个地址的I2C设备已经有驱动在使用占用它了,那这个I2C设备肯定是存在的;
其他数值表示该地址对应的I2C设备是存在的,并且还没有驱动程序跟它匹配。
根据上图,我们可以知道0x38就是触摸屏设备,为什么!为什么不是0x60?你可以把屏幕取下,再重新执行命令,就可以看到“38”消失了。
根据0x38,我们得找到对应的芯片型号,怎么找?去内核设备树目录里找。
$ cd arch/arm/boot/dts/
$ grep "@38" * -nR
地址为0x38的I2C芯片有不少,比如HDMI PHY,还有ft5306、ft5x06。你在百度搜一下“ft5306”,
它确实就是触摸屏芯片。所以这款触摸屏的主控芯片就是ft5x06。x表示某些数字,可能有多个型号。
在设备树中指定触摸IC信息
**
所以,我们要确定的信息是:
a. 它接在哪个I2C控制器上?
b. 它的I2C地址是?
c. 复位引脚使用哪个GPIO?低电平有效还是高电平有效?
d. 中断引脚使用哪个GPIO?低电平有效还是高电平有效?
修改分析过程
a. 对于ft5x06,设备树节点中有哪些内容?
b. 那些内容怎么适配自己的板子?即怎么改成我们所用的GPIO引脚?
前面说过,根据I2C设备的地址0x38,执行如下命令:
$ cd arch/arm/boot/dts/
$ grep "@38" * -nR
我们得到很多结果,打开跟imx6ull最相近的imx6ul-tx6ul.dtsi,可以看到如下代码
将上面的数据复制到我们自己的设备树文件里面。根据原有的触摸芯片I C配置修改。
重新编译设备树,更新到板子上,发现触摸屏还是不能用。
重新编译内核
搜索 compatible = “edt,edt-ft5x06” 对应的驱动
grep "edt-ft5x06" * -nr
edt-ft5x06.c:1071: { .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },bash
Kconfig:667: module will be called edt-ft5x06.
Makefile:31:obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o
显然 配置 CONFIG_TOUCHSCREEN_EDT_FT5X06 就可以了。
make menuconfig # 将 CONFIG_TOUCHSCREEN_EDT_FT5X06 设置为 y
调试-校准
现在触摸,但是效果不好。使用 Tslib 调试。
# 去掉本来有的 Qt系统以后
export TSLIB_TSDEVICE=/dev/input/event1 # 输入子系统
export TSLIB_CONFFILE=/etc/ts.conf #
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_PLUGINDIR=/usr/lib/ts
ts_test_mt # 执行 ts_test_mt
关于输入子系统,可以参考我以前写的文章。 输入子系统-触摸事件数据分析。
可以在LCD屏幕上看到提示,你点击某个位置,正常的话在该位置就会显示一个标号。
我们发现有意思的现象:从左往右点,标号从上边移动到下边;从上往下点,标号从左边移动到右边。
猜测:XY坐标对调了。
再试一下,执行 ts_print_raw,然后从左往右点,现象如下:
从左往右点,x坐标应该发生变化,y坐标保持不变;但是从上图看来,这是相反的。
所以,确实是xy坐标对调了。
解决方法
可以从应用层面(比如修改设备树)解决,也可以从驱动层面(比如修改配置文件/etc/ts.conf)解决,二种方法任选其一,不要同时做。
方法一,/etc/ts.conf文件修改
方法二、修改设备树
禁止更新
gt9xx芯片功能强大,可以写入配置信息让它支持不同分辨率的触摸屏。
但是出厂的触摸屏IC一般都已经写好配置信息了,我们不应
息。可以在设备树中加上这一句,禁止驱动去修改配置信息:
goodix,driver-send-cfg = <0>; # 设备树中加上这一句,禁止更新。
参考资料
参考内核文档: Documentation/devicetree/bindings/input/touchscreen