MT6573驱动开发日志之touchpanel.docx
- 文档编号:4310899
- 上传时间:2022-11-29
- 格式:DOCX
- 页数:14
- 大小:19.88KB
MT6573驱动开发日志之touchpanel.docx
《MT6573驱动开发日志之touchpanel.docx》由会员分享,可在线阅读,更多相关《MT6573驱动开发日志之touchpanel.docx(14页珍藏版)》请在冰豆网上搜索。
MT6573驱动开发日志之touchpanel
MT6573驱动开发日志之touchpanel
1)添加一款TOUCHPANEL
在projectConfig.mk文件里面修改如下:
CUSTOM_KERNEL_TOUCHPANEL=cy8ctma300
在mediatek\custom\common\kernel\touchpanel文件夹添加文件夹如下:
mediatek\custom\common\kernel\touchpanel\cy8ctma300.c
(2)源码分析
1)我们知道linux内核,添加驱动的初始化函数,大都是通过宏module_init;添加退出函数大都通过宏module_exit,具体这两个宏的作用,我这里就不细说了。
例如:
module_init(tpd_driver_init);
module_exit(tpd_driver_exit);
2)下面分析这个初始化函数和退出函数
/*calledwhenloadedintokernel*/
staticint__inittpd_driver_init(void)
{
if(tpd_driver_add(&tpd_device_driver)<0)
TPD_DMESG("addgenericdriverfailed\n");
return0;
}
/*shouldneverbecalled*/
staticvoid__exittpd_driver_exit(void)
{
tpd_driver_remove(&tpd_device_driver);
}
可以看出分别是添加和移除tpd驱动
3)再接着分析tpd_driver_init和tpd_driver_exit
inttpd_driver_add(structtpd_driver_t*tpd_drv)
{
inti;
if(g_tpd_drv!
=NULL)
{
TPD_DMESG("touchdriverexist\n");
return-1;
}
/*checkparameter*/
if(tpd_drv==NULL)
{
return-1;
}
/*R-touch*/
if(strcmp(tpd_drv->tpd_device_name,"generic")==0)
{
tpd_driver_list[0].tpd_device_name=tpd_drv->tpd_device_name;
tpd_driver_list[0].tpd_local_init=tpd_drv->tpd_local_init;
tpd_driver_list[0].suspend=tpd_drv->suspend;
tpd_driver_list[0].resume=tpd_drv->resume;
tpd_driver_list[0].tpd_have_button=tpd_drv->tpd_have_button;
return0;
}
for(i=1;i { /*addtpddriverintolist*/ 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; #if0 if(tpd_drv->tpd_local_init()==0) { TPD_DMESG("load%ssucessfully\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) { return1;//driverexist } } return0; } inttpd_driver_remove(structtpd_driver_t*tpd_drv) { inti=0; /*checkparameter*/ if(tpd_drv==NULL) { return-1; } for(i=0;i { /*findit*/ if(strcmp(tpd_driver_list[i].tpd_device_name,tpd_drv->tpd_device_name)==0) { memset(&tpd_driver_list[i],0,sizeof(structtpd_driver_t)); break; } } return0; } 可以看出主要是把当前的驱动从数组tpd_driver_list加进或者移出,这里我们发现一个重点的结构体 structtpd_driver_t { char*tpd_device_name; int(*tpd_local_init)(void); void(*suspend)(structearly_suspend*h); void(*resume)(structearly_suspend*h); inttpd_have_button; }; 下面我们接着分析如何初始化这个结构体 staticstructtpd_driver_ttpd_device_driver={ .tpd_device_name="cy8ctma300", .tpd_local_init=tpd_local_init, .suspend=tpd_suspend, .resume=tpd_resume, #ifdefTPD_HAVE_BUTTON .tpd_have_button=1, #else .tpd_have_button=0, #endif 4)接下来就看上面三个函数是如何实现的 inttpd_local_init(void) { if(tpd_em_debuglog==1){ TPD_DMESG("[mtk-tpd]%s\n",__FUNCTION__); } if(i2c_add_driver(&tpd_i2c_driver)! =0){ TPD_DMESG("unabletoaddi2cdriver.\n"); return-1; } if(tpd_load_status==0) { TPD_DMESG("adderrortouchpaneldriver.\n"); i2c_del_driver(&tpd_i2c_driver); return-1; } #ifdefTPD_HAVE_BUTTON tpd_button_setting(TPD_KEY_COUNT,tpd_keys_local,tpd_keys_dim_local);//initializetpdbuttondata #endif #if(defined(TPD_WARP_START)&&defined(TPD_WARP_END)) TPD_DO_WARP=1; memcpy(tpd_wb_start,tpd_wb_start_local,TPD_WARP_CNT*4); memcpy(tpd_wb_end,tpd_wb_start_local,TPD_WARP_CNT*4); #endif #if(defined(TPD_HAVE_CALIBRATION)&&! defined(TPD_CUSTOM_CALIBRATION)) memcpy(tpd_calmat,tpd_calmat_local,8*4); memcpy(tpd_def_calmat,tpd_def_calmat_local,8*4); #endif TPD_DMESG("end%s,%d\n",__FUNCTION__,__LINE__); tpd_type_cap=1; return0; } 这里面核心的就是i2c_add_driver,添加一个I2C设备 /*Functiontomanagelowpowersuspend*/ voidtpd_suspend(structearly_suspend*h) { if(tpd_em_debuglog==1){ TPD_DMESG("[mtk-tpd]%s\n",__FUNCTION__); } tpd_halt=1; while (1){ if(tpd_flag==1)msleep(1000); elsebreak; } mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM); #ifdefTPD_HAVE_POWER_ON_OFF mt_set_gpio_mode(GPIO_CTP_EN_PIN,GPIO_CTP_EN_PIN_M_GPIO); mt_set_gpio_dir(GPIO_CTP_EN_PIN,GPIO_DIR_OUT); mt_set_gpio_out(GPIO_CTP_EN_PIN,GPIO_OUT_ZERO); //msleep (1); mdelay (1); mt_set_gpio_mode(GPIO_CTP_RST_PIN,GPIO_CTP_RST_PIN_M_GPIO); mt_set_gpio_dir(GPIO_CTP_RST_PIN,GPIO_DIR_OUT); mt_set_gpio_out(GPIO_CTP_RST_PIN,GPIO_OUT_ZERO); #endif } 通过GPIO,挂起,使TPD不起作用 /*Functiontomanagepower-onresume*/ voidtpd_resume(structearly_suspend*h) { if(tpd_em_debuglog==1){ TPD_DMESG("[mtk-tpd]%s\n",__FUNCTION__); } #ifdefTPD_HAVE_POWER_ON_OFF //msleep(100); mt_set_gpio_mode(GPIO_CTP_EN_PIN,GPIO_CTP_EN_PIN_M_GPIO); mt_set_gpio_dir(GPIO_CTP_EN_PIN,GPIO_DIR_OUT); mt_set_gpio_out(GPIO_CTP_EN_PIN,GPIO_OUT_ONE); msleep (1); mt_set_gpio_out(GPIO_CTP_RST_PIN,GPIO_OUT_ZERO); msleep (1); mt_set_gpio_out(GPIO_CTP_RST_PIN,GPIO_OUT_ONE); msleep(100); #endif mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); tpd_halt=0; } 通过GPIO,恢复,使TPD起作用 5)下面看看I2C设备是如何被初始化的 structi2c_drivertpd_i2c_driver={ .probe=tpd_i2c_probe, .remove=tpd_i2c_remove, .detect=tpd_i2c_detect, .driver.name="mtk-tpd", .id_table=tpd_i2c_id, .address_data=&addr_data, }; 6)下面下面接着分析三个I2C函数 staticinttpd_i2c_detect(structi2c_client*client,intkind,structi2c_board_info*info){ strcpy(info->type,"mtk-tpd"); return0; } staticinttpd_i2c_remove(structi2c_client*client){return0;} staticinttpd_i2c_probe(structi2c_client*client,conststructi2c_device_id*id){ interr=0; charbuffer[2]; intstatus=0; i2c_client=client; #ifdefTPD_NO_GPIO u16temp; temp=*(volatileu16*)TPD_RESET_PIN_ADDR; temp=temp|0x40; *(volatileu16*)TPD_RESET_PIN_ADDR=temp; #endif #ifndefTPD_NO_GPIO mt_set_gpio_mode(GPIO_CTP_RST_PIN,GPIO_CTP_RST_PIN_M_GPIO); mt_set_gpio_dir(GPIO_CTP_RST_PIN,GPIO_DIR_OUT); mt_set_gpio_out(GPIO_CTP_RST_PIN,GPIO_OUT_ZERO); msleep(10); mt_set_gpio_mode(GPIO_CTP_EN_PIN,GPIO_CTP_EN_PIN_M_GPIO); mt_set_gpio_dir(GPIO_CTP_EN_PIN,GPIO_DIR_OUT); mt_set_gpio_out(GPIO_CTP_EN_PIN,GPIO_OUT_ONE); // mt_set_gpio_mode(GPIO_CTP_RST_PIN,GPIO_CTP_RST_PIN_M_GPIO); // mt_set_gpio_dir(GPIO_CTP_RST_PIN,GPIO_DIR_OUT); // mt_set_gpio_out(GPIO_CTP_RST_PIN,GPIO_OUT_ONE); // msleep(10); mt_set_gpio_out(GPIO_CTP_RST_PIN,GPIO_OUT_ZERO); msleep (1); mt_set_gpio_out(GPIO_CTP_RST_PIN,GPIO_OUT_ONE); mt_set_gpio_mode(GPIO_CTP_EINT_PIN,GPIO_CTP_EINT_PIN_M_EINT); mt_set_gpio_dir(GPIO_CTP_EINT_PIN,GPIO_DIR_IN); mt_set_gpio_pull_enable(GPIO_CTP_EINT_PIN,GPIO_PULL_ENABLE); mt_set_gpio_pull_select(GPIO_CTP_EINT_PIN,GPIO_PULL_UP); #endif msleep(50); status=i2c_smbus_read_i2c_block_data(i2c_client,0x00,1,&(buffer[0])); if(status<0) { TPD_DMESG("[mtk-tpd],cy8ctma300tpd_i2c_probefailed! ! \n"); status=i2c_smbus_read_i2c_block_data(i2c_client,0x00,1,&(buffer[0])); if(status<0){ TPD_DMESG("[mtk-tpd],cy8ctma300tpd_i2c_proberetryfailed! ! \n"); returnstatus; } } TPD_DMESG("[mtk-tpd],cy8ctma300tpd_i2c_probesuccess! ! \n"); tpd_load_status=1; if((buffer[0]&0x70)! =0x00){ buffer[0]=0x00;//switchtooperationmode i2c_smbus_write_i2c_block_data(i2c_client,0x00,1,&(buffer[0])); msleep(50); } thread=kthread_run(touch_event_handler,0,TPD_DEVICE); if(IS_ERR(thread)){ err=PTR_ERR(thread); TPD_DMESG(TPD_DEVICE"failedtocreatekernelthread: %d\n",err); } mt65xx_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM,CUST_EINT_TOUCH_PANEL_SENSITIVE); mt65xx_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM,CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN); mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM,CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN,CUST_EINT_TOUCH_PANEL_POLARITY,tpd_eint_interrupt_handler,1); mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); return0; } 7)我们发现这个函数是主要函数 主要实现了配置TPD中断的GPIO口,I2C读写数据,设置中断相关函数,如下 mt65xx_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM,CUST_EINT_TOUCH_PANEL_SENSITIVE); mt65xx_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM,CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN); mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM,CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN,CUST_EINT_TOUCH_PANEL_POLARITY,tpd_eint_interrupt_handler,1); mt65xx_ei
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MT6573 驱动 开发 日志 touchpanel