Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2cf0fb68 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "input: touchscreen: st: add touch notification when suspend"

parents a2f23619 cb4493d8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
# Each configuration option enables a list of files.

obj-$(CONFIG_INPUT)		+= input-core.o
input-core-y := input.o input-compat.o input-mt.o ff-core.o
input-core-y := input.o input-compat.o input-mt.o ff-core.o event_notify.o

obj-$(CONFIG_INPUT_FF_MEMLESS)	+= ff-memless.o
obj-$(CONFIG_INPUT_POLLDEV)	+= input-polldev.o
+34 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 */

#include <linux/export.h>
#include <linux/notifier.h>
#include <linux/input/touch_event_notify.h>

static BLOCKING_NOTIFIER_HEAD(touch_notifier_list);

int touch_event_register_notifier(struct notifier_block *nb)
{
	return blocking_notifier_chain_register(&touch_notifier_list, nb);
}
EXPORT_SYMBOL(touch_event_register_notifier);

int touch_event_unregister_notifier(struct notifier_block *nb)
{
	return blocking_notifier_chain_unregister(&touch_notifier_list, nb);
}
EXPORT_SYMBOL(touch_event_unregister_notifier);

void touch_event_call_notifier(unsigned long action, void *data)
{
	blocking_notifier_call_chain(&touch_notifier_list, action, data);
}
EXPORT_SYMBOL(touch_event_call_notifier);
+1 −1
Original line number Diff line number Diff line
@@ -3,4 +3,4 @@
## Makefile for the STMicroelectronics touchscreen driver.
#

obj-$(CONFIG_TOUCHSCREEN_ST) += fts.o fts_gui.o fts_driver_test.o fts_lib/
obj-$(CONFIG_TOUCHSCREEN_ST) += fts.o fts_gui.o fts_driver_test.o fts_aoi_event.o fts_lib/
+99 −60
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * fts.c
 *
 * FTS Capacitive touch screen controller (FingerTipS)
 *
 * Copyright (C) 2016-2019, STMicroelectronics Limited.
 * Authors: AMG(Analog Mems Group)
 *
@@ -47,6 +43,7 @@
#include <linux/input/mt.h>
#endif

#include <linux/input/touch_event_notify.h>

#include "fts.h"
#include "fts_lib/ftsCompensation.h"
@@ -60,8 +57,6 @@
#include "fts_lib/ftsTool.h"
#include "linux/moduleparam.h"



#define LINK_KOBJ_NAME "tp"

/*
@@ -70,7 +65,6 @@
 */
// #define FTS_USE_POLLING_MODE


/*
 * Event installer helpers
 */
@@ -80,7 +74,6 @@
#define install_handler(_i, _evt, _hnd) \
	(_i->event_dispatch_table[event_id(_evt)].handler = handler_name(_hnd))


/*
 * Asyncronouns command helper
 */
