mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 15:11:48 -04:00
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: Shashank Babu Chinta Venkata <sbchin@codeaurora.org>
This commit is contained in:
parent
6a16d11bf3
commit
f57ed9297e
4 changed files with 132 additions and 11 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue