3TP调试

一:基础知识
    Kernel 通过input 子系统与Android交互,每当我们点击屏幕或抬起都会产生中断,
    每当kernel收到中断会通过i2c总线读取TP控制器产生的坐标数据,kernel就会通过input系统上报给android层, android层会完成相应的动作。
    1. 硬件管脚:
        SCL0: IIC 时钟引脚
        SDA0:IIC数据引脚
        RST: 复位引脚
        EINT: IIC 中断引脚,触摸事件通过IIC 贯穿到系统
    2. TP  增加驱动原理    
        TMK 增加驱动到静态数组 tpd_driver_list 数组中
            static struct tpd_driver_t tpd_device_driver = {
                .tpd_device_name = "FT5x0x",
                .tpd_local_init = tpd_local_init,
            };
            module_init(tpd_driver_init)--->tpd_driver_add(&tpd_device_driver)
        kernel-3.18/drivers/input/touchscreen/mediatek/mtk_tpd.c TP 设备加载、卸载和平台总线注册
        
        运行 tpd_probe
            static int tpd_probe(struct platform_device *pdev)
            {
                ...
                /*    全局数组tpd_driver_lsit[i]中的tp驱动依次进行如下操作 ,遍历整个数组
                    执行tp驱动中的tpd_local_init()接口,此接口主要是对tpd_i2c_driver进行i2c
                    总线的注册,匹配成功后执行tpd_i2c_driver中的probe ,这个probe比较重要,
                    其中系统会跟TP进行一次i2c通信,如果成功则说明找到了这个驱动,根据
                    此,可以兼容多款不同IC的TP设备* /
                for (i = 1; i < TP_DRV_MAX_COUNT; i++) {
                    /* add tpd driver into list */
                    if (tpd_driver_list[i].tpd_device_name != NULL) {
                        //运行驱动中i2c_add_driver(&tpd_i2c_driver) -->tpd_probe 读取成功则全局 tpd_load_status设置为1 ,这可以兼容不同TP
                        tpd_driver_list[i].tpd_local_init(); 
                        /* msleep(1); */
                        if (tpd_load_status == 1) {//// 如果上面的i2c总线注册成功,则将tpd_load_status置位
                            TPD_DMESG("[mtk-tpd]tpd_probe, tpd_driver_name=%s\n",
                                  tpd_driver_list[i].tpd_device_name);
                            g_tpd_drv = &tpd_driver_list[i];  //并将g_tpd_drv指向这个驱动  
                            break;
                        }
                    }
                }
                ...
                if(input_register_device(tpd->dev))   //向输入子系统注册输入设备  
                ...
            }
二:从零添加新TP
            1. 修改kernel-3.18/arch/arm/configs/hys6737m_35_m0_debug_defconfig
                kernel-3.18/arch/arm/configs/hys6737m_35_m0_defconfig    
                -CONFIG_TOUCHSCREEN_MTK_GT1151=y
                +CONFIG_TOUCHSCREEN_MTK_FT6X36=y                        //打开指定的tp,关闭其他的
            
            2. 修改 device/teksun/hys6737m_35_m0/ProjectConfig.mk
                +CUSTOM_KERNEL_TOUCHPANEL = ft6x36                        //修改为指定tp
         
            3. 添加驱动代码,把ft6x36放到 kernel-3.18/drivers/input/touchscreen/mediatek/ 中        
                对TP功能进行修改,分辨率,等。
                有dts 的需要修改kernel-3.18/arch/arm/boot/dts/hys6737m_35_m0.dts
                -       tpd-resolution = <720 1280>;
                -       use-tpd-button = <0>;
                -       tpd-key-num = <3>;
                -       tpd-key-local= <139 172 158 0>;
                -       tpd-key-dim-local = <90 883 100 40 230 883 100 40 370 883 100 40 0 0 0 0>;
                +       tpd-resolution = <480 854>;
                +       use-tpd-button = <1>;
                +       tpd-key-num = <2>;
                +       tpd-key-local= <139 158 0 0>;
                +       tpd-key-dim-local = <160 2100 100 40 570 2100 100 40 0 0 0 0 0 0 0 0>;
             
            4. kernel-3.18/drivers/input/touchscreen/mediatek/Kconfig 添加:
                +config TOUCHSCREEN_MTK_FT6X36
                +       bool "FT6X36 for Mediatek package"
                +       default n
                +       help
                +         Say Y here if you have FT6X36 touch panel.
                +
                +         If unsure, say N.
                +
                +         To compile this dirver as a module, choose M here: the
                +         module will be called.
                +
            
            5. 在 kernel-3.18\drivers\input\touchscreen\mediatek\Makefile 添加:
                +obj-$(CONFIG_TOUCHSCREEN_MTK_FT6X36)   +=  ft6x36/
 
