mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge "input: touchscreen: synaptics_tcm: Fix Propagation"
This commit is contained in:
commit
12652534c7
10 changed files with 315 additions and 216 deletions
|
|
@ -1314,4 +1314,18 @@ source "drivers/input/touchscreen/st/Kconfig"
|
|||
|
||||
source "drivers/input/touchscreen/focaltech_touch/Kconfig"
|
||||
|
||||
config TOUCHSCREEN_SYNAPTICS_TCM
|
||||
bool "Synaptics TCM Touchscreen Driver"
|
||||
depends on I2C
|
||||
default y
|
||||
help
|
||||
Say Y here if you have a Synaptics Touchscreen.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called synaptics_tcm.
|
||||
|
||||
source "drivers/input/touchscreen/synaptics_tcm/Kconfig"
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -112,3 +112,4 @@ obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o
|
|||
obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ST) += st/
|
||||
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/
|
||||
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_TCM) += synaptics_tcm/
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
menuconfig TOUCHSCREEN_SYNAPTICS_TCM
|
||||
bool "Synaptics TCM touchscreen"
|
||||
default y
|
||||
help
|
||||
Say Y here if you have a Synaptics TCM touchscreen connected
|
||||
to your system.
|
||||
|
|
@ -41,6 +42,7 @@ endchoice
|
|||
config TOUCHSCREEN_SYNAPTICS_TCM_CORE
|
||||
tristate "Synaptics TCM core module"
|
||||
depends on I2C || SPI_MASTER
|
||||
default y
|
||||
help
|
||||
Say Y here to enable core functionality.
|
||||
|
||||
|
|
@ -52,6 +54,7 @@ config TOUCHSCREEN_SYNAPTICS_TCM_CORE
|
|||
config TOUCHSCREEN_SYNAPTICS_TCM_TOUCH
|
||||
tristate "Synaptics TCM touch module"
|
||||
depends on TOUCHSCREEN_SYNAPTICS_TCM_CORE
|
||||
default y
|
||||
help
|
||||
Say Y here to enable support for touch reporting.
|
||||
|
||||
|
|
@ -63,6 +66,7 @@ config TOUCHSCREEN_SYNAPTICS_TCM_TOUCH
|
|||
config TOUCHSCREEN_SYNAPTICS_TCM_DEVICE
|
||||
tristate "Synaptics TCM device module"
|
||||
depends on TOUCHSCREEN_SYNAPTICS_TCM_CORE
|
||||
default y
|
||||
help
|
||||
Say Y here to enable support for TCM device functionality.
|
||||
|
||||
|
|
@ -85,6 +89,7 @@ config TOUCHSCREEN_SYNAPTICS_TCM_TESTING
|
|||
config TOUCHSCREEN_SYNAPTICS_TCM_REFLASH
|
||||
tristate "Synaptics TCM reflash module"
|
||||
depends on TOUCHSCREEN_SYNAPTICS_TCM_CORE
|
||||
default y
|
||||
help
|
||||
Say Y here to enable support for reflash functionality.
|
||||
|
||||
|
|
@ -96,6 +101,7 @@ config TOUCHSCREEN_SYNAPTICS_TCM_REFLASH
|
|||
config TOUCHSCREEN_SYNAPTICS_TCM_RECOVERY
|
||||
tristate "Synaptics TCM recovery module"
|
||||
depends on TOUCHSCREEN_SYNAPTICS_TCM_CORE
|
||||
default y
|
||||
help
|
||||
Say Y here to enable support for recovery functionality.
|
||||
|
||||
|
|
@ -118,6 +124,7 @@ config TOUCHSCREEN_SYNAPTICS_TCM_ZEROFLASH
|
|||
config TOUCHSCREEN_SYNAPTICS_TCM_DIAGNOSTICS
|
||||
tristate "Synaptics TCM diagnostics module"
|
||||
depends on TOUCHSCREEN_SYNAPTICS_TCM_CORE
|
||||
default y
|
||||
help
|
||||
Say Y here to enable support for diagnostics functionality.
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,16 @@
|
|||
|
||||
/* #define FORCE_RUN_APPLICATION_FIRMWARE */
|
||||
|
||||
#define SYNA_VTG_MIN_UV 2800000
|
||||
|
||||
#define SYNA_VTG_MAX_UV 3300000
|
||||
|
||||
#define SYNA_LOAD_MAX_UA 30000
|
||||
|
||||
#define SYNA_VDD_VTG_MIN_UV 1800000
|
||||
|
||||
#define SYNA_VDD_VTG_MAX_UV 2000000
|
||||
|
||||
#define NOTIFIER_PRIORITY 2
|
||||
|
||||
#define RESPONSE_TIMEOUT_MS 3000
|
||||
|
|
@ -1911,6 +1921,22 @@ static int syna_tcm_enable_regulator(struct syna_tcm_hcd *tcm_hcd, bool en)
|
|||
}
|
||||
|
||||
if (tcm_hcd->bus_reg) {
|
||||
retval = regulator_set_voltage(tcm_hcd->bus_reg,
|
||||
SYNA_VDD_VTG_MIN_UV, SYNA_VDD_VTG_MAX_UV);
|
||||
if (retval) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"set bus regulator voltage failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
retval = regulator_set_load(tcm_hcd->bus_reg,
|
||||
SYNA_LOAD_MAX_UA);
|
||||
if (retval) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"set bus regulator load failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
retval = regulator_enable(tcm_hcd->bus_reg);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
|
|
@ -1920,6 +1946,23 @@ static int syna_tcm_enable_regulator(struct syna_tcm_hcd *tcm_hcd, bool en)
|
|||
}
|
||||
|
||||
if (tcm_hcd->pwr_reg) {
|
||||
if (regulator_count_voltages(tcm_hcd->pwr_reg) > 0) {
|
||||
retval = regulator_set_voltage(tcm_hcd->pwr_reg,
|
||||
SYNA_VTG_MIN_UV, SYNA_VTG_MAX_UV);
|
||||
if (retval) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"set power regulator voltage failed\n");
|
||||
goto disable_bus_reg;
|
||||
}
|
||||
retval = regulator_set_load(tcm_hcd->pwr_reg,
|
||||
SYNA_LOAD_MAX_UA);
|
||||
if (retval) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"set power regulator load failed\n");
|
||||
goto disable_bus_reg;
|
||||
}
|
||||
}
|
||||
|
||||
retval = regulator_enable(tcm_hcd->pwr_reg);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
|
|
@ -1932,12 +1975,22 @@ static int syna_tcm_enable_regulator(struct syna_tcm_hcd *tcm_hcd, bool en)
|
|||
return 0;
|
||||
|
||||
disable_pwr_reg:
|
||||
if (tcm_hcd->pwr_reg)
|
||||
if (tcm_hcd->pwr_reg) {
|
||||
if (regulator_count_voltages(tcm_hcd->pwr_reg) > 0) {
|
||||
regulator_set_load(tcm_hcd->pwr_reg, 0);
|
||||
regulator_set_voltage(tcm_hcd->pwr_reg, 0,
|
||||
SYNA_VTG_MAX_UV);
|
||||
}
|
||||
regulator_disable(tcm_hcd->pwr_reg);
|
||||
}
|
||||
|
||||
disable_bus_reg:
|
||||
if (tcm_hcd->bus_reg)
|
||||
if (tcm_hcd->bus_reg) {
|
||||
regulator_set_load(tcm_hcd->bus_reg, 0);
|
||||
regulator_set_voltage(tcm_hcd->bus_reg, 0,
|
||||
SYNA_VDD_VTG_MAX_UV);
|
||||
regulator_disable(tcm_hcd->bus_reg);
|
||||
}
|
||||
|
||||
exit:
|
||||
return retval;
|
||||
|
|
@ -2840,6 +2893,9 @@ static int syna_tcm_resume(struct device *dev)
|
|||
|
||||
if (!tcm_hcd->init_okay)
|
||||
syna_tcm_deferred_probe(dev);
|
||||
|
||||
if (!tcm_hcd->in_suspend)
|
||||
return 0;
|
||||
else {
|
||||
if (tcm_hcd->irq_enabled) {
|
||||
tcm_hcd->watchdog.run = false;
|
||||
|
|
@ -2848,8 +2904,11 @@ static int syna_tcm_resume(struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
if (!tcm_hcd->in_suspend)
|
||||
return 0;
|
||||
retval = syna_tcm_enable_regulator(tcm_hcd, true);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"Failed to enable regulators\n");
|
||||
}
|
||||
|
||||
retval = pinctrl_select_state(
|
||||
tcm_hcd->ts_pinctrl,
|
||||
|
|
@ -2945,6 +3004,7 @@ static int syna_tcm_suspend(struct device *dev)
|
|||
{
|
||||
struct syna_tcm_module_handler *mod_handler;
|
||||
struct syna_tcm_hcd *tcm_hcd = dev_get_drvdata(dev);
|
||||
int retval;
|
||||
|
||||
if (tcm_hcd->in_suspend || !tcm_hcd->init_okay)
|
||||
return 0;
|
||||
|
|
@ -2967,11 +3027,17 @@ static int syna_tcm_suspend(struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
retval = syna_tcm_enable_regulator(tcm_hcd, false);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"Failed to disable regulators\n");
|
||||
}
|
||||
|
||||
mutex_unlock(&mod_pool.mutex);
|
||||
|
||||
tcm_hcd->in_suspend = true;
|
||||
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -3040,21 +3106,18 @@ static int syna_tcm_fb_notifier_cb(struct notifier_block *nb,
|
|||
unsigned long action, void *data)
|
||||
{
|
||||
int retval = 0;
|
||||
int *transition;
|
||||
struct msm_drm_notifier *evdata = data;
|
||||
int transition;
|
||||
struct drm_panel_notifier *evdata = data;
|
||||
struct syna_tcm_hcd *tcm_hcd =
|
||||
container_of(nb, struct syna_tcm_hcd, fb_notifier);
|
||||
|
||||
if (!evdata || (evdata->id != 0))
|
||||
if (!evdata)
|
||||
return 0;
|
||||
|
||||
if (!evdata->data || !tcm_hcd)
|
||||
return 0;
|
||||
|
||||
transition = (int *) evdata->data;
|
||||
transition = *(int *)evdata->data;
|
||||
|
||||
if (atomic_read(&tcm_hcd->firmware_flashing)
|
||||
&& *transition == MSM_DRM_BLANK_POWERDOWN) {
|
||||
&& transition == DRM_PANEL_BLANK_POWERDOWN) {
|
||||
retval = wait_event_interruptible_timeout(tcm_hcd->reflash_wq,
|
||||
!atomic_read(&tcm_hcd->firmware_flashing),
|
||||
msecs_to_jiffies(RESPONSE_TIMEOUT_MS));
|
||||
|
|
@ -3066,21 +3129,21 @@ static int syna_tcm_fb_notifier_cb(struct notifier_block *nb,
|
|||
}
|
||||
}
|
||||
|
||||
if (action == MSM_DRM_EARLY_EVENT_BLANK &&
|
||||
*transition == MSM_DRM_BLANK_POWERDOWN)
|
||||
if (action == DRM_PANEL_EARLY_EVENT_BLANK &&
|
||||
transition == DRM_PANEL_BLANK_POWERDOWN)
|
||||
retval = syna_tcm_early_suspend(&tcm_hcd->pdev->dev);
|
||||
else if (action == MSM_DRM_EVENT_BLANK) {
|
||||
if (*transition == MSM_DRM_BLANK_POWERDOWN) {
|
||||
else if (action == DRM_PANEL_EVENT_BLANK) {
|
||||
if (transition == DRM_PANEL_BLANK_POWERDOWN) {
|
||||
retval = syna_tcm_suspend(&tcm_hcd->pdev->dev);
|
||||
tcm_hcd->fb_ready = 0;
|
||||
} else if (*transition == MSM_DRM_BLANK_UNBLANK) {
|
||||
} else if (transition == DRM_PANEL_BLANK_UNBLANK) {
|
||||
#ifndef RESUME_EARLY_UNBLANK
|
||||
retval = syna_tcm_resume(&tcm_hcd->pdev->dev);
|
||||
tcm_hcd->fb_ready++;
|
||||
#endif
|
||||
}
|
||||
} else if (action == MSM_DRM_EARLY_EVENT_BLANK &&
|
||||
*transition == MSM_DRM_BLANK_UNBLANK) {
|
||||
} else if (action == DRM_PANEL_EARLY_EVENT_BLANK &&
|
||||
transition == DRM_PANEL_BLANK_UNBLANK) {
|
||||
#ifdef RESUME_EARLY_UNBLANK
|
||||
retval = syna_tcm_resume(&tcm_hcd->pdev->dev);
|
||||
tcm_hcd->fb_ready++;
|
||||
|
|
@ -3249,6 +3312,7 @@ static int syna_tcm_probe(struct platform_device *pdev)
|
|||
struct syna_tcm_hcd *tcm_hcd;
|
||||
const struct syna_tcm_board_data *bdata;
|
||||
const struct syna_tcm_hw_interface *hw_if;
|
||||
struct drm_panel *active_panel = tcm_get_panel();
|
||||
|
||||
hw_if = pdev->dev.platform_data;
|
||||
if (!hw_if) {
|
||||
|
|
@ -3356,10 +3420,30 @@ static int syna_tcm_probe(struct platform_device *pdev)
|
|||
goto err_get_regulator;
|
||||
}
|
||||
|
||||
retval = synaptics_tcm_pinctrl_init(tcm_hcd);
|
||||
retval = syna_tcm_enable_regulator(tcm_hcd, true);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent, "Failed to init pinctrl\n");
|
||||
goto err_pinctrl_init;
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"Failed to enable regulators\n");
|
||||
goto err_enable_regulator;
|
||||
}
|
||||
|
||||
retval = syna_tcm_config_gpio(tcm_hcd);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"Failed to configure GPIO's\n");
|
||||
goto err_config_gpio;
|
||||
}
|
||||
|
||||
retval = synaptics_tcm_pinctrl_init(tcm_hcd);
|
||||
if (!retval && tcm_hcd->ts_pinctrl) {
|
||||
retval = pinctrl_select_state(
|
||||
tcm_hcd->ts_pinctrl,
|
||||
tcm_hcd->pinctrl_state_active);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"%s: Failed to select %s pinstate %d\n",
|
||||
__func__, PINCTRL_STATE_ACTIVE, retval);
|
||||
}
|
||||
}
|
||||
|
||||
sysfs_dir = kobject_create_and_add(PLATFORM_DRIVER_NAME,
|
||||
|
|
@ -3405,11 +3489,17 @@ static int syna_tcm_probe(struct platform_device *pdev)
|
|||
|
||||
#ifdef CONFIG_DRM
|
||||
tcm_hcd->fb_notifier.notifier_call = syna_tcm_fb_notifier_cb;
|
||||
retval = msm_drm_register_client(&tcm_hcd->fb_notifier);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"Failed to register DRM notifier client\n");
|
||||
if (active_panel) {
|
||||
retval = drm_panel_notifier_register(active_panel,
|
||||
&tcm_hcd->fb_notifier);
|
||||
if (retval < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"%s: Failed to register fb notifier client\n",
|
||||
__func__);
|
||||
goto err_drm_reg;
|
||||
}
|
||||
}
|
||||
|
||||
#elif CONFIG_FB
|
||||
tcm_hcd->fb_notifier.notifier_call = syna_tcm_fb_notifier_cb;
|
||||
retval = fb_register_client(&tcm_hcd->fb_notifier);
|
||||
|
|
@ -3452,7 +3542,9 @@ static int syna_tcm_probe(struct platform_device *pdev)
|
|||
|
||||
err_create_run_kthread:
|
||||
#ifdef CONFIG_DRM
|
||||
msm_drm_unregister_client(&tcm_hcd->fb_notifier);
|
||||
if (active_panel)
|
||||
drm_panel_notifier_unregister(active_panel,
|
||||
&tcm_hcd->fb_notifier);
|
||||
#elif CONFIG_FB
|
||||
fb_unregister_client(&tcm_hcd->fb_notifier);
|
||||
#endif
|
||||
|
|
@ -3475,7 +3567,21 @@ err_sysfs_create_file:
|
|||
kobject_put(tcm_hcd->sysfs_dir);
|
||||
|
||||
err_sysfs_create_dir:
|
||||
err_pinctrl_init:
|
||||
if (bdata->irq_gpio >= 0)
|
||||
syna_tcm_set_gpio(tcm_hcd, bdata->irq_gpio, false, 0, 0);
|
||||
|
||||
if (bdata->power_gpio >= 0)
|
||||
syna_tcm_set_gpio(tcm_hcd, bdata->power_gpio, false, 0, 0);
|
||||
|
||||
if (bdata->reset_gpio >= 0)
|
||||
syna_tcm_set_gpio(tcm_hcd, bdata->reset_gpio, false, 0, 0);
|
||||
|
||||
err_config_gpio:
|
||||
syna_tcm_enable_regulator(tcm_hcd, false);
|
||||
|
||||
err_enable_regulator:
|
||||
syna_tcm_get_regulator(tcm_hcd, false);
|
||||
|
||||
err_get_regulator:
|
||||
device_init_wakeup(&pdev->dev, 0);
|
||||
|
||||
|
|
@ -3487,6 +3593,7 @@ err_alloc_mem:
|
|||
RELEASE_BUFFER(tcm_hcd->out);
|
||||
RELEASE_BUFFER(tcm_hcd->in);
|
||||
|
||||
err_drm_reg:
|
||||
kfree(tcm_hcd);
|
||||
|
||||
return retval;
|
||||
|
|
@ -3495,33 +3602,8 @@ err_alloc_mem:
|
|||
static int syna_tcm_deferred_probe(struct device *dev)
|
||||
{
|
||||
int retval;
|
||||
const struct syna_tcm_board_data *bdata;
|
||||
struct syna_tcm_hcd *tcm_hcd = dev_get_drvdata(dev);
|
||||
|
||||
retval = pinctrl_select_state(
|
||||
tcm_hcd->ts_pinctrl,
|
||||
tcm_hcd->pinctrl_state_active);
|
||||
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"Failed to pinctrl_select_state\n");
|
||||
goto err_pinctrl_select_state;
|
||||
}
|
||||
|
||||
retval = syna_tcm_enable_regulator(tcm_hcd, true);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"Failed to enable regulators\n");
|
||||
goto err_enable_regulator;
|
||||
}
|
||||
|
||||
retval = syna_tcm_config_gpio(tcm_hcd);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
"Failed to configure GPIO's\n");
|
||||
goto err_config_gpio;
|
||||
}
|
||||
|
||||
retval = tcm_hcd->enable_irq(tcm_hcd, true, NULL);
|
||||
if (retval < 0) {
|
||||
LOGE(tcm_hcd->pdev->dev.parent,
|
||||
|
|
@ -3552,27 +3634,6 @@ err_reset:
|
|||
#endif
|
||||
err_enable_irq:
|
||||
|
||||
err_config_gpio:
|
||||
syna_tcm_enable_regulator(tcm_hcd, false);
|
||||
|
||||
err_enable_regulator:
|
||||
syna_tcm_get_regulator(tcm_hcd, false);
|
||||
|
||||
err_pinctrl_select_state:
|
||||
if (!tcm_hcd->hw_if || !tcm_hcd->hw_if->bdata)
|
||||
return -EINVAL;
|
||||
|
||||
bdata = tcm_hcd->hw_if->bdata;
|
||||
|
||||
if (bdata->irq_gpio >= 0)
|
||||
syna_tcm_set_gpio(tcm_hcd, bdata->irq_gpio, false, 0, 0);
|
||||
|
||||
if (bdata->power_gpio >= 0)
|
||||
syna_tcm_set_gpio(tcm_hcd, bdata->power_gpio, false, 0, 0);
|
||||
|
||||
if (bdata->reset_gpio >= 0)
|
||||
syna_tcm_set_gpio(tcm_hcd, bdata->reset_gpio, false, 0, 0);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -3584,6 +3645,7 @@ static int syna_tcm_remove(struct platform_device *pdev)
|
|||
struct syna_tcm_module_handler *tmp_handler;
|
||||
struct syna_tcm_hcd *tcm_hcd = platform_get_drvdata(pdev);
|
||||
const struct syna_tcm_board_data *bdata = tcm_hcd->hw_if->bdata;
|
||||
struct drm_panel *active_panel = tcm_get_panel();
|
||||
|
||||
mutex_lock(&mod_pool.mutex);
|
||||
|
||||
|
|
@ -3624,7 +3686,9 @@ static int syna_tcm_remove(struct platform_device *pdev)
|
|||
kthread_stop(tcm_hcd->notifier_thread);
|
||||
|
||||
#ifdef CONFIG_DRM
|
||||
msm_drm_unregister_client(&tcm_hcd->fb_notifier);
|
||||
if (active_panel)
|
||||
drm_panel_notifier_unregister(active_panel,
|
||||
&tcm_hcd->fb_notifier);
|
||||
#elif CONFIG_FB
|
||||
fb_unregister_client(&tcm_hcd->fb_notifier);
|
||||
#endif
|
||||
|
|
@ -3668,11 +3732,6 @@ static int syna_tcm_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void syna_tcm_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
syna_tcm_remove(pdev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static const struct dev_pm_ops syna_tcm_dev_pm_ops = {
|
||||
#if !defined(CONFIG_DRM) && !defined(CONFIG_FB)
|
||||
|
|
@ -3692,7 +3751,6 @@ static struct platform_driver syna_tcm_driver = {
|
|||
},
|
||||
.probe = syna_tcm_probe,
|
||||
.remove = syna_tcm_remove,
|
||||
.shutdown = syna_tcm_shutdown,
|
||||
};
|
||||
|
||||
static int __init syna_tcm_module_init(void)
|
||||
|
|
@ -3713,7 +3771,7 @@ static void __exit syna_tcm_module_exit(void)
|
|||
syna_tcm_bus_exit();
|
||||
}
|
||||
|
||||
module_init(syna_tcm_module_init);
|
||||
late_initcall(syna_tcm_module_init);
|
||||
module_exit(syna_tcm_module_exit);
|
||||
|
||||
MODULE_AUTHOR("Synaptics, Inc.");
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/input/synaptics_tcm.h>
|
||||
#ifdef CONFIG_DRM
|
||||
#include <linux/msm_drm_notify.h>
|
||||
#include <drm/drm_panel.h>
|
||||
#elif CONFIG_FB
|
||||
#include <linux/fb.h>
|
||||
#include <linux/notifier.h>
|
||||
|
|
@ -522,6 +522,8 @@ struct syna_tcm_hw_interface {
|
|||
const struct syna_tcm_bus_io *bus_io;
|
||||
};
|
||||
|
||||
struct drm_panel *tcm_get_panel(void);
|
||||
|
||||
int syna_tcm_bus_init(void);
|
||||
|
||||
void syna_tcm_bus_exit(void);
|
||||
|
|
|
|||
|
|
@ -411,9 +411,6 @@ static void diag_report(void)
|
|||
diag_hcd->state = state;
|
||||
state = PING;
|
||||
}
|
||||
|
||||
if (diag_hcd->pid)
|
||||
send_sig_info(SIGIO, &diag_hcd->sigio, diag_hcd->task);
|
||||
}
|
||||
|
||||
static int diag_init(struct syna_tcm_hcd *tcm_hcd)
|
||||
|
|
|
|||
|
|
@ -47,145 +47,95 @@ static struct syna_tcm_hw_interface hw_if;
|
|||
|
||||
static struct platform_device *syna_tcm_i2c_device;
|
||||
|
||||
active_tp_setup(synaptics_tcm);
|
||||
static struct drm_panel *active_tcm_panel;
|
||||
|
||||
struct drm_panel *tcm_get_panel(void)
|
||||
{
|
||||
return active_tcm_panel;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static int parse_dt(struct device *dev, struct syna_tcm_board_data *bdata)
|
||||
{
|
||||
int retval;
|
||||
u32 value;
|
||||
struct property *prop;
|
||||
struct device_node *np = dev->of_node;
|
||||
const char *name;
|
||||
|
||||
prop = of_find_property(np, "synaptics,irq-gpio", NULL);
|
||||
if (prop && prop->length) {
|
||||
bdata->irq_gpio = of_get_named_gpio_flags(np,
|
||||
"synaptics,irq-gpio", 0,
|
||||
(enum of_gpio_flags *)&bdata->irq_flags);
|
||||
} else {
|
||||
bdata->irq_gpio = -1;
|
||||
retval = of_get_named_gpio_flags(np,
|
||||
"synaptics,irq-gpio", 0,
|
||||
(enum of_gpio_flags *)&bdata->irq_flags);
|
||||
if (!gpio_is_valid(retval)) {
|
||||
if (retval != -EPROBE_DEFER)
|
||||
dev_err(dev, "Error getting irq_gpio\n");
|
||||
return retval;
|
||||
}
|
||||
bdata->irq_gpio = retval;
|
||||
|
||||
retval = of_property_read_u32(np, "synaptics,irq-on-state", &value);
|
||||
if (retval < 0)
|
||||
bdata->irq_on_state = 0;
|
||||
else
|
||||
bdata->irq_on_state = value;
|
||||
of_property_read_u32(np, "synaptics,irq-on-state",
|
||||
&bdata->irq_on_state);
|
||||
of_property_read_string(np, "synaptics,pwr-reg-name",
|
||||
&bdata->pwr_reg_name);
|
||||
of_property_read_string(np, "synaptics,bus-reg-name",
|
||||
&bdata->bus_reg_name);
|
||||
of_property_read_string(np, "synaptics,firmware-name",
|
||||
&bdata->fw_name);
|
||||
|
||||
retval = of_property_read_string(np, "synaptics,pwr-reg-name", &name);
|
||||
if (retval < 0)
|
||||
bdata->pwr_reg_name = NULL;
|
||||
else
|
||||
bdata->pwr_reg_name = name;
|
||||
bdata->power_gpio = of_get_named_gpio_flags(np,
|
||||
"synaptics,power-gpio", 0, NULL);
|
||||
|
||||
retval = of_property_read_string(np, "synaptics,bus-reg-name", &name);
|
||||
if (retval < 0)
|
||||
bdata->bus_reg_name = NULL;
|
||||
else
|
||||
bdata->bus_reg_name = name;
|
||||
|
||||
prop = of_find_property(np, "synaptics,power-gpio", NULL);
|
||||
if (prop && prop->length) {
|
||||
bdata->power_gpio = of_get_named_gpio_flags(np,
|
||||
"synaptics,power-gpio", 0, NULL);
|
||||
} else {
|
||||
bdata->power_gpio = -1;
|
||||
}
|
||||
|
||||
prop = of_find_property(np, "synaptics,power-on-state", NULL);
|
||||
if (prop && prop->length) {
|
||||
retval = of_property_read_u32(np, "synaptics,power-on-state",
|
||||
&value);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Failed to read synaptics,power-on-state\n");
|
||||
return retval;
|
||||
}
|
||||
bdata->power_on_state = value;
|
||||
} else {
|
||||
retval = of_property_read_u32(np, "synaptics,power-on-state",
|
||||
&bdata->power_on_state);
|
||||
if (retval < 0) {
|
||||
LOGD(dev, "Failed to read synaptics,power-on-state\n");
|
||||
bdata->power_on_state = 0;
|
||||
}
|
||||
|
||||
prop = of_find_property(np, "synaptics,power-delay-ms", NULL);
|
||||
if (prop && prop->length) {
|
||||
retval = of_property_read_u32(np, "synaptics,power-delay-ms",
|
||||
&value);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Failed to read synaptics,power-delay-ms\n");
|
||||
return retval;
|
||||
}
|
||||
bdata->power_delay_ms = value;
|
||||
} else {
|
||||
bdata->power_delay_ms = 0;
|
||||
retval = of_property_read_u32(np, "synaptics,power-delay-ms",
|
||||
&bdata->power_delay_ms);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Failed to read synaptics,power-delay-ms\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
prop = of_find_property(np, "synaptics,reset-gpio", NULL);
|
||||
if (prop && prop->length) {
|
||||
bdata->reset_gpio = of_get_named_gpio_flags(np,
|
||||
"synaptics,reset-gpio", 0, NULL);
|
||||
} else {
|
||||
bdata->reset_gpio = -1;
|
||||
retval = of_get_named_gpio_flags(np,
|
||||
"synaptics,reset-gpio", 0, NULL);
|
||||
if (!gpio_is_valid(retval)) {
|
||||
if (retval != -EPROBE_DEFER)
|
||||
dev_err(dev, "Error getting reset gpio\n");
|
||||
return retval;
|
||||
}
|
||||
bdata->reset_gpio = retval;
|
||||
|
||||
retval = of_property_read_u32(np, "synaptics,reset-on-state",
|
||||
&bdata->reset_on_state);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Failed to read synaptics,reset-on-state\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
prop = of_find_property(np, "synaptics,reset-on-state", NULL);
|
||||
if (prop && prop->length) {
|
||||
retval = of_property_read_u32(np, "synaptics,reset-on-state",
|
||||
&value);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Failed to read synaptics,reset-on-state\n");
|
||||
return retval;
|
||||
}
|
||||
bdata->reset_on_state = value;
|
||||
} else {
|
||||
bdata->reset_on_state = 0;
|
||||
retval = of_property_read_u32(np, "synaptics,reset-active-ms",
|
||||
&bdata->reset_active_ms);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Failed to read synaptics,reset-active-ms\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
prop = of_find_property(np, "synaptics,reset-active-ms", NULL);
|
||||
if (prop && prop->length) {
|
||||
retval = of_property_read_u32(np, "synaptics,reset-active-ms",
|
||||
&value);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Failed to read synaptics,reset-active-ms\n");
|
||||
return retval;
|
||||
}
|
||||
bdata->reset_active_ms = value;
|
||||
} else {
|
||||
bdata->reset_active_ms = 0;
|
||||
retval = of_property_read_u32(np, "synaptics,reset-delay-ms",
|
||||
&bdata->reset_delay_ms);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Unable to read synaptics,reset-delay-ms\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
prop = of_find_property(np, "synaptics,reset-delay-ms", NULL);
|
||||
if (prop && prop->length) {
|
||||
retval = of_property_read_u32(np, "synaptics,reset-delay-ms",
|
||||
&value);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Unable to read synaptics,reset-delay-ms\n");
|
||||
return retval;
|
||||
}
|
||||
bdata->reset_delay_ms = value;
|
||||
} else {
|
||||
bdata->reset_delay_ms = 0;
|
||||
}
|
||||
bdata->x_flip = of_property_read_bool(np, "synaptics,x-flip");
|
||||
bdata->y_flip = of_property_read_bool(np, "synaptics,y-flip");
|
||||
bdata->swap_axes = of_property_read_bool(np, "synaptics,swap-axes");
|
||||
|
||||
prop = of_find_property(np, "synaptics,x-flip", NULL);
|
||||
bdata->x_flip = prop > 0 ? true : false;
|
||||
|
||||
prop = of_find_property(np, "synaptics,y-flip", NULL);
|
||||
bdata->y_flip = prop > 0 ? true : false;
|
||||
|
||||
prop = of_find_property(np, "synaptics,swap-axes", NULL);
|
||||
bdata->swap_axes = prop > 0 ? true : false;
|
||||
|
||||
prop = of_find_property(np, "synaptics,ubl-i2c-addr", NULL);
|
||||
if (prop && prop->length) {
|
||||
retval = of_property_read_u32(np, "synaptics,ubl-i2c-addr",
|
||||
&value);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Unable to read synaptics,ubl-i2c-addr\n");
|
||||
return retval;
|
||||
}
|
||||
bdata->ubl_i2c_addr = value;
|
||||
} else {
|
||||
bdata->ubl_i2c_addr = 0;
|
||||
retval = of_property_read_u32(np, "synaptics,ubl-i2c-addr",
|
||||
&bdata->ubl_i2c_addr);
|
||||
if (retval < 0) {
|
||||
LOGE(dev, "Unable to read synaptics,ubl-i2c-addr\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
bdata->extend_report = of_property_read_bool(np,
|
||||
|
|
@ -219,7 +169,7 @@ static int syna_tcm_i2c_alloc_mem(struct syna_tcm_hcd *tcm_hcd,
|
|||
static int syna_tcm_i2c_rmi_read(struct syna_tcm_hcd *tcm_hcd,
|
||||
unsigned short addr, unsigned char *data, unsigned int length)
|
||||
{
|
||||
int retval;
|
||||
int retval = 0;
|
||||
unsigned char address;
|
||||
unsigned int attempt;
|
||||
struct i2c_msg msg[2];
|
||||
|
|
@ -327,7 +277,7 @@ exit:
|
|||
static int syna_tcm_i2c_read(struct syna_tcm_hcd *tcm_hcd, unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
int retval;
|
||||
int retval = 0;
|
||||
unsigned int attempt;
|
||||
struct i2c_msg msg;
|
||||
struct i2c_client *i2c = to_i2c_client(tcm_hcd->pdev->dev.parent);
|
||||
|
|
@ -365,7 +315,7 @@ exit:
|
|||
static int syna_tcm_i2c_write(struct syna_tcm_hcd *tcm_hcd, unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
int retval;
|
||||
int retval = 0;
|
||||
unsigned int attempt;
|
||||
struct i2c_msg msg;
|
||||
struct i2c_client *i2c = to_i2c_client(tcm_hcd->pdev->dev.parent);
|
||||
|
|
@ -400,15 +350,73 @@ exit:
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int syna_tcm_check_dt(struct device_node *np)
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
struct device_node *node;
|
||||
struct drm_panel *panel;
|
||||
|
||||
count = of_count_phandle_with_args(np, "panel", NULL);
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
node = of_parse_phandle(np, "panel", i);
|
||||
panel = of_drm_find_panel(node);
|
||||
of_node_put(node);
|
||||
if (!IS_ERR(panel)) {
|
||||
active_tcm_panel = panel;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int syna_tcm_check_default_tp(struct device_node *dt, const char *prop)
|
||||
{
|
||||
const char *active_tp;
|
||||
const char *compatible;
|
||||
char *start;
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_string(dt->parent, prop, &active_tp);
|
||||
if (ret) {
|
||||
pr_err(" %s:fail to read %s %d\n", __func__, prop, ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = of_property_read_string(dt, "compatible", &compatible);
|
||||
if (ret < 0) {
|
||||
pr_err(" %s:fail to read %s %d\n", __func__, "compatible", ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
start = strnstr(active_tp, compatible, strlen(active_tp));
|
||||
if (start == NULL) {
|
||||
pr_err(" %s:no match compatible, %s, %s\n",
|
||||
__func__, compatible, active_tp);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int syna_tcm_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *dev_id)
|
||||
{
|
||||
int retval;
|
||||
struct device_node *dt = i2c->dev.of_node;
|
||||
|
||||
if (synaptics_tcm_check_assigned_tp(dt, "compatible",
|
||||
"qcom,i2c-touch-active") < 0)
|
||||
return -ENODEV;
|
||||
if (syna_tcm_check_dt(dt)) {
|
||||
if (!syna_tcm_check_default_tp(dt, "qcom,i2c-touch-active"))
|
||||
retval = -EPROBE_DEFER;
|
||||
else
|
||||
retval = -ENODEV;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
syna_tcm_i2c_device = platform_device_alloc(PLATFORM_DRIVER_NAME, 0);
|
||||
if (!syna_tcm_i2c_device) {
|
||||
|
|
@ -424,7 +432,11 @@ static int syna_tcm_i2c_probe(struct i2c_client *i2c,
|
|||
"Failed to allocate memory for board data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
parse_dt(&i2c->dev, hw_if.bdata);
|
||||
retval = parse_dt(&i2c->dev, hw_if.bdata);
|
||||
if (retval < 0) {
|
||||
LOGE(&i2c->dev, "Failed to parse dt\n");
|
||||
return retval;
|
||||
}
|
||||
#else
|
||||
hw_if.bdata = i2c->dev.platform_data;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -744,7 +744,7 @@ static int recovery_do_recovery(void)
|
|||
|
||||
static int recovery_init(struct syna_tcm_hcd *tcm_hcd)
|
||||
{
|
||||
int retval;
|
||||
int retval = 0;
|
||||
int idx;
|
||||
|
||||
recovery_hcd = kzalloc(sizeof(*recovery_hcd), GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -926,15 +926,22 @@ static int reflash_parse_fw_image(void)
|
|||
static int reflash_get_fw_image(void)
|
||||
{
|
||||
int retval;
|
||||
const char *fw_name;
|
||||
struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
|
||||
const struct syna_tcm_board_data *bdata = tcm_hcd->hw_if->bdata;
|
||||
|
||||
if (bdata->fw_name)
|
||||
fw_name = bdata->fw_name;
|
||||
else
|
||||
fw_name = FW_IMAGE_NAME;
|
||||
|
||||
if (reflash_hcd->image == NULL) {
|
||||
retval = request_firmware(&reflash_hcd->fw_entry, FW_IMAGE_NAME,
|
||||
retval = request_firmware(&reflash_hcd->fw_entry, fw_name,
|
||||
tcm_hcd->pdev->dev.parent);
|
||||
if (retval < 0) {
|
||||
LOGD(tcm_hcd->pdev->dev.parent,
|
||||
"Failed to request %s\n",
|
||||
FW_IMAGE_NAME);
|
||||
fw_name);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1761,7 +1768,7 @@ static int reflash_update_boot_config(bool lock)
|
|||
int retval;
|
||||
unsigned char slot_used;
|
||||
unsigned int idx;
|
||||
unsigned int addr;
|
||||
unsigned int addr = 0;
|
||||
struct boot_config *data;
|
||||
struct boot_config *last_slot;
|
||||
struct syna_tcm_hcd *tcm_hcd = reflash_hcd->tcm_hcd;
|
||||
|
|
@ -1976,7 +1983,7 @@ static void reflash_startup_work(struct work_struct *work)
|
|||
|
||||
static int reflash_init(struct syna_tcm_hcd *tcm_hcd)
|
||||
{
|
||||
int retval;
|
||||
int retval = 0;
|
||||
int idx;
|
||||
|
||||
reflash_hcd = kzalloc(sizeof(*reflash_hcd), GFP_KERNEL);
|
||||
|
|
|
|||
Loading…
Reference in a new issue