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

Commit 30be72c8 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "input: synaptics: secure touch support"

parents 20c75df7 f5e0a47f
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -992,10 +992,10 @@ config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE

config SECURE_TOUCH
	bool "Secure Touch"
	depends on TOUCHSCREEN_ATMEL_MXT
	depends on (TOUCHSCREEN_ATMEL_MXT || TOUCHSCREEN_SYNAPTICS_I2C_RMI4 || \
	  TOUCHSCREEN_SYNAPTICS_DSX_I2C_v21)
	help
	  Say Y here to enable Secure Touch support in the Atmel MXT
	  driver.
	  Say Y here to enable Secure Touch in supported drivers.

	  If unsure, say N.

+220 −7
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 *
 * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
 * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
 * Copyright (c) 2014, 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 as published by
@@ -31,6 +32,10 @@
#ifdef KERNEL_ABOVE_2_6_38
#include <linux/input/mt.h>
#endif
#if defined(CONFIG_SECURE_TOUCH)
#include <linux/errno.h>
#include <asm/system.h>
#endif

#define INPUT_PHYS_NAME "synaptics_dsx/input0"
#define DEBUGFS_DIR_NAME "ts_debug"
@@ -134,6 +139,19 @@ static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
static ssize_t synaptics_rmi4_suspend_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count);

static irqreturn_t synaptics_rmi4_irq(int irq, void *data);

#if defined(CONFIG_SECURE_TOUCH)
static ssize_t synaptics_secure_touch_enable_show(struct device *dev,
		struct device_attribute *attr, char *buf);

static ssize_t synaptics_secure_touch_enable_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count);

static ssize_t synaptics_secure_touch_show(struct device *dev,
		struct device_attribute *attr, char *buf);
#endif

struct synaptics_rmi4_f01_device_status {
	union {
		struct {
@@ -362,6 +380,14 @@ static struct device_attribute attrs[] = {
	__ATTR(suspend, S_IWUGO,
			synaptics_rmi4_show_error,
			synaptics_rmi4_suspend_store),
#if defined(CONFIG_SECURE_TOUCH)
	__ATTR(secure_touch_enable, (S_IRUGO | S_IWUGO),
			synaptics_secure_touch_enable_show,
			synaptics_secure_touch_enable_store),
	__ATTR(secure_touch, S_IRUGO ,
			synaptics_secure_touch_show,
			NULL),
#endif
};

static int synaptics_rmi4_debug_suspend_set(void *_data, u64 val)
@@ -388,6 +414,174 @@ static int synaptics_rmi4_debug_suspend_get(void *_data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, synaptics_rmi4_debug_suspend_get,
			synaptics_rmi4_debug_suspend_set, "%lld\n");

#if defined(CONFIG_SECURE_TOUCH)
static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data)
{
	init_completion(&data->st_powerdown);
	init_completion(&data->st_irq_processed);
}
static void synaptics_secure_touch_notify(struct synaptics_rmi4_data *rmi4_data)
{
	sysfs_notify(&rmi4_data->input_dev->dev.kobj, NULL, "secure_touch");
}
static irqreturn_t synaptics_filter_interrupt(
	struct synaptics_rmi4_data *rmi4_data)
{
	if (atomic_read(&rmi4_data->st_enabled)) {
		if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, 0, 1) == 0) {
			synaptics_secure_touch_notify(rmi4_data);
			wait_for_completion_interruptible(
				&rmi4_data->st_irq_processed);
		}
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}
static void synaptics_secure_touch_stop(
	struct synaptics_rmi4_data *rmi4_data,
	int blocking)
{
	if (atomic_read(&rmi4_data->st_enabled)) {
		atomic_set(&rmi4_data->st_pending_irqs, -1);
		synaptics_secure_touch_notify(rmi4_data);
		if (blocking)
			wait_for_completion_interruptible(
				&rmi4_data->st_powerdown);
	}
}
#else
static void synaptics_secure_touch_init(struct synaptics_rmi4_data *rmi4_data)
{
}
static irqreturn_t synaptics_filter_interrupt(
	struct synaptics_rmi4_data *rmi4_data)
{
	return IRQ_NONE;
}
static void synaptics_secure_touch_stop(
	struct synaptics_rmi4_data *rmi4_data,
	int blocking)
{
}
#endif

#if defined(CONFIG_SECURE_TOUCH)
static ssize_t synaptics_secure_touch_enable_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
	return scnprintf(
		buf,
		PAGE_SIZE,
		"%d",
		atomic_read(&rmi4_data->st_enabled));
}
/*
 * Accept only "0" and "1" valid values.
 * "0" will reset the st_enabled flag, then wake up the reading process and
 * the interrupt handler.
 * The bus driver is notified via pm_runtime that it is not required to stay
 * awake anymore.
 * It will also make sure the queue of events is emptied in the controller,
 * in case a touch happened in between the secure touch being disabled and
 * the local ISR being ungated.
 * "1" will set the st_enabled flag and clear the st_pending_irqs flag.
 * The bus driver is requested via pm_runtime to stay awake.
 */
