在智能设备上,tp一般随lcd休眠,这样可以减少整机功耗,防止tp误触。也就是说,按下电源键熄屏后,lcd会走休眠流程,该过程lcd会发通知lcd已经进入休眠了,由于tp驱动中注册了lcd内核通知链,tp也随之进入休眠。按电源键唤醒后,lcd唤醒了,tp也随之唤醒。如
#if defined(CONFIG_FB)
INIT_WORK(&data->fb_notify_work, fb_notify_resume_work);
data->fb_notif.notifier_call = fb_notifier_callback;
err = fb_register_client(&data->fb_notif);
#endif
#if defined(CONFIG_FB)
static void fb_notify_resume_work(struct work_struct *work)
{
struct ft5x06_ts_data *ft5x06_data =
container_of(work, struct ft5x06_ts_data, fb_notify_work);
ft5x06_ts_resume(&ft5x06_data->client->dev);
}
static int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data)
{
struct fb_event *evdata = data;
int *blank;
struct ft5x06_ts_data *ft5x06_data =
container_of(self, struct ft5x06_ts_data, fb_notif);
if (evdata && evdata->data && ft5x06_data && ft5x06_data->client) {
blank = evdata->data;
if (ft5x06_data->pdata->resume_in_workqueue) {
if (event == FB_EARLY_EVENT_BLANK &&
*blank == FB_BLANK_UNBLANK)
schedule_work(&ft5x06_data->fb_notify_work);
else if (event == FB_EVENT_BLANK &&
*blank == FB_BLANK_POWERDOWN) {
flush_work(&ft5x06_data->fb_notify_work);
ft5x06_ts_suspend(&ft5x06_data->client->dev);
}
} else {
if (event == FB_EVENT_BLANK) {
if (*blank == FB_BLANK_UNBLANK)
ft5x06_ts_resume(
&ft5x06_data->client->dev);
else if (*blank == FB_BLANK_POWERDOWN)
ft5x06_ts_suspend(
&ft5x06_data->client->dev);
}
}
}
return 0;
}
#endif
由于某些tp上存在物理按键,这样熄屏后台播放音乐便无法使用按键(调节音量),可以改写tp驱动,让tp作为一个普通驱动,走正常的suspend和resume流程,并屏蔽tp坐标点的汇报(放置误触),只保留按键的汇报,这样就可调节音量了 。
某些tp的resume执行时间过长,会导致整机唤醒时间加长(所有resume函数跑完才真正唤醒),这时可采取工作队列来实现唤醒,减少整机唤醒时间。