简介

  1. kernel 4.9.88
  2. imx6ull Arm-v7 内核

移植思路

  • LCD 以及 触摸屏 ``` LCD 的驱动Linux 以及相当完善了,我们只需要修改时序等东西就可以了。以及修改背光引脚等引脚参数就可以。

触摸屏的驱动在内核中一般也有了,各厂家用的触摸屏IC可能不同。需要配置内核把它加进去,同时修改设备树:指定触摸IC的信息(比如I2C地址),指定中断引脚

  1. 我们拥有这一块板子在其他板子上面的源码,就可以知道他的LCD参数,触摸IC参数。以及使用到的GPIO找出来
  2. <a name="9u73h"></a>
  3. ## 移植LCD驱动
  4. **<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 />- **完善驱动**。
  5. <a name="suaYS"></a>
  6. ## **确定LCD参数**
  7. - 分辨率 800*480
  8. 这个东西没什么好讲的。
  9. - 确定LCD的详细时序
  10. 同样是查看LCD的芯片手册,不过更快的办法是可以查看设备树文件,
  11. ```bash
  12. # 确定对应大小的设备树文件
  13. $ cd arch/arm/boot/dts/
  14. $ ls *imx6ull*.dts

查看LCD的内容
RGB屏幕接口移植 - 图1

修改我们自己的设备树

打开我们自己的设备树,将timing0的属性全部复制过去。替换原有的内容,重新编译设备树即可。

完善驱动

移植成功以后,发现LCD有时候显示,有时候没有。不断的重新启动。
在技术交流群里问了大佬,说是LCD的复位问题。查看硬件原理图,确定LCD的复位引脚是GPIO3_IO04。既然是GPIO那么我们就可以使用GPIO子系统来手动复位测试一下。

使用GPIO子系统复位LCD

GPIO3_IO04在GPIO子系统中编号为:(3-1)*32+4=68,它是第68号GPIO。
fb-test 是一个简单的demo。用作点亮使用。

  1. $ fb-test // LCD上应该红绿蓝色块
  2. $ echo 68 > /sys/class/gpio/export // 导出68GPIO
  3. $ echo out > /sys/class/gpio/gpio68/direction // 设置为输出引脚
  4. $ echo 0 > /sys/class/gpio/gpio68/value // 让它输出0
  5. $ echo 1 > /sys/class/gpio/gpio68/value // 让它输出1
  6. $ echo 68 > /sys/class/gpio/unexport // unexport

我发现一旦执行上述命令,LCD立刻就有显示了。所以,LCD驱动不完善,应该加上复位信号。

修改设备树:指定复位引脚

修改设备树lcd控制的复位引脚。

  1. reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>;

修改驱动mxsfb_probe函数

