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. Change-Id: Id43118120d4a1f0682904f48b3584d3ba62ef1dd Signed-off-by: Shantanu Jain <shjain@codeaurora.org>
This commit is contained in:
parent
930440dc31
commit
52344fa3c6
3 changed files with 178 additions and 0 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue