: Trigger fod event only when FOD is enabled

1. Register  FOD state thru mmi_relay.
2. Send Fod event when FOD is enabled.

Change-Id: I56fed42e8377dc86c84e8dd1042cd04a55fb0a16
Signed-off-by: Yan Zhang <zhangy26@motorola.com>
Reviewed-on: https://gerrit.mot.com/2205960
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Yan Zhang 2022-03-03 12:13:46 +08:00
commit 0732d87c21
8 changed files with 93 additions and 39 deletions

View file

@ -1173,13 +1173,19 @@ static void goodix_ts_report_pen(struct input_dev *dev,
input_sync(dev);
mutex_unlock(&dev->mutex);
}
#ifdef CONFIG_GTP_FOD
#define GOODIX_GESTURE_FOD_DOWN 0x46
#define GOODIX_GESTURE_FOD_UP 0x55
#endif
static void goodix_ts_report_finger(struct input_dev *dev,
struct goodix_touch_data *touch_data)
{
unsigned int touch_num = touch_data->touch_num;
int i;
#ifdef CONFIG_GTP_FOD
struct goodix_ts_core *core_data = goodix_modules.core_data;
struct goodix_ts_event *ts_event = &goodix_modules.core_data ->ts_event;
#endif
mutex_lock(&dev->mutex);
for (i = 0; i < GOODIX_MAX_TOUCH; i++) {
@ -1203,6 +1209,23 @@ static void goodix_ts_report_finger(struct input_dev *dev,
input_report_key(dev, BTN_TOUCH, touch_num > 0 ? 1 : 0);
input_sync(dev);
#ifdef CONFIG_GTP_FOD
if(core_data->fod_enable) {
if(ts_event->gesture_type == GOODIX_GESTURE_FOD_DOWN && touch_num > 0) {
input_report_key(dev, BTN_TRIGGER_HAPPY1, 1);
input_sync(dev);
input_report_key(dev, BTN_TRIGGER_HAPPY1, 0);
input_sync(dev);
}else if(ts_event->gesture_type == GOODIX_GESTURE_FOD_UP && touch_num <=0) {
input_report_key(dev, BTN_TRIGGER_HAPPY2, 1);
input_sync(dev);
input_report_key(dev, BTN_TRIGGER_HAPPY2, 0);
input_sync(dev);
}
}
ts_debug("fod_enable= %d, gesture_type =%x, touch_num= %d", core_data->fod_enable,
ts_event->gesture_type, touch_num);
#endif
mutex_unlock(&dev->mutex);
}
@ -1228,10 +1251,6 @@ static int goodix_ts_request_handle(struct goodix_ts_core *cd,
ts_event->request_code);
return ret;
}
#ifdef CONFIG_GTP_FOD
#define GOODIX_GESTURE_FOD_DOWN 0x46
#define GOODIX_GESTURE_FOD_UP 0x55
#endif
/**
* goodix_ts_threadirq_func - Bottom half of interrupt
* This functions is excuted in thread context,
@ -1268,7 +1287,6 @@ static irqreturn_t goodix_ts_threadirq_func(int irq, void *data)
}
}
mutex_unlock(&goodix_modules.mutex);
/* read touch data from touch device */
ret = hw_ops->event_handler(core_data, ts_event);
if (likely(!ret)) {
@ -1276,19 +1294,6 @@ static irqreturn_t goodix_ts_threadirq_func(int irq, void *data)
/* report touch */
goodix_ts_report_finger(core_data->input_dev,
&ts_event->touch_data);
#ifdef CONFIG_GTP_FOD
if(ts_event->gesture_type == GOODIX_GESTURE_FOD_DOWN) {
input_report_key(core_data->input_dev, BTN_TRIGGER_HAPPY1, 1);
input_sync(core_data->input_dev);
input_report_key(core_data->input_dev, BTN_TRIGGER_HAPPY1, 0);
input_sync(core_data->input_dev);
} else if(ts_event->gesture_type == GOODIX_GESTURE_FOD_UP) {
input_report_key(core_data->input_dev, BTN_TRIGGER_HAPPY2, 1);
input_sync(core_data->input_dev);
input_report_key(core_data->input_dev, BTN_TRIGGER_HAPPY2, 0);
input_sync(core_data->input_dev);
}
#endif
}
if (core_data->board_data.pen_enable &&
ts_event->event_type == EVENT_PEN) {

View file

@ -537,6 +537,8 @@ struct goodix_ts_core {
bool need_update_cfg;
#ifdef CONFIG_GTP_FOD
unsigned char gesture_type;
int zerotap_data[1];
int fod_enable;
#endif
atomic_t pm_resume;
wait_queue_head_t pm_wq;

View file

@ -335,7 +335,7 @@ static int gsx_gesture_init(struct goodix_ts_core *cd,
gsx->ts_core = cd;
/*enable all gesture wakeup by default */
gsx->ts_core->gesture_type = GESTURE_SINGLE_TAP |GESTURE_FOD_PRESS;
cd->ts_event.gesture_data[0] = 0;
cd->zerotap_data[0] = 0;
atomic_set(&gsx_gesture->registered, 1);
return 0;
}
@ -375,7 +375,7 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
struct gesture_event_data mmi_event;
static unsigned long start = 0;
int fod_down_interval = 0;
int fod_down = cd->ts_event.gesture_data[0];
int fod_down = cd->zerotap_data[0];
#endif
if (atomic_read(&cd->suspended) == 0 || cd->gesture_type == 0)
return EVT_CONTINUE;
@ -420,12 +420,16 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
fodx = le16_to_cpup((__le16 *)gs_event.gesture_data);
fody = le16_to_cpup((__le16 *)(gs_event.gesture_data + 2));
overlay_area = gs_event.gesture_data[4];
//goodix firmware do not send coordinate, we need hardcode a vaild coordinate
if(!cd->fod_enable) {
ts_info("Get FOD-DOWN gesture when fod is not enabled, ignore");
goto gesture_ist_exit;
}
//goodix firmware do not send coordinate, need mmi touch to define a vaild coordinate thru dts
mmi_event.evcode = 2;
mmi_event.evdata.x= 540;
mmi_event.evdata.y= 2164;
mmi_event.evdata.x= 0;
mmi_event.evdata.y= 0;
ts_debug("Get FOD-DOWN gesture down:%d interval:%d",fod_down,fod_down_interval);
ts_debug("Get FOD-DOWN gesture:%d interval:%d",fod_down,fod_down_interval);
if(fod_down_interval > 2000)
fod_down = 0;
if(fod_down_interval > 0 && fod_down_interval < 250 && fod_down) {
@ -440,6 +444,11 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
}
fod_down++;
}else if(cd->gesture_type & GESTURE_FOD_PRESS && gs_event.gesture_type == GOODIX_GESTURE_FOD_UP) {
if(!cd->fod_enable) {
ts_info("Get FOD-UP gesture when fod is not enabled, ignore");
fod_down = 0;
goto gesture_ist_exit;
}
ts_info("Get FOD-UP gesture");
mmi_event.evcode = 3;
mmi_event.evdata.x= 0;
@ -522,7 +531,7 @@ re_send_ges_cmd:
gesture_ist_exit:
if (!cd->tools_ctrl_sync)
hw_ops->after_event_handler(cd);
cd->ts_event.gesture_data[0] = fod_down;
cd->zerotap_data[0] = fod_down;
return EVT_CANCEL_IRQEVT;
}

View file

@ -927,10 +927,10 @@ static int goodix_ts_mmi_post_resume(struct device *dev) {
}
mutex_unlock(&core_data->mode_lock);
#ifdef CONFIG_GTP_FOD
if(core_data->ts_event.gesture_data[0]) {
ts_info("FOD is down during PM active");
if(core_data->zerotap_data[0]) {
ts_info("FOD is down during PM resume fod_enable=%d",core_data->fod_enable);
}
core_data->ts_event.gesture_data[0] = 0;
core_data->zerotap_data[0] = 0;
#endif
return 0;
}
@ -978,7 +978,18 @@ static int goodix_ts_mmi_post_suspend(struct device *dev) {
ts_info("Suspend end");
return 0;
}
#ifdef CONFIG_GTP_FOD
static int goodix_ts_mmi_update_fps_mode(struct device *dev, int mode) {
struct goodix_ts_core *core_data;
struct platform_device *pdev;
GET_GOODIX_DATA(dev);
core_data->fod_enable = (mode >0) ? 0x01 : 0x00;
ts_info(" update_fps_mode %s:%d\n", (mode > 0) ? "enable" : "disable", mode);
return 0;
}
#endif
static struct ts_mmi_methods goodix_ts_mmi_methods = {
.get_vendor = goodix_ts_mmi_methods_get_vendor,
.get_productinfo = goodix_ts_mmi_methods_get_productinfo,
@ -1005,6 +1016,9 @@ static struct ts_mmi_methods goodix_ts_mmi_methods = {
.post_resume = goodix_ts_mmi_post_resume,
.pre_suspend = goodix_ts_mmi_pre_suspend,
.post_suspend = goodix_ts_mmi_post_suspend,
#ifdef CONFIG_GTP_FOD
.update_fod_mode = goodix_ts_mmi_update_fps_mode,
#endif
};
int goodix_ts_mmi_dev_register(struct platform_device *pdev) {

View file

@ -212,6 +212,7 @@ static int ts_mmi_gesture_handler(struct gesture_event_data *gev)
{
int key_code;
bool need2report = true;
struct ts_mmi_dev *touch_cdev = sensor_pdata->touch_cdev;
switch (gev->evcode) {
case 1:
@ -220,6 +221,10 @@ static int ts_mmi_gesture_handler(struct gesture_event_data *gev)
break;
case 2:
key_code = KEY_F2;
if(gev->evdata.x == 0)
gev->evdata.x = touch_cdev->pdata.fod_x ;
if(gev->evdata.y== 0)
gev->evdata.y = touch_cdev->pdata.fod_y;
input_report_abs(sensor_pdata->input_sensor_dev, ABS_X, gev->evdata.x);
input_report_abs(sensor_pdata->input_sensor_dev, ABS_Y, gev->evdata.y);
pr_info("%s: zero tap; x=%x, y=%x\n", __func__, gev->evdata.x, gev->evdata.y);

View file

@ -336,14 +336,20 @@ static void ts_mmi_worker_func(struct work_struct *w)
TRY_TO_CALL(refresh_rate, (int)touch_cdev->refresh_rate);
break;
case TS_MMI_DO_FPS:
if (touch_cdev->fps_state) {/* on */
TRY_TO_CALL(update_baseline, TS_MMI_UPDATE_BASELINE_OFF);
touch_cdev->delay_baseline_update = true;
} else { /* off */
if (touch_cdev->delay_baseline_update) {
TRY_TO_CALL(update_baseline, TS_MMI_UPDATE_BASELINE_ON);
touch_cdev->delay_baseline_update = false;
if (touch_cdev->pdata.fps_detection) {
if (touch_cdev->fps_state) {/* on */
TRY_TO_CALL(update_baseline, TS_MMI_UPDATE_BASELINE_OFF);
touch_cdev->delay_baseline_update = true;
} else { /* off */
if (touch_cdev->delay_baseline_update) {
TRY_TO_CALL(update_baseline, TS_MMI_UPDATE_BASELINE_ON);
touch_cdev->delay_baseline_update = false;
}
}
}
if (touch_cdev->pdata.fod_detection) {
TRY_TO_CALL(update_fod_mode, touch_cdev->fps_state);
}
break;
@ -548,7 +554,7 @@ int ts_mmi_notifiers_register(struct ts_mmi_dev *touch_cdev)
goto FREQ_NOTIF_REGISTER_FAILED;
}
if (touch_cdev->pdata.fps_detection) {
if (touch_cdev->pdata.fps_detection || touch_cdev->pdata.fod_detection) {
ret = ts_mmi_fps_notifier_register(touch_cdev, true);
if (ret < 0)
dev_err(DEV_TS,
@ -573,7 +579,7 @@ void ts_mmi_notifiers_unregister(struct ts_mmi_dev *touch_cdev)
return;
}
if (touch_cdev->pdata.fps_detection)
if (touch_cdev->pdata.fps_detection || touch_cdev->pdata.fod_detection)
ts_mmi_fps_notifier_register(touch_cdev, false);
if (touch_cdev->pdata.update_refresh_rate)

View file

@ -140,7 +140,16 @@ int ts_mmi_parse_dt(struct ts_mmi_dev *touch_cdev,
ppdata->max_x = coords[0] - 1;
ppdata->max_y = coords[1] - 1;
}
if (of_property_read_bool(of_node, "mmi,fod_detection")) {
dev_info(DEV_TS, "%s: using fod detection\n", __func__);
ppdata->fod_detection = true;
}
if (!of_property_read_u32_array(of_node, "mmi,fod_coords", coords, 2)) {
ppdata->fod_x = coords[0];
ppdata->fod_y = coords[1];
dev_info(DEV_TS, "%s: get fod_coords property x:%d y:%d\n", __func__,ppdata->fod_x,ppdata->fod_y);
}
chosen = of_find_node_by_name(NULL, "chosen");
if (chosen) {
struct device_node *child;

View file

@ -370,6 +370,7 @@ enum ts_mmi_panel_event {
int (*poison_distance)(struct device *dev, int dis);
int (*poison_trigger_distance)(struct device *dev, int dis);
int (*update_baseline)(struct device *dev, int enable);
int (*update_fod_mode)(struct device *dev, int enable);
/* Firmware */
int (*firmware_update)(struct device *dev, char *fwname);
int (*firmware_erase)(struct device *dev);
@ -397,6 +398,7 @@ enum ts_mmi_panel_event {
struct ts_mmi_dev_pdata {
bool power_off_suspend;
bool fps_detection;
bool fod_detection;
bool usb_detection;
bool update_refresh_rate;
bool gestures_enabled;
@ -410,6 +412,8 @@ struct ts_mmi_dev_pdata {
bool poison_slot_ctrl;
int max_x;
int max_y;
int fod_x;
int fod_y;
int ctrl_dsi;
int reset;
const char *class_entry_name;