diff options
Diffstat (limited to 'drivers')
5 files changed, 78 insertions, 10 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 61a13ddabc5e..69028bd45fdd 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1177,14 +1177,4 @@ config TOUCHSCREEN_FT5X06 To compile this driver as a module, choose M here: the module will be called ft5x06_ts. -config SECURE_TOUCH_SYNAPTICS_DSX_V26 - bool "Secure Touch support for Synaptics V2.6 Touchscreen" - depends on TOUCHSCREEN_SYNAPTICS_DSX_I2C_v26 - help - Say Y here - -Synaptics DSX V2.6 touch driver is connected - -To enable secure touch for Synaptics DSX V2.6 touch driver - - If unsure, say N. - endif diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig b/drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig index 78b995ec7c8a..53896288ba77 100644 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig +++ b/drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig @@ -114,4 +114,14 @@ config TOUCHSCREEN_SYNAPTICS_DSX_VIDEO_v26 To compile this driver as a module, choose M here: the module will be called synaptics_dsx_video. +config SECURE_TOUCH_SYNAPTICS_DSX_V26 + bool "Secure Touch support for Synaptics V2.6 Touchscreen" + depends on TOUCHSCREEN_SYNAPTICS_DSX_I2C_v26 + help + Say Y here + -Synaptics DSX V2.6 touch driver is connected + -To enable secure touch for Synaptics DSX V2.6 touch driver + + If unsure, say N. + endif diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c index f0bf062c8a3c..f3e939c3686a 100644 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c +++ b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.c @@ -651,8 +651,33 @@ static struct kobj_attribute virtual_key_map_attr = { #if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26) static void synaptics_secure_touch_init(struct synaptics_rmi4_data *data) { + int ret = 0; + + data->st_initialized = 0; init_completion(&data->st_powerdown); init_completion(&data->st_irq_processed); + + /* Get clocks */ + data->core_clk = devm_clk_get(data->pdev->dev.parent, "core_clk"); + if (IS_ERR(data->core_clk)) { + ret = PTR_ERR(data->core_clk); + data->core_clk = NULL; + dev_warn(data->pdev->dev.parent, + "%s: error on clk_get(core_clk): %d\n", __func__, ret); + return; + } + + data->iface_clk = devm_clk_get(data->pdev->dev.parent, "iface_clk"); + if (IS_ERR(data->iface_clk)) { + ret = PTR_ERR(data->iface_clk); + data->iface_clk = NULL; + dev_warn(data->pdev->dev.parent, + "%s: error on clk_get(iface_clk): %d\n", __func__, ret); + return; + } + + data->st_initialized = 1; + return; } static void synaptics_secure_touch_notify(struct synaptics_rmi4_data *rmi4_data) @@ -745,6 +770,9 @@ static ssize_t synaptics_rmi4_secure_touch_enable_store(struct device *dev, if (err != 0) return err; + if (!rmi4_data->st_initialized) + return -EIO; + err = count; switch (value) { diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.h b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.h index f0d8c124bac6..25decbdf41d0 100644 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.h +++ b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_core.h @@ -52,6 +52,7 @@ #include <linux/completion.h> #include <linux/atomic.h> #include <linux/pm_runtime.h> +#include <linux/clk.h> #endif #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)) @@ -385,6 +386,9 @@ struct synaptics_rmi4_data { atomic_t st_pending_irqs; struct completion st_powerdown; struct completion st_irq_processed; + bool st_initialized; + struct clk *core_clk; + struct clk *iface_clk; #endif }; diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c index 56c5d5e1b9f2..fbf90f4ae62b 100644 --- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c +++ b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c @@ -498,6 +498,34 @@ exit: } #if defined(CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26) +static int synaptics_rmi4_clk_prepare_enable( + struct synaptics_rmi4_data *rmi4_data) +{ + int ret; + + ret = clk_prepare_enable(rmi4_data->iface_clk); + if (ret) { + dev_err(rmi4_data->pdev->dev.parent, + "error on clk_prepare_enable(iface_clk):%d\n", ret); + return ret; + } + + ret = clk_prepare_enable(rmi4_data->core_clk); + if (ret) { + clk_disable_unprepare(rmi4_data->iface_clk); + dev_err(rmi4_data->pdev->dev.parent, + "error clk_prepare_enable(core_clk):%d\n", ret); + } + return ret; +} + +static void synaptics_rmi4_clk_disable_unprepare( + struct synaptics_rmi4_data *rmi4_data) +{ + clk_disable_unprepare(rmi4_data->core_clk); + clk_disable_unprepare(rmi4_data->iface_clk); +} + static int synaptics_rmi4_i2c_get(struct synaptics_rmi4_data *rmi4_data) { int retval; @@ -505,6 +533,12 @@ static int synaptics_rmi4_i2c_get(struct synaptics_rmi4_data *rmi4_data) mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex); retval = pm_runtime_get_sync(i2c->adapter->dev.parent); + if (retval >= 0 && rmi4_data->core_clk != NULL && + rmi4_data->iface_clk != NULL) { + retval = synaptics_rmi4_clk_prepare_enable(rmi4_data); + if (retval) + pm_runtime_put_sync(i2c->adapter->dev.parent); + } mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); return retval; @@ -515,6 +549,8 @@ 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); + if (rmi4_data->core_clk != NULL && rmi4_data->iface_clk != NULL) + synaptics_rmi4_clk_disable_unprepare(rmi4_data); pm_runtime_put_sync(i2c->adapter->dev.parent); mutex_unlock(&rmi4_data->rmi4_io_ctrl_mutex); } |