原文地址:http://blog.chinaunix.net/uid-26009923-id-3999758.html
MTK6577---touch驱动分析
Resistance screen 电阻屏
Capacitive screen 电容屏
1. 在ProjectConfig.mk中配置touch
mediatek/config/mobitek77_m01_ics2/ProjectConfig.mk
CUSTOM_KERNEL_TOUCHPANEL=mtk_gslX680
2. touch驱动初始化
在mediatek/custom/common/kernel/touchpanel/mtk_gslX680/mtk_gslX680.c中
-
module_init(tpd_driver_init);
-
{
-
tpd_driver_add
-
{
-
i2c_register_board_info(0, &gslX680_i2c_tpd, 1); //注册i2c信息
-
//将tpd_device_driver中的函数指针,注册到tpd_driver_list中
-
tpd_driver_add(&tpd_device_driver);
-
}
-
}
在mediatek/custom/common/kernel/touchpanel/src/mtk_tpd.c中
module_init(tpd_device_init);
--> platform_driver_register(&tpd_driver)
--> tpd_driver->tpd_probe
-
static int tpd_probe(struct platform_device *pdev)
-
{
-
a. 申请分配内存 tpd_device tpd
-
b. 申请分配内存 tpd->dev=input_allocate_device();
-
c. set_bit
-
d. tpd_driver_list[i].tpd_local_init();
-
{
-
i2c_add_driver(); //注册i2c设备,并调用probe函数
-
--> tpd_probe(); //注意这个probe是在i2c_add_driver时会被调用
-
}
-
e. tpd_i2c_probe 被i2c_add_driver调用
-
{
-
hwPowerOn(MT65XX_POWER_LDO_VGP2, VOL_2800, "TP");
-
hwPowerOn(MT65XX_POWER_LDO_VGP, VOL_1800, "TP");
-
设置gpio引脚: GPIO_CTP_RST_PIN 与 GPIO_CTP_EINT_PIN
-
init_chip //下载fw,reset, startup_chip等芯片初使化
-
注册中断句柄: tpd_eint_interrupt_handler
-
启动线程touch_event_handler,等侍wait_event_interruptible(waiter, tpd_flag != 0);
-
}
-
f. g_tpd_drv = &tpd_driver_list[i]; //即:初始化g_tpd_drv
-
}
3.中断处理流程
当有中断发生时进入中断处理函数,设两个标志,并唤醒等侍队列
-
void tpd_eint_interrupt_handler(void)
-
{
-
eint_flag = 1;
-
tpd_flag=1;
-
wake_up_interruptible(&waiter);
-
}
线程一直在等侍唤醒中,收到信号后,结束等侍,并执行下一条代码
-
static int touch_event_handler(void *unused)
-
{
-
struct sched_param param = { .sched_priority = RTPM_PRIO_TPD };
-
sched_setscheduler(current, SCHED_RR, ¶m);
-
do
-
{
-
mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); //一上来先清中断
-
set_current_state(TASK_INTERRUPTIBLE);
-
wait_event_interruptible(waiter, tpd_flag != 0); //收到唤醒信号,结束等侍,执行下一条代码
-
tpd_flag = 0; //清标志位
-
set_current_state(TASK_RUNNING); //设置状态
-
eint_flag = 0; //清标志位
-
report_data_handle(); //向上层报告数据
-
} while (!kthread_should_stop());
-
return 0;
-
}
touch_event_handler
--> report_data_handle
-
static void report_data_handle(void)
-
{
-
1. 从i2c中读取数据,并解析出每个点的(x,y)坐标,可能有多个
-
2. record_point(x, y , id);
-
tpd_down(id, x_new, y_new, 10);
-
{
-
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_report_abs(tpd->dev, ABS_MT_TRACKING_ID, id);
input_mt_sync(tpd->dev); //每一个点都要发送input_mt_sync
-
}
-
id_state_flag[id] = 1;
-
if(0 == point_num) //如果当前的finger变为0,就要发送btn_up
{
input_report_key(tpd->dev, BTN_TOUCH, 0);
input_mt_sync(tpd->dev);
}
-
input_sync(tpd->dev); //所有点都发送完成后,发送input_sync
-
}
阅读(1236) | 评论(0) | 转发(0) |