gt9x双击唤醒屏幕

出现I2C通信失败问题
在这里插入图片描述

里面可以看到irq 和 rst的gpio引脚从设备树获取失败,导致无法按照手册规定初始化上电时序设置I2C地址(GT的触摸芯片是通过初始时序来决定I2C地址),排查设备树发现是GPIO属性名写错了:

修改之后如下:

&i2c1 {
	status = "okay";
	goodix_ts@5d {
		compatible = "goodix,gt9xx";
		reg = <0x5d>;
		// tp-size = <89>;
		touchscreen-size-x = <1280>;
		touchscreen-size-y = <800>;
		// pinctrl-0 = <&touch_gpio>;
		irq-gpios = <&gpio1 RK_PA0 IRQ_TYPE_LEVEL_LOW>;
		reset-gpios	= <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>;
		irq-flags = <2>;
		goodix,slide-wakeup = <1>;//滑动唤醒
		goodix,resume-in-workqueue = <0>;
		goodix,int-sync = <1>;
		goodix,swap-x2y = <1>;//x2y
		goodix,revert_x = <1>;//x轴转换
		goodix,revert_y = <0>;//y轴转换
	};

};

除了上面的一些属性外,还有其他可以选择的属性,比如,触摸屏幕上面的按键可以用,touchscreen-key-map=<172>,<158>,<139>来设置主页,返回,菜单三个按键

驱动补丁(使用的是2.8版本):

//自定义双击唤醒
#ifdef my_WAKE
static int my_gesture_handler(struct goodix_ts_data *ts)
{
	u8 point_state = 0;
	u8 key_value = 0;
	s32 i = 0;
	u16 cur_touch = 0;
	static u16 pre_touch;
	static struct timespec64 start;
	struct timespec64 end;
	__kernel_time64_t sec;

	struct goodix_point_t spoints[GTP_MAX_TOUCH_ID];
	struct goodix_point_t *points = spoints;
	point_state = gtp_get_points(ts, points, &key_value);
	point_state = point_state & 0x0f;//函数获取当前触摸点状态和按键值,并且只保留低4位的触摸点状态

	for (i = 0; i < ts->pdata->max_touch_id; i++) 
    {
        //遍历当前的触摸ID,如果当前触摸点状态中有相应的ID,则设置cur_touch相应的位
		if (point_state && i == points->id) {
			cur_touch |= 0x01 << points->id;
			points++;
		}
        //如果前一次触摸状态中有相应的ID,则根据wake_count处理不同的逻辑,记录时间并判断是否超时
        else if (pre_touch & 0x01 << i) 
        {
			if(ts->wake_count == 0) //第一次按下,开始记录时间
            {
				ktime_get_real_ts64(&start);
			} 
            else if (ts->wake_count == 1) 
            {
				ktime_get_real_ts64(&end);	
				sec = end.tv_sec - start.tv_sec;
				if(sec > my_WAKE_TIMEOUT) 
                {
					ts->wake_count = 0;
					ktime_get_real_ts64(&start);
					dev_err(&ts->client->dev, "new wake sec=%ld",sec);
				}
			}	
			ts->wake_count++;											
		}
	}

	pre_touch = cur_touch;//更新前一次触摸状态

	if(ts->wake_count > 1 )//第二次按下,结束记录时间	
    { 
		ktime_get_real_ts64(&end);	
		sec = end.tv_sec - start.tv_sec;
		if(sec > my_WAKE_TIMEOUT) //如果两次记录时间超过my_WAKE_TIMEOUT,则认为无效,从新开始
        {
			ts->wake_count = 0;
			dev_err(&ts->client->dev, "timeout sec=%ld",sec);
			return 0;
		}
		doze_status = DOZE_WAKEUP;//设置标志为唤醒
		dev_err(&ts->client->dev, "KEY_POWER wake_count=%d sec=%ld",ts->wake_count,sec);

//上报电源按键事件,唤醒
		input_report_key(ts->input_dev, KEY_POWER, 1);
		input_sync(ts->input_dev);
		input_report_key(ts->input_dev, KEY_POWER, 0);
		input_sync(ts->input_dev);
		ts->wake_count = 0;
	}
	return 0;
}
+
+static int my_enter_doze(struct goodix_ts_data *ts)
+{
+	int ret = 0;
+	set_bit(DOZE_MODE, &ts->flags);
+	dev_dbg(&ts->client->dev, "Entering gesture mode.");
+	return ret;
+}
+
+static int my_gesture_wakeup(struct goodix_ts_data *ts)
+{
+	int ret = 0;
+	clear_bit(DOZE_MODE, &ts->flags);
+	return ret;
+}
+

 /*
  * return touch state register value
  * pen event id fixed with 9 and set tool type TOOL_PEN
@@ -575,7 +659,11 @@ static void gtp_work_func(struct goodix_ts_data *ts)
 
 	/* gesture event */
 	if (ts->pdata->slide_wakeup && test_bit(DOZE_MODE, &ts->flags)) {
+		#ifdef my_WAKE
+		ret = my_gesture_handler(ts);
+		#else
 		ret =  gtp_gesture_handler(ts);
+		#endif	
 		if (ret)
 			dev_err(&ts->client->dev,
 				"Failed handler gesture event %d\n", ret);
@@ -827,6 +915,8 @@ void gtp_reset_guitar(struct i2c_client *client, s32 ms)
 	clear_bit(PANEL_RESETTING, &ts->flags);
 }


 static s8 gtp_enter_sleep(struct goodix_ts_data *ts)
 {
@@ -2090,7 +2181,9 @@ static int gtp_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		devm_kfree(&client->dev, ts);
 		return -EINVAL;
 	}