static ssize_t synaptics_secure_touch_enable_store(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
	unsigned long value;
	int err = 0;

	if (count > 2)
		return -EINVAL;

	err = kstrtoul(buf, 10, &value);
	if (err != 0)
		return err;

	err = count;

	switch (value) {
	case 0:
		if (atomic_read(&rmi4_data->st_enabled) == 0)
			break;

		synaptics_rmi4_bus_put(rmi4_data);
		atomic_set(&rmi4_data->st_enabled, 0);
		synaptics_secure_touch_notify(rmi4_data);
		complete(&rmi4_data->st_irq_processed);
		synaptics_rmi4_irq(rmi4_data->irq, rmi4_data);
		complete(&rmi4_data->st_powerdown);

		break;
	case 1:
		if (atomic_read(&rmi4_data->st_enabled)) {
			err = -EBUSY;
			break;
		}

		synchronize_irq(rmi4_data->irq);

		if (synaptics_rmi4_bus_get(rmi4_data) < 0) {
			dev_err(
				rmi4_data->pdev->dev.parent,
				"synaptics_rmi4_bus_get failed\n");
			err = -EIO;
			break;
		}

		INIT_COMPLETION(rmi4_data->st_powerdown);
		INIT_COMPLETION(rmi4_data->st_irq_processed);
		atomic_set(&rmi4_data->st_enabled, 1);
		atomic_set(&rmi4_data->st_pending_irqs,  0);
		break;
	default:
		dev_err(
			rmi4_data->pdev->dev.parent,
			"unsupported value: %lu\n", value);
		err = -EINVAL;
		break;
	}
	return err;
}

/*
 * This function returns whether there are pending interrupts, or
 * other error conditions that need to be signaled to the userspace library,
 * according tot he following logic:
 * - st_enabled is 0 if secure touch is not enabled, returning -EBADF
 * - st_pending_irqs is -1 to signal that secure touch is in being stopped,
 *   returning -EINVAL
 * - st_pending_irqs is 1 to signal that there is a pending irq, returning
 *   the value "1" to the sysfs read operation
 * - st_pending_irqs is 0 (only remaining case left) if the pending interrupt
 *   has been processed, so the interrupt handler can be allowed to continue.
 */
static ssize_t synaptics_secure_touch_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
	int val = 0;
	if (atomic_read(&rmi4_data->st_enabled) == 0)
		return -EBADF;

	if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, -1, 0) == -1)
		return -EINVAL;

	if (atomic_cmpxchg(&rmi4_data->st_pending_irqs, 1, 0) == 1)
		val = 1;
	else
		complete(&rmi4_data->st_irq_processed);

	return scnprintf(buf, PAGE_SIZE, "%u", val);

}
#endif

static ssize_t synaptics_rmi4_full_pm_cycle_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
@@ -1122,6 +1316,9 @@ static irqreturn_t synaptics_rmi4_irq(int irq, void *data)
{
	struct synaptics_rmi4_data *rmi4_data = data;

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

	if (!rmi4_data->touch_stopped)
		synaptics_rmi4_sensor_report(rmi4_data);

@@ -2963,6 +3160,9 @@ static int synaptics_rmi4_probe(struct platform_device *pdev)
		}
	}

	synaptics_secure_touch_init(rmi4_data);
	synaptics_secure_touch_stop(rmi4_data, 1);

	return retval;

