生产线 在烧录固件时,会偶然出现稍完之后屏幕触摸用不了。前期以为是烧录没弄好,后面又发生,就怀疑与产品有关了。
首先进行抓日志分析:有问题的设备先确认下dmesg信息
adb连接设备进行日志抓取:
logcat > /sdcard/logcat.log
dmesg > /sdcard/dmesg.log
确认问题日志信息如下:
[ 6.224059] ___touch_compatible_probe() start____
[ 6.225273] \x0avfs_read return ret=12
[ 6.225292] touch_compatible:Not first Start the system,Already read touch\xef\xbc\x9aUSB_touch
[ 6.225297] LOUHN in touch_module_init:USB_touch
[ 6.225514] pwm-backlight backlight1: backlight1 supply power not found, using dummy regulator
[ 6.225780] pwm-backlight backlight1: Linked as a consumer to regulator.0
[ 6.225837] pwm-backlight backlight1: Dropping the link to regulator.0
[ 6.249039] usb 1-1: new high-speed USB device number 3 using ehci-platform
[ 6.400229] usb 1-1: New USB device found, idVendor=a69c, idProduct=8801, bcdDevice= 1.00
[ 6.400245] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
根据找出有问题的日志片段,我们可以进行详细的分析:
touch_compatible_probe() start:说明这时刚刚开始触摸匹配。
touch_compatible:Not first Start the system,Already read touch\xef\xbc\x9aUSB_touch:该消息表明这不是系统的第一次启动,之前已经读取了触摸输入设备,且是通过 USB 接口连接的。
LOUHN in touch_module_init:USB_touch:指明正在初始化的触摸模块是通过 USB 接口连接的。
但是我们的触摸是I2C触摸,外什么会识别成USB触摸呢?所以我们要到的驱动里去看一下这个touch_compatible_probe()函数的实现。
触摸驱动路径:
Android12.0/kernel-4.19/drivers/input/touchscreen/touch_adapter_driver/touch_adapter.c
touch_compatible_probe实现:
static int touch_compatible_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int ret = 0,i = 0;
struct device_node *np = client->dev.of_node;
printk("___%s() start____ \n", __func__);
ret = read_touch_type(TOUCH_TYPE_FILE,touch_type,31);
if(ret) {
printk("touch_compatible:read %s faild ret=%d!",TOUCH_TYPE_FILE,ret);
return -ENOMEM;
} else {
if( strlen(touch_type) ) {//touch_type不为空,则说明不是第一次启动
printk("touch_compatible:Not first Start the system,Already read touch:%s\n",touch_type);
touch_module_init(touch_type);
return 0;
}
}
comp_irq_gpio = of_get_named_gpio(np, "compatible,riq-gpio",0);
comp_reset_gpio = of_get_named_gpio(np, "compatible,reset-gpio", 0);
//gtp_request_io_port
ret = gpio_request(comp_reset_gpio, "touch_gpio_reset");
ret += gpio_request(comp_irq_gpio, "touch_gpio_irq");
if(!ret) {
for (i = 0; i < (sizeof(ts_list) / sizeof(touchscreen)); i++) {
if (ts_list[i].check_i2c_func) {
if((ts_list[i].check_i2c_func)(client, ts_list[i].i2c_addr)) {
printk("Found Touch I2C IC: %s\n",ts_list[i].touch_name);
if (save_data_to_file(TOUCH_TYPE_FILE,ts_list[i].touch_name,strlen(ts_list[i].touch_name)) ) {
printk("touch_compatible:save %s faild!",TOUCH_TYPE_FILE);
return -ENOMEM;
}
touch_module_init(ts_list[i].touch_name);
break;
}
} else {
printk("Touch[%s] Handle function is NULL\n", ts_list[i].touch_name);
}
if (i == ((sizeof(ts_list) / sizeof(touchscreen) -1)) ) {
save_data_to_file(TOUCH_TYPE_FILE,USB_TOUCH,strlen(ts_list[i].touch_name));//没有匹配到I2C触摸,默认为USB触摸
return 0;
}
}
}
return 0;
}
由上述信息可知:
gpio_request
函数通过请求comp_reset_gpio
和comp_irq_gpio
的 GPIO 引脚。如果请求成功,循环遍历ts_list
数组中的元素,逐个检查是否存在 I2C 触摸设备。如果存在 I2C 触摸设备,打印信息并将触摸设备的名称写入TOUCH_TYPE_FILE
文件中,然后调用touch_module_init
进行触摸模块的初始化,最后跳出循环。如果循环结束后仍未找到匹配的 I2C 触摸设备,将默认将触摸设备类型写入TOUCH_TYPE_FILE
文件中。该函数的主要功能是通过 I2C 获取与触摸设备有关的信息,并根据配置信息选择不同的触摸模块进行初始化。如果没有找到匹配的触摸设备,将默认选择 USB 触摸设备进行初始化。
很明显,出现问题的设备就肯定是识别为了USB触摸,但我们使用的是I2C触摸,所以才会导致触摸无法使用的情况。我们先找到TOUCH_TYPE_FILE这个文件,进行删除,定位一下原因。
文件位置查找:
Android12.0/kernel-4.19/drivers/input/touchscreen/touch_adapter_driver/touch_compatible.h
可知TOUCH_TYPE_FILE的文件路径在 /data/hardware_status/touch_type
对 touch_type 进行删除后重新创建,触摸能正常使用。初步考虑是烧录固件的时候没用接入I2C触摸,烧录完成后才进行组装。所以第一次并未识别到I2C触摸屏,如果没有找到任何匹配的I2C触摸屏设备,那么会调用save_data_to_file函数将触摸屏类型设置为USB触摸。后面和生产线落实确实是这种情况。后面将会进行代码逻辑优化,优化上述情况。