diff options
author | davidycchen <davidycchen@google.com> | 2021-10-15 11:36:24 +0800 |
---|---|---|
committer | David Chen <davidycchen@google.com> | 2021-10-21 09:19:57 +0000 |
commit | bf9731c028f5959aa4e80834bd5579c906b894b9 (patch) | |
tree | 368bc9e2cca3f68537aee65f4f339ff8a7fc37bc | |
parent | 89fea965cf3ec4f058d9f4dec13ddc583db43673 (diff) | |
download | synaptics_touch-bf9731c028f5959aa4e80834bd5579c906b894b9.tar.gz |
synaptics: support more bus reference mode
Support force touch bus active and sysfs bus reference bit to make sure
the touch bus is avtive while transferring SPI data.
Bug: 199104466
Test: write the sysfs command successfully.
Signed-off-by: davidycchen <davidycchen@google.com>
Change-Id: Ic0ffe78917a749b5b1e9796972846b5e13440485
-rw-r--r-- | syna_tcm2.c | 7 | ||||
-rw-r--r-- | syna_tcm2.h | 4 | ||||
-rw-r--r-- | syna_tcm2_sysfs.c | 103 |
3 files changed, 114 insertions, 0 deletions
diff --git a/syna_tcm2.c b/syna_tcm2.c index f43d6cd..96f4606 100644 --- a/syna_tcm2.c +++ b/syna_tcm2.c @@ -1947,6 +1947,13 @@ static int syna_pm_suspend(struct device *dev) if (tcm->pwr_state == PWR_ON) { LOGW("can't suspend because touch bus is in use!\n"); + if (tcm->bus_refmask == SYNA_BUS_REF_BUGREPORT && + ktime_ms_delta(ktime_get(), tcm->bugreport_ktime_start) > 30 * MSEC_PER_SEC) { + syna_set_bus_ref(tcm, SYNA_BUS_REF_BUGREPORT, false); + pm_relax(&tcm->pdev->dev); + tcm->bugreport_ktime_start = 0; + LOGE("Force release SYNA_BUS_REF_BUGREPORT reference bit."); + } return -EBUSY; } diff --git a/syna_tcm2.h b/syna_tcm2.h index b98170c..39def51 100644 --- a/syna_tcm2.h +++ b/syna_tcm2.h @@ -262,6 +262,9 @@ enum { SYNA_BUS_REF_SCREEN_ON = 0x0001, SYNA_BUS_REF_IRQ = 0x0002, SYNA_BUS_REF_FW_UPDATE = 0x0004, + SYNA_BUS_REF_SYSFS = 0x0008, + SYNA_BUS_REF_FORCE_ACTIVE = 0x0010, + SYNA_BUS_REF_BUGREPORT = 0x0020, }; /** @@ -324,6 +327,7 @@ struct syna_tcm { u32 bus_refmask; struct mutex bus_mutex; + ktime_t bugreport_ktime_start; /* IOCTL-related variables */ pid_t proc_pid; diff --git a/syna_tcm2_sysfs.c b/syna_tcm2_sysfs.c index a74cdb0..03ac8d2 100644 --- a/syna_tcm2_sysfs.c +++ b/syna_tcm2_sysfs.c @@ -474,6 +474,8 @@ static ssize_t syna_sysfs_reset_store(struct kobject *kobj, syna_pal_mutex_lock(&g_extif_mutex); + syna_set_bus_ref(tcm, SYNA_BUS_REF_SYSFS, true); + if (input == 1) { retval = syna_tcm_reset(tcm->tcm_dev); if (retval < 0) { @@ -501,6 +503,7 @@ static ssize_t syna_sysfs_reset_store(struct kobject *kobj, retval = count; exit: + syna_set_bus_ref(tcm, SYNA_BUS_REF_SYSFS, false); syna_pal_mutex_unlock(&g_extif_mutex); return retval; } @@ -553,6 +556,8 @@ static ssize_t syna_sysfs_scan_mode_store(struct kobject *kobj, syna_pal_mutex_lock(&g_extif_mutex); + syna_set_bus_ref(tcm, SYNA_BUS_REF_SYSFS, true); + if (hw_if->ops_hw_reset) { hw_if->ops_hw_reset(hw_if); } else { @@ -595,6 +600,7 @@ static ssize_t syna_sysfs_scan_mode_store(struct kobject *kobj, retval = count; exit: + syna_set_bus_ref(tcm, SYNA_BUS_REF_SYSFS, false); syna_pal_mutex_unlock(&g_extif_mutex); return retval; } @@ -603,6 +609,102 @@ static struct kobj_attribute kobj_attr_scan_mode = __ATTR(scan_mode, 0220, NULL, syna_sysfs_scan_mode_store); /** + * syna_sysfs_force_active_store() + * + * Attribute to set different scan mode. + * 0x10 - Set SYNA_BUS_REF_FORCE_ACTIVE bit 0. + * 0x11 - Set SYNA_BUS_REF_FORCE_ACTIVE bit 1. + * 0x20 - Set SYNA_BUS_REF_BUGREPORT bit 0. + * 0x21 - Set SYNA_BUS_REF_BUGREPORT bit 1. + * + * @param + * [ in] kobj: an instance of kobj + * [ in] attr: an instance of kobj attribute structure + * [ in] buf: string buffer input + * [ in] count: size of buffer input + * + * @return + * on success, return count; otherwise, return error code + */ +static ssize_t syna_sysfs_force_active_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int retval = 0; + unsigned char input; + struct device *p_dev; + struct kobject *p_kobj; + struct syna_tcm *tcm; + bool active; + u32 ref = 0; + + p_kobj = g_sysfs_dir->parent; + p_dev = container_of(p_kobj, struct device, kobj); + tcm = dev_get_drvdata(p_dev); + + if (kstrtou8(buf, 16, &input)) + return -EINVAL; + + if (!tcm->is_connected) { + LOGW("Device is NOT connected\n"); + retval = count; + goto exit; + } + + syna_pal_mutex_lock(&g_extif_mutex); + + switch (input) { + case 0x10: + ref = SYNA_BUS_REF_FORCE_ACTIVE; + active = false; + break; + case 0x11: + ref = SYNA_BUS_REF_FORCE_ACTIVE; + active = true; + break; + case 0x20: + ref = SYNA_BUS_REF_BUGREPORT; + active = false; + tcm->bugreport_ktime_start = 0; + break; + case 0x21: + ref = SYNA_BUS_REF_BUGREPORT; + active = true; + tcm->bugreport_ktime_start = ktime_get(); + break; + default: + LOGE("Invalid input %#x.\n", input); + retval = -EINVAL; + goto exit; + } + + LOGI("Set bus reference bit %#x %s.", ref, + active ? "enable" : "disable"); + + if (active) + pm_stay_awake(&tcm->pdev->dev); + else + pm_relax(&tcm->pdev->dev); + + retval = syna_set_bus_ref(tcm, ref, active); + if (retval < 0) { + LOGE("Set bus reference bit %#x %s failed.", ref, + active ? "enable" : "disable"); + goto exit; + } + + retval = count; + +exit: + syna_pal_mutex_unlock(&g_extif_mutex); + return retval; +} + +static struct kobj_attribute kobj_attr_force_active = + __ATTR(force_active, 0220, NULL, syna_sysfs_force_active_store); + + + +/** * declaration of sysfs attributes */ static struct attribute *attrs[] = { @@ -610,6 +712,7 @@ static struct attribute *attrs[] = { &kobj_attr_irq_en.attr, &kobj_attr_reset.attr, &kobj_attr_scan_mode.attr, + &kobj_attr_force_active.attr, NULL, }; |