1.1、    MTK Touch 驱动的组成
Mtk  Touch  driver 驱动包括:Mtk platform 虚拟平台设备驱动、Module touch IC 驱动、Input subsystem。
Mtk platform 设备驱动是mtk为了兼容多个touch IC 驱动而设计出来的虚拟驱动,它会去遍历每一个touch  IC 驱动,直到其中一个初始化成功。
Linux input_subsystem是linux 的输入子系统,我们的输入设备都要通过这个子系统进行上报事件以及设置事件的类型。
 
图1 MTk Touch 架构图
1.2、    Platform 驱动
Platfiorm 驱动主要是负责mtk虚拟touch 平台的驱动的注册,执行probe函数遍历每一个具体的touch IC 驱动。
    Kernel/touchpanel/src/mtk_tpd.c
Platform 设备moudle_init 函数:

static int __init tpd_device_init(void) {
            printk("MediaTek touch panel driver init\n");
            if(platform_driver_register(&tpd_driver)!=0) {
        TPD_DMESG("unable to register touch panel driver.\n");
        return -1;
        }   
        return 0;

}
module_init(tpd_device_init)
上面的moduel_init首先加载的函数tpd_device_init 函数中调用platform_driver_register进行注册一个mtk_touch_driver 平台驱动。
其中注册的平台驱动tpd_driver定义如下:
static struct platform_driver tpd_driver = {
    .remove     = tpd_remove,
    .shutdown   = NULL,
    .probe      = tpd_probe,
    #ifndef CONFIG_HAS_EARLYSUSPEND
    .suspend    = NULL,
    .resume     = NULL,
    #endif
    .driver     = {
        .name = TPD_DEVICE,
    },
};

根据platform bus mathc的规则:driver_name 和device_name相同就会调用platform_drive 的probe函数。这里牵扯到Linux的设备模型知识,需要了解的人可以看下Linux platform bus。
#define TPD_DEVICE            "mtk-tpd"
Platform device 注册:retval = platform_device_register(&mtk_tpd_dev);
mtk_tpd_dev的定义如下:
static struct platform_device mtk_tpd_dev = {
    .name = "mtk-tpd",
    .id   = -1,
};
/mediatek/platform/mt6589/kernel/core/mt_devs.c
上面这个路径是mtk的板极支持的文件,很多板极的注册和初始化的动作都是放在上面的C文件里面的。
根据我上面所说的platform bus的match 规则,设备名字和驱动名字相同。进而就会调用
1.2.1、Platform 驱动入口probe函数
static int tpd_probe(struct platform_device *pdev) {
        int  touch_type = 1; // 0:R-touch, 1: Cap-touch
        int i=0;
      TPD_DMESG("enter %s, %d\n", __FUNCTION__, __LINE__);
      /* Select R-Touch */
     // if(g_tpd_drv == NULL||tpd_load_status == 0)
    if((tpd=(struct tpd_device*)kmalloc(sizeof(struct tpd_device), GFP_KERNEL))==NULL) return -ENOMEM;//分配一个Mtk tpd_device
    memset(tpd, 0, sizeof(struct tpd_device));

/* allocate input device */
    if((tpd->dev=input_allocate_device())==NULL) { kfree(tpd); return -ENOMEM; }
  //上面是分配一个input 设备
    TPD_RES_X = simple_strtoul(LCM_WIDTH, NULL, 0);
    TPD_RES_Y = simple_strtoul(LCM_HEIGHT, NULL, 0);
 
    printk("mtk_tpd: TPD_RES_X = %d, TPD_RES_Y = %d\n", TPD_RES_X, TPD_RES_Y);
 
    tpd_mode = TPD_MODE_NORMAL;
    tpd_mode_axis = 0;
    tpd_mode_min = TPD_RES_Y/2;
    tpd_mode_max = TPD_RES_Y;
    tpd_mode_keypad_tolerance = TPD_RES_X*TPD_RES_X/1600;
    /* struct input_dev dev initialization and registration */
    tpd->dev->name = TPD_DEVICE;
    set_bit(EV_ABS, tpd->dev->evbit);
    set_bit(EV_KEY, tpd->dev->evbit);
    set_bit(ABS_X, tpd->dev->absbit);
    set_bit(ABS_Y, tpd->dev->absbit);
    set_bit(ABS_PRESSURE, tpd->dev->absbit);
    set_bit(BTN_TOUCH, tpd->dev->keybit);
set_bit(INPUT_PROP_DIRECT, tpd->dev->propbit);
//上面都是input 设备事件类型的设置
#if 1    
  for(i = 1; i < TP_DRV_MAX_COUNT; i++)
    {
            /* add tpd driver into list */
        if(tpd_driver_list[i].tpd_device_name != NULL)//这里是在遍历mtk的tpd_driver_list里面的所有的驱动,判断名字是否为NULL,每一个module touch IC 驱动都会添加到这个静态数组里面
        {
            tpd_driver_list[i].tpd_local_init();
            //msleep(1);
            if(tpd_load_status ==1) {//这里我们会判断我们所遍历的每一个module IC 驱动的初始化函数。成功的话就会将tpd_load_status至1,所以我们就是通过这个值判断哪一个驱动的
                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];
                break;
            }
        }    
  }
