TP的结构

TP驱动芯片厂商主要有:focaltech(敦泰科技),synaptics(新思),atmel(爱特梅尔),iliteck(奕立)

手机显示屏LCD&TP的不同贴合工艺
主要结构上主要分为in-cell on-cell ogs,主要是面板模组厂商和触摸屏模组厂商的不同倾向的选择所产生的。

OGS(ONE GLASSS SOLUTION)技术,现在主要由触控屏厂商主导并发展,显示面板厂商倾向推动On-Cell或In-Cell的技术是因为其本身就是生产显示屏的,因此倾向于将触摸层制作在显示屏;而触控模组厂商或上游材料厂商则倾向于OGS,即将触控层制作在保护玻璃上,主要原因是该技术具备较强的制作工艺能力和技术。

In-cell是指将TP触摸面板功能嵌入到LCD液晶像素中的方法,因此原本3层的保护玻璃+TP+LCD变成了两层的保护玻璃+带触控功能的LCD,这样能使屏幕变得更加轻薄,留给手机的空间就更大,可扩充电池,同时若出现触摸出现问题,需要同屏幕一起换掉。

On-cell是指将触摸屏嵌入到显示屏的彩色滤光片基板和偏光片之间的方法,即在液晶面板上配触摸传感器,相比in-cell技术难度降低不少。三星、日立、LG等厂商在on-cell结构触摸屏上进展较快,目前,on-cell多应用于三星Amoled面板产品上,技术上尚未能克服薄型化、触控时产生的颜色不均等问题。

目前InCell&Oncell是一个阵营,OSG是一个阵营。低端一般用OSG。

TP的硬件接口

硬件原理图可以结合Android Qcom Display学习博客中的部分,硬件接口主要是

中断引脚:TS_INT_N GPIO80
复位引脚:TS_RESET_N GPIO71
总线通信:TOUCH_SCL TS_I2C_SCL/SDA GPIO7 GPIO6
供电相关:LCD_IOVDD_1P8 VREG_L9A_1P8 1.65V to 3.3V
TP使能引脚:TOUCH_3V3_EN_GPIO90 GPIO45

