Merge "input: touchscreen: synaptics_tcm: Fix Propagation"

This commit is contained in:
qctecmdr 2020-07-22 12:28:37 -07:00 • committed by Gerrit - the friendly Code Review server
commit 12652534c7
10 changed files with 315 additions and 216 deletions

View file

@ -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

View file

@ -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/

View file

@ -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.

View file

@ -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.");

View file

@ -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);

View file

@ -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)

View file

@ -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

View file

@ -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);

View file

@ -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);