err_sysfs:
@@ -3202,13 +3402,18 @@ static int fb_notifier_callback(struct notifier_block *self,
	struct synaptics_rmi4_data *rmi4_data =
		container_of(self, struct synaptics_rmi4_data, fb_notif);

	if (evdata && evdata->data && event == FB_EVENT_BLANK &&
		rmi4_data) {
	if (evdata && evdata->data && rmi4_data) {
		if (event == FB_EARLY_EVENT_BLANK)
			synaptics_secure_touch_stop(rmi4_data, 0);
		else if (event == FB_EVENT_BLANK) {
			blank = evdata->data;
			if (*blank == FB_BLANK_UNBLANK)
			synaptics_rmi4_resume(&(rmi4_data->input_dev->dev));
				synaptics_rmi4_resume(
					&(rmi4_data->input_dev->dev));
			else if (*blank == FB_BLANK_POWERDOWN)
			synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev));
				synaptics_rmi4_suspend(
					&(rmi4_data->input_dev->dev));
		}
	}

	return 0;
@@ -3237,6 +3442,8 @@ static void synaptics_rmi4_early_suspend(struct early_suspend *h)
		rmi4_data->staying_awake = false;
	}

	synaptics_secure_touch_stop(rmi4_data, 0);

	rmi4_data->touch_stopped = true;
	synaptics_rmi4_irq_enable(rmi4_data, false);
	synaptics_rmi4_sensor_sleep(rmi4_data);
@@ -3276,6 +3483,8 @@ static void synaptics_rmi4_late_resume(struct early_suspend *h)
	if (rmi4_data->staying_awake)
		return;

	synaptics_secure_touch_stop(rmi4_data, 0);

	if (rmi4_data->full_pm_cycle)
		synaptics_rmi4_resume(&(rmi4_data->input_dev->dev));

@@ -3328,6 +3537,8 @@ static int synaptics_rmi4_suspend(struct device *dev)
	if (rmi4_data->suspended)
		return 0;

	synaptics_secure_touch_stop(rmi4_data, 1);

	if (!rmi4_data->sensor_sleep) {
		rmi4_data->touch_stopped = true;
		synaptics_rmi4_irq_enable(rmi4_data, false);
@@ -3387,6 +3598,8 @@ static int synaptics_rmi4_resume(struct device *dev)
	if (!rmi4_data->suspended)
		return 0;

	synaptics_secure_touch_stop(rmi4_data, 1);

	synaptics_dsx_regulator_enable(rmi4_data, true);

	if (bdata->disable_gpios) {
+26 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 *
 * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
 * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
 * Copyright (c) 2014, 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 as published by
@@ -33,6 +34,10 @@
#elif defined(CONFIG_HAS_EARLYSUSPEND)
#include <linux/earlysuspend.h>
#endif
#if defined(CONFIG_SECURE_TOUCH)
#include <linux/completion.h>
#include <linux/atomic.h>
#endif

#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38))
#define KERNEL_ABOVE_2_6_38
@@ -273,6 +278,12 @@ struct synaptics_rmi4_data {
	struct pinctrl_state *gpio_state_suspend;
	char fw_name[SYNA_FW_NAME_MAX_LEN];
	bool suspended;
#if defined(CONFIG_SECURE_TOUCH)
	atomic_t st_enabled;
	atomic_t st_pending_irqs;
	struct completion st_powerdown;
	struct completion st_irq_processed;
#endif
};

struct synaptics_dsx_bus_access {
@@ -281,6 +292,10 @@ struct synaptics_dsx_bus_access {
		unsigned char *data, unsigned short length);
	int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr,
		unsigned char *data, unsigned short length);
#if defined(CONFIG_SECURE_TOUCH)
	int (*get)(struct synaptics_rmi4_data *rmi4_data);
	void (*put)(struct synaptics_rmi4_data *rmi4_data);
#endif
};

struct synaptics_rmi4_exp_fn {
@@ -324,6 +339,17 @@ static inline int synaptics_rmi4_reg_write(
	return rmi4_data->hw_if->bus_access->write(rmi4_data, addr, data, len);
}

#if defined(CONFIG_SECURE_TOUCH)
static inline int synaptics_rmi4_bus_get(struct synaptics_rmi4_data *rmi4_data)
{
	return rmi4_data->hw_if->bus_access->get(rmi4_data);
}
static inline void synaptics_rmi4_bus_put(struct synaptics_rmi4_data *rmi4_data)
{
	rmi4_data->hw_if->bus_access->put(rmi4_data);
}
#endif

static inline ssize_t synaptics_rmi4_show_error(struct device *dev,
		struct device_attribute *attr, char *buf)
{
+30 −0
Original line number Diff line number Diff line
@@ -33,6 +33,9 @@
#include "synaptics_dsx_core.h"
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#if defined(CONFIG_SECURE_TOUCH)
#include <linux/pm_runtime.h>
#endif

#define SYN_I2C_RETRY_TIMES 10
#define RESET_DELAY 100
@@ -177,10 +180,37 @@ exit:
	return retval;
}

#if defined(CONFIG_SECURE_TOUCH)
static int synaptics_rmi4_i2c_get(struct synaptics_rmi4_data *rmi4_data)
{
	int retval;
	struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent);

	mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex);
	retval = pm_runtime_get_sync(i2c->adapter->dev.parent);
	mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex);

	return retval;
}

static void synaptics_rmi4_i2c_put(struct synaptics_rmi4_data *rmi4_data)
{
	struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent);

	mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex);
	pm_runtime_put_sync(i2c->adapter->dev.parent);
	mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex);
}
#endif

static struct synaptics_dsx_bus_access bus_access = {
	.type = BUS_I2C,
	.read = synaptics_rmi4_i2c_read,
	.write = synaptics_rmi4_i2c_write,
#if defined(CONFIG_SECURE_TOUCH)
	.get = synaptics_rmi4_i2c_get,
	.put = synaptics_rmi4_i2c_put,
#endif
};

static struct synaptics_dsx_hw_interface hw_if;
+212 −7
Original line number Diff line number Diff line
@@ -30,6 +30,13 @@
#include <linux/pinctrl/consumer.h>
#include <linux/input/synaptics_dsx.h>
#include <linux/of_gpio.h>

#if defined(CONFIG_SECURE_TOUCH)
#include <linux/pm_runtime.h>
#include <linux/errno.h>
#include <asm/system.h>
#endif

#include "synaptics_i2c_rmi4.h"
#include <linux/input/mt.h>

@@ -185,6 +192,19 @@ static int synaptics_rmi4_capacitance_button_map(
				struct synaptics_rmi4_data *rmi4_data,
				struct synaptics_rmi4_fn *fhandler);

static irqreturn_t synaptics_rmi4_irq(int irq, void *data);

#if defined(CONFIG_SECURE_TOUCH)
static ssize_t synaptics_secure_touch_enable_show(struct device *dev,
		struct device_attribute *attr, char *buf);

static ssize_t synaptics_secure_touch_enable_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count);

static ssize_t synaptics_secure_touch_show(struct device *dev,
	    struct device_attribute *attr, char *buf);
#endif