部分dtsi
&qupv3_se2_i2c { /* BLSP1 QUP4 (Touch) */status = "okay";atmel_maxtouch_ts@4a {compatible = "atmel,maxtouch-ts";reg = <0x4a>;vdd-supply = <&L9A>; //vddio, 1.8vatmel,vdd-voltage = <1800000>;atmel,tp-enable-gpio = <&tlmm 45 0x00>;//3.3v enableatmel,reset-gpio = <&tlmm 71 0x00>;interrupt-parent = <&tlmm>;interrupts = <80 0x2008>;//irq gpio + irq flags(interrupt.h)atmel,irq-gpio = <&tlmm 80 0x2008>;pinctrl-names = "pmx_ts_active", "pmx_ts_suspend";pinctrl-0 = <&ts_int_active    &ts_reset_active  &ts_en_active>;pinctrl-1 = <&ts_reset_suspend &ts_int_suspend  &ts_en_suspend>;atmel,display-coords = <0  0 1080 1920>;atmel,panel-coords = <0  0 1080 1920>;atmel,cfg-name = "mxt640u.raw"; /delete-property/ atmel,fw-name;atmel,middle-keycode = <256>;panel  = <&dsi_hx8399_1080_video>;
};&tlmm{pmx_ts_reset_active {ts_reset_active: ts_reset_active {mux {pins = "gpio71";function = "gpio";};config {pins = "gpio71";drive-strength = <8>;bias-pull-up;};};};pmx_ts_reset_suspend {ts_reset_suspend: ts_reset_suspend {mux {pins = "gpio71";function = "gpio";};config {pins = "gpio71";drive-strength = <2>;bias-pull-down;};};};pmx_ts_int_active {ts_int_active: ts_int_active {mux {pins = "gpio80";function = "gpio";};config {pins = "gpio80";drive-strength = <8>;bias-pull-up;};};};pmx_ts_int_suspend {ts_int_suspend: ts_int_suspend {mux {pins = "gpio80";function = "gpio";};config {pins = "gpio80";drive-strength = <2>;bias-pull-down;};};};pmx_ts_en_active {ts_en_active: ts_en_active {mux {pins = "gpio45";function = "gpio";};config {pins = "gpio45";drive-strength = <8>;bias-pull-up;};};};pmx_ts_en_suspend {ts_en_suspend: ts_en_suspend {mux {pins = "gpio45";function = "gpio";};config {pins = "gpio45";drive-strength = <2>;bias-pull-down;};};};
};

TP驱动代码解析

[Linux] 内核通知链 notifier
Linux firmware子系统的实现机制学习笔记
TouchPanel–Qcom DRM休眠唤醒通知链的注册及回调流程

mxt_probemxt_parse_dt(&client->dev, pdata);mxt_get_dt_coords(dev, "atmel,panel-coords", pdata);mxt_get_dt_coords(dev, "atmel,display-coords", pdata);atmel_check_dt_panel(client->dev.of_node) /* data->active_panel */node = of_parse_phandle(np, "panel", i);panel = of_drm_find_panel(node); /* panel的注册列表中找到匹配的 */gpio_to_irq(data->pdata->gpio_irq);request_threaded_irq(data->irq, NULL, mxt_interrupt,data->pdata->irqflags | IRQF_ONESHOT,client->name, data);mxt_regulator_enable(data); /* 使能 设置上下电时序 */gpio_set_value(data->pdata->gpio_reset, 0);regulator_enable(data->reg_vdd);gpio_set_value(data->pdata->tp_en_gpio, 1);mdelay(MXT_640U_REGULATOR_DELAY);gpio_set_value(data->pdata->gpio_reset, 1);mdelay(MXT_640U_POWERON_DELAY);disable_irq(data->irq);mxt_initialize(data);mxt_read_info_block(data); mxt_update_cfg_version(data); /* 读取cfg_version 后续mxt_load_cfg */mxt_update_mode(data); /* __mxt_read_reg 读取寄存器的值存入mxt_data-> cfg_mode*/mxt_choose_mode(data); /* configure mode enum 根据cfgmode去更新mxt_data->cfg_name */mxt_check_fw_version(data); /* 判断fw是否需要更新*/request_firmware_nowait(THIS_MODULE, true, data->cfg_name,&data->client->dev, GFP_KERNEL, data,mxt_config_cb);fw_get_filesystem_firmware(device, fw->priv); // fw_path = {fw_path_para, "vendor/firmware"};mxt_load_cfg(ctx, cfg, false);/* download configuration to chip */mxt_configure_objects(data); /* 创建了input device*/mxt_create_input_dev(data);input_allocate_device();input_dev->open = mxt_input_open;input_set_capability(input_dev, EV_KEY, BTN_TOUCH);input_set_abs_params(input_dev, ABS_X,data->pdata->disp_minx, data->pdata->disp_maxx,0, 0);input_set_abs_params(input_dev, ABS_Y,data->pdata->disp_miny, data->pdata->disp_maxy,0, 0);input_register_device(input_dev);sysfs_create_group(&client->dev.kobj, &mxt_attr_group); /* 注册文件 *//sys/devices/platform/soc/4a88000.i2c/i2c-1/1-004a/fw_version sysfs_bin_attr_init(&data->mem_access_attr); /* lockdep死锁检测需要分配动态 attr.name = mem_access */ata->fb_notif.notifier_call = fb_notifier_callback;drm_panel_notifier_register(data->active_panel,&data->fb_notif); /* 休眠唤醒通知链 */request_firmware_nowait(THIS_MODULE, true, data->fw_name,&data->client->dev, GFP_KERNEL, data,mxt_fw_cb);
部分log:
atmel_maxtouch_ts 1-004a: enter mxt_parse_dt
atmel_maxtouch_ts 1-004a: success to update touch cords.
atmel_maxtouch_ts 1-004a: success to update display cords.
atmel_maxtouch_ts 1-004a: touch cords: 0 0 1079 1919 , diplay cords: 0 0 1079 1919
atmel_maxtouch_ts 1-004a: mxt_parse_dt: atmel,reset-gpio is 1238
atmel_maxtouch_ts 1-004a: mxt_parse_dt: atmel,irq-gpio is 1247
atmel_maxtouch_ts 1-004a: read atmel middle scan key success.
atmel_maxtouch_ts 1-004a: Success to get active_panel
atmel_maxtouch_ts 1-004a: tp_en_gpio : 1212
atmel_maxtouch_ts 1-004a: Linked as a consumer to regulator.30
atmel_maxtouch_ts 1-004a: mxt_regulator_enable 3124 set tp_en_gpio high ...
atmel_maxtouch_ts 1-004a: Family: 166 Variant: 1 Firmware V1.1.AA Objects: 41 cfg version: 0.7.0.5 ( driver function:mxt_read_info_block )
atmel_maxtouch_ts 1-004a: path: mxt640u.raw ( mxt_choose_mode )
atmel_maxtouch_ts 1-004a: Initialised power cfg: ACTV 16, IDLE 32 ( mxt_init_t7_power_cfg )
atmel_maxtouch_ts 1-004a: Falling back to syfs fallback for: mxt640u.raw
input: atmel_mxt_ts as /devices/platform/soc/4a88000.i2c/i2c-1/1-004a/input/input5 ( input_register_device )
counters_connect atmel_mxt_ts
atmel_maxtouch_ts 1-004a: Register drm_fb_notifier success
atmel_maxtouch_ts 1-004a: mxt_config_cb >>>>>>
atmel_maxtouch_ts 1-004a: controller version:0.7.0.5 file version:0.7.0.5
atmel_maxtouch_ts 1-004a: configuration is up-to-date
atmel_maxtouch_ts 1-004a: Unable to load_cfg
如果request_firmware_nowait没有找到cfg文件则会打印
atmel_maxtouch_ts 1-004a: Failure to request config file mxt640u.raw

Linux 固件子系统

linux firmware 实现原理
Linux固件子系统的实现机制简介
linux内核下载固件函数request_firmware流程分析

int request_firmware(const struct firmware **fw, const char *name, struct device *device);
int request_firmware_nowait(struct module *module, /*= THIS_MODULE*/int uevent, const char *name, struct device *device,gfp_t gfp,void *context,/*不由固件子系统使用的私有数据指针*/void (*cont)(const struct firmware *fw, void *context));INIT_WORK(&fw_work->work, request_firmware_work_func); chedule_work(&fw_work->work);

request_firmware 会请求用户空间,所以返回前将保持休眠,若probe函数调用会一直等待文件系统的挂载
request_firmware_nowait 是通过异步的工作队列去获取固件,使得请求固件不会进入休眠,可以不阻塞probe函数,会通过任务队列调用request_firmware_work_func,request_firmware相关的底层都会调用到_request_firmware函数

从源码driver/base/firmware_loader/main.c fallback.c中得知查找固件有三种方式:
第一种:builtin段,判断是否被编译到kernel中,Hacker_Albert博客有分享一种

fw_get_builtin_firmware(firmware, name, dbuf, size)CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE_DIR="firmware"  // this means $(source_dir)/firmware
CONFIG_EXTRA_FIRMWARE="fw_sst_0f28.bin"

第二种:cache,寻找之前是否有保存了以前load过的fw的信息,比如name, data, size等

alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size, opt_flags);