三:TP兼容
    不同ic的tp模组做兼容 
        在 /kernel-3.18/arch/arm/configs/hys6737m_35_m0_debug_defconfig
            kernel-3.18/arch/arm/configs/hys6737m_35_m0_defconfig    配置要增加的IC驱动,
            如     CONFIG_TOUCHSCREEN_MTK_FT6X36=y CONFIG_TOUCHSCREEN_MTK_ICN8711=y
            TP进行一次i2c通信,成功则说明找到了这个驱动
    相同ic的tp模组做兼容  
        通过线距兼容2种gsl1680TP ,原理是不同的屏长 ,线距 不一样,i2c通信 2次同的数据不一样
        dts .在dws 配置
        Slave Device  Channel     Device Address
        CAP_TOUCH   I2C_CHANNEL_1 0x38
        (codegen.dws编译生成)
        ./out/target/product/hys6737m_35_m0/obj/KERNEL_OBJ/arch/arm/boot/dts/cust.dtsi
            &i2c1 {                                        //在那路I2上挂载设备
            #address-cells = <1>;
            #size-cells = <0>;
            cap_touch@38 {
                compatible = "mediatek,cap_touch";        //设备配备Ic驱动 重要
                reg = <0x38>;                            //可以随便配置
                status = "okay";
            };
            }
        为了兼容其他IP 一般在probe 强制转换成自己的device address 如
        敦太tp
            if(i2c_client->addr != 0x38)
            {
                i2c_client->addr = 0x38;
                TPD_DMESG("set i2c_client->addr = 0x%x\n",i2c_client->addr);
            }
        ICN8711 TP
            #define ICN85XX_NORMAL_IIC_ADDR     (0x90>>1)
            i2c_client = client;
            i2c_client->addr=ICN85XX_NORMAL_IIC_ADDR;
        TP IC 地址 7为地址         软件合成八位 ,最后一位表示读下位
            1. 思立微的tp:gsl915      0x40
        
            2. 汇顶的tp: GT5668      0x5d    (0xba>>1)  
            
            3. 敦太tp: FT6X36         0x38    (0x70>>1)  
            
            4. ICN8711:             0x48    (0x90>>1)

    