struct synaptics_rmi4_f01_device_status {
	union {
		struct {
@@ -433,12 +453,178 @@ static struct device_attribute attrs[] = {
	__ATTR(flipy, (S_IRUGO | S_IWUSR | S_IWGRP),
			synaptics_rmi4_flipy_show,
			synaptics_rmi4_flipy_store),
#if defined(CONFIG_SECURE_TOUCH)
	__ATTR(secure_touch_enable, (S_IRUGO | S_IWUGO),
			synaptics_secure_touch_enable_show,
			synaptics_secure_touch_enable_store),
	__ATTR(secure_touch, S_IRUGO ,
			synaptics_secure_touch_show,
			NULL),
#endif
};

static bool exp_fn_inited;
static struct mutex exp_fn_list_mutex;
static struct list_head exp_fn_list;

#if defined(CONFIG_SECURE_TOUCH)
static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data)
{
	init_completion(&data->st_powerdown);
	init_completion(&data->st_irq_processed);
}
static void synaptics_secure_touch_notify(struct synaptics_rmi4_data *data)
{
	sysfs_notify(&data->i2c_client->dev.kobj, NULL, "secure_touch");
}
static irqreturn_t synaptics_filter_interrupt(struct synaptics_rmi4_data *data)
{
	if (atomic_read(&data->st_enabled)) {
		if (atomic_cmpxchg(&data->st_pending_irqs, 0, 1) == 0) {
			synaptics_secure_touch_notify(data);
			wait_for_completion_interruptible(
				&data->st_irq_processed);
		}
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}
static void synaptics_secure_touch_stop(
	struct synaptics_rmi4_data *data,
	int blocking)
{
	if (atomic_read(&data->st_enabled)) {
		atomic_set(&data->st_pending_irqs, -1);
		synaptics_secure_touch_notify(data);
		if (blocking)
			wait_for_completion_interruptible(&data->st_powerdown);
	}
}
#else
static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data)
{
}
static irqreturn_t synaptics_filter_interrupt(struct synaptics_rmi4_data *data)
{
	return IRQ_NONE;
}
static void synaptics_secure_touch_stop(
	struct synaptics_rmi4_data *data,
	int blocking)
{
}
#endif

#if defined(CONFIG_SECURE_TOUCH)
static ssize_t synaptics_secure_touch_enable_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	struct synaptics_rmi4_data *data = dev_get_drvdata(dev);
	return scnprintf(buf, PAGE_SIZE, "%d", atomic_read(&data->st_enabled));
}
/*
 * Accept only "0" and "1" valid values.
 * "0" will reset the st_enabled flag, then wake up the reading process and
 * the interrupt handler.
 * The bus driver is notified via pm_runtime that it is not required to stay
 * awake anymore.
 * It will also make sure the queue of events is emptied in the controller,
 * in case a touch happened in between the secure touch being disabled and
 * the local ISR being ungated.
 * "1" will set the st_enabled flag and clear the st_pending_irqs flag.
 * The bus driver is requested via pm_runtime to stay awake.
 */
static ssize_t synaptics_secure_touch_enable_store(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	struct synaptics_rmi4_data *data = dev_get_drvdata(dev);
	unsigned long value;
	int err = 0;

	if (count > 2)
		return -EINVAL;

	err = kstrtoul(buf, 10, &value);
	if (err != 0)
		return err;

	err = count;

	switch (value) {
	case 0:
		if (atomic_read(&data->st_enabled) == 0)
			break;

		pm_runtime_put_sync(data->i2c_client->adapter->dev.parent);
		atomic_set(&data->st_enabled, 0);
		synaptics_secure_touch_notify(data);
		complete(&data->st_irq_processed);
		synaptics_rmi4_irq(data->irq, data);
		complete(&data->st_powerdown);

		break;
	case 1:
		if (atomic_read(&data->st_enabled)) {
			err = -EBUSY;
			break;
		}

		synchronize_irq(data->irq);

		if (pm_runtime_get_sync(
			data->i2c_client->adapter->dev.parent) < 0) {
			dev_err(&data->i2c_client->dev,
				"pm_runtime_get failed\n");
			err = -EIO;
			break;
		}
		INIT_COMPLETION(data->st_powerdown);
		INIT_COMPLETION(data->st_irq_processed);
		atomic_set(&data->st_enabled, 1);
		atomic_set(&data->st_pending_irqs,  0);
		break;
	default:
		dev_err(&data->i2c_client->dev,
			"unsupported value: %lu\n", value);
		err = -EINVAL;
		break;
	}
	return err;
}

/*
 * This function returns whether there are pending interrupts, or
 * other error conditions that need to be signaled to the userspace library,
 * according tot he following logic:
 * - st_enabled is 0 if secure touch is not enabled, returning -EBADF
 * - st_pending_irqs is -1 to signal that secure touch is in being stopped,
 *   returning -EINVAL
 * - st_pending_irqs is 1 to signal that there is a pending irq, returning
 *   the value "1" to the sysfs read operation
 * - st_pending_irqs is 0 (only remaining case left) if the pending interrupt
 *   has been processed, so the interrupt handler can be allowed to continue.
 */
static ssize_t synaptics_secure_touch_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	struct synaptics_rmi4_data *data = dev_get_drvdata(dev);
	int val = 0;
	if (atomic_read(&data->st_enabled) == 0)
		return -EBADF;

	if (atomic_cmpxchg(&data->st_pending_irqs, -1, 0) == -1)
		return -EINVAL;

	if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) == 1)
		val = 1;
	else
		complete(&data->st_irq_processed);

	return scnprintf(buf, PAGE_SIZE, "%u", val);

}
#endif
static int synaptics_rmi4_debug_suspend_set(void *_data, u64 val)
{
	struct synaptics_rmi4_data *rmi4_data = _data;
@@ -1370,6 +1556,9 @@ static irqreturn_t synaptics_rmi4_irq(int irq, void *data)
{
	struct synaptics_rmi4_data *rmi4_data = data;

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

	synaptics_rmi4_sensor_report(rmi4_data);

	return IRQ_HANDLED;
@@ -3426,6 +3615,9 @@ static int synaptics_rmi4_probe(struct i2c_client *client,
		goto err_sysfs;
	}

	synaptics_secure_touch_init(rmi4_data);
	synaptics_secure_touch_stop(rmi4_data, 1);

	retval = synaptics_rmi4_check_configuration(rmi4_data);
	if (retval < 0) {
		dev_err(&client->dev, "Failed to check configuration\n");
@@ -3663,13 +3855,18 @@ static int fb_notifier_callback(struct notifier_block *self,
	struct synaptics_rmi4_data *rmi4_data =
		container_of(self, struct synaptics_rmi4_data, fb_notif);

	if (evdata && evdata->data && event == FB_EVENT_BLANK &&
		rmi4_data && rmi4_data->i2c_client) {
	if (evdata && evdata->data && rmi4_data && rmi4_data->i2c_client) {
		if (event == FB_EARLY_EVENT_BLANK)
			synaptics_secure_touch_stop(rmi4_data, 0);
		else if (event == FB_EVENT_BLANK) {
			blank = evdata->data;
			if (*blank == FB_BLANK_UNBLANK)
			synaptics_rmi4_resume(&(rmi4_data->input_dev->dev));
				synaptics_rmi4_resume(
					&(rmi4_data->input_dev->dev));
			else if (*blank == FB_BLANK_POWERDOWN)
			synaptics_rmi4_suspend(&(rmi4_data->input_dev->dev));
				synaptics_rmi4_suspend(
					&(rmi4_data->input_dev->dev));
		}
	}

	return 0;
@@ -3695,6 +3892,8 @@ static void synaptics_rmi4_early_suspend(struct early_suspend *h)
	else
		rmi4_data->staying_awake = false;

	synaptics_secure_touch_stop(rmi4_data, 0);

	rmi4_data->touch_stopped = true;
	wake_up(&rmi4_data->wait);
	synaptics_rmi4_irq_enable(rmi4_data, false);
@@ -3724,6 +3923,8 @@ static void synaptics_rmi4_late_resume(struct early_suspend *h)
	if (rmi4_data->staying_awake)
		return;

	synaptics_secure_touch_stop(rmi4_data, 0);

	if (rmi4_data->full_pm_cycle)
		synaptics_rmi4_resume(&(rmi4_data->input_dev->dev));

@@ -3925,6 +4126,8 @@ static int synaptics_rmi4_suspend(struct device *dev)
		return 0;
	}

	synaptics_secure_touch_stop(rmi4_data, 1);

	if (!rmi4_data->fw_updating) {
		if (!rmi4_data->sensor_sleep) {
			rmi4_data->touch_stopped = true;
@@ -4005,6 +4208,8 @@ static int synaptics_rmi4_resume(struct device *dev)
		return 0;
	}

	synaptics_secure_touch_stop(rmi4_data, 1);

	retval = synaptics_rmi4_regulator_lpm(rmi4_data, false);
	if (retval < 0) {
		dev_err(dev, "Failed to enter active power mode\n");
Loading