98 lines
3.0 KiB
Diff
98 lines
3.0 KiB
Diff
|
From: Ondrej Jirman <megous@megous.com>
|
||
|
Date: Sun, 25 Apr 2021 03:16:42 +0200
|
||
|
Subject: 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 <megous@megous.com>
|
||
|
---
|
||
|
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 aaa3c45..81a9bca 100644
|
||
|
--- a/drivers/input/touchscreen/goodix.c
|
||
|
+++ b/drivers/input/touchscreen/goodix.c
|
||
|
@@ -1154,6 +1154,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;
|
||
|
@@ -1173,6 +1174,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)
|
||
|
@@ -1282,6 +1284,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);
|
||
|
@@ -1327,6 +1338,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 02065d1..e265695 100644
|
||
|
--- a/drivers/input/touchscreen/goodix.h
|
||
|
+++ b/drivers/input/touchscreen/goodix.h
|
||
|
@@ -102,6 +102,7 @@ struct goodix_ts_data {
|
||
|
u8 main_clk[GOODIX_MAIN_CLK_LEN];
|
||
|
int bak_ref_len;
|
||
|
u8 *bak_ref;
|
||
|
+ bool poweroff_in_suspend;
|
||
|
};
|
||
|
|
||
|
int goodix_i2c_read(struct i2c_client *client, u16 reg, u8 *buf, int len);
|