四:TP附加功能
    ps功能:贴脸灭屏
        #define TPD_PROXIMITY
        #ifdef TPD_PROXIMITY
        #include "alsps.h"
        #endif
        #ifdef TPD_PROXIMITY
        {
            obj_ps.polling = 1;         //0--interrupt mode;1--polling mode;
            obj_ps.sensor_operate = tpd_ps_operate;
            if ((err = hwmsen_attach(ID_PROXIMITY, &obj_ps)))
            {
                TPD_DEBUG("hwmsen attach fail, return:%d.", err);
            }
        }
    #endif
    手势唤醒 
        TPD_SLIDE_WAKEUP
    虚拟按键
        dts修改:
            #define KEY_BACK        158 /* AC Back */
            #define KEY_HOME        172 /* AC Home */
            #define KEY_MENU        139 /*   Menu  */
            &touch {
                tpd-resolution = <480 854>;             //tp分辨率
                use-tpd-button = <1>;                 //tp虚拟按键使能
                tpd-key-num = <3>;                    //tp虚拟按键个数
                tpd-key-local= <KEY_MENU KEY_HOME KEY_BACK 0>;    //3个虚拟按键参数(第4个为0)
                tpd-key-dim-local = <80 1000 100 40 240 1000 100 40 400 1000 100 40 0 0 0 0>;  //3个虚拟按键参数(第4个为0)4*4(x,y,weith,height)
                tpd-max-touch-num = <5>;             //5点触控
                tpd-filter-enable = <1>;             //tp过滤器使能
                tpd-filter-pixel-density = <124>;            //tp过滤器像素密度
                tpd-filter-pixel-density = <124>;            //tp过滤器像素密度
                tpd-filter-custom-prameters = <0 0 0 0 0 0 0 0 0 0 0 0>;
                tpd-filter-custom-speed = <0 0 0>;
                pinctrl-names = "default", "state_eint_as_int", "state_eint_output0", "state_eint_output1", 、//TP GPIO
                    "state_rst_output0", "state_rst_output1";
                pinctrl-0 = <&CTP_pins_default>;
                pinctrl-1 = <&CTP_pins_eint_as_int>;
                pinctrl-2 = <&CTP_pins_eint_output0>;
                pinctrl-3 = <&CTP_pins_eint_output1>;
                pinctrl-4 = <&CTP_pins_rst_output0>;
                pinctrl-5 = <&CTP_pins_rst_output1>;
                status = "okay";
            };
        驱动中修改
            #define TPD_RES_X               480
            #define TPD_RES_Y               854
            #define TPD_HAVE_BUTTON            // if have virtual key,need define the MACRO
            #define TPD_KEY_COUNT           3    //  4
            #define TPD_BUTTON_HEIGH        (60)  //100
            #define TPD_KEYS                {KEY_MENU, KEY_HOMEPAGE, KEY_BACK}
            #define TPD_KEYS_DIM            {{90,1000,80,TPD_BUTTON_HEIGH},{240,1000,80,TPD_BUTTON_HEIGH},{400,1000,80,TPD_BUTTON_HEIGH}}
    tp翻转180度
    ./kernel-3.18/drivers/input/touchscreen/mediatek/ft6x36/focaltech_core.c 
        #define CONFIG_TPD_ROTATE_180
        
    可以按下面修改
     #if defined(CONFIG_TPD_ROTATE_90) || defined(CONFIG_TPD_ROTATE_270) || defined(CONFIG_TPD_ROTATE_180)
        static void tpd_swap_xy(int *x, int *y)
        {
            int temp = 0;    temp = *x;    *x = *y;    *y = temp;
        }
        static void tpd_rotate_90(int *x, int *y)
        {    
            *x = TPD_RES_X1 + 1 - *x;    
            *x = (*x * TPD_RES_Y1) / TPD_RES_X1;
            *y = (*y * TPD_RES_X1) / TPD_RES_Y1;    
            tpd_swap_xy(x, y);
        }
        static void tpd_rotate_180(int *x, int *y)
        {
            *y = TPD_RES_Y1 + 1 - *y;
            *x = TPD_RES_X1 + 1 - *x;
        }
        static void tpd_rotate_270(int *x, int *y)
        {
        
            *y = TPD_RES_Y1 + 1 - *y;    
            *x = (*x * TPD_RES_Y1) / TPD_RES_X1;
            *y = (*y * TPD_RES_X1) / TPD_RES_Y1;
        
            tpd_swap_xy(x, y);
        }
        
        static void tpd_down(int x, int y, int p, int id)
        {
        #if defined(CONFIG_TPD_ROTATE_90)
            tpd_rotate_90(&x, &y);
        #elif defined(CONFIG_TPD_ROTATE_270)
            tpd_rotate_270(&x, &y);
        #elif defined(CONFIG_TPD_ROTATE_180)
            tpd_rotate_180(&x, &y);
        #endif    
                input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, id);
                printk("%s x:%d y:%d p:%d\n", __func__, x, y, p);
                input_report_key(tpd->dev, BTN_TOUCH, 1);
                input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 1);
                input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
                input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
                input_mt_sync(tpd->dev);
            }
        }
        static void tpd_up(int x, int y)
        {
        #if defined(CONFIG_TPD_ROTATE_90)
            tpd_rotate_90(&x, &y);
        #elif defined(CONFIG_TPD_ROTATE_270)
            tpd_rotate_270(&x, &y);
        #elif defined(CONFIG_TPD_ROTATE_180)
            tpd_rotate_180(&x, &y);
        #endif
                printk("%s x:%d y:%d\n", __func__, x, y);
                input_report_key(tpd->dev, BTN_TOUCH, 0);
                input_mt_sync(tpd->dev);
        }
    打开ESD
        #define    FT_ESD_PROTECT
