首先调用suspend之后
static void focal_suspend_work(struct work_struct *work)
{
uint8_t buf[2] = {0};
int i;
struct ftxxxx_ts_data *ts = ftxxxx_ts;
suspend_resume_process = true;
mutex_lock(&ftxxxx_ts->g_device_mutex);
if (ftxxxx_ts->suspend_flag) {
focal_debug(DEBUG_VERBOSE, "[Focal][Touch]--->[Focal][Touch] IC in suspend !! \n");
mutex_unlock(&ftxxxx_ts->g_device_mutex);
suspend_resume_process = false;
return;
}
dclick_flags=true;
if ((ftxxxx_ts->dclick_mode_eable == true) || (ftxxxx_ts->gesture_mode_eable == true)) { 如果进入了dclick_mode或者gesture_mode
printk(KERN_EMERG "[Focal][Touch] %s : Touch gesture mode \n", __func__);
enable_irq_wake(ftxxxx_ts->client->irq);
ftxxxx_write_reg(ts->client, 0xd0, 0x01);
if (ftxxxx_ts->dclick_mode_eable == true) {
printk(KERN_EMERG "[Focal][Touch] %s : open dclick mode \n", __func__);
ftxxxx_write_reg(ts->client, 0xd1, 0x10);
}
if (ftxxxx_ts->gesture_mode_eable == true) {
if (ftxxxx_ts->dclick_mode_eable == true)
ftxxxx_write_reg(ts->client, 0xd1, 0x30);
else
ftxxxx_write_reg(ts->client, 0xd1, 0x20);
ftxxxx_write_reg(ts->client, 0xd2, FTS_gesture_register_d2);
ftxxxx_write_reg(ts->client, 0xd5, FTS_gesture_register_d5);
ftxxxx_write_reg(ts->client, 0xd6, FTS_gesture_register_d6);
ftxxxx_write_reg(ts->client, 0xd7, FTS_gesture_register_d7); //<asus-Jeffery20150427+>
}
Gesture_flag=1; //置位Gesture_flag
{
u8 FTS_gesture_register_d1;
u8 FTS_gesture_register_d0;
ftxxxx_read_reg(ts->client, 0xd1, &FTS_gesture_register_d1);
ftxxxx_read_reg(ts->client, 0xd0, &FTS_gesture_register_d0);
printk("[Focal][Touch]suspend FTS_gesture_register_d0=0x%x\n",FTS_gesture_register_d0);
printk("[Focal][Touch]suspend FTS_gesture_register_d1=0x%x\n",FTS_gesture_register_d1);
}
} else { //如果没有设置那些mode,那么进入深度睡眠模式
ftxxxx_irq_disable(ts->client);
printk(KERN_EMERG "1[Focal][Touch] %s : Touch suspend and disable touch\n", __func__);
buf[0] = 0xA5;
buf[1] = 0x03;
ftxxxx_write_reg(ftxxxx_ts->client, buf[0], buf[1]);
}
for(i=0;i<CFG_MAX_TOUCH_POINTS;i++)
{
input_mt_slot(ftxxxx_ts->input_dev, i);
input_mt_report_slot_state(ftxxxx_ts->input_dev, MT_TOOL_FINGER, 0);
}
input_mt_report_pointer_emulation(ftxxxx_ts->input_dev, false);
input_sync(ftxxxx_ts->input_dev);
ftxxxx_ts->suspend_flag = 1; //置位suspend模式
mutex_unlock(&ftxxxx_ts->g_device_mutex);
suspend_resume_process = false;
printk(KERN_EMERG "[Focal][Touch] %s : Touch suspend --- \n", __func__);
return;
}
而resume的时候
static void focal_resume_work(struct work_struct *work)
{
uint8_t buf[2] = {0};
struct ftxxxx_ts_data *ts = ftxxxx_ts;
suspend_resume_process = true;
disable_tp_flag=false;
wake_lock(&ftxxxx_ts->wake_lock);
mutex_lock(&ftxxxx_ts->g_device_mutex);
if (!ftxxxx_ts->suspend_flag) { //如果没有在suspend状态就return
mutex_unlock(&ftxxxx_ts->g_device_mutex);
wake_unlock(&ftxxxx_ts->wake_lock);
suspend_resume_process = false;
return;
}
if ((ftxxxx_ts->dclick_mode_eable == true) ||(ftxxxx_ts->gesture_mode_eable == true)) {
if (ftxxxx_ts->reset_pin_status == 1) {
printk("[Focal][Touch] %s : Touch resume from gesture mode \n", __func__);
disable_irq_wake(ts->client->irq);
gpio_set_value(ts->pdata->rst_gpio, 0);
msleep(20);
gpio_set_value(ts->pdata->rst_gpio, 1);
msleep(80);
asus_check_touch_mode();
if (ts->glove_mode_eable == true) {
buf[0] = 0xC0;
buf[1] = 0x01;
ftxxxx_write_reg(ftxxxx_ts->client, buf[0], buf[1]);
}
ftxxxx_write_reg(ts->client, 0xD0, 0x00);
ftxxxx_irq_enable(ts->client);
if(ftxxxx_ts->cover_mode_states == false)
{
ftxxxx_write_reg(ftxxxx_ts->client,0xC3,0);//the filp cover is open
printk("[Focal][Touch] the filp cover is open in resume! \n");
}
} else {
printk("[Focal][Touch] %s : ftxxxx_ts->reset_pin_status set to 0 ! skip reset IC \n", __func__);
}
Gesture_flag=0;
{
u8 FTS_gesture_register_d1;
u8 FTS_gesture_register_d0;
ftxxxx_read_reg(ts->client, 0xd1, &FTS_gesture_register_d1);
ftxxxx_read_reg(ts->client, 0xd0, &FTS_gesture_register_d0);
}
ftxxxx_irq_enable(ts->client);
} else {
if (ftxxxx_ts->reset_pin_status == 1) {
printk("[Focal][Touch] %s : Touch resume from sleep mode \n", __func__);
gpio_set_value(ts->pdata->rst_gpio, 0); //reset ic 所以会导致iic前几次通信失败
msleep(20);
gpio_set_value(ts->pdata->rst_gpio, 1);
msleep(80);
asus_check_touch_mode();
if (ts->glove_mode_eable == true) {
buf[0] = 0xC0;
buf[1] = 0x01;
ftxxxx_write_reg(ftxxxx_ts->client, buf[0], buf[1]);
}
buf[0] = 0xA5;
buf[1] = 0x00;
ftxxxx_write_reg(ftxxxx_ts->client, buf[0], buf[1]);
ftxxxx_irq_enable(ts->client);
} else {
ftxxxx_irq_enable(ts->client);
}
ftxxxx_write_reg(ftxxxx_ts->client,0xC3,0);//the filp cover is open
}
ftxxxx_ts->suspend_flag = 0;
mutex_unlock(&ftxxxx_ts->g_device_mutex);
wake_unlock(&ftxxxx_ts->wake_lock);
suspend_resume_process = false;
return;
}
而上层调用节点设置皮套模式的时候
static ssize_t flip_cover_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int tmp = 0;
tmp = buf[0] - 48;
wake_lock(&ftxxxx_ts->wake_lock);
mutex_lock(&ftxxxx_ts->g_device_mutex);
if (tmp == 0) {
ftxxxx_ts->cover_mode_states = false;
if ((ftxxxx_ts->dclick_mode_eable == true) ||(ftxxxx_ts->gesture_mode_eable == true)) //这是一个办法,在开了两个mode的情况下不去操作这两个寄存器
{
ftxxxx_write_reg(ftxxxx_ts->client,0xC3,0);//the filp cover is open //会在这里操作寄存器
}
} else if (tmp == 1) {
ftxxxx_ts->cover_mode_states = true;
ftxxxx_write_reg(ftxxxx_ts->client,0xC1,1);
ftxxxx_write_reg(ftxxxx_ts->client,0xC3,2);//the flip cover is close
printk("[Focal][Touch] the flip cover is close ! \n");
}
mutex_unlock(&ftxxxx_ts->g_device_mutex);
wake_unlock(&ftxxxx_ts->wake_lock);
return count;
}
总的说问题就在与如果在suspend的时候让ic进入sleep模式那么cover mode一开始和ic通信会fail,所以要想缩短唤醒时间只能在suspend的时候不让ic sleep,同时在resume的时候不要reset
打开皮套,要Driver 要Call TP 进皮套模式,不能做A5 写3, Driver 写法要跟打开手势Mode的写法一样。
A5 写3是关闭function, 进入深度Sleep, 只有Reset 或on/off power 才能恢复工作模式。
另外:
我们FT5X46 TP功耗有3种状态:
1. Active mode: 手指触摸的全速工作active mode 约耗电流15 mA(跟屏体通道数和Report rate 有关)
2. Monitor mode手指没有触摸,空闲数秒后,进入Monitor mode, 耗电流约0.7 mA.
3. Sleep mode: A5 写3 进入Sleep mode ,功耗电流 只有30~40 uA.