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

Commit f57ed929 authored by Shashank Babu Chinta Venkata's avatar Shashank Babu Chinta Venkata
Browse files

input: touchscreen: st: toggle reset gpio during error on SVM



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

Change-Id: I5d296248c88a6eef13887884892894faa4c984e6
Signed-off-by: default avatarShashank Babu Chinta Venkata <sbchin@codeaurora.org>
parent 6a16d11b
Loading
Loading
Loading
Loading
+67 −1
Original line number Diff line number Diff line
@@ -270,6 +270,49 @@ static void fts_trusted_touch_tvm_vm_mode_disable(struct fts_ts_info *info);
static void fts_trusted_touch_abort_tvm(struct fts_ts_info *info);
static void fts_trusted_touch_event_notify(struct fts_ts_info *info, int event);

void fts_trusted_touch_tvm_i2c_failure_report(struct fts_ts_info *info)
{
	pr_err("initiating trusted touch abort due to i2c failure\n");
	fts_trusted_touch_abort_handler(info,
			TRUSTED_TOUCH_EVENT_I2C_FAILURE);
}

static void fts_trusted_touch_reset_gpio_toggle(struct fts_ts_info *info)
{
	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_info *info,
		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_trusted_touch_get_tvm_driver_state(struct fts_ts_info *info)
{
	int state;
@@ -401,6 +444,7 @@ static void fts_trusted_touch_tvm_vm_mode_enable(struct fts_ts_info *info)
	kfree(expected_sgl_desc);
	kfree(acl_desc);

	fts_trusted_touch_intr_gpio_toggle(info, false);
	irq = hh_irq_accept(info->vm_info->irq_label, -1, IRQ_TYPE_LEVEL_HIGH);
	if (irq < 0) {
		pr_err("failed to accept irq\n");
@@ -1065,6 +1109,14 @@ static void fts_trusted_touch_abort_handler(struct fts_ts_info *info, int error)
{
	atomic_set(&info->trusted_touch_abort_status, error);
	pr_err("TUI session aborted with failure:%d\n", error);
#ifdef CONFIG_ARCH_QTI_VM
	pr_err("Resetting touch controller\n");
	if (fts_trusted_touch_get_tvm_driver_state(info) >= TVM_IOMEM_ACCEPTED
			&& error == TRUSTED_TOUCH_EVENT_I2C_FAILURE) {
		pr_err("Resetting touch controller\n");
		fts_trusted_touch_reset_gpio_toggle(info);
	}
#endif
	fts_trusted_touch_event_notify(info, error);
}

@@ -4621,6 +4673,7 @@ static irqreturn_t fts_interrupt_handler(int irq, void *handle)
		pr_err("%s: Invalid info\n", __func__);
		return IRQ_HANDLED;
	}

	disable_irq_nosync(info->client->irq);

	queue_work(info->event_wq, &info->work);
@@ -4700,13 +4753,26 @@ static void fts_interrupt_uninstall(struct fts_ts_info *info)

static void fts_interrupt_enable(struct fts_ts_info *info)
{
	int ret =  0;
#ifdef FTS_USE_POLLING_MODE
	hrtimer_start(&info->timer, ktime_set(0, 10000000), HRTIMER_MODE_REL);
#else
	enable_irq(info->client->irq);
#endif
	/* enable the touch IC irq */
	fts_enableInterrupt();
	ret = fts_enableInterrupt();
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifndef CONFIG_ARCH_QTI_VM
	if ((ret < 0) && atomic_read(&info->trusted_touch_enabled)) {
		fts_chip_powercycle2(info, 300);
		ret = fts_system_reset();
		ret |= fts_mode_handler(info, 0);
		ret |= fts_enableInterrupt();
		if (ret < 0)
			pr_err("failed to enable touch interrupts\n");
	}
#endif
#endif
}

static void fts_interrupt_disable(struct fts_ts_info *info)
+15 −3
Original line number Diff line number Diff line
@@ -251,17 +251,25 @@ enum trusted_touch_tvm_states {
	TRUSTED_TOUCH_TVM_STATE_MAX
};

#ifdef CONFIG_ST_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_ST_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;
@@ -279,6 +287,10 @@ struct trusted_touch_vm_info {
	atomic_t pvm_state;
#endif
};

#ifdef CONFIG_ARCH_QTI_VM
void fts_trusted_touch_tvm_i2c_failure_report(struct fts_ts_info *info);
#endif
#endif

/*
+45 −4
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
 *
 */

#include <linux/pm_runtime.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
@@ -141,13 +142,32 @@ int fts_readCmd(u8 *cmd, int cmdLength, u8 *outBuf, int byteToRead)
	while (retry < I2C_RETRY && ret < OK) {
		ret = i2c_transfer(client->adapter, I2CMsg, 2);
		retry++;
		if (ret < OK)
		if (ret < OK) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
			if (atomic_read(&info->trusted_touch_enabled) &&
					ret == -ECONNRESET){
				pr_err("failed i2c read reacquiring session\n");
				pm_runtime_put_sync(
					info->client->adapter->dev.parent);
				pm_runtime_get_sync(
					info->client->adapter->dev.parent);
			}
#endif
#endif
			msleep(I2C_WAIT_BEFORE_RETRY);
		}
	}
	if (ret < 0) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
		pr_err("initiating abort due to i2c xfer failure\n");
		fts_trusted_touch_tvm_i2c_failure_report(info);
#endif
#endif
		logError(1, "%s %s: ERROR %02X\n",
			tag, __func__, ERROR_I2C_R);
		return ERROR_I2C_R;
		return ret;
	}

	memcpy(outBuf, buf + cmdLength, byteToRead);
@@ -189,13 +209,34 @@ int fts_writeCmd(u8 *cmd, int cmdLength)
	while (retry < I2C_RETRY && ret < OK) {
		ret = i2c_transfer(client->adapter, I2CMsg, 1);
		retry++;
		if (ret < OK)
		if (ret < OK) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
			if (atomic_read(&info->trusted_touch_enabled) &&
					ret == -ECONNRESET){
				pr_err("failed i2c write reacquiring session\n");
				pm_runtime_put_sync(
					info->client->adapter->dev.parent);
				pm_runtime_get_sync(
					info->client->adapter->dev.parent);

			}
#endif
#endif
			msleep(I2C_WAIT_BEFORE_RETRY);
			logError(1, "ERROR: %d\n", ret);
		}
		//logError(1,"%s fts_writeCmd: attempt %d\n", tag, retry);
	}
	if (ret < 0) {
#ifdef CONFIG_ST_TRUSTED_TOUCH
#ifdef CONFIG_ARCH_QTI_VM
		pr_err("initiating abort due to i2c xfer failure\n");
		fts_trusted_touch_tvm_i2c_failure_report(info);
#endif
#endif
		logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_W);
		return ERROR_I2C_W;
		return ret;
	}
	return OK;
}
+5 −3
Original line number Diff line number Diff line
@@ -789,11 +789,13 @@ int fts_disableInterrupt(void)
int fts_enableInterrupt(void)
{
	u8 cmd[4] = { FTS_CMD_HW_REG_W, 0x00, 0x00, IER_ENABLE };
	int ret = 0;

	u16ToU8_be(IER_ADDR, &cmd[1]);
	if (fts_writeCmd(cmd, 4) < 0) {
		logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_W);
		return ERROR_I2C_W;
	ret = fts_writeCmd(cmd, 4);
	if (ret < 0) {
		logError(1, "%s %s: ERROR %d\n", tag, __func__, ret);
		return ret;
	}
	logError(0, "%s Interrupt Enabled!\n", tag);
	return OK;