五:TP调试方法
    TP .一般修改是I2c地址,上电压,复位时序。中断过程,上报过程
    1 检查硬件
            用万用表测量6个引脚的电压:
                正常工作电压    休眠电压
            INT        1.8V        0V
            RST        1.8V        1.8V
            VDD        2.8V        2.8V
            SDA        1.8V        1.8V
            SCL        1.8V        1.8V
            GND        0V            0V
            
            通过[万用表]查看中断脚有无中断 - 实测可以
            通过[万用表]查看TP的GND是否与主板的GND导通
            通过[示波器]查看sda有无数据波形
    2 通过i2驱动名字 查找设备节点
         static struct i2c_driver tpd_i2c_driver = {
          .driver = {
          .name = "fts",
        } 
        cat /sys/bus/i2c/devices/i2c-1/1-0038/name
        cat /sys/devices/bus.2/11008000.I2C1/i2c-1/1-0038/name
        ls -l /sys/bus/i2c/drivers 
        是否有fts文件夹
    3. 开启 log 查看 tp型号 。函数是否有调用
    
    4. 查看tp报点 /dev/input/event2   //司机生成的节点
        2.1 驱动中有打印的话:
            cat /proc/kmsg | grep "tpd"
        2.2 可以直接从input设备节点/dev/input/event?读取
            getevent -i
            add device 3: /dev/input/event2
              bus:      0000
              vendor    0000
              product   0000
              version   0000
              name:     "mtk-tpd"
              location: ""
              id:       ""
              version:  1.0.1
              events:
                KEY (0001): 008b  009e  00ac  014a        //虚拟按键
                ABS (0003): 0000  : value 0, min 0, max 480, fuzz 0, flat 0, resolution 48
                            0001  : value 0, min 0, max 854, fuzz 0, flat 0, resolution 85
                            0018  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
                            0030  : value 0, min 0, max 100, fuzz 0, flat 0, resolution 0
                            0031  : value 0, min 0, max 100, fuzz 0, flat 0, resolution 0
                            0035  : value 0, min 0, max 480, fuzz 0, flat 0, resolution 0
                            0036  : value 0, min 0, max 854, fuzz 0, flat 0, resolution 0
                            0039  : value 0, min 0, max 10, fuzz 0, flat 0, resolution 0
            getevent -t /dev/input/event2        (event?,用[getevent -i] 查看)
            
            --     查看到的是原始数据,看不出坐标点,只能看出有无上报    
        5. 查看TP虚拟坐标
            cat /sys/board_properties/virtualkeys.mtk-tpd
            0x01:139:90:1000:80:60:0x01:172:240:1000:80:60:0x01:158:400:1000:80:60
六:案例分析
    案例一: tp虚拟按键无功能 - dts中配置有误
        现象:
        平台:
        排查过程:
        修改:
    案例二: tp无上报 - gpio 引脚 ,电压引脚错误 i2c地址 - 八位地址与七位地址 - dws写7位地址
        现象:
        平台:
        排查过程:
        修改:
    案例三: tp开机 休眠唤醒 重启 - 修改休眠唤醒的  tpd_suspend 或者 关防静电的宏 
        现象:
        平台:
        排查过程:
        修改:
    案例四: TP 有功能 上报点不对
        现象:
        平台:
        排查过程:
        修改: FAR支持 ,修改固件
    案例五: TP 有功能 有无点现象
        现象:
        平台:
        排查过程:
        修改: 修改DMA传 。固件初始应FIFO传输 ,MTK FIFO传只能连续传16个字节,大于要用DMA传
    案例六: TP 虚拟按键无功能 
        现象: 开始 一批虚拟按键有功能,后一批TP无虚拟按键
        平台:MT6737m
        排查过程:
        修改: TP虚拟按键块和LCD的地连在一起。贴高温胶纸防止短接。
七:TP流程分析

猜你喜欢

转载自blog.csdn.net/alifrank/article/details/87881893
tp3