@@ -100,7 +93,6 @@ do { \
static struct class *fts_cmd_class;
#endif


//struct chipInfo ftsInfo;

/**
@@ -256,7 +248,6 @@ static ssize_t fts_fwupdate_show(struct device *dev,
	return snprintf(buf, PAGE_SIZE, "AA%08XBB\n", info->fwupdate_stat);
}


/****UTILITIES (current fw_ver/conf_id, active mode, file fw_ver/conf_id)****/
/**
 * cat appid show on the terminal fw_version.config_id of
@@ -288,7 +279,6 @@ static ssize_t fts_mode_active_show(struct device *dev,
	return snprintf(buf, PAGE_SIZE, "AA%08XBB\n", info->mode);
}


/**
 * cat fw_file_test show on the terminal fw_version and config_id of the FW
 * stored in the fw file/header file
@@ -315,7 +305,6 @@ static ssize_t fts_fw_test_show(struct device *dev,
	return 0;
}


/**
 * cat lockdown_info to show the lockdown info on the terminal
 * (example output in the terminal = "AA00000000X1X2..X10BB" )
@@ -389,7 +378,6 @@ static ssize_t fts_strength_frame_store(struct device *dev,
	return count;
}


static ssize_t fts_strength_frame_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
@@ -735,7 +723,6 @@ static ssize_t fts_feature_enable_show(struct device *dev,
			tag, __func__, feature_feasibility);
	}


	all_strbuff = kmalloc(size, GFP_KERNEL);
	if (all_strbuff != NULL) {
		memset(all_strbuff, 0, size);
@@ -809,7 +796,6 @@ static ssize_t fts_edge_rej_show(struct device *dev,
	return count;
}


static ssize_t fts_edge_rej_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -819,7 +805,6 @@ static ssize_t fts_edge_rej_store(struct device *dev,
	struct i2c_client *client = to_i2c_client(dev);
	struct fts_ts_info *info = i2c_get_clientdata(client);


	/**
	 * in case of a different elaboration of the input,
	 * just modify this initial part of the code
@@ -908,7 +893,6 @@ static ssize_t fts_corner_rej_show(struct device *dev,
	return count;
}


static ssize_t fts_corner_rej_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1015,7 +999,6 @@ static ssize_t fts_edge_palm_rej_show(struct device *dev,
	return count;
}


static ssize_t fts_edge_palm_rej_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1114,7 +1097,6 @@ static ssize_t fts_charger_mode_show(struct device *dev,
	return count;
}


static ssize_t fts_charger_mode_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1216,7 +1198,6 @@ static ssize_t fts_glove_mode_show(struct device *dev,
	return count;
}


static ssize_t fts_glove_mode_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1315,7 +1296,6 @@ static ssize_t fts_vr_mode_show(struct device *dev,
	return count;
}


static ssize_t fts_vr_mode_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1325,7 +1305,6 @@ static ssize_t fts_vr_mode_store(struct device *dev,
	struct i2c_client *client = to_i2c_client(dev);
	struct fts_ts_info *info = i2c_get_clientdata(client);


	/**
	 * in case of a different elaboration of the input,
	 * just modify this initial part of the code
@@ -1418,7 +1397,6 @@ static ssize_t fts_cover_mode_show(struct device *dev,
	return count;
}


static ssize_t fts_cover_mode_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1517,7 +1495,6 @@ static ssize_t fts_stylus_mode_show(struct device *dev,
	return count;
}


static ssize_t fts_stylus_mode_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1527,7 +1504,6 @@ static ssize_t fts_stylus_mode_store(struct device *dev,
	struct i2c_client *client = to_i2c_client(dev);
	struct fts_ts_info *info = i2c_get_clientdata(client);


	/**
	 * in case of a different elaboration of the input,
	 * just modify this initial part of the code
@@ -1562,7 +1538,6 @@ static ssize_t fts_stylus_mode_store(struct device *dev,
		}
	}


	return count;
}
#endif
@@ -1756,7 +1731,6 @@ static ssize_t fts_gesture_mask_show(struct device *dev,
	return count;
}


static ssize_t fts_gesture_mask_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -1881,7 +1855,6 @@ static ssize_t fts_add_custom_gesture_show(struct device *dev,
	return count;
}


static ssize_t fts_add_custom_gesture_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -2162,8 +2135,6 @@ static ssize_t fts_gesture_coordinates_store(struct device *dev,
}
#endif



/***************** PRODUCTION TEST ****************/
static ssize_t fts_stm_cmd_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
@@ -2519,7 +2490,6 @@ static ssize_t fts_stm_cmd_show(struct device *dev,
				strlcat(all_strbuff, buff, 4);
			}


			/* Copying self raw data Sense */
			for (j = 0; j < frameSS.header.sense_node; j++) {
				snprintf(buff, sizeof(buff), "%04X",
@@ -2751,7 +2721,6 @@ static int fts_command(struct fts_ts_info *info, unsigned char cmd)
	return ret;
}


void fts_input_report_key(struct fts_ts_info *info, int key_code)
{
	mutex_lock(&info->input_report_mutex);
@@ -2762,7 +2731,6 @@ void fts_input_report_key(struct fts_ts_info *info, int key_code)
	mutex_unlock(&info->input_report_mutex);
}


/*
 * New Interrupt handle implementation
 */
@@ -2798,6 +2766,7 @@ static void fts_enter_pointer_event_handler(struct fts_ts_info *info,
	int minor;
	int major, distance;
	u8 touchsize;
	struct touch_event *touch = NULL;

	distance = 0;
	if (!info->resume_bit)
@@ -2828,9 +2797,6 @@ static void fts_enter_pointer_event_handler(struct fts_ts_info *info,
	input_mt_slot(info->input_dev, touchId);
	input_mt_report_slot_state(info->input_dev, MT_TOOL_FINGER, 1);

	logError(0, "%s %s : TouchID = %d,Touchcount = %d,minor:%d,major:%d\n",
		tag, __func__, touchId, touchcount, minor, major);

	if (touchcount == 1) {
		input_report_key(info->input_dev, BTN_TOUCH, 1);
		input_report_key(info->input_dev, BTN_TOOL_FINGER, 1);
@@ -2840,6 +2806,40 @@ static void fts_enter_pointer_event_handler(struct fts_ts_info *info,
	input_report_abs(info->input_dev, ABS_MT_TOUCH_MAJOR, major);
	input_report_abs(info->input_dev, ABS_MT_TOUCH_MINOR, minor);
	input_report_abs(info->input_dev, ABS_MT_DISTANCE, distance);

	if (!info->aoi_notify_enabled)
		goto no_report;

	if ((x >= info->aoi_left && x < info->aoi_right)
		&& (y >= info->aoi_top && y < info->aoi_bottom)) {

		touch = &info->event[touchId];
		touch->x = x;
		touch->y = y;
		touch->fid = touchId;
		touch->type = 'M';
		do_gettimeofday(&touch->time);

		if (!test_bit(touchId, &info->finger_pressed)) {
			touch->type = 'D';
			__set_bit(touchId, &info->finger_pressed);
		}
		__set_bit(touchId, &info->event_mask);
	} else {
		if (test_bit(touchId, &info->finger_pressed)) {

			touch = &info->event[touchId];
			touch->x = 0;
			touch->y = 0;
			touch->fid = touchId;
			touch->type = 'U';
			do_gettimeofday(&touch->time);

			__clear_bit(touchId, &info->finger_pressed);
			__set_bit(touchId, &info->event_mask);
		}
	}

no_report:
	return;

@@ -2849,9 +2849,9 @@ static void fts_enter_pointer_event_handler(struct fts_ts_info *info,
static void fts_leave_pointer_event_handler(struct fts_ts_info *info,
			unsigned char *event)
{

	unsigned char touchId, touchcount;
	u8 touchsize;
	struct touch_event *touch = NULL;

	touchId = event[1] & 0x0F;
	touchcount = (event[1] & 0xF0) >> 4;
@@ -2869,6 +2869,20 @@ static void fts_leave_pointer_event_handler(struct fts_ts_info *info,

	input_report_abs(info->input_dev, ABS_MT_TRACKING_ID, -1);

	if (!info->aoi_notify_enabled)
		return;

	if (test_bit(touchId, &info->finger_pressed)) {
		touch = &info->event[touchId];
		touch->x = 0;
		touch->y = 0;
		touch->fid = touchId;
		touch->type = 'U';
		do_gettimeofday(&touch->time);

		__clear_bit(touchId, &info->finger_pressed);
		__set_bit(touchId, &info->event_mask);
	}
}

/* EventId : 0x05 */
@@ -3225,9 +3239,7 @@ static void fts_event_handler(struct work_struct *work)
	 * read all the FIFO and parsing events
	 */

	/* wake_lock_timeout(&info->wakelock, HZ); */
	__pm_wakeup_event(&info->wakeup_source, HZ);
	/* logError(1, "%s %s: begin\n", tag, __func__); */
	regAdd = FIFO_CMD_READONE;

	for (count = 0; count < FIFO_DEPTH; count++) {
@@ -3237,9 +3249,6 @@ static void fts_event_handler(struct work_struct *work)
			eventId = data[0];
		else
			break;
		/* if(data[7]&0x20) */
		/* logError(1, "%s %s overflow ID = %02X  Last = %02X\n",*/
		/* tag, __func__, data[0], data[7]);*/

		if (eventId < EVENTID_LAST) {
			event_handler = info->event_dispatch_table[eventId];
@@ -3248,8 +3257,13 @@ static void fts_event_handler(struct work_struct *work)
	}
	input_sync(info->input_dev);

	/* re-enable interrupts */
	fts_interrupt_enable(info);

	if (info->event_mask) {
		touch_event_call_notifier(info->event_mask,
				(void *)&info->event[0]);
		info->event_mask = 0;
	}
}

static int cx_crc_check(void)
@@ -3538,7 +3552,6 @@ static int fts_interrupt_install(struct fts_ts_info *info)

static void fts_interrupt_uninstall(struct fts_ts_info *info)
{

	fts_disableInterrupt();

	kfree(info->event_dispatch_table);
@@ -3654,7 +3667,6 @@ int fts_chip_powercycle(struct fts_ts_info *info)
	/* time needed by the regulators for reaching the regime values */
	msleep(20);


	if (info->bdata->reset_gpio != GPIO_NOT_DEFINED) {
		/* time to wait before bring up the reset */
		/* gpio after the power up of the regulators */
@@ -3718,7 +3730,6 @@ int fts_chip_powercycle2(struct fts_ts_info *info, unsigned long sleep)
	/* time needed by the regulators for reaching the regime values */
	msleep(500);


	if (info->bdata->reset_gpio != GPIO_NOT_DEFINED) {
		/*
		 * time to wait before bring up the reset
@@ -4045,7 +4056,6 @@ static int fts_mode_handler(struct fts_ts_info *info, int force)
	return res;
}


static void fts_resume_work(struct work_struct *work)
{
	struct fts_ts_info *info;
@@ -4087,7 +4097,6 @@ static void fts_resume_work(struct work_struct *work)
	fts_interrupt_enable(info);
}


static void fts_suspend_work(struct work_struct *work)
{
	struct fts_ts_info *info;
@@ -4119,12 +4128,10 @@ static void fts_suspend_work(struct work_struct *work)

}


#if defined(CONFIG_FB_MSM)
static int fts_fb_state_chg_callback(struct notifier_block *nb,
			unsigned long val, void *data)
{

	struct fts_ts_info *info = container_of(nb,
			struct fts_ts_info, notifier);
	struct fb_event *evdata = data;
@@ -4193,17 +4200,28 @@ static int fts_fb_state_chg_callback(struct notifier_block *nb,
		case MSM_DRM_BLANK_POWERDOWN:
			if (info->sensor_sleep)
				break;
			logError(0, "%s %s: MSM_DRM_BLANK_UNBLANK\n",
					tag, __func__);

			if (info->aoi_notify_enabled)
				info->aoi_wake_on_suspend = true;
			else
				info->aoi_wake_on_suspend = false;

			if (info->aoi_wake_on_suspend)
				info->sensor_sleep = true;
			else
				queue_work(info->event_wq, &info->suspend_work);
			break;

		case MSM_DRM_BLANK_UNBLANK:
			if (!info->sensor_sleep)
				break;
			logError(0, "%s %s: MSM_DRM_BLANK_UNBLANK\n",
					tag, __func__);

			if (!info->resume_bit)
				queue_work(info->event_wq, &info->resume_work);

			if (info->aoi_wake_on_suspend)
				info->sensor_sleep = false;

			break;
		default:
			break;
@@ -4661,7 +4679,6 @@ static int fts_probe(struct i2c_client *client,

	mutex_init(&(info->input_report_mutex));


#ifdef PHONE_GESTURE
	mutex_init(&gestureMask_mutex);
#endif
@@ -4742,7 +4759,6 @@ static int fts_probe(struct i2c_client *client,
	}
#endif


#ifdef DRIVER_TEST
	if (fts_cmd_class == NULL)
		fts_cmd_class = class_create(THIS_MODULE, FTS_TS_DRV_NAME);
@@ -4764,9 +4780,33 @@ static int fts_probe(struct i2c_client *client,
		goto ProbeErrorExit_11;
	}
#endif

	if (fts_cmd_class == NULL)
		fts_cmd_class = class_create(THIS_MODULE, FTS_TS_DRV_NAME);
	info->aoi_cmd_dev = device_create(fts_cmd_class,
			NULL, DCHIP_ID_0, info, "touch_aoi");
	if (IS_ERR(info->aoi_cmd_dev)) {
		logError(1,
			"%s ERROR: Failed to create device for the sysfs\n",
			tag);
		goto ProbeErrorExit_10;
	}

	dev_set_drvdata(info->aoi_cmd_dev, info);

	error = sysfs_create_group(&info->aoi_cmd_dev->kobj,
			&aoi_cmd_attr_group);
	if (error) {
		logError(1, "%s ERROR: Failed to create sysfs group\n", tag);
		goto ProbeErrorExit_11;
	}

	queue_delayed_work(info->fwu_workqueue, &info->fwu_work,
			msecs_to_jiffies(EXP_FN_WORK_DELAY_MS));
	logError(1, "%s Probe Finished!\n", tag);

	info->event_mask = 0;

	return OK;

	/* error exit path */
@@ -4935,7 +4975,6 @@ static void __exit fts_driver_exit(void)
	i2c_del_driver(&fts_i2c_driver);
}


late_initcall(fts_driver_init);
module_exit(fts_driver_exit);

+19 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

/*#include <linux/wakelock.h>*/
#include <linux/pm_wakeup.h>
#include <linux/input/touch_event_notify.h>

#include "fts_lib/ftsSoftware.h"
#include "fts_lib/ftsHardware.h"
@@ -311,6 +312,20 @@ struct fts_ts_info {

	uint8_t *i2c_data;
	uint8_t i2c_data_len;

	struct device *aoi_cmd_dev;
	bool aoi_notify_enabled;
	bool aoi_wake_on_suspend;

	unsigned long event_mask;
	unsigned long finger_pressed;
	struct touch_event event[FIFO_DEPTH];

	/* aoi region */
	int aoi_left;
	int aoi_top;
	int aoi_bottom;
	int aoi_right;
};

extern struct chipInfo ftsInfo;
@@ -323,6 +338,8 @@ int fts_chip_powercycle2(struct fts_ts_info *info, unsigned long sleep);
extern int input_register_notifier_client(struct notifier_block *nb);
extern int input_unregister_notifier_client(struct notifier_block *nb);

extern struct attribute_group aoi_cmd_attr_group;

#ifdef SCRIPTLESS
extern struct attribute_group i2c_cmd_attr_group;
#endif
Loading