From a0732e6085b0b0f62444edf5b4d0e076de130d6b Mon Sep 17 00:00:00 2001 From: Shantanu Jain Date: Mon, 21 Mar 2016 14:09:27 +0530 Subject: [PATCH] input: synaptics_dsx_2.6: Add support for clocks for secure touch Because of a change in the underlying bus driver, the secure touch layer in the input drivers is now required to control directly the clocks which are needed during the touch sessions. The clocks which are associated with the underlying I2C bus are clk_gcc_blsp1_ahb_clk and clk_gcc_blsp1_qup3_i2c_apps_clk. These clocks are turned on/off when the secure touch session is started/ended. CRs-Fixed: 990820 Change-Id: Ie2f6f5b736b27792e6e4dc2c39064e0ebdc03d7b Signed-off-by: Shantanu Jain Signed-off-by: Abinaya P --- .../touchscreen/synaptics_dsxv26_i2c.txt | 7 ++++ drivers/input/touchscreen/Kconfig | 10 ------ .../touchscreen/synaptics_dsx_2.6/Kconfig | 10 ++++++ .../synaptics_dsx_2.6/synaptics_dsx_core.c | 28 +++++++++++++++ .../synaptics_dsx_2.6/synaptics_dsx_core.h | 4 +++ .../synaptics_dsx_2.6/synaptics_dsx_i2c.c | 36 +++++++++++++++++++ 6 files changed, 85 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt b/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt index 7dece8e06240..c10fd981df2b 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/synaptics_dsxv26_i2c.txt @@ -25,6 +25,9 @@ Optional property: - synaptics,y-flip : modify orientation of the y axis. - synaptics,reset-delay-ms : reset delay for controller (ms), default 100. - synaptics,max-y-for-2d : maximal y value of the panel. + - clock-names : Clock names used for secure touch. They are: "iface_clk", "core_clk" + - clocks : Defined if 'clock-names' DT property is defined. These clocks + are associated with the underlying I2C bus. Example: i2c@78b7000 { @@ -46,5 +49,9 @@ Example: synaptics,max-y-for-2d = <1919>; /* remove if no virtual buttons */ synaptics,cap-button-codes = <139 172 158>; synaptics,vir-button-codes = <139 180 2000 320 160 172 540 2000 320 160 158 900 2000 320 160>; + /* Underlying clocks used by secure touch */ + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup3_i2c_apps_clk>; }; }; 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 #include #include +#include #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); }