第三种:fw_path,比较直观的可以知道从列表支持的file system路径中去寻找是否有存在对应的固件

fw_get_filesystem_firmware(device, fw->priv);static const char * const fw_path[] = {fw_path_para,"/mnt/vendor/persist/tpp","/lib/firmware/updates/" UTS_RELEASE,"/lib/firmware/updates","/lib/firmware/" UTS_RELEASE,"/lib/firmware"
};
module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644);
firmware_class.path=$CUSTOMIZED_PATH'
firmware_class.path=/system/etc/firmware

第四中:usespace,通过通过/sys/class/firmware/ 内核向用户空间发送uevent,udevd接收到事件后去寻找

firmware_fallback_sysfs(fw, name, device, opt_flags, ret);fw_load_from_user_helper(fw, name, device, opt_flags);system/core/rootdir/ueventd.rcfirmware_directories /etc/firmware/ /odm/firmware/ /vendor/firmware/ /firmware/image/

Linux 中断子系统

linux驱动request_threaded_irq()
linux中断申请之request_threaded_irq
中断要尽可能耗时比较短,尽快恢复系统正常调试,所以把中断触发、中断执行分开,也就是所说的“上半部分(中断触发)、底半部(中断执行)”,也就是所说的中断上下文。上半部分处理紧急、不耗时的硬件操作,下半部分一般处理不紧急的耗时操作采用tasklet、workqueue实现

