NXP

Freescale i.MX 6Q MNC平台移植Goodix GT911x TP驱动

2019-07-12 12:05发布

Freescale i.MX 6Q MNC平台移植Goodix GT911x TP驱动

标签: PortingFreescale 583人阅读 评论(1) 收藏 举报 本文章已收录于: 分类: 作者同类文章X 作者同类文章X 版权声明:本文为博主原创文章,未经博主允许不得转载。        接手的Freescalei.MX 6Q平台,移植了Android 6.0 MNC系统,Kernel (v3.14.52)可以启动了,从其它项目拿了一块Touch Panel过来。需要移植,Touch Panel移植按理是比较简单的,一开始以为最多半天的活,但实际却用了两天时间,中间走了不少弯路。          Touch Panel的Driver IC用的是Goodix 的GT9110,应该属于比较常用的,屏是8 Inch的屏。先查原理图:        原理图TP接了四根线,INT/RESET/SDA/SCL,找到主芯片上位置。          对应的管脚分别是EIM_D21(SCL)/EIM_D28(SDA)/EIM_A25(RST)/DISP0_DAT12(INT)。打开Freescale的工具IO Mux,找到这些脚相对的分别是:        EIM_D21/EIM_D28 为i2c1 的SCL/SDA        EIM_A25为GPIO5_2        DISP0_DAT12为GPIO5_6          管脚查清楚了,开始配置,先配置DTS文件,打开kernel_imx/arch/arm/boot/dts/imx6qdl-sabresd.dtsi文件,找到i2c1。在最后增加:        touchpanel: gd111x@5d {                compatible ="gd,gd111x";                reg = <0x5d>;                interrupt-parent =<&gpio5>;                interrupts = <6 2>;                irq-gpios = <&gpio5 61>;                rst-gpios = <&gpio5 21>;        };        以上配置参考了其它项目的代码,I2C地址为0x5D,实际上配置为0x14也可以,因为Goodix的I2C地址是根据开机时RST/INT的逻辑来决定的。驱动中做了自动适配。        Compatible随便写了一个,只要不容易重名就可以了。        interrupt-parent设置为gpio5        irq-gpios和rst-gpios分别是用于中断和复位的。根据之前查出来的值设置正确。          确认一下i2c1的相关GPIO是否正确,相关的PIN为pinctrl_i2c1 &i2c1 {               clock-frequency = <100000>;               pinctrl-names ="default";               pinctrl-0 = <&pinctrl_i2c1>;               status = "okay";          发现配置不正确,改为正确值。                 pinctrl_i2c1: i2c1grp {                     fsl,pins = < -                    MX6QDL_PAD_CSI0_DAT8__I2C1_SDA         0x4001b8b1 -                    MX6QDL_PAD_CSI0_DAT9__I2C1_SCL         0x4001b8b1 +                    MX6QDL_PAD_EIM_D28__I2C1_SDA           0x4001b8b1 +                    MX6QDL_PAD_EIM_D21__I2C1_SCL           0x4001b8b1                     >;                 };          另外,再查找一下两个IRQ/RST的两个GPIO是否有其它配置,如果有,简单处理可以先注释掉。          DTS修改完成,移代码,把驱动文件gt9xx.c和gt9xx.h拷贝到drivers/input/touchscreen 目录下,修改此目录下的Kconfig和Makefile. ---a/kernel_imx/drivers/input/touchscreen/Kconfig +++b/kernel_imx/drivers/input/touchscreen/Kconfig @@ -966,5 +966,17@@ config TOUCHSCREEN_ZFORCE             To compile this driver as a module,choose M here: the           module will be called zforce_ts. + +configTOUCHSCREEN_GT9XX +       tristate "GT9XX I2CTouchscreen" +       depends on I2C +       help +         Say Y here if you have I2C touchscreen, +         such as GT9XX, connected to yoursystem.   +         If unsure, say N. + +         To compile this driver as a module,choose M here: the +         module will be called gt9xx. +  endif   ---a/kernel_imx/drivers/input/touchscreen/Makefile +++b/kernel_imx/drivers/input/touchscreen/Makefile @@ -79,3 +79,4 @@obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE)    += zylonite-wm97xx.o  obj-$(CONFIG_TOUCHSCREEN_W90X900)      += w90p910_ts.o  obj-$(CONFIG_TOUCHSCREEN_TPS6507X)     += tps6507x-ts.o  obj-$(CONFIG_TOUCHSCREEN_ZFORCE)       += zforce_ts.o +obj-$(CONFIG_TOUCHSCREEN_GT9XX)        += gt9xx.o          修改Kernel配置文件arch/arc/configs/imx_v7_android_defconfig,把配置加上。 ---a/kernel_imx/arch/arm/configs/imx_v7_android_defconfig +++b/kernel_imx/arch/arm/configs/imx_v7_android_defconfig @@ -310,6 +310,7@@ CONFIG_INPUT_TOUCHSCREEN=y  # CONFIG_TOUCHSCREEN_MC13783 is not set  # CONFIG_TOUCHSCREEN_TSC2007 is not set  # CONFIG_TOUCHSCREEN_STMPE is not set +CONFIG_TOUCHSCREEN_GT9XX=y  CONFIG_INPUT_MISC=y  CONFIG_INPUT_MMA8450=y  CONFIG_INPUT_KEYCHORD=y          编译,出错,原来提供过来的驱动不是针对DTS的,还是老的一套,修改gt9xx.h #include<Linux/gpio.h> //#include   //#include #include #include          增加ts_platform_data结构,由于只用到int_port和rst_port,所以只定义这两项就可以了。 structts_platform_data {     int int_port;     int rst_port; };          注释掉structearly_suspend early_suspend;          再编译,还是出错,late_initcall(goodix_ts_init);什么的不认识,OK,改造init和exit函数。把__init注释掉,如下: static int /*__init*/goodix_ts_init(void) static void /*__exit*/goodix_ts_exit(void)   以下也不需要了 //late_initcall(goodix_ts_init); //module_exit(goodix_ts_exit);          把这两个函数分别放在probe函数的最前面及remove函数的最后执行就可以了。   增加两个表 static const struct i2c_device_id goodix_ts_id[] = {            {"gd111x", 0 },     { } }; MODULE_DEVICE_TABLE(i2c, goodix_ts_id);   static const struct of_device_id goodix_ts_dt_ids[] ={               { .compatible ="gd,gd111x", },               { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, goodix_ts_dt_ids);          i2c_driver中增加项 static structi2c_driver goodix_ts_driver = {     .probe     = goodix_ts_probe,     .remove    = goodix_ts_remove, #if 0 #ifndefCONFIG_HAS_EARLYSUSPEND     .suspend   = goodix_ts_early_suspend,     .resume    = goodix_ts_late_resume, #endif #endif     .id_table  = goodix_ts_id,     .driver = {         .name     = "gd111x_ts",         .owner    = THIS_MODULE,         .of_match_table =of_match_ptr(goodix_ts_dt_ids),     }, };          最后把i2c驱动注册一下。 module_i2c_driver(goodix_ts_driver);          编译通过了。下载,开机,原以为就OK了,谁知道问题才刚刚开始。看了一下Log,I2C读写失败。          一开始怀疑是不是I2C配错了。查dts文件,把I2C脚相关的其它地方的配置统统删掉,再下载,还是不通。用示波器量了一下,发现SCL/SDA波形很奇怪,基本没有波形,大约每读一次只出一次低最平,而且两个PIN的动作是同步的,没有时差,不像是I2C起始信号。          看到这个现象,更坚定了I2C或驱动有问题的判断,所以开始从其它项目找相似的驱动,对比移植,测试,折腾了一天,试了N种组合,都不行。最后要下班了,决定试一下另一块板了。下载了,I2C居然通了。后来才发现,我一开始调试的板子Touch Panel的FPC没有接好,所以一直通信不上,另外Freescale的平台也比较怪,如果没有设备,就不出I2C信号了,害我花了一天时间才搞明白。          I2C是通了,而且从Driver中读取ID,Firmware Version都正确,但就是按屏不出中断,也不报点,通过轮询方式读取出来的数据也一直是零。          现在开始怀疑TouchPanel是坏了,从老机器上拆了一块确认是好的Touch Panel下来,接上来测试,发现也不行,最怪的是再把它接回到老设备上也不能用了。仔细对比了一下驱动,发现以下项最设置成了1 #define GTP_DRIVER_SEND_CFG   1        查了一下驱动,把它设置成1时,会得新发配置信息到驱动,因为驱动的配置信息不知道是哪里来的,所以不适合现在的Touch Panel,传到Touch Panel中后,就不工作了。出现这种情况后,只能通过重新下载一个合适的配置文件才能使Touch Panel重新可用。          把它设置为0,然后重新找了块新Touch Panel,接上,getevent就能正确出数了。 adb shell getevent * daemon notrunning. starting it now on port 5037 * * daemon startedsuccessfully * add device 1:/dev/input/event1   name:    "PixArt HP USB Optical Mouse" could not getdriver version for /dev/input/mouse0, Not a typewriter add device 2: /dev/input/event0   name:    "goodix-ts" could not getdriver version for /dev/input/mice, Not a typewriter /dev/input/event0:0001 014a 00000001 /dev/input/event0:0003 0035 0000014d /dev/input/event0:0003 0036 0000012c /dev/input/event0:0003 0030 0000001c /dev/input/event0:0003 0032 0000001c /dev/input/event0:0003 0039 00000000 /dev/input/event0:0000 0002 00000000 /dev/input/event0:0000 0000 00000000 /dev/input/event0:0003 0035 0000014d /dev/input/event0:0003 0036 0000012c          数据有了,但屏上没有反应,说明传到Frameworks层有问题,或被Frameworks认为无效数据扔掉了。在Frameworks中增加调试代码,frameworks/native/services/inputflinger/InputReader.cpp文件void TouchInputMapper::sync(nsecs_t when)函数,增加Log: ALOGD("syncTouch, get sync, mode%d ",mDeviceMode);          发现mode为零,表示被禁止了,看来是注册input_device时的参数有问题。 enum DeviceMode {         DEVICE_MODE_DISABLED, // input isdisabled         DEVICE_MODE_DIRECT, // direct mapping(touchscreen)         DEVICE_MODE_UNSCALED, // unscaledmapping (touchpad)        DEVICE_MODE_NAVIGATION, // unscaled mapping with assist gesture (touchnavigation)         DEVICE_MODE_POINTER, // pointer mapping(pointer)     };     DeviceMode mDeviceMode;   还是用getevent来查 getevent-i add device 2:/dev/input/event0   bus:     0018   vendor   dead   product  beef   version  28bb   name:    "goodix-ts"   location: "▒"   id:      ""   version: 1.0.1   events:     KEY (0001): 014a     ABS (0003): 0030  : value 0, min 0, max 255, fuzz 0, flat 0,resolution 0                 0032  : value 0, min 0, max 255, fuzz 0, flat 0,resolution 0                 0035  : value 0, min 0, max 0, fuzz 0, flat 0,resolution 0                 0036  : value 0, min 0, max 0, fuzz 0, flat 0,resolution 0                 0039  : value 0, min 0, max 255, fuzz 0, flat 0,resolution 0   input props:     INPUT_PROP_DIRECT could not getdriver version for /dev/input/mice, Not a typewriter          发现数据有异常,有两组数据的max值为0,这应该是屏的分辨率的数据,查看代码,这个数据是从Touch Panel内置的配置数据中获取的,但来是内置的数据有问题。直接改为硬编码。     input_set_abs_params(ts->input_panel,ABS_MT_POSITION_X, 0, 800, 0, 0);     input_set_abs_params(ts->input_panel,ABS_MT_POSITION_Y, 0, 480, 0, 0);          另外,发现设置多点触摸的值设置成了255,也改为实际值5.     input_set_abs_params(ts->input_panel,ABS_MT_TRACKING_ID, 0, 5, 0, 0);          改完,下载后,重新用getevent–i查看,已经正确了。 add device 2: /dev/input/event0  bus:      0018  vendor    dead  product   beef  version   28bb  name:     "goodix-ts"  location: "▒"  id:       ""  version:  1.0.1  events:    KEY (0001): 014a    ABS (0003): 0030  : value 0, min0, max 255, fuzz 0, flat 0, resolution 0                0032  : value 0, min 0, max 255, fuzz 0, flat 0,resolution 0                 0035  : value 0, min 0, max 800, fuzz 0, flat 0,resolution 0                 0036  : value 0, min 0, max 480, fuzz 0, flat 0,resolution 0                 0039  : value 0, min 0, max 5, fuzz 0, flat 0,resolution 0  input props:    INPUT_PROP_DIRECT could not get driver version for/dev/input/mice, Not a typewriter   屏上有反应了,不过出现了一个小白圈,这个问题之前解决过。在设置input_device参数的地方,增加以下一行。重新下载就一切正常了。        __set_bit(INPUT_PROP_DIRECT,ts->input_panel->propbit);   一些个人体会        Freescale平台如果设备没有接好,I2C读写时是不会出Clock的,这一点需要注意,之前调试过的平台,就算设备没接,也是会有Clock的。        Goodix的Touch Panel的配置参数不能乱改,之前就因为下载了不正确的配置文件,导致Touch Panel不工作了,不出数据,不出中断。所以如果出厂前已经设置正确配置的情况下,默认就不要再传配置参数了。因为参考的代码中,有的打开,有的关闭,所以一开始没有注意到这个问题。        可以通过getevent来看Touch Panel驱动是否正确,如果触点时,getevent有数据输出,基本上可以认为TouchPanel正常工作了。getevent -i可以查看input_device的配置,Android中不允许max值为0的情况,如果有这种情况,会把它认为是无效设备。        Frameworks中可以在TouchInputMapper::sync()函数中增加Log来看TouchPanel数据是否已经传到Frameworks中,来确定问题所在。        此屏的配置数据是有问题的,但由于之前的项目是非Android的项目(Yocto),所以只有有数据上报,就可以工作了。
0
0
   

我的同类文章

http://blog.csdn.net