。。。。。。。。。。。。。。
。。。。。。。。。。。。。。
    #ifdef CONFIG_HAS_EARLYSUSPEND
    MTK_TS_early_suspend_handler.suspend = g_tpd_drv->suspend;
    MTK_TS_early_suspend_handler.resume = g_tpd_drv->resume;
register_early_suspend(&MTK_TS_early_suspend_handler);
//touch 的suspend应该属于eraly_suspend
    #endif          
#endif      
。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。
    if(input_register_device(tpd->dev))//将我们的touch以Input方式进行注册
        TPD_DMESG("input_register_device failed.(tpd)\n");
    else
            tpd_register_flag = 1;
    /* init R-Touch */
    #if 0
      if(touch_type == 0)
      {
          g_tpd_drv->tpd_local_init();
      }    
        #endif
    if(g_tpd_drv->tpd_have_button)
    {
        tpd_button_init();
    }

return 0;
}

1.3、    Ft6306 module driver
Ft6306是敦泰的Touch IC ,这个里面,我们可以进行IC的上电、设置中断、Update FW等动作。
Ft6306中首先执行的代码是:
static int __init tpd_driver_init(void) {
     printk("MediaTek FT5206 touch panel driver init\n");
     i2c_register_board_info(0, &ft5206_i2c_tpd, 1);
         if(tpd_driver_add(&tpd_device_driver) < 0)
             TPD_DMESG("add FT5206 driver failed\n");
     return 0;
 }
module_init(tpd_driver_init);
tpd_driver_init函数会注册一个I2C Touch设备、调用tpd_driver_add添加添加一个驱动,其实就是讲这个驱动添加到上面说的静态数组pd_driver_lis里面。
Tpd_driver_add函数定义如下:
int tpd_driver_add(struct tpd_driver_t *tpd_drv)
{
。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。    
for(i = 1; i < TP_DRV_MAX_COUNT; i++)
    {
        /* add tpd driver into list */
        if(tpd_driver_list[i].tpd_device_name == NULL)
        {
            tpd_driver_list[i].tpd_device_name = tpd_drv->tpd_device_name;
            tpd_driver_list[i].tpd_local_init = tpd_drv->tpd_local_init;
            tpd_driver_list[i].suspend = tpd_drv->suspend;
            tpd_driver_list[i].resume = tpd_drv->resume;
            tpd_driver_list[i].tpd_have_button = tpd_drv->tpd_have_button;
            #if 0
            if(tpd_drv->tpd_local_init()==0)
            {
                TPD_DMESG("load %s sucessfully\n", tpd_driver_list[i].tpd_device_name);
                g_tpd_drv = &tpd_driver_list[i];
            }
            #endif
            break;
        }
        if(strcmp(tpd_driver_list[i].tpd_device_name, tpd_drv->tpd_device_name) == 0)
        {
            return 1; // driver exist
        }
    }
    
    return 0;
}
上面会将我们的每一个注册的Moudle IC touch驱动进行添加到 tpd_driver_list数组中。添加进去后,我们就会调用tpd_local_init函数进行touch IC 的初始化。

