8、TSP功耗优化:休眠唤醒机制、低功耗模式、动态频率调整
各位做触控的同行,大家好。今天我们来聊聊TSP的功耗优化。说实话,功耗问题在手机整机调试中,往往是最后才被重视的——但一旦出了问题,就是大问题。我见过不少项目,功能都调通了,结果一测待机电流,多了好几毫安,查来查去,最后发现是触控IC没睡好。
功耗优化说白了就三件事:什么时候睡、怎么睡、醒了怎么跑。下面我们一个一个说。
8.1 休眠唤醒机制:让触控IC学会“闭眼”
触控IC的休眠唤醒,核心思路很简单:屏幕不亮的时候,IC就别全功率工作了。但这里有个矛盾——你睡着了,用户摸一下屏幕,你得能醒过来。所以休眠不是彻底断电,而是进入一种“半梦半醒”的状态。
我习惯把休眠唤醒分成三个等级:
- 浅度休眠(Idle):扫描频率降低,比如从120Hz降到10Hz。手指放上去能快速唤醒,但功耗降得有限。
- 深度休眠(Sleep):几乎停止所有扫描,只保留一个极低功耗的“唤醒检测”电路。功耗可以降到微安级别。
- 关机(Power Down):彻底断电,唤醒需要系统重新初始化。这个一般不常用,因为唤醒太慢。
实际项目中,我们通常用深度休眠。我记得有一次调试一个项目,待机电流总是比竞品高0.5mA。查了半天,发现是触控IC在屏幕灭掉后,还在以30Hz的频率扫描。改成深度休眠后,电流直接降下来了。
关键点:休眠唤醒的触发时机,通常由系统框架控制。Android里通过early_suspend或input_suspend通知驱动。驱动收到通知后,调用触控IC的休眠指令。
驱动里大概是这样做的:
static int tsp_suspend(struct device *dev) {
struct tsp_data *data = dev_get_drvdata(dev);
// 通知IC进入深度休眠
tsp_i2c_write(data->client, CMD_SLEEP, 0x01);
// 关闭中断,避免误唤醒
disable_irq(data->irq);
return 0;
}
static int tsp_resume(struct device *dev) {
struct tsp_data *data = dev_get_drvdata(dev);
// 唤醒IC
tsp_i2c_write(data->client, CMD_WAKEUP, 0x01);
// 重新使能中断
enable_irq(data->irq);
return 0;
}
嗯,这里要注意:唤醒后一定要等IC稳定了再开中断。我曾经遇到过唤醒后立即上报误触,导致手机在口袋里自动拨号。后来加了个10ms的延迟,问题就解决了。
8.2 低功耗模式:精细化的“省电策略”
休眠唤醒是粗粒度的控制,低功耗模式则是细粒度的。说白了,就是在IC工作时,怎么让它更省电。
常见的低功耗模式有这几种:
| 模式 | 原理 | 适用场景 | 功耗降低 |
|---|---|---|---|
| 间断扫描 | 扫描一阵,停一阵 | 待机、无操作 | 30%~50% |
| 降电压 | 降低驱动电压 | 低噪声环境 | 10%~20% |
| 降通道数 | 只扫描部分通道 | 边缘区域检测 | 20%~40% |
| 降分辨率 | 降低ADC采样精度 | 非精确触摸场景 | 5%~10% |
我个人习惯的做法是:根据场景动态切换。比如用户正在看视频,手指没动,那就用间断扫描+降电压。用户开始打字了,立刻切回全速模式。
小技巧:很多触控IC支持“手势唤醒”,比如双击亮屏。这种模式下,IC只扫描特定区域(比如屏幕中央),功耗极低。我建议在项目中尽量用这个功能,用户体验好,功耗也低。
8.3 动态频率调整:按需分配“算力”
动态频率调整,英文叫Dynamic Frequency Scaling,简称DFS。这个思路其实和CPU的调频很像——负载高的时候跑快点,负载低的时候跑慢点。
触控IC的扫描频率,直接决定了功耗。120Hz扫描和60Hz扫描,功耗差一倍。但问题是,你不能一直用60Hz,因为用户滑动的时候会感觉卡顿。
所以我们需要一个策略:
- 无触摸时:降到最低频率(比如10Hz),只做唤醒检测。
- 有触摸但静止:用中等频率(比如60Hz),保证响应速度。
- 滑动/多点触摸:用最高频率(比如120Hz),保证流畅度。
驱动里实现这个逻辑,我一般用一个状态机:
enum tsp_freq_state {
FREQ_IDLE, // 无触摸
FREQ_TOUCH, // 有触摸
FREQ_ACTIVE, // 滑动/多点
};
static void tsp_update_freq(struct tsp_data *data) {
switch (data->freq_state) {
case FREQ_IDLE:
tsp_set_scan_rate(data, 10); // 10Hz
break;
case FREQ_TOUCH:
tsp_set_scan_rate(data, 60); // 60Hz
break;
case FREQ_ACTIVE:
tsp_set_scan_rate(data, 120); // 120Hz
break;
}
}
这里有个坑:频率切换不能太频繁。你想想看,如果用户手指稍微抖一下,频率就从120Hz降到60Hz再升回去,反而会引入延迟。我一般会加一个滞回逻辑——比如连续100ms没有滑动,才降频。
避坑指南:我曾经在一个项目里,把频率切换阈值设得太灵敏。结果用户在玩游戏时,手指快速点击,频率一直在60Hz和120Hz之间跳,导致触摸响应忽快忽慢。后来改成“连续5个采样点无位移才降频”,问题就解决了。
8.4 知识体系总览
下面这张图,是我自己总结的TSP功耗优化整体框架。你可以把它当作一个检查清单:
这张图把三个模块的关系理清楚了。你实际做项目的时候,可以对照着看:休眠唤醒是“开关”,低功耗模式是“档位”,动态频率是“油门”。三者配合好了,功耗自然就降下来了。
好了,关于TSP功耗优化,我就讲这么多。记住一点:功耗优化不是一锤子买卖,它需要你在项目各个阶段反复调优。多测、多试、多总结,慢慢就有感觉了。
公众号:蓝海资料掘金营,微信deep3321