确定驱动的源码

  1. $ ls drivers/video/fbdev/*.o
  2. drivers/video/fbdev/built-in.o drivers/video/fbdev/mx3fb.o drivers/video/fbdev/mxsfb.o

通过一些关键字的匹配,确定我们使用的是 mxsfb.c文件.修改mxsfb_probe函数,

  1. # 下面都是我们增加的代码。
  2. rst_gpio = of_get_named_gpio(pdev->dev.of_node, "reset-gpios", 0); # 注意这个, 这里就是我们设备树中的复位引脚名称。
  3. if (gpio_is_valid(rst_gpio)) {
  4. ret = gpio_request(rst_gpio, "lcdif_rst");
  5. if (ret < 0) {
  6. dev_err(&pdev->dev,
  7. "Failed to request GPIO:%d, ERRNO:%d\n",
  8. (s32)rst_gpio, ret);
  9. } else {
  10. gpio_direction_output(rst_gpio, 0); # 输出0
  11. msleep(2); # 睡眠
  12. gpio_direction_output(rst_gpio, 1); # 输出1
  13. dev_info(&pdev->dev, "Success seset LCDIF\n");
  14. }
  15. }

移植触摸屏驱动

确定触摸屏型号

如果有触摸屏数据手册,看手册就。

  • 没有手册

触摸屏的主控芯片一般都是I2C接口的,那么我们可以把屏接到板子上,用i2cdetect检测出I2C设备的地址,根据地址就可以知道它的型号。

  1. i2cdetect -y 1

RGB屏幕接口移植 - 图2
上图中,
“—”表示没有这个地址对应的I2C设备;
“UU”表示这个地址的I2C设备已经有驱动在使用占用它了,那这个I2C设备肯定是存在的;
其他数值表示该地址对应的I2C设备是存在的,并且还没有驱动程序跟它匹配。
根据上图,我们可以知道0x38就是触摸屏设备,为什么!为什么不是0x60?你可以把屏幕取下,再重新执行命令,就可以看到“38”消失了。
根据0x38,我们得找到对应的芯片型号,怎么找?去内核设备树目录里找。

  1. $ cd arch/arm/boot/dts/
  2. $ grep "@38" * -nR

RGB屏幕接口移植 - 图3
地址为0x38的I2C芯片有不少,比如HDMI PHY,还有ft5306、ft5x06。你在百度搜一下“ft5306”,
它确实就是触摸屏芯片。所以这款触摸屏的主控芯片就是ft5x06。x表示某些数字,可能有多个型号。

在设备树中指定触摸IC信息

image.png
**
所以,我们要确定的信息是:
a. 它接在哪个I2C控制器上?
b. 它的I2C地址是?
c. 复位引脚使用哪个GPIO?低电平有效还是高电平有效?
d. 中断引脚使用哪个GPIO?低电平有效还是高电平有效?

修改分析过程

a. 对于ft5x06,设备树节点中有哪些内容?
b. 那些内容怎么适配自己的板子?即怎么改成我们所用的GPIO引脚?
前面说过,根据I2C设备的地址0x38,执行如下命令:

  1. $ cd arch/arm/boot/dts/
  2. $ grep "@38" * -nR

我们得到很多结果,打开跟imx6ull最相近的imx6ul-tx6ul.dtsi,可以看到如下代码

RGB屏幕接口移植 - 图5

将上面的数据复制到我们自己的设备树文件里面。根据原有的触摸芯片I C配置修改。
RGB屏幕接口移植 - 图6

重新编译设备树,更新到板子上,发现触摸屏还是不能用。

重新编译内核

搜索 compatible = “edt,edt-ft5x06” 对应的驱动

  1. grep "edt-ft5x06" * -nr
  2. edt-ft5x06.c:1071: { .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },bash
  3. Kconfig:667: module will be called edt-ft5x06.
  4. Makefile:31:obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o

显然 配置 CONFIG_TOUCHSCREEN_EDT_FT5X06 就可以了。

  1. make menuconfig # 将 CONFIG_TOUCHSCREEN_EDT_FT5X06 设置为 y

重新编译就可以了。

调试-校准

现在触摸,但是效果不好。使用 Tslib 调试。

  1. # 去掉本来有的 Qt系统以后
  2. export TSLIB_TSDEVICE=/dev/input/event1 # 输入子系统
  3. export TSLIB_CONFFILE=/etc/ts.conf #
  4. export TSLIB_CALIBFILE=/etc/pointercal
  5. export TSLIB_PLUGINDIR=/usr/lib/ts
  6. ts_test_mt # 执行 ts_test_mt

关于输入子系统,可以参考我以前写的文章。 输入子系统-触摸事件数据分析
可以在LCD屏幕上看到提示,你点击某个位置,正常的话在该位置就会显示一个标号。
我们发现有意思的现象:从左往右点,标号从上边移动到下边;从上往下点,标号从左边移动到右边。
猜测:XY坐标对调了。
再试一下,执行 ts_print_raw,然后从左往右点,现象如下:

RGB屏幕接口移植 - 图7

从左往右点,x坐标应该发生变化,y坐标保持不变;但是从上图看来,这是相反的。
所以,确实是xy坐标对调了。

解决方法

可以从应用层面(比如修改设备树)解决,也可以从驱动层面(比如修改配置文件/etc/ts.conf)解决,二种方法任选其一,不要同时做。

方法一,/etc/ts.conf文件修改

如下图加上xyswap就可以了:**RGB屏幕接口移植 - 图8

方法二、修改设备树

RGB屏幕接口移植 - 图9

禁止更新

gt9xx芯片功能强大,可以写入配置信息让它支持不同分辨率的触摸屏。
但是出厂的触摸屏IC一般都已经写好配置信息了,我们不应
息。可以在设备树中加上这一句,禁止驱动去修改配置信息:

  1. goodix,driver-send-cfg = <0>; # 设备树中加上这一句,禁止更新。

这一个坑,找了好久,!!!!。

参考资料

  1. 参考内核文档: Documentation/devicetree/bindings/input/touchscreen