summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavidycchen <davidycchen@google.com>2021-10-15 11:36:24 +0800
committerDavid Chen <davidycchen@google.com>2021-10-21 09:19:57 +0000
commitbf9731c028f5959aa4e80834bd5579c906b894b9 (patch)
tree368bc9e2cca3f68537aee65f4f339ff8a7fc37bc
parent89fea965cf3ec4f058d9f4dec13ddc583db43673 (diff)
downloadsynaptics_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.c7
-rw-r--r--syna_tcm2.h4
-rw-r--r--syna_tcm2_sysfs.c103
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,
};