-
+#ifdef my_WAKE
+	ts->wake_count = 0;
+#endif	
 	ts->init_done = false;
 
 #ifdef CONFIG_OF
@@ -2318,7 +2411,11 @@ static void gtp_suspend(struct goodix_ts_data *ts)
 	gtp_esd_off(ts);
 	gtp_work_control_enable(ts, false);
 	if (ts->pdata->slide_wakeup) {
+	#ifdef my_WAKE	
+		ret = my_enter_doze(ts);
+	#else
 		ret = gtp_enter_doze(ts);
+    #endif
 		gtp_work_control_enable(ts, true);
 	} else if (ts->pdata->power_off_sleep) {
 		/*TODO: power off routine */
@@ -2336,6 +2433,7 @@ static void gtp_suspend(struct goodix_ts_data *ts)
 	msleep(GTP_58_DLY_MS);
 }
### RK356X 芯片休眠唤醒实现方法 #### 1. 休眠唤醒功能概述 休眠唤醒是指系统在低功耗模式下保存当前状态,并能够在特定条件下恢复到正常工作状态的功能。对于嵌入式系统而言,这一特性至关重要,因为它不仅有助于节省能源,还能提升用户体验[^1]。 #### 2. 硬件设计指南 为了确保RK356X平台上的设备可以稳定地进入和退出休眠状态,硬件设计师需注意电源管理单元的设计,确保其能响应外部中断请求(如按下Power按钮),并通过GPIO或其他接口向处理器发送唤醒信号。此外,还需考虑时钟源的选择与配置,以支持最低限度的操作频率,从而减少能耗。 #### 3. 软件开发指南 针对Rockchip平台的休眠唤醒功能实现,主要涉及以下几个方面: - **驱动程序编写**:需要为具体的外设(例如Wi-Fi模块RTL8821CS)定制化开发相应的驱动代码,以便于正确处理不同类型的睡眠指令以及后续的重新初始化过程。 - **系统配置调整**:修改内核参数或BIOS设置来优化系统的待机行为;这可能涉及到更改默认超时时长、启用/禁用某些服务等操作。 - **应用程序层的支持**:确保高层应用能够感知并适当地应对即将发生的挂起事件,比如提前释放资源或者保存未完成的工作进度。 ```c // 示例:注册一个用于监听电源按键事件的回调函数 static int power_key_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { if (type == EV_KEY && code == KEY_POWER && value == 0) { // 当检测到松开电源键时触发唤醒逻辑 pm_wakeup_request(); // 发送唤醒请求给PMU } return 0; } ``` #### 4. 调试与优化 当遇到类似于“RK3568 RTL8821CS Wi-Fi模块在一分钟后的唤醒过程中无法找到任何可用接入点”的情况时,可以从多个角度入手解决问题: - 检查固件版本是否最新; - 验证无线网卡是否已成功加载必要的微码; - 排除其他可能导致干扰的因素,如蓝牙共存问题; - 尝试增加延迟时间让WiFi模组有更多的时间去扫描周围的SSID列表[^2]。 另外,关于较长时间才亮屏的现象,则可能是由于某个组件在恢复期间消耗了大量的CPU周期所致。可以通过`dmesg | grep wakeup`命令获取详细的日志记录,进而定位具体原因所在[^3]。 #### 5. 常见问题与解决方案 面对诸如“息屏休眠后电流超出预期范围”的挑战,建议采取以下措施来进行诊断: - 审视整个电路板布局是否存在不必要的漏电路径; - 对比官方给出的标准值判断实际测量数据是否有异常波动; - 如果发现是由于进入了更深级别的省电模式所引起的,则应适当放宽阈值限制或是缩短过渡期长度,以此达到平衡性能与续航之间的关系[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知道起个啥名“”

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值