您的位置:首页 > 编程语言 > PHP开发

MTK平台 CTP流程解析

2014-01-06 15:29 676 查看
http://blog.csdn.net/macxen_gunter/article/details/10591077

MTK 平台tp相关,以联永的nt11004为例

一 硬件
tp硬件上主要有6根线:vdd,int,sda,scl,reset,gnd

vdd:电压值为2.8v

int:输入脚,低电平有效。int的触发电平需为电平触发

sda,scl为i2c脚

reset:低电平有效,tp正常工作模式此脚需为高电平。

gnd:地

tp里如有fireware,则无需初始化,只要vdd,reset,gnd接上后,触摸tp,int就有正常中断产生,如没请联系tp fae,此为判断tp是否有硬件问题。

二 软件

代码路径:

V:\mt6577\alps\mediatek\custom\common\kernel\touchpanel\nt11004\nt11004_driver.c

V:\mt6577\alps\mediatek\custom\basicom77_cu_ics2\kernel\touchpanel\nt11004\tpd_custom_nt11004.h

1 宏定义:

ProjectConfig.mk CUSTOM_KERNEL_TOUCHPANEL=nt11004

2 在dws中配置tp reset 和 int脚

3 跟相关tp原厂要份驱动代码,如果没有,就copy一份之前的,修改。

tp设备是通过module_init(tpd_driver_init)挂载到系统上的,tpd_driver_init中主要实现注册i2c设备和tp设备,具体挂载在哪一路i2c上需看原理图。

4 probe中申请int,创建tp时间处理线程,当有触摸时,tp产生中断,bb通过i2c总线读取相应的坐标,将坐标点传递给上层驱动。大致的流程图如下:

三 tp虚拟按键

目前智能机都采用全触控的方式实现手机的正常使用,故往往会用到tp做虚拟按键,下面也简单介绍下mtk tp虚拟按键的实现方式:

整个Android的Virtual key的整个的简单框图如下:

APP------->

          Framework------->

                         Kernel------->

                                      Hardware

struct tpd_driver_t

{

          char *tpd_device_name;

          int (*tpd_local_init)(void);

          void (*suspend)(struct early_suspend *h);

          void (*resume)(struct early_suspend *h);

          int tpd_have_button;

};

其中变量int tpd_have_button就是判断是否存在tp按键,如项目有使用tp虚拟按键,这在注册时须将此处的值设置为1,如:

static struct tpd_driver_t tpd_device_driver = {

     .tpd_device_name = NT11004_TS_NAME,

     .tpd_local_init = tpd_local_init,

     .suspend = tpd_suspend,

     .resume = tpd_resume,

#ifdef  TPD_HAVE_BUTTON

     .tpd_have_button = 1,

#else

     .tpd_have_button = 0,

#endif

}

tp 按键相关的驱动代码:

X:\MT6577\alps\mediatek\custom\common\kernel\touchpanel\src\tpd_button.c

//#ifdef TPD_HAVE_BUTTON

//static int tpd_keys[TPD_KEY_COUNT] = TPD_KEYS;

//static int tpd_keys_dim[TPD_KEY_COUNT][4] = TPD_KEYS_DIM;

static unsigned int tpd_keycnt = 0;

static int tpd_keys[TPD_VIRTUAL_KEY_MAX]={0};

static int tpd_keys_dim[TPD_VIRTUAL_KEY_MAX][4];// = {0};

