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

Commit 88af9a72 authored by Ritesh Kumar's avatar Ritesh Kumar Committed by Gerrit - the friendly Code Review server
Browse files

input: touchscreen: focaltech: toggle reset gpio during error



Toggle reset gpio of touch controller during an error scenario
on Secondary Virtual Machine(SVM).

Change-Id: Id5fdbb8e0106e636676060edfb05b6219f7400c8
Signed-off-by: default avatarRitesh Kumar <riteshk@codeaurora.org>
parent 6aca8a8c
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -247,6 +247,49 @@ static void fts_ts_trusted_touch_tvm_vm_mode_disable(struct fts_ts_data *fts_dat
static void fts_ts_trusted_touch_abort_tvm(struct fts_ts_data *fts_data);
static void fts_ts_trusted_touch_event_notify(struct fts_ts_data *fts_data, int event);

void fts_ts_trusted_touch_tvm_i2c_failure_report(struct fts_ts_data *fts_data)
{
	pr_err("initiating trusted touch abort due to i2c failure\n");
	fts_ts_trusted_touch_abort_handler(fts_data,
			TRUSTED_TOUCH_EVENT_I2C_FAILURE);
}

static void fts_ts_trusted_touch_reset_gpio_toggle(struct fts_ts_data *fts_data)
{
	void __iomem *base;

	base = ioremap(TOUCH_RESET_GPIO_BASE, TOUCH_RESET_GPIO_SIZE);
	writel_relaxed(0x1, base + TOUCH_RESET_GPIO_OFFSET);
	/* wait until toggle to finish*/
	wmb();
	writel_relaxed(0x0, base + TOUCH_RESET_GPIO_OFFSET);
	/* wait until toggle to finish*/
	wmb();
	iounmap(base);
}

static void fts_trusted_touch_intr_gpio_toggle(struct fts_ts_data *fts_data,
		bool enable)
{
	void __iomem *base;
	u32 val;

	base = ioremap(TOUCH_INTR_GPIO_BASE, TOUCH_INTR_GPIO_SIZE);
	val = readl_relaxed(base + TOUCH_RESET_GPIO_OFFSET);
	if (enable) {
		val |= BIT(0);
		writel_relaxed(val, base + TOUCH_INTR_GPIO_OFFSET);
		/* wait until toggle to finish*/
		wmb();
	} else {
		val &= ~BIT(0);
		writel_relaxed(val, base + TOUCH_INTR_GPIO_OFFSET);
		/* wait until toggle to finish*/
		wmb();
	}
	iounmap(base);
}

static int fts_ts_trusted_touch_get_tvm_driver_state(struct fts_ts_data *fts_data)
{
	int state;
@@ -376,6 +419,7 @@ static void fts_ts_trusted_touch_tvm_vm_mode_enable(struct fts_ts_data *fts_data
	kfree(acl_desc);

	irq = hh_irq_accept(fts_data->vm_info->irq_label, -1, IRQ_TYPE_EDGE_RISING);
	fts_trusted_touch_intr_gpio_toggle(fts_data, false);
	if (irq < 0) {
		pr_err("failed to accept irq\n");
		goto accept_fail;
@@ -1040,6 +1084,14 @@ static void fts_ts_trusted_touch_abort_handler(struct fts_ts_data *fts_data, int
	atomic_set(&fts_data->trusted_touch_abort_status, error);
	pr_err("TUI session aborted with failure:%d\n", error);
	fts_ts_trusted_touch_event_notify(fts_data, error);
#ifdef CONFIG_ARCH_QTI_VM
	pr_err("Resetting touch controller\n");
	if (fts_ts_trusted_touch_get_tvm_driver_state(fts_data) >= TVM_IOMEM_ACCEPTED
			&& error == TRUSTED_TOUCH_EVENT_I2C_FAILURE) {
		pr_err("Resetting touch controller\n");
		fts_ts_trusted_touch_reset_gpio_toggle(fts_data);
	}
#endif
}

static int fts_ts_vm_init(struct fts_ts_data *fts_data)
+16 −3
Original line number Diff line number Diff line
@@ -178,17 +178,25 @@ enum trusted_touch_tvm_states {
	TRUSTED_TOUCH_TVM_STATE_MAX
};

#ifdef CONFIG_FTS_TRUSTED_TOUCH
#define TRUSTED_TOUCH_MEM_LABEL 0x7

#define TOUCH_RESET_GPIO_BASE 0xF116000
#define TOUCH_RESET_GPIO_SIZE 0x1000
#define TOUCH_RESET_GPIO_OFFSET 0x4
#define TOUCH_INTR_GPIO_BASE 0xF117000
#define TOUCH_INTR_GPIO_SIZE 0x1000
#define TOUCH_INTR_GPIO_OFFSET 0x8

#define TRUSTED_TOUCH_EVENT_LEND_FAILURE -1
#define TRUSTED_TOUCH_EVENT_LEND_NOTIFICATION_FAILURE -2
#define TRUSTED_TOUCH_EVENT_ACCEPT_FAILURE -3
#define	TRUSTED_TOUCH_EVENT_FUNCTIONAL_FAILURE -4
#define	TRUSTED_TOUCH_EVENT_RELEASE_FAILURE -5
#define	TRUSTED_TOUCH_EVENT_RECLAIM_FAILURE -6
#define	TRUSTED_TOUCH_EVENT_I2C_FAILURE -7
#define	TRUSTED_TOUCH_EVENT_NOTIFICATIONS_PENDING 5

#ifdef CONFIG_FTS_TRUSTED_TOUCH
#define TRUSTED_TOUCH_MEM_LABEL 0x7

struct trusted_touch_vm_info {
	enum hh_irq_label irq_label;
	enum hh_vm_names vm_name;
@@ -346,4 +354,9 @@ void fts_irq_disable(void);
void fts_irq_enable(void);
int fts_ts_handle_trusted_touch_pvm(struct fts_ts_data *ts_data, int value);
int fts_ts_handle_trusted_touch_tvm(struct fts_ts_data *ts_data, int value);
#ifdef CONFIG_FTS_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
void fts_ts_trusted_touch_tvm_i2c_failure_report(struct fts_ts_data *fts_data);
#endif
#endif
#endif /* __LINUX_FOCALTECH_CORE_H__ */
+43 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@
* Included header files
*****************************************************************************/
#include "focaltech_core.h"

#include <linux/pm_runtime.h>
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
@@ -101,6 +101,18 @@ int fts_read(u8 *cmd, u32 cmdlen, u8 *data, u32 datalen)
	for (i = 0; i < I2C_RETRY_NUMBER; i++) {
		ret = i2c_transfer(ts_data->client->adapter, msg, msg_num);
		if (ret < 0) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
			if (atomic_read(&ts_data->trusted_touch_enabled) &&
					ret == -ECONNRESET) {
				pr_err("failed i2c read reacquiring session\n");
				pm_runtime_put_sync(
					ts_data->client->adapter->dev.parent);
				pm_runtime_get_sync(
					ts_data->client->adapter->dev.parent);
			}
#endif
#endif
			FTS_ERROR("i2c_transfer(read) fail,ret:%d", ret);
		} else {
			memcpy(data, ts_data->bus_rx_buf, datalen);
@@ -108,6 +120,15 @@ int fts_read(u8 *cmd, u32 cmdlen, u8 *data, u32 datalen)
		}
	}

	if (ret < 0) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
		pr_err("initiating abort due to i2c xfer failure\n");
		fts_ts_trusted_touch_tvm_i2c_failure_report(ts_data);
#endif
#endif
	}

	mutex_unlock(&ts_data->bus_lock);
	return ret;
}
@@ -135,11 +156,32 @@ int fts_write(u8 *writebuf, u32 writelen)
	for (i = 0; i < I2C_RETRY_NUMBER; i++) {
		ret = i2c_transfer(ts_data->client->adapter, &msgs, 1);
		if (ret < 0) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
			if (atomic_read(&ts_data->trusted_touch_enabled) &&
				ret == -ECONNRESET){
				pr_err("failed i2c write reacquiring session\n");
				pm_runtime_put_sync(
					ts_data->client->adapter->dev.parent);
				pm_runtime_get_sync(
					ts_data->client->adapter->dev.parent);
			}
#endif
#endif
			FTS_ERROR("i2c_transfer(write) fail,ret:%d", ret);
		} else {
			break;
		}
	}

	if (ret < 0) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
		pr_err("initiating abort due to i2c xfer failure\n");
		fts_ts_trusted_touch_tvm_i2c_failure_report(ts_data);
#endif
#endif
	}
	mutex_unlock(&ts_data->bus_lock);
	return ret;
}