int request_irq(unsigned int irq, irq_handler_t handler,unsigned long flags,const char* name, void *dev)
int request_threaded_irq(unsigned int irq, irq_handler_t handler,        irq_handler_t thread_fn,unsigned long flags, const char *name, void *dev);
IRQF_SHARED : allow sharing the irq among several devices
IRQF_SHARED 共享中断时,dev_id不能为空,因为释放irq时要区分哪个共享中断
IRQF_ONESHOT:Interrupt is not reenabled after the hardirq handler finished.Used by threaded interrupts which need to keep the irq line disabled until the threaded handler has been run
IRQF_ONESHOT 例如:设备是低电平产生中断,而硬中断函数为NULL,如果不使用IRQF_ONESHOT,就会一直产生中断执行NULL函数,中断线程得不到执行,声明IRQF_ONESHOT后,会执行完线程才使能该中断

request_threaded_irq 是在将上半部的硬件中断处理缩短为所需设备的硬体中断,唤醒kernel thread 执行任务。没必要再使用request_irq加tasklet/workqueue或者内核线程的方式;如果中断处理简单时也不要执着使用request_threaded_irq

Android 输入系统架构


以上是Android input系统的整体架构,可以查看十分钟了解Android触摸事件原理(InputManagerService)
个人学习总结,Android input gpio driver手动对焦 + Android input epoll/inotify机制

MT协议上报点位

linux下多点电容触摸屏实验
Type A:适用于触摸点不能被区分或者追踪,此类型的设备上报原始数据(此类型在实际使用中非常少!
Type B:适用于有硬件追踪并能区分触摸点的触摸设备,此类型设备通过 slot 更新某一个触摸点的信息,并且可以可以减少上报到用户空间的数据量,当只在X轴上移动时,只会上报ABS_MT_POSITION_Y。

1.设置能力,不然上报的过程中会被拦截
__set_bit(EV_ABS, input_dev->evbit);
input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X,data->pdata->disp_minx, data->pdata->disp_maxx, 0, 0);
input_set_abs_params(input_dev, ABS_Y,data->pdata->disp_miny, data->pdata->disp_maxy, 0, 0);input_mt_init_slots(input_dev, num_mt_slots, mt_flags); //多点触摸的个数2.根据MT协议上报点位
input_mt_slot(input_dev, id);                         //slot
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);     //tracking id
input_report_abs(input_dev, ABS_MT_POSITION_X, x);            //MT_X
input_report_abs(input_dev, ABS_MT_POSITION_Y, y);            //MT_Y    //以下几个点由于没有set_bit所以在上报过程中会被过滤掉
input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, major);       //触摸点区域大小
input_report_abs(input_dev, ABS_MT_PRESSURE, pressure);       //触摸点压力
input_report_abs(input_dev, ABS_MT_DISTANCE, distance);       //触摸点与触摸面的距离
input_report_abs(input_dev, ABS_MT_ORIENTATION, orientation); //触底的方向       //单点+Sync同步
input_mt_report_pointer_emulation(input_dev, false);//input_event + BTN_TOUCH+ABS_X+ABS_Y
input_sync(input_dev);Event Types
#define EV_SYN          0x00
#define EV_KEY          0x01
#define EV_ABS          0x03
Code
#define ABS_MT_SLOT     0x2f    /* MT slot being modified */
#define ABS_MT_TRACKING_ID  0x39    /* Unique ID of initiated contact */
#define ABS_MT_POSITION_X   0x35    /* Center X touch position */
#define ABS_MT_POSITION_Y   0x36    /* Center Y touch position */#define BTN_TOUCH      0x14a   /* pressure on/off */
#define ABS_X           0x00
#define ABS_Y           0x01

