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

Commit a75bcbc3 authored by Shantanu Jain's avatar Shantanu Jain
Browse files

input: synaptics_dsx_2.6: creation of secure touch sysfs ifiles



This patch creates two sysfs files for secure touch - secure_touch
and secure_touch_enable, which will be accessed by secure UI app.
We also define the store and show function for these sysfs files.

CRs-Fixed: 990820
Change-Id: Id43118120d4a1f0682904f48b3584d3ba62ef1dd
Signed-off-by: default avatarShantanu Jain <shjain@codeaurora.org>
parent 4a580c23
Loading
Loading
Loading
Loading
+136 −0
Original line number Diff line number Diff line
@@ -172,6 +172,19 @@ static ssize_t synaptics_rmi4_wake_gesture_store(struct device *dev,
static ssize_t synaptics_rmi4_virtual_key_map_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf);

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

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

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

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

struct synaptics_rmi4_f01_device_status {
	union {
		struct {
@@ -617,6 +630,14 @@ static struct device_attribute attrs[] = {
	__ATTR(wake_gesture, (S_IRUGO | S_IWUSR | S_IWGRP),
			synaptics_rmi4_wake_gesture_show,
			synaptics_rmi4_wake_gesture_store),
#if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26)
	__ATTR(secure_touch_enable, (S_IRUGO | S_IWUSR | S_IWGRP),
			synaptics_rmi4_secure_touch_enable_show,
			synaptics_rmi4_secure_touch_enable_store),
	__ATTR(secure_touch, S_IRUGO ,
			synaptics_rmi4_secure_touch_show,
			NULL),
#endif
};

static struct kobj_attribute virtual_key_map_attr = {
@@ -688,6 +709,121 @@ static void synaptics_secure_touch_stop(struct synaptics_rmi4_data *rmi4_data,
}
#endif

#if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26)
static ssize_t synaptics_rmi4_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_rmi4_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;
		}
		reinit_completion(&rmi4_data->st_powerdown);
		reinit_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_rmi4_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_f01_reset_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
+15 −0
Original line number Diff line number Diff line
@@ -394,6 +394,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_SYNAPTICS_DSX_V26)
	int (*get)(struct synaptics_rmi4_data *rmi4_data);
	void (*put)(struct synaptics_rmi4_data *rmi4_data);
#endif
};

struct synaptics_dsx_hw_interface {
@@ -444,6 +448,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_SYNAPTICS_DSX_V26)
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)
{
+27 −0
Original line number Diff line number Diff line
@@ -497,10 +497,37 @@ exit:
	return retval;
}

#if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26)
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_SYNAPTICS_DSX_V26)
	.get = synaptics_rmi4_i2c_get,
	.put = synaptics_rmi4_i2c_put,
#endif
};

static void synaptics_rmi4_i2c_dev_release(struct device *dev)