1.3.1、Module tpd_local_init函数
static int tpd_local_init(void)
 {
    int i;
 
  TPD_DMESG("Focaltech FT5206 I2C Touchscreen Driver (Built %s @ %s)\n", __DATE__, __TIME__);
 
 
   if(i2c_add_driver(&tpd_i2c_driver)!=0)
       {
          TPD_DMESG("unable to add i2c driver.\n");
          return -1;
}
。。。。。。
}
/kernel/touchpanel/ft6106/ft5206_drive.c
上面是以I2C的方式注册FT 驱动。记得在前面我们有注册一个I2C 设备。I2C 总线也有一套自己的匹配方式,是通过id_table里面的值进行匹配的,当匹配成功就会调用I2c 驱动的probe函数。
 tpd_i2c_driver定义如下:
static struct i2c_driver tpd_i2c_driver = {
  .driver = {
     .name = TPD_DEVICE,
     .owner = THIS_MODULE,
  },
  .probe = tpd_probe,
  .remove = __devexit_p(tpd_remove),
  .id_table = ft5206_tpd_id,
  .detect = tpd_detect,
//  .address_data = &addr_data,
  .address_list = (const unsigned short*) forces,
 };

当我们匹配成功后,我们就会调用上面的tpd_probe函数。
1.3.1.1、module I2C probe函数
Tpd_probe函数是touch IC 的核心函数,在里面我们会进行上电、申请中断、设置GPIO等、Update FW、IC提供的控制 touch 的interface等。
tpd_probe函数定义如下:
static int __devinit tpd_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {    
    int retval = TPD_OK;
    char data;
    i2c_client = client;
#if (defined(MT6575)||defined( MT6577) ||defined(CONFIG_ARCH_MT6589))
    //power on, need confirm with SA
    hwPowerOn(TPD_POWER_SOURCE_CUSTOM, VOL_2800, "TP");//这里是在上电,我在porting的过程中就遇到了上电没有成功,后来查看电路才上对Pin脚,下面会有touch 的电路图

mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);//设置GPIO的工作模式
    mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);//将GPIO设置成out方向
    mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE);
    msleep(2);
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
    }
    else if(data == 0x55)
    {
        sprintf(tpd_chip_name,"%s", "FT5x06");
    }

tpd_load_status = 1;
    thread = kthread_run(touch_event_handler, 0, TPD_DEVICE);//这里是创建一个线程,我们会执行这个线程
    if (IS_ERR(thread))
    {
        retval = PTR_ERR(thread);
        TPD_DMESG(TPD_DEVICE " failed to create kernel thread: %d\n", retval);
    }

