出现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);
}