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

Commit 4a64f8cd authored by Abinaya P's avatar Abinaya P
Browse files

input: ft5x06: add secure touch support for Focaltech on 8937 QRD



8937 QRD supports Focaltech touch controller. For ft5x06_ts driver
to work with the TrustZone secure touch, all the touch interrupts must
be forwarded between the Linux Kernel and the TrustZone input driver.
Add APIs and configuration to support this.

CRs-Fixed: 974549
Change-Id: Ibf873594722c6f299eb4cacf81804cb6548824a4
Signed-off-by: default avatarAbinaya P <abinayap@codeaurora.org>
parent 7b262653
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1051,6 +1051,16 @@ config TOUCHSCREEN_FT5X06
         To compile this driver as a module, choose M here: the
         module will be called ft5x06_ts.

config FT_SECURE_TOUCH
	bool "Secure Touch support for Focaltech Touchscreen"
	depends on TOUCHSCREEN_FT5X06
	help
	  Say Y here
	  -Focaltech touch driver is connected
	  -To enable secure touch for Focaltech touch driver

	  If unsure, say N.

config TOUCHSCREEN_SYNAPTICS_I2C_RMI4
	tristate "Synaptics DSX I2C touchscreen"
	depends on I2C
+79 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * FocalTech ft5x06 TouchScreen driver.
 *
 * Copyright (c) 2010  Focal tech Ltd.
 * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -47,6 +47,12 @@
#define FT_SUSPEND_LEVEL 1
#endif

#if defined(CONFIG_FT_SECURE_TOUCH)
#include <linux/completion.h>
#include <linux/atomic.h>
#include <linux/pm_runtime.h>
#endif

#define FT_DRIVER_VERSION	0x02

#define FT_META_REGS		3
@@ -262,11 +268,66 @@ struct ft5x06_ts_data {
	struct pinctrl_state *pinctrl_state_active;
	struct pinctrl_state *pinctrl_state_suspend;
	struct pinctrl_state *pinctrl_state_release;
#if defined(CONFIG_FT_SECURE_TOUCH)
	atomic_t st_enabled;
	atomic_t st_pending_irqs;
	struct completion st_powerdown;
	struct completion st_irq_processed;
#endif
};

static int ft5x06_ts_start(struct device *dev);
static int ft5x06_ts_stop(struct device *dev);

#if defined(CONFIG_FT_SECURE_TOUCH)
static void ft5x06_secure_touch_init(struct ft5x06_ts_data *data)
{
	init_completion(&data->st_powerdown);
	init_completion(&data->st_irq_processed);
}

static void ft5x06_secure_touch_notify(struct ft5x06_ts_data *data)
{
	sysfs_notify(&data->input_dev->dev.kobj, NULL, "secure_touch");
}

static irqreturn_t ft5x06_filter_interrupt(struct ft5x06_ts_data *data)
{
	if (atomic_read(&data->st_enabled)) {
		if (atomic_cmpxchg(&data->st_pending_irqs, 0, 1) == 0) {
			reinit_completion(&data->st_irq_processed);
			ft5x06_secure_touch_notify(data);
			wait_for_completion_interruptible(
						&data->st_irq_processed);
		}
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}

static void ft5x06_secure_touch_stop(struct ft5x06_ts_data *data, int blocking)
{
	if (atomic_read(&data->st_enabled)) {
		atomic_set(&data->st_pending_irqs, -1);
		ft5x06_secure_touch_notify(data);
		if (blocking)
			wait_for_completion_interruptible(
						&data->st_powerdown);
	}
}
#else
static void ft5x06_secure_touch_init(struct ft5x06_ts_data *data)
{
}
static irqreturn_t ft5x06_filter_interrupt(struct ft5x06_ts_data *data)
{
	return IRQ_NONE;
}
static void ft5x06_secure_touch_stop(struct ft5x06_ts_data *data, int blocking)
{
}
#endif

static inline bool ft5x06_gesture_support_enabled(void)
{
	return config_enabled(CONFIG_TOUCHSCREEN_FT5X06_GESTURE);
@@ -593,6 +654,9 @@ static irqreturn_t ft5x06_ts_interrupt(int irq, void *dev_id)
		return IRQ_HANDLED;
	}

	if (IRQ_HANDLED == ft5x06_filter_interrupt(data))
		return IRQ_HANDLED;

	ip_dev = data->input_dev;
	buf = data->tch_data;

@@ -620,6 +684,10 @@ static irqreturn_t ft5x06_ts_interrupt(int irq, void *dev_id)
	}

	for (i = 0; i < data->pdata->num_max_touches; i++) {
		/*
		 * Getting the finger ID of the touch event incase of
		 * multiple touch events
		 */
		id = (buf[FT_TOUCH_ID_POS + FT_ONE_TCH_LEN * i]) >> 4;
		if (id >= FT_MAX_ID)
			break;
@@ -1057,6 +1125,8 @@ static int ft5x06_ts_suspend(struct device *dev)
		return 0;
	}

	ft5x06_secure_touch_stop(data, 1);

	if (ft5x06_gesture_support_enabled() && data->pdata->gesture_support &&
		device_may_wakeup(dev) &&
		data->gesture_pdata->gesture_enable_to_set) {
@@ -1083,6 +1153,8 @@ static int ft5x06_ts_resume(struct device *dev)
		return 0;
	}

	ft5x06_secure_touch_stop(data, 1);

	if (ft5x06_gesture_support_enabled() && data->pdata->gesture_support &&
		device_may_wakeup(dev) &&
		!(data->gesture_pdata->in_pocket) &&
@@ -1185,6 +1257,7 @@ static void ft5x06_ts_early_suspend(struct early_suspend *handler)
						   struct ft5x06_ts_data,
						   early_suspend);

	ft5x06_secure_touch_stop(data, 0);
	ft5x06_ts_suspend(&data->client->dev);
}

@@ -1194,6 +1267,7 @@ static void ft5x06_ts_late_resume(struct early_suspend *handler)
						   struct ft5x06_ts_data,
						   early_suspend);

	ft5x06_secure_touch_stop(data, 0);
	ft5x06_ts_resume(&data->client->dev);
}
#endif
@@ -2285,6 +2359,10 @@ static int ft5x06_ts_probe(struct i2c_client *client,
		}
	}

	/*Initialize secure touch */
	ft5x06_secure_touch_init(data);
	ft5x06_secure_touch_stop(data, 1);

	ft5x06_update_fw_ver(data);
	ft5x06_update_fw_vendor_id(data);