summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuper Liu <supercjliu@google.com>2020-04-24 11:31:08 +0800
committerSuper Liu <supercjliu@google.com>2020-06-02 02:57:58 +0000
commit3af7c5ad298d8981ab8c8b46c0e4fe81f0465492 (patch)
treedd7aee54cc703d8325d15e5125fe465d31c912c0
parent7539c8997d0eb5137c2402c17abbcbd75217a040 (diff)
downloadsec_touch-3af7c5ad298d8981ab8c8b46c0e4fe81f0465492.tar.gz
sec_touch: change charger mode if wireless charger online
When wireless charger is online, harmonic by charging frequency will hit the touch band and cause ghost touch. Bug: 154486745 Change-Id: Ic8bbab34e96ef8545233250ab444087f3febcfd5 Signed-off-by: Super Liu <supercjliu@google.com>
-rw-r--r--sec_ts.c184
-rw-r--r--sec_ts.h17
-rw-r--r--sec_ts_fn.c4
3 files changed, 174 insertions, 31 deletions
diff --git a/sec_ts.c b/sec_ts.c
index ce8939b..9e82084 100644
--- a/sec_ts.c
+++ b/sec_ts.c
@@ -31,6 +31,7 @@ static void sec_ts_reset_work(struct work_struct *work);
static void sec_ts_fw_update_work(struct work_struct *work);
static void sec_ts_suspend_work(struct work_struct *work);
static void sec_ts_resume_work(struct work_struct *work);
+static void sec_ts_charger_work(struct work_struct *work);
#ifdef USE_OPEN_CLOSE
static int sec_ts_input_open(struct input_dev *dev);
@@ -1969,6 +1970,13 @@ static void sec_ts_read_event(struct sec_ts_data *ts)
event_buff[7]);
switch (status_id) {
+ case SEC_TS_EVENT_STATUS_ID_WLC:
+ input_info(true,
+ &ts->client->dev,
+ "STATUS: wlc mode change to %x\n",
+ status_data_1);
+ break;
+
case SEC_TS_EVENT_STATUS_ID_NOISE:
input_info(true,
&ts->client->dev,
@@ -2249,35 +2257,6 @@ int get_tsp_status(void)
}
EXPORT_SYMBOL(get_tsp_status);
-void sec_ts_set_charger(bool enable)
-{
- return;
-/*
- * int ret;
- * u8 noise_mode_on[] = {0x01};
- * u8 noise_mode_off[] = {0x00};
- *
- * if (enable) {
- * input_info(true, &ts->client->dev,
- * "sec_ts_set_charger : charger CONNECTED!!\n");
- * ret = sec_ts_write(ts, SEC_TS_CMD_NOISE_MODE, noise_mode_on,
- * sizeof(noise_mode_on));
- * if (ret < 0)
- * input_err(true, &ts->client->dev,
- * "sec_ts_set_charger: fail to write NOISE_ON\n");
- * } else {
- * input_info(true, &ts->client->dev,
- * "sec_ts_set_charger : charger DISCONNECTED!!\n");
- * ret = sec_ts_write(ts, SEC_TS_CMD_NOISE_MODE, noise_mode_off,
- * sizeof(noise_mode_off));
- * if (ret < 0)
- * input_err(true, &ts->client->dev,
- * "%s: fail to write NOISE_OFF\n", __func__);
- * }
- **/
-}
-EXPORT_SYMBOL(sec_ts_set_charger);
-
int sec_ts_glove_mode_enables(struct sec_ts_data *ts, int mode)
{
int ret;
@@ -3182,6 +3161,7 @@ static void sec_ts_device_init(struct sec_ts_data *ts)
}
static struct notifier_block sec_ts_screen_nb;
+static struct notifier_block sec_ts_psy_nb;
#ifdef I2C_INTERFACE
static int sec_ts_probe(struct i2c_client *client,
@@ -3268,6 +3248,7 @@ static int sec_ts_probe(struct spi_device *client)
#endif
INIT_WORK(&ts->suspend_work, sec_ts_suspend_work);
INIT_WORK(&ts->resume_work, sec_ts_resume_work);
+ INIT_WORK(&ts->charger_work, sec_ts_charger_work);
ts->event_wq = alloc_workqueue("sec_ts-event-queue", WQ_UNBOUND |
WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1);
if (!ts->event_wq) {
@@ -3502,6 +3483,16 @@ static int sec_ts_probe(struct spi_device *client)
ts_dup = ts;
ts->probe_done = true;
+ ts->wlc_online = false;
+ ts->usb_present = false;
+ ts->charger_mode = SEC_TS_BIT_CHARGER_MODE_NO;
+ ts->wireless_psy = power_supply_get_by_name("wireless");
+ ts->usb_psy = power_supply_get_by_name("usb");
+ ts->psy_nb = sec_ts_psy_nb;
+ ret = power_supply_reg_notifier(&ts->psy_nb);
+ if (ret < 0)
+ input_err(true, &ts->client->dev, "psy notifier register failed\n");
+
input_err(true, &ts->client->dev, "%s: done\n", __func__);
input_log_fix();
@@ -4055,6 +4046,7 @@ static int sec_ts_remove(struct spi_device *client)
cancel_work_sync(&ts->suspend_work);
cancel_work_sync(&ts->resume_work);
+ cancel_work_sync(&ts->charger_work);
destroy_workqueue(ts->event_wq);
#ifdef SEC_TS_FW_UPDATE_ON_PROBE
@@ -4480,6 +4472,19 @@ static void sec_ts_resume_work(struct work_struct *work)
"%s: failed to set 16:9 mode.\n", __func__);
}
+ /* set charger mode */
+ ret = ts->sec_ts_write(ts, SET_TS_CMD_SET_CHARGER_MODE,
+ &ts->charger_mode, 1);
+ if (ret < 0)
+ input_err(true, &ts->client->dev,
+ "%s: write reg %#x %#x failed, returned %i\n",
+ __func__, SET_TS_CMD_SET_CHARGER_MODE, ts->charger_mode,
+ ret);
+ else
+ input_info(true, &ts->client->dev, "%s: set charger mode %#x\n",
+ __func__, ts->charger_mode);
+ queue_work(ts->event_wq, &ts->charger_work);
+
/* Sense_on */
ret = sec_ts_write(ts, SEC_TS_CMD_SENSE_ON, NULL, 0);
if (ret < 0)
@@ -4493,6 +4498,84 @@ static void sec_ts_resume_work(struct work_struct *work)
mutex_unlock(&ts->device_mutex);
}
+static void sec_ts_charger_work(struct work_struct *work)
+{
+ int ret;
+ union power_supply_propval prop = {0,};
+ struct sec_ts_data *ts = container_of(work, struct sec_ts_data,
+ charger_work);
+ u8 charger_mode = SEC_TS_BIT_CHARGER_MODE_NO;
+ bool usb_present = ts->usb_present;
+ bool wlc_online = ts->wlc_online;
+
+ /* usb case */
+ ret = power_supply_get_property(ts->usb_psy,
+ POWER_SUPPLY_PROP_PRESENT, &prop);
+ if (ret == 0) {
+ usb_present = !!prop.intval;
+ if (usb_present)
+ charger_mode = SEC_TS_BIT_CHARGER_MODE_WIRE_CHARGER;
+ }
+
+ /* wlc case */
+ ret = power_supply_get_property(ts->wireless_psy,
+ POWER_SUPPLY_PROP_ONLINE, &prop);
+ if (ret == 0) {
+ wlc_online = !!prop.intval;
+ if (wlc_online)
+ charger_mode = SEC_TS_BIT_CHARGER_MODE_WIRELESS_CHARGER;
+ }
+
+ /* rtx case */
+ ret = power_supply_get_property(ts->wireless_psy,
+ POWER_SUPPLY_PROP_RTX, &prop);
+ if (ret == 0)
+ pr_debug("%s: RTX %s", __func__,
+ (!!prop.intval) ? "ON" : "OFF");
+
+ if (usb_present == ts->usb_present &&
+ wlc_online == ts->wlc_online &&
+ ts->keep_wlc_mode == false)
+ return;
+
+ /* keep wlc mode if usb plug in w/ wlc off case */
+ if (ts->keep_wlc_mode) {
+ input_info(true, &ts->client->dev,
+ "keep wlc mode after usb plug in during wlc online");
+ charger_mode = SEC_TS_BIT_CHARGER_MODE_WIRELESS_CHARGER;
+ }
+
+ input_info(true, &ts->client->dev,
+ "%s: keep_wlc_mode %d, USB(%d->%d), WLC(%d->%d), charger_mode(%#x->%#x)",
+ __func__,
+ ts->keep_wlc_mode,
+ ts->usb_present, usb_present,
+ ts->wlc_online, wlc_online,
+ ts->charger_mode, charger_mode);
+
+ if (ts->charger_mode != charger_mode) {
+ ret = ts->sec_ts_write(ts, SET_TS_CMD_SET_CHARGER_MODE,
+ &charger_mode, 1);
+ if (ret < 0) {
+ input_err(true, &ts->client->dev,
+ "%s: write reg %#x %#x failed, returned %i\n",
+ __func__, SET_TS_CMD_SET_CHARGER_MODE, charger_mode,
+ ret);
+ return;
+ }
+
+ input_info(true, &ts->client->dev,
+ "%s: charger_mode change from %#x to %#x\n",
+ __func__, ts->charger_mode, charger_mode);
+ ts->charger_mode = charger_mode;
+ }
+
+ /* update final charger state */
+ ts->wlc_online = wlc_online;
+ ts->usb_present = usb_present;
+ ts->keep_wlc_mode = false;
+}
+
static void sec_ts_aggregate_bus_state(struct sec_ts_data *ts)
{
input_dbg(true, &ts->client->dev, "%s: bus_refmask = 0x%02X.\n",
@@ -4609,6 +4692,49 @@ static struct notifier_block sec_ts_screen_nb = {
.notifier_call = sec_ts_screen_state_chg_callback,
};
+/*
+ * power supply callback
+ */
+static int sec_ts_psy_cb(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ u64 debounce = 500;
+ struct sec_ts_data *ts = container_of(nb, struct sec_ts_data, psy_nb);
+
+ pr_debug("%s: val %lu", __func__, val);
+
+ if (val != PSY_EVENT_PROP_CHANGED ||
+ ts->wireless_psy == NULL ||
+ ts->usb_psy == NULL ||
+ (ts->wireless_psy != data && ts->usb_psy != data))
+ return NOTIFY_OK;
+
+ if (ts->usb_psy == data) {
+ ts->usb_changed_timestamp = ktime_get();
+ if (ts->wlc_online) {
+ input_dbg(true, &ts->client->dev,
+ "%s: ignore this usb_psy changed during wlc_online!",
+ __func__);
+ return NOTIFY_OK;
+ }
+ }
+
+ if (ts->wireless_psy == data) {
+ /* keep wlc mode after usb plug in during wlc online */
+ if (ts->wlc_online == true &&
+ ts->usb_present == false &&
+ ktime_before(ktime_get(),
+ ktime_add_ms(ts->usb_changed_timestamp, debounce)))
+ ts->keep_wlc_mode = true;
+ }
+ queue_work(ts->event_wq, &ts->charger_work);
+ return NOTIFY_OK;
+}
+
+static struct notifier_block sec_ts_psy_nb = {
+ .notifier_call = sec_ts_psy_cb,
+};
+
#ifdef CONFIG_OF
static const struct of_device_id sec_ts_match_table[] = {
{ .compatible = "sec,sec_ts",},
diff --git a/sec_ts.h b/sec_ts.h
index 8cf287a..4a7f8e0 100644
--- a/sec_ts.h
+++ b/sec_ts.h
@@ -37,6 +37,7 @@
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/pm_qos.h>
+#include <linux/power_supply.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/time.h>
@@ -507,6 +508,12 @@ enum switch_system_mode {
TO_FLASH_MODE = 3,
};
+enum noise_mode_param {
+ NOISE_MODE_DEFALUT = 0x00,
+ NOISE_MODE_OFF = 0x10,
+ NOISE_MODE_FORCE_ON = 0x11,
+};
+
enum {
TYPE_RAW_DATA = 0, /* Total - Offset : delta data
**/
@@ -729,6 +736,7 @@ struct sec_ts_gesture_status {
/* status id for sec_ts event */
#define SEC_TS_EVENT_STATUS_ID_NOISE 0x64
+#define SEC_TS_EVENT_STATUS_ID_WLC 0x66
#define SEC_TS_EVENT_STATUS_ID_GRIP 0x69
#define SEC_TS_EVENT_STATUS_ID_PALM 0x70
@@ -878,6 +886,7 @@ struct sec_ts_data {
struct delayed_work fw_update_work;
struct workqueue_struct *fw_update_wq;
#endif
+ struct work_struct charger_work; /* charger work */
struct work_struct suspend_work;
struct work_struct resume_work;
struct workqueue_struct *event_wq; /* Used for event handler,
@@ -985,6 +994,14 @@ struct sec_ts_data {
struct tbn_context *tbn;
#endif
+ struct power_supply *wireless_psy;
+ struct power_supply *usb_psy;
+ struct notifier_block psy_nb;
+ bool wlc_online;
+ bool usb_present;
+ bool keep_wlc_mode;
+ ktime_t usb_changed_timestamp;
+
int (*sec_ts_write)(struct sec_ts_data *ts, u8 reg,
u8 *data, int len);
diff --git a/sec_ts_fn.c b/sec_ts_fn.c
index 2e8049a..02925c6 100644
--- a/sec_ts_fn.c
+++ b/sec_ts_fn.c
@@ -375,9 +375,9 @@ static void set_noise_mode_enable(void *device_data)
sec_cmd_set_default_result(sec);
if (sec->cmd_param[0] == 1)
- para = 0x00;
+ para = NOISE_MODE_DEFALUT;
else if (sec->cmd_param[0] == 0)
- para = 0x10;
+ para = NOISE_MODE_OFF;
else {
input_info(true, &ts->client->dev,
"%s: param error! param = %d\n",