根据getevent来查看具体的上报事件, type code value

TypeB  slot
单点                                         单点slot可能会被忽略
/dev/input/event4: 0003 0039 00000066        type=0x3代表为EV_ABS事件,上报Tracking id
/dev/input/event4: 0003 0035 00000004        上报触摸点的X轴坐标(触摸点靠近左上角)
/dev/input/event4: 0003 0036 0000000d        上报触摸点的Y轴坐标(x = 04 y = 0d)
/dev/input/event4: 0001 014a 00000001        BTN_TOUCH type为KEY的事件代表触摸点摁下
/dev/input/event4: 0003 0000 00000004        用于单点触摸的时候上报的X轴坐标,同MT_X
/dev/input/event4: 0003 0001 0000000d        同上,ABS_Y = ABS_POSITION_Y
/dev/input/event4: 0000 0000 00000000        input_sync的EV_SYN事件同步上报操作
/frameworks/native/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp多点
/dev/input/event4: 0003 002f 00000000         0x2f代表slot,用于区分点value=0第一个点
/dev/input/event4: 0003 0039 0000007c         ABS_MT_TRACKING_ID
/dev/input/event4: 0003 0035 0000025c         ABS_MT_POSITION_X
/dev/input/event4: 0003 0036 00000318         ABS_MT_POSITION_Y
/dev/input/event4: 0003 002f 00000001         slot1,表示当前有两个点在触摸
/dev/input/event4: 0003 0039 0000007d         ABS_MT_TRACKING_ID
/dev/input/event4: 0003 0035 000001d5         ABS_MT_POSITION_X
/dev/input/event4: 0003 0036 00000260         ABS_MT_POSITION_Y
/dev/input/event4: 0001 014a 00000001         BTN_TOUCH
/dev/input/event4: 0003 0000 0000025c         ABS_X
/dev/input/event4: 0003 0001 00000318         ABS_Y
/dev/input/event4: 0000 0000 00000000         EV_SYN
/frameworks/native/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp 抬手
/dev/input/event4: 0003 0039 ffffffff         0xffffffff代表触摸点离开屏幕
/dev/input/event4: 0001 014a 00000000         BTN_TOUCH = 0 手指离开屏幕
/dev/input/event4: 0000 0000 00000000


有可能会遇到模组厂于实际安装位置出现翻转的现象,其实也是很容易就能解决的,当然如果厂商能修改寄存器或者类型atmel的cfg更新,以下可以当作临时修改,还得防止出现负值的情况

x = (int)data->pdata->panel_maxx -x;
y = (int)data->pdata->panel_maxy -y;