Mtk Ft6306 touch 驱动 .的更多相关文章

  1. 我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)

    非常久没有关注RTOS了,所以也一直没有更新.近期闲了,把GPIO I2C调通了.简单移植了Touch.在S5PV210上使用. 调试I2C时.废了非常多周折,最后借助示波器才发现一个小小的错误.折腾 ...

  2. STM32F407+STemwin学习笔记之STemwin移植补充Touch

    原文地址:http://www.cnblogs.com/NickQ/p/8857213.html 环境:keil5.20  STM32F407ZGT6  LCD(320*240)  STemwin:S ...

  3. Ubuntu Touch环境搭建

    最近搞了一下Nexus 5的MultiRom Manger,体验了一把Ubuntu Touch和Android L,总体感觉还不错,不过Android L的NFC驱动还有问题,Ubuntu Touch ...

  4. Mtk Camera

    MTK6577+Android之Camera驱动 http://blog.csdn.net/loongembedded/article/details/41695205 MTK Camera 开机启动 ...

  5. 1、硬件IO口配置;

    对于MTK TP驱动移植一般分为六部分: 1.硬件IO口配置: 2.TP驱动移植. 3.I2C通信: 4.中断触发: 5.数据上报: 6.虚拟按键. 硬件电路: 1.GPIO配置 打开 mediate ...

  6. Camera 涉及的文件70

    点击打开链接 Camera 涉及的文件 1.上电时序 Mediate/custom/$PROJECT/Camera/Camera/kd_camera_hw.c Mediate/custom/$PROJ ...

  7. 红米1线刷救砖教程V5版(移动联通适用,线刷包永久有效)

    红米1线刷救砖教程V5版(移动联通适用,线刷包永久有效) 原文来自:http://www.miui.com/thread-1890972-1-1.html?mobile=2 ,加了些自己的经验. (我 ...

  8. android MTK驱动背光唤醒流程

    在标准的android驱动中,睡眠唤醒流程非常清晰,能够较方便的更改lcd唤醒时间和led背光的点亮时间,但是也很容易出现问题,比如说闪屏,唤醒慢! 出现闪屏有两个原因 1. 开背光时间在唤醒lcd前 ...

  9. mtk lcm驱动加载流程 (转载)

    平台:mt6582 + Android 4.4 前面就说过,在mtk代码中支持屏是可兼容的,通过调用驱动中的compare_id函数来匹配驱动和屏,这里来细看一下代码. 1. LK部分(mediate ...

随机推荐

  1. 超链接的那些事(三): 属性target

    a标签的属性之一 target 1. 定义     规定在何处打开链接文档. 如果a标签中有target属性,浏览器将会载入和显示用这个标签的 href 属性命名的.名称与这个目标吻合的框架或者窗口中 ...

  2. html的<head><title><meta>

    head <head>用来标记HTML的头部,里面通常需要包括标题,基础信息,源信息等,定义在HTML头部的内容往往不会在网页上直接显示 title <title>的内容设置在 ...

  3. 一·创建Linux服务器(基于阿里云)

    本系统是基于阿里云服务器,购买请前往https://www.aliyun.com/?spm=5176.8142029.388261.1.taXish ,由于经济能力的限制,本人购买的是最低配置如下 其 ...

  4. Mathout

    1. 用Maven搭建Mahout的开发环境,并完成PPT 26页,最简单的例子.要求有过程说明和截图. 2. 用案例的数据集,基于Mahout,任选一种算法,对任意一个女性用户进行协同过滤推荐,并解 ...

  5. [转]SQLServer 2008数据库查看死锁、堵塞的SQL语句

    本文转自:http://www.cnblogs.com/zhuque/archive/2012/11/08/2763343.html 死锁和堵塞一直是性能测试执行中关注的重点. 下面是我整理的监控sq ...

  6. JAVA基础之对象的初始化

    本文主要记录JAVA中对象的初始化过程,包括实例变量的初始化和类变量的初始化以及 final 关键字对初始化的影响.另外,还讨论了由于继承原因,探讨了引用变量的编译时类型和运行时类型 一,实例变量的初 ...

  7. codeforces 713B B. Searching Rectangles(二分)

    题目链接: B. Searching Rectangles time limit per test 1 second memory limit per test 256 megabytes input ...

  8. mysql查询语句包含有关键字

    查询mysql的时候,有时候mysql表名或者列名会有关键字.这时候查询会有错误.例如表名是order,查询时候会出错. 简单的办法是sql语句里表名或者列名加上`[tab键上面]来加以区别,例如se ...

  9. easyui 的 DataGrid View 使用

    easyui真是后台人员的宝呀,让不会前台的程序员,不用再用那些自己看着都恶心的表格了! 今天来说说easyui datagrid 的 数据表格详细展示表格,这个有趣多了! 先上图 然后是代码 $(' ...

  10. Converting a Polygon ZM shape file to a regular Shape Polygon

    from:http://blog.csdn.net/qb371/article/details/8102109 Locate the following tool - ArcToolbox > ...