版權聲明:本文爲博主原創文章,未經博主允許不得轉載。
接手的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<linux/earlysuspend.h>
//#include<linux/ts_platform_data.h>
#include<linux/slab.h>
#include<linux/of_gpio.h>
增加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\n",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
我的同類文章
- •換平臺項目移植2016-11-02
- •Kernel啓動時間優化2016-11-02
- •Freescale i.MX 6 MNC平臺移植BT/WIFI驅動2016-11-02