Android input touchpanel驱动流程相关推荐

  1. android移植wifi驱动流程porting

    android载入wifi驱动流程 wifi_load_driver check_wifi_chip_type_string get_wifi_device_id save_wifi_chip_typ ...

  2. input device驱动流程

    input驱动简介 struct input_dev; 根据linux驱动的基本设计思路,任何设备可以挂载到任易的总线下,所以,input_dev也 不例外.例如传统的PS2键盘,其实是一个串口设备, ...

  3. android 休眠唤醒驱动流程分析,Android 电源管理——gotosleep和userActivity关注

    一.Android power management应用层分析 Android提供了android.os.PowerManager类,该类用于控制设备的电源状态的切换. 该类对外有三个接口函数: 1. ...

  4. android休眠唤醒驱动流程分析【转】

    转自:http://blog.csdn.net/hanmengaidudu/article/details/11777501 标准linux休眠过程: l        power managemen ...

  5. android 休眠唤醒驱动流程分析,Android4.0.4休眠唤醒机制分析(基于MSM8260)

    当手机满足一定的条件时,会进入休眠状态.从手机进入休眠到唤醒,主要分为三个阶段: early suspend suspend late resume early suspend执行在休眠前需要完成的一 ...

  6. MTK 按键驱动流程总结

    前言 简单介绍了 Input 按键驱动流程 流程 位置:Kpd.c (kernel-3.18\drivers\input\keyboard\mediatek) module_init(kpd_mod_ ...

  7. MTK8788[android 9.0]汇顶GT9XX TP触摸屏驱动流程分析

    TP 相关引脚DTS中的定义 我们这个项目TP复位引脚是GPIO158,中断引脚是GPIO1,由下图原理图知道我们的TP挂载在I2c0上,3.3v的供电电压是有PMIC 2.8V供电电压通过i2c电平 ...

  8. 【SemiDrive源码分析】【MailBox核间通信】46 - Android侧 RPMSG_IPCC_RPC驱动分析(下) 之 RPMSG_IPCC_RPC驱动初始化、数据收发流程分析

    [SemiDrive源码分析][MailBox核间通信]46 - Android侧 RPMSG_IPCC_RPC驱动分析(下) 之 RPMSG_IPCC_RPC驱动初始化.数据收发流程分析 三. rp ...

  9. 基于MT6752/32平台 Android L版本驱动移植步骤

    基于MT6752/32平台 Android L版本驱动移植步骤 根据MK官网所述,在Android L 版本上Turnkey ABS 架构将会phase out,而Mediatek Turnkey架构 ...

  10. c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...

    在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析​zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...

最新文章

  1. rocketmq 顺序消费_必须先理解的RocketMQ入门手册,才能再次深入解读
  2. 分布式转码初步方案(hadoop+ffmpeg)
  3. Junit5集成到SpringBoot工程
  4. JDK安装、java环境配置
  5. An error occured executing the microsoft VC++ runtime installer
  6. scrapy[skp]快速入门
  7. 【DevOps】在CentOS中安装Rancher2,并配置kubernetes集群
  8. 计算机三级考点3:构建宽带城域网的基本技术与方案。
  9. 百度网盘免费jdk1.8中文chm下载(不要积分点个赞就好)
  10. 瀑布模型、迭代模型和敏捷开发
  11. Python海龟画图
  12. java毕业设计木材产销系统的生产管理模块mybatis+源码+调试部署+系统+数据库+lw
  13. 苹果Xr用不了浏览器显示服务器已停止响应,苹果xrsafari浏览器用不了?
  14. 利用simulink分析系统各种传递函数的BODE图、阶跃响应、单位脉冲响应
  15. 快时钟到慢时钟的同步问题
  16. GPS从入门到放弃(六) --- 开普勒轨道参数
  17. [KALI] 新装KALI自动化配置
  18. Python 爬取 201865 条《隐秘的角落》弹幕数据,发现看剧不如爬山?
  19. 千只瓶子找毒药的问题
  20. 胖哈勃 web--NewSql Mysql 8 注入

热门文章

  1. 数据库安全关键技术之数据库脱敏技术详解
  2. 安川机器人仿真软件安装
  3. [转]: GB2312-80区位编码表
  4. 【盘点】python最常用的快捷键,一定要收藏!
  5. 一文搞懂激活函数(Sigmoid/ReLU/LeakyReLU/PReLU/ELU)
  6. 网线连接威纶触摸屏失败的解决方法
  7. 关于周志华老师的几篇深度森林论文的介绍
  8. 网易云音乐广告CTR预估模型演进过程
  9. 联想M7650DF加粉和重置/清零的正确方法
  10. APP开发之APP研发流程微信棋牌程序制作