build/patch/kernel/archive/sunxi-6.1/patches.megous/input-goodix-Add-option-to-power-off-the-controller-during-susp.patch

103 lines
3.2 KiB
Diff

From b83124e3e2306d63c112e401478592efad327b14 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Jirman?= <megi@xff.cz>
Date: Sun, 25 Apr 2021 03:16:42 +0200
Subject: [PATCH 084/389] input: goodix: Add option to power off the controller
during suspend
For whatever reason the controller is not suspended on Pinephone
by the default procedure. It consumes quite a bit of power (~40mW)
during system sleep, and more when the screen is touched.
Let's power off the controller during system sleep instead.
Signed-off-by: Ondrej Jirman <megi@xff.cz>
---
drivers/input/touchscreen/goodix.c | 37 ++++++++++++++++++++++++++++++
drivers/input/touchscreen/goodix.h | 1 +
2 files changed, 38 insertions(+)
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index a27422940e5d..f1fabcaa0aac 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -1300,6 +1300,7 @@ static void goodix_disable_regulators(void *arg)
static int goodix_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device_node *np = client->dev.of_node;
struct goodix_ts_data *ts;
const char *cfg_name;
int error;
@@ -1319,6 +1320,7 @@ static int goodix_ts_probe(struct i2c_client *client,
i2c_set_clientdata(client, ts);
init_completion(&ts->firmware_loading_complete);
ts->contact_size = GOODIX_CONTACT_SIZE;
+ ts->poweroff_in_suspend = of_property_read_bool(np, "poweroff-in-suspend");
error = goodix_get_gpio_config(ts);
if (error)
@@ -1428,6 +1430,15 @@ static int __maybe_unused goodix_suspend(struct device *dev)
if (ts->load_cfg_from_disk)
wait_for_completion(&ts->firmware_loading_complete);
+ if (ts->poweroff_in_suspend) {
+ goodix_free_irq(ts);
+ goodix_irq_direction_output(ts, 0);
+ gpiod_direction_output(ts->gpiod_rst, 0);
+ regulator_disable(ts->avdd28);
+ regulator_disable(ts->vddio);
+ return 0;
+ }
+
/* We need gpio pins to suspend/resume */
if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
disable_irq(client->irq);
@@ -1473,6 +1484,32 @@ static int __maybe_unused goodix_resume(struct device *dev)
u8 config_ver;
int error;
+ if (ts->poweroff_in_suspend) {
+ error = regulator_enable(ts->avdd28);
+ if (error) {
+ dev_err(dev, "Regulator avdd28 enable failed.\n");
+ return error;
+ }
+
+ error = regulator_enable(ts->vddio);
+ if (error) {
+ dev_err(dev, "Regulator vddio enable failed.\n");
+ return error;
+ }
+
+ error = goodix_reset(ts);
+ if (error) {
+ dev_err(dev, "Controller reset failed.\n");
+ return error;
+ }
+
+ error = goodix_request_irq(ts);
+ if (error)
+ return error;
+
+ return 0;
+ }
+
if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
enable_irq(client->irq);
return 0;
diff --git a/drivers/input/touchscreen/goodix.h b/drivers/input/touchscreen/goodix.h
index 7c44aa110ee6..db9f03149b11 100644
--- a/drivers/input/touchscreen/goodix.h
+++ b/drivers/input/touchscreen/goodix.h
@@ -105,6 +105,7 @@ struct goodix_ts_data {
int bak_ref_len;
u8 *bak_ref;
struct dentry *debug_root;
+ bool poweroff_in_suspend;
};
int goodix_i2c_read(struct i2c_client *client, u16 reg, u8 *buf, int len);
--
2.35.3