static ssize_t mtk_virtual_keys_show(struct kobject *kobj,

                   struct kobj_attribute *attr, char *buf) {

    int i, j;

    for(i=0, j=0;i<tpd_keycnt;i++)

        j+=sprintf(buf, "%s%s:%d:%d:%d:%d:%d%s",buf,

           __stringify(EV_KEY),tpd_keys[i],

           tpd_keys_dim[i][0],tpd_keys_dim[i][1],

           tpd_keys_dim[i][2],tpd_keys_dim[i][3],

           (i==tpd_keycnt-1?"\n":":"));

    return j;

static struct kobj_attribute mtk_virtual_keys_attr = {

    .attr = {

        .name = "virtualkeys.mtk-tpd",

        .mode = S_IRUGO,

    },

    .show = &mtk_virtual_keys_show,

};

static struct attribute *mtk_properties_attrs[] = {

    &mtk_virtual_keys_attr.attr,

    NULL

};

static struct attribute_group mtk_properties_attr_group = {

    .attrs = mtk_properties_attrs,

};

void tpd_button_init(void) {

    int ret = 0, i = 0;

//    if((tpd->kpd=input_allocate_device())==NULL) return -ENOMEM;

    tpd->kpd=input_allocate_device();

    /* struct input_dev kpd initialization and registration */

    tpd->kpd->name = TPD_DEVICE "-kpd";

    set_bit(EV_KEY, tpd->kpd->evbit);

    //set_bit(EV_REL, tpd->kpd->evbit);

    //set_bit(EV_ABS, tpd->kpd->evbit);

    for(i=0;i<tpd_keycnt;i++)

        __set_bit(tpd_keys[i], tpd->kpd->keybit);

    tpd->kpd->id.bustype = BUS_HOST;

    tpd->kpd->id.vendor  = 0x0001;

    tpd->kpd->id.product = 0x0001;

    tpd->kpd->id.version = 0x0100;

    if(input_register_device(tpd->kpd))

        TPD_DMESG("input_register_device failed.(kpd)\n");

    set_bit(EV_KEY, tpd->dev->evbit);

    for(i=0;i<tpd_keycnt;i++)

        __set_bit(tpd_keys[i], tpd->dev->keybit);

    properties_kobj = kobject_create_and_add("board_properties", NULL);

    if(properties_kobj)

        ret = sysfs_create_group(properties_kobj,&mtk_properties_attr_group);

    if(!properties_kobj || ret)

    printk("failed to create board_properties\n");

}

在sys/board_properties/下创建一个叫virtualkeys.*节点;在frameworks/base/services/input下的文件EventHub.cpp中对这个节点进行访问;

如果采用以上方式注册tp虚拟按键,则需要在X:\MT6577\alps\mediatek\config\basicom_6462k有对应的mtk-kpd.kl中有对应虚拟按键的键值映射表。用adb shell 可以再/system/usr/keylayout目录下看到此文件。

EventHub.cpp中会检测是否有tp事件发生,如果tp坐标点值落在主次的虚拟按键virtualkeys.*中的话,则转成上次按键消息传递给上层。

四 tp接近的功能

此功能是在中断处理函数中通过调用ret = hwmsen_get_interrupt_data(ID_PROXIMITY, &sensor_data),更新psensor的数据,senosr处理模块polling时检测到有数据更新后将消息传递上hal层。代码请参考X:\MT6577\alps\kernel\mediatek\source\kernel\drivers\hwmon\hwmsen\hwmsen_dev.c

故此功能需保证驱动和hal都需要先注册上psensor相关的模块。

当一个模块需调用其他模块的函数或者变量时:可使用EXPORT_SYMBOL和EXPORT_SYMBOL_GPL来定义:

/proc/kallsyms”文件对应着内核符号表,记录了符号以及符号所在的内存地址。

模块可以使用如下宏导出符号到内核符号表:

1 EXPORT_SYMBOL(符号名);  

2 EXPORT_SYMBOL_GPL(符号名)  

导出的符号可以被其他模块使用,不过使用之前一定要声明一下。EXPORT_SYMBOL_GPL()只适用于包含GPL许可权的模块。

五 tp apk升级功能的实现方法

static int nvt_flash_init()

{         

     int ret=0;

       NVT_proc_entry = create_proc_entry(DEVICE_NAME, 0666, NULL);

     if(NVT_proc_entry == NULL)

     {

          TPD_DMESG("Couldn't create proc entry!\n");

          ret = -ENOMEM;

          return ret ;

     }

     else

     {

          TPD_DMESG("Create proc entry success!\n");

          NVT_proc_entry->proc_fops = &nvt_flash_fops;

     }

     flash_priv=kzalloc(sizeof(*flash_priv),GFP_KERNEL);    

     TPD_DMESG("============================================================\n");

     TPD_DMESG("NVT_flash driver loaded\n");

     TPD_DMESG("============================================================\n");    

     return 0;

error:

     if(ret != 0)

     {

          TPD_DMESG("flash_priv error!\n");

     }

     return -1;

}

通过create_proc_entry(DEVICE_NAME, 0666, NULL)创建一个虚拟的文件, 虚拟文件一方面可以向用户呈现内核中的一些信息,也可以用作一种从用户空间向内核发送信息的手段。故用户空间可直对该文件节点进行读写操作来控制内核驱动。我们可以通过

adbshell后再proc目录下看到我们创建的节点DEVICE_NAME。

struct file_operations nvt_flash_fops =

{

     .owner = THIS_MODULE,

     .open = nvt_flash_open,

     .release = nvt_flash_close,

     .write = nvt_flash_write,

     .read = nvt_flash_read,

};

当我们需要知道tp的一些信息,只需通过去读该虚拟文件,调用nvt_flash_read则可以知道,而tp升级是通过对虚拟文件进行写操作,调用nvt_flash_write将二进制文件fw通过i2c总线写到tp ic的rom中。

六 经常遇到一些问题

调试中遇到一些问题总结:

tp触摸按键没有功能

1 检查在sys/board_properties/是否有注册上相关节点

2 检查kl文件的键值映射表

tp触摸无效:

1 硬件量int是否有中断产生

2 tp address是否正确,i2c时候有ack
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: