一、屏幕唤醒流程
这部分一开始我也不是很懂,然后百度一下,发现这哥们写得不错,所以这部分内容参考一下这个网址
http://blog.csdn.net/shadow_dance/article/details/8070252
二、触摸唤醒屏幕思路
1.让系统在休眠的时候,不要sleep触摸屏
2.在触摸屏驱动上屏触摸数据时,先判断是否处于休眠状态,是的话就上报一个power按键事件,这样就可以唤醒屏幕了
三、修改驱动
首先修改,让系统在休眠的时候,不要sleep触摸屏
先看一下kernel/kernel/power/earlysuspend.c 的以下函数
休眠时会调用这个
static void early_suspend(struct work_struct *work)
{
......
if (debug_mask & DEBUG_SUSPEND)
pr_info("early_suspend: call handlers\n");
//这里是遍历所有需要休眠的设备
list_for_each_entry(pos, &early_suspend_handlers, link) {
if (pos->suspend != NULL) {
if (debug_mask & DEBUG_VERBOSE){
pr_info("early_suspend: calling %pf\n", pos->suspend);
starttime = ktime_get();
}
pos->suspend(pos); //执行休眠动作,最终会调用到这个函数
......
}
唤醒会调用
static void late_resume(struct work_struct *work)
{
......
if (debug_mask & DEBUG_SUSPEND)
pr_info("late_resume: call handlers\n");
pm_wd_enable();
list_for_each_entry_reverse(pos, &early_suspend_handlers, link) {
if (pos->resume != NULL) {
if (debug_mask & DEBUG_VERBOSE){
pr_info("late_resume: calling %pf\n", pos->resume);
starttime = ktime_get();
}
pos->resume(pos); //执行唤醒动作,最终会调用到这个函数
......
}
这时候我们就相应的找出触摸驱动里的pos->suspend(pos)和pos->resume(pos) 指向的函数即可,找下驱动很容易就发现了 以下代码
(说明下,我用的 是gt9xx.c的驱动)
static s8 gtp_request_input_dev(struct goodix_ts_data *ts)
{
......
ts->early_suspend.suspend = goodix_ts_early_suspend; //休眠时调用这个函数
ts->early_suspend.resume = goodix_ts_late_resume; //唤醒时调用这个函数
register_early_suspend(&ts->early_suspend); //调用了这个注册,就会在刚才那里遍历到这个设备
......
}
所以只要屏蔽掉register_early_suspend(&ts->early_suspend)这个函数,就可以让触摸屏在休眠时也能工作,上报触摸信息
修改为屏蔽,编译,烧写,果然是和预想的结果一样,但是,这里不能这样修改,为什么呢,因为我们还要靠这两个goodix_t s_early_suspend和goodix_ts_late_resume 来获取系统是否休眠的状态,当然也还有别的方法可以获取(比如读取/sys/powe r/state 这个节点的状态,又或者读取屏幕亮度值)但是我觉得这种方法是最简单的,所以我选择不屏蔽,而是修改goodix_t s_early_suspend和goodix_ts_late_resume这两个函数,让两个函数什么都不做,直接设置一个休眠的标志sleepFlag;,当然sleepFlag这个是自己定义的一个变量。
接下来就修改驱动上报的函数,其实也就是 判断是否处于休眠状态,是的话就上报一个power按键事件
static void goodix_ts_work_func(struct work_struct *work)
{
......
//这段代码添加在读取完数据之后,上报触摸信息之前,如果在上报触摸信息之后,会有一些误触的可能,
if(sleepFlag == 0)//wake up the system
{
sleepFlag = 1;
//这里上报一个power按键事件
input_report_key(ts->input_dev, 116, 1);
input_sync(ts->input_dev);
input_report_key(ts->input_dev, 116, 0);
input_sync(ts->input_dev);
return;
}
......
}
这里面还有一些初始按键事件的细节,可以参考其它类似代码,到此,修改成功!