一、前文
主板是friendlyarm的NanoPC-T4的主板,RK3399的主芯片,原本适配了1280 * 800的7寸屏和1920 * 1200的11寸屏。
现在又想要用一款10.1寸的屏,接口都是edp,触摸是iic。插上去屏能亮,显示都没问题,但是触摸有点不准。
用了一个画图软件,发现横轴的点位有点偏移,偏移不固定,线性的偏移,就是靠左边的时候偏移大,靠右边的时候偏移小。
二、Debug看日志
我第一步就把主板的串口接到电脑,看log,很快就看到一些关键log,分辨率1280*800,触摸ic是gt928,这些都对了。
那问题就很明显了,应该是cfg不对,然后找屏厂的人拿了cfg文件。
[ 1.178927] <<-GTP-INFO->> GTP Driver Version: V2.4 <2014/11/28>
[ 1.178940] <<-GTP-INFO->> GTP I2C Address: 0x5d
[ 1.179032] <<-GTP-INFO->> Guitar reset
[ 1.223737] fusb302 4-0022: CC connected in 1 as UFP
[ 1.271403] <<-GTP-INFO->> IC Version: 928_1060
[ 1.271447] <<-GTP-DEBUG->> [1348]Config Groups' Lengths: 186, 0, 0, 0, 0, 186
[ 1.272118] <<-GTP-INFO->> Sensor_ID: 0
[ 1.272128] <<-GTP-DEBUG->> [1402]Get config data from header file.
[ 1.272140] <<-GTP-INFO->> Config group0 used,length: 186
[ 1.272482] <<-GTP-DEBUG->> [1446]Config Version: 95, 0x5F; IC Config Version: 95, 0x5F
[ 1.272497] <<-GTP-INFO->> Driver send config.
[ 1.278407] <<-GTP-INFO->> X_MAX: 1280, Y_MAX: 800, TRIGGER: 0x01
[ 1.290916] <<-GTP-INFO->> create proc entry gt9xx_config success
[ 1.290937] <<-GTP-INFO->> Ready to run update thread.
[ 1.292208] input: goodix-ts as /devices/virtual/input/input1
[ 1.292345] <<-GTP-DEBUG->> [2283][update_proc]Begin update ......
[ 1.292361] <<-GTP-DEBUG->> [805]Search for /data/_goodix_update_.bin, /sdcard/_goodix_update_.bin for fw update.(1/2)
[ 1.292397] <<-GTP-DEBUG->> [1766]INT trigger type:1
[ 1.292454] <<-GTP-DEBUG->> [842]Search for /data/_goodix_config_.cfg, /sdcard/_goodix_config_.cfg for config update.(1/2)
[ 1.292457] <<-GTP-INFO->> GTP works in interrupt mode.
[ 1.292464] <<-GTP-INFO->> Applied memory size:2562.
[ 1.292468] <<-GTP-INFO->> I2C function: without pre and end cmd!
[ 1.292477] <<-GTP-INFO->> Create proc entry success!
三、搭建开发环境
- 开始搭环境
- 下载源码,看源码
- 编译,因为我们只改动了kernel部分,所以只要编译kernel.img就行了。
android 7系统
cd kernel
make ARCH=arm64 nanopi4_nougat_defconfig
make -j2 ARCH=arm64 kernel.img
android 8系统
cd kernel
make -j2 ARCH=arm64 nanopi4_oreo_defconfig
make -j2 ARCH=arm64 kernel.img
四、快速编译
其中有个东西可以提一下的,如何用最快的速度编译,关键在make -jN
。
这个N
就是你cpu的核心数,如果你不知道你的cpu核心数是多少, 可以用命令查一下
grep processor /proc/cpuinfo | awk '{field=$NF};END{print field+1}'
五、代码定位
在改代码的时候,发生了有意思的事情,原本进入/kernel/drivers/input/touchscreen/目录下面,找到gt9xx目录
root@ubuntu:/home/weijian/Android/RK3399/rk3399-nougat/kernel/drivers/input/touchscreen/gt9xx# ls
goodix_tool.c gt9xx_update.c
GT9110P_Config_20160217_1526_2048_97.cfg Makefile
GT9271_Config_20170526.cfg WGJ10162B_GT9271_1060_Config_20140821_1341110X42.cfg
GT928_Config_TR1060_1280X800_FPC_D.cfg WGJ10162_GT9271_Config_20140820_182456.cfg
gt9xx.c WGJ10187_GT9271_Config_20140623_104014_0X41.cfg
gt9xx_firmware.h WGJ89006B_GT911_Config_20140625_085816_0X43.cfg
gt9xx.h WGJ89006B_GT9271_Config_20140625_085816_0X41.cfg
就自以为找对了,然后就开始动手看代码,修改代码,发现改了无效,一脸懵逼。
想了想,往GTP-INFO里面添加自定义的关键代码比如weijian等等,然后也没打印出来。这时候才开始看Makefile文件
#
# Makefile for the touchscreen drivers.
#
# Each configuration option enables a list of files.
……
ifndef CONFIG_TOUCHSCREEN_FE_PANELS
obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/
endif
……
obj-$(CONFIG_TOUCHSCREEN_FE_PANELS) += friendlyelec/
这才发现gt9xx目录下的文件不一定会被编译,需要打开CONFIG_TOUCHSCREEN_FE_PANELS。
而另外friendlyelec目录下是一定会被编译,且该目录同样有gt9xx.c和gt9xx.h文件。
root@ubuntu:/home/weijian/Android/RK3399/rk3399-nougat/kernel/drivers/input/touchscreen/friendlyelec# ls
built-in.o goodix_tool.o gt9xx_firmware.h gt9xx.o gt9xx_update.o Makefile modules.order
goodix_tool.c gt9xx.c gt9xx.h gt9xx_update.c Kconfig modules.builtin
六、代码修改
这时候才开始恍然大悟,然后修改,编译,下载,验证ok。
gt9xx.h
的部分代码,只修改了CTP_CFG_GROUP0
// TODO: define your own default or for Sensor_ID == 0 config here.
// The predefined one is just a sample config, which is not suitable for your tp in most cases.
//#define CTP_CFG_GROUP0 {\
/* HD101B */ \
/* 0x00,0x00,0x05,0x20,0x03,0x05,0x3D,0x00,0x01,0x08,0x28,\
0x05,0x50,0x32,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,\
0x01,0x1A,0x1C,0x1E,0x14,0x8E,0x2E,0x88,0x20,0x1E,0x31,\
0x0D,0x00,0x00,0x00,0x9C,0x03,0x1D,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x64,0x94,0xC5,\
0x02,0x07,0x00,0x00,0x04,0x51,0x2C,0x00,0x4A,0x34,0x00,\
0x44,0x3F,0x00,0x40,0x4C,0x00,0x3E,0x5B,0x00,0x3E,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x01,0x04,0x05,0x06,0x07,0x08,0x09,0x0C,\
0x0D,0x0E,0x0F,0x10,0x11,0x14,0x15,0xFF,0xFF,0xFF,0xFF,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0F,0x10,0x11,\
0x12,0x13,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x22,0x23,\
0x24,0x25,0x26,0x27,0x28,0xFF,0xFF,0xFF,0xFF,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1A,0x01\
}*/
#define CTP_CFG_GROUP0 {\
/* 10.1 1280*800 */\
0x5F,0x00,0x05,0x20,0x03,0x05,0x0D,0x00,0x01,0x08,0x28,\
0x05,0x50,0x3C,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x8F,0x2F,0xAA,0x43,0x45,0x0C,\
0x08,0x00,0x00,0x00,0x00,0x03,0x1D,0x00,0x00,0x00,0x00,\
0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x3C,0x64,0x94,0xD5,\
0x02,0x07,0x00,0x00,0x04,0x80,0x3F,0x00,0x7B,0x46,0x00,\
0x73,0x4D,0x00,0x6B,0x55,0x00,0x63,0x5F,0x00,0x63,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x01,0x04,0x05,0x06,0x07,0x08,0x09,0x0C,\
0x0D,0x0E,0x0F,0x10,0x11,0x14,0x15,0x16,0x17,0x18,0x19,\
0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x02,0x04,0x06,0x07,0x08,0x0A,0x0C,0x0D,0x0F,0x10,0x11,\
0x12,0x13,0x14,0x19,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x22,\
0x23,0x24,0x25,0x26,0x27,0x28,0x29,0xFF,0xFF,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9A,0x01\
}
// TODO: define your config for Sensor_ID == 1 here, if needed
#define CTP_CFG_GROUP1 {\
}
// TODO: define your config for Sensor_ID == 2 here, if needed
#define CTP_CFG_GROUP2 {\
}
// TODO: define your config for Sensor_ID == 3 here, if needed
#define CTP_CFG_GROUP3 {\
}
// TODO: define your config for Sensor_ID == 4 here, if needed
#define CTP_CFG_GROUP4 {\
}
// TODO: define your config for Sensor_ID == 5 here, if needed
#define CTP_CFG_GROUP5 {\
/* HD702 */ \
0x50,0x20,0x03,0x00,0x05,0x05,0x34,0x20,0x02,0x2B,0x28,\
0x0F,0x50,0x3C,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x18,0x1A,0x1E,0x14,0x8D,0x2D,0x88,0x3A,0x37,0x33,\
0x0F,0x00,0x00,0x00,0x02,0x02,0x2D,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x41,0x94,0xC5,\
0x02,0x07,0x00,0x00,0x04,0xD6,0x1E,0x1E,0xB6,0x24,0x00,\
0x9F,0x2A,0x00,0x8A,0x32,0x00,0x79,0x3B,0x00,0x79,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x01,0x04,0x05,0x06,0x07,0x08,0x09,0x0C,\
0x0D,0x0E,0x0F,0x10,0x11,0x14,0x15,0xFF,0xFF,0xFF,0xFF,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27,\
0x26,0x25,0x24,0x23,0x22,0x21,0x20,0x1F,0x1E,0x1C,0x1B,\
0x19,0x13,0x12,0x11,0x10,0x0F,0x0C,0x0A,0x08,0x07,0x06,\
0x04,0x02,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x01\
}
CTP_CFG_GROUP0
原本适配11寸屏(1920 * 1200),现在改成适配10寸屏(1280 * 800)CTP_CFG_GROUP5
适配7寸屏(1280 * 800)- 其余空着,不做适配
七、其他源码分析
看了一点代码,简单说一下的触摸驱动的流程。
触摸屏通过iic控制,驱动部分适配了5种不同的屏幕,通过读取触摸ic(GT928)的sensor id来判断,适配哪个屏幕,即哪个cfg。
关键代码是gt9xx.c里面
static s32 gtp_init_panel(struct goodix_ts_data *ts)
{
……
ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID, &sensor_id, 1);
if (SUCCESS == ret)
{
if (sensor_id >= 0x06)
{
GTP_ERROR("Invalid sensor_id(0x%02X), No Config Sent!", sensor_id);
ts->pnl_init_error = 1;
return -1;
}
}
else
{
GTP_ERROR("Failed to get sensor_id, No config sent!");
ts->pnl_init_error = 1;
return -1;
}
GTP_INFO("Sensor_ID: %d", sensor_id);
/* parse config data*/
#ifdef GTP_CONFIG_OF
GTP_DEBUG("Get config data from device tree.");
ret = gtp_parse_dt_cfg(&ts->client->dev, &config[GTP_ADDR_LENGTH], &ts->gtp_cfg_len, sensor_id);
if (ret < 0) {
GTP_ERROR("Failed to parse config data form device tree.");
ts->pnl_init_error = 1;
return -1;
}
#else
GTP_DEBUG("Get config data from header file.");
if ((!cfg_info_len[1]) && (!cfg_info_len[2]) &&
(!cfg_info_len[3]) && (!cfg_info_len[4]) &&
(!cfg_info_len[5]))
{
sensor_id = 0;
}
ts->gtp_cfg_len = cfg_info_len[sensor_id];
memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH);
memcpy(&config[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id], ts->gtp_cfg_len);
#endif
……
}