linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/4] Add a property to turn off the max touch controller if not used
@ 2024-07-08  7:15 Stefan Eichenberger
  2024-07-08  7:15 ` [PATCH v5 1/4] Input: atmel_mxt_ts - add power off and power on functions Stefan Eichenberger
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Stefan Eichenberger @ 2024-07-08  7:15 UTC (permalink / raw)
  To: nick, dmitry.torokhov, robh, krzk+dt, conor+dt, nicolas.ferre,
	alexandre.belloni, claudiu.beznea, linus.walleij,
	francesco.dolcini, joao.goncalves
  Cc: linux-input, devicetree, linux-arm-kernel, linux-kernel

Our hardware has a shared regulator that powers various peripherals such
as the display, touch, USB hub, etc. Since the Maxtouch controller
doesn't currently allow it to be turned off, this regulator has to stay
on when not used. This increases the overall power consumption. In order
to turn off the controller when the system does not use it, this series
adds a device tree property to the maxtouch driver that allows the
controller to be turned off completely and ensures that it can resume
from the power off state.

Changes since v4:
- Load configuration firmware during probe and not after resume (Dmitry)
- Do some improvements on error handling (Dmitry)
- Add Reviewed-by tag from Joao

Changes since v3:
- Move the power on part to mxt_start and the power off part to
  mxt_stop. This allows to turn the touch controller off even when not
  in use and not only when being suspended (Dmitry)

Changes since v2:
- Add Reviewed-by tags from Linus and Krzysztof to the dt-bindings patch

Changes since v1:
- Rename the property and change the description (Krzysztof, Linus,
  Dmitry, Conor)

Stefan Eichenberger (4):
  Input: atmel_mxt_ts - add power off and power on functions
  Input: atmel_mxt_ts - move calls to register the input device to
    separate function
  dt-bindings: input: atmel,maxtouch: add poweroff-sleep property
  Input: atmel_mxt_ts - add support for poweroff-sleep

 .../bindings/input/atmel,maxtouch.yaml        |   6 +
 drivers/input/touchscreen/atmel_mxt_ts.c      | 148 ++++++++++++++----
 2 files changed, 121 insertions(+), 33 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v5 1/4] Input: atmel_mxt_ts - add power off and power on functions
  2024-07-08  7:15 [PATCH v5 0/4] Add a property to turn off the max touch controller if not used Stefan Eichenberger
@ 2024-07-08  7:15 ` Stefan Eichenberger
  2024-07-08  7:15 ` [PATCH v5 2/4] Input: atmel_mxt_ts - move calls to register the input device to separate function Stefan Eichenberger
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Stefan Eichenberger @ 2024-07-08  7:15 UTC (permalink / raw)
  To: nick, dmitry.torokhov, robh, krzk+dt, conor+dt, nicolas.ferre,
	alexandre.belloni, claudiu.beznea, linus.walleij,
	francesco.dolcini, joao.goncalves
  Cc: linux-input, devicetree, linux-arm-kernel, linux-kernel,
	Stefan Eichenberger

From: Stefan Eichenberger <stefan.eichenberger@toradex.com>

Add a separate function for power off and power on instead of calling
regulator_bulk_enable and regulator_bulk_disable directly.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
Reviewed-by: Joao Paulo Goncalves <joao.goncalves@toradex.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 59 +++++++++++++++---------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 8a606bd441ae6..4fc83a4cabd9b 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1307,6 +1307,38 @@ static int mxt_soft_reset(struct mxt_data *data)
 	return 0;
 }
 
+static int mxt_power_on(struct mxt_data *data)
+{
+	int error;
+
+	error = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
+				      data->regulators);
+	if (error) {
+		dev_err(&data->client->dev, "failed to enable regulators: %d\n",
+			error);
+		return error;
+	}
+
+	msleep(MXT_BACKUP_TIME);
+
+	if (data->reset_gpio) {
+		/* Wait a while and then de-assert the RESET GPIO line */
+		msleep(MXT_RESET_GPIO_TIME);
+		gpiod_set_value(data->reset_gpio, 0);
+		msleep(MXT_RESET_INVALID_CHG);
+	}
+
+	return 0;
+}
+
+static void mxt_power_off(struct mxt_data *data)
+{
+	if (data->reset_gpio)
+		gpiod_set_value(data->reset_gpio, 1);
+
+	regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators);
+}
+
 static void mxt_update_crc(struct mxt_data *data, u8 cmd, u8 value)
 {
 	/*
@@ -3305,25 +3337,9 @@ static int mxt_probe(struct i2c_client *client)
 		return error;
 	}
 
-	error = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
-				      data->regulators);
-	if (error) {
-		dev_err(&client->dev, "failed to enable regulators: %d\n",
-			error);
+	error = mxt_power_on(data);
+	if (error)
 		return error;
-	}
-	/*
-	 * The device takes 40ms to come up after power-on according
-	 * to the mXT224 datasheet, page 13.
-	 */
-	msleep(MXT_BACKUP_TIME);
-
-	if (data->reset_gpio) {
-		/* Wait a while and then de-assert the RESET GPIO line */
-		msleep(MXT_RESET_GPIO_TIME);
-		gpiod_set_value(data->reset_gpio, 0);
-		msleep(MXT_RESET_INVALID_CHG);
-	}
 
 	/*
 	 * Controllers like mXT1386 have a dedicated WAKE line that could be
@@ -3361,8 +3377,8 @@ static int mxt_probe(struct i2c_client *client)
 	mxt_free_input_device(data);
 	mxt_free_object_table(data);
 err_disable_regulators:
-	regulator_bulk_disable(ARRAY_SIZE(data->regulators),
-			       data->regulators);
+	mxt_power_off(data);
+
 	return error;
 }
 
@@ -3374,8 +3390,7 @@ static void mxt_remove(struct i2c_client *client)
 	sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
 	mxt_free_input_device(data);
 	mxt_free_object_table(data);
-	regulator_bulk_disable(ARRAY_SIZE(data->regulators),
-			       data->regulators);
+	mxt_power_off(data);
 }
 
 static int mxt_suspend(struct device *dev)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v5 2/4] Input: atmel_mxt_ts - move calls to register the input device to separate function
  2024-07-08  7:15 [PATCH v5 0/4] Add a property to turn off the max touch controller if not used Stefan Eichenberger
  2024-07-08  7:15 ` [PATCH v5 1/4] Input: atmel_mxt_ts - add power off and power on functions Stefan Eichenberger
@ 2024-07-08  7:15 ` Stefan Eichenberger
  2024-07-08  7:15 ` [PATCH v5 3/4] dt-bindings: input: atmel,maxtouch: add poweroff-sleep property Stefan Eichenberger
  2024-07-08  7:15 ` [PATCH v5 4/4] Input: atmel_mxt_ts - add support for poweroff-sleep Stefan Eichenberger
  3 siblings, 0 replies; 5+ messages in thread
From: Stefan Eichenberger @ 2024-07-08  7:15 UTC (permalink / raw)
  To: nick, dmitry.torokhov, robh, krzk+dt, conor+dt, nicolas.ferre,
	alexandre.belloni, claudiu.beznea, linus.walleij,
	francesco.dolcini, joao.goncalves
  Cc: linux-input, devicetree, linux-arm-kernel, linux-kernel,
	Stefan Eichenberger

From: Stefan Eichenberger <stefan.eichenberger@toradex.com>

The calls to register the input device are moved to a separate function
so that we can call it without having to confiugre the device. This is
necessary if we want to power on the device only when it is opened.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
Reviewed-by: Joao Paulo Goncalves <joao.goncalves@toradex.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 34 +++++++++++++++++-------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 4fc83a4cabd9b..85f3c685bf526 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2277,6 +2277,28 @@ static void mxt_config_cb(const struct firmware *cfg, void *ctx)
 	release_firmware(cfg);
 }
 
+static void mxt_debug_init(struct mxt_data *data);
+
+static int mxt_device_register(struct mxt_data *data)
+{
+	int error;
+
+	/* If input device is not already registered */
+	if (!data->input_dev) {
+		if (data->multitouch) {
+			error = mxt_initialize_input_device(data);
+			if (error)
+				return error;
+		} else {
+			dev_warn(&data->client->dev, "No touch object detected\n");
+		}
+
+		mxt_debug_init(data);
+	}
+
+	return 0;
+}
+
 static int mxt_initialize(struct mxt_data *data)
 {
 	struct i2c_client *client = data->client;
@@ -2831,15 +2853,9 @@ static int mxt_configure_objects(struct mxt_data *data,
 			dev_warn(dev, "Error %d updating config\n", error);
 	}
 
-	if (data->multitouch) {
-		error = mxt_initialize_input_device(data);
-		if (error)
-			return error;
-	} else {
-		dev_warn(dev, "No touch object detected\n");
-	}
-
-	mxt_debug_init(data);
+	error = mxt_device_register(data);
+	if (error)
+		return error;
 
 	return 0;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v5 3/4] dt-bindings: input: atmel,maxtouch: add poweroff-sleep property
  2024-07-08  7:15 [PATCH v5 0/4] Add a property to turn off the max touch controller if not used Stefan Eichenberger
  2024-07-08  7:15 ` [PATCH v5 1/4] Input: atmel_mxt_ts - add power off and power on functions Stefan Eichenberger
  2024-07-08  7:15 ` [PATCH v5 2/4] Input: atmel_mxt_ts - move calls to register the input device to separate function Stefan Eichenberger
@ 2024-07-08  7:15 ` Stefan Eichenberger
  2024-07-08  7:15 ` [PATCH v5 4/4] Input: atmel_mxt_ts - add support for poweroff-sleep Stefan Eichenberger
  3 siblings, 0 replies; 5+ messages in thread
From: Stefan Eichenberger @ 2024-07-08  7:15 UTC (permalink / raw)
  To: nick, dmitry.torokhov, robh, krzk+dt, conor+dt, nicolas.ferre,
	alexandre.belloni, claudiu.beznea, linus.walleij,
	francesco.dolcini, joao.goncalves
  Cc: linux-input, devicetree, linux-arm-kernel, linux-kernel,
	Stefan Eichenberger, Krzysztof Kozlowski

From: Stefan Eichenberger <stefan.eichenberger@toradex.com>

Add a new property to indicate that the device should power off rather
than use deep sleep. Deep sleep is a feature of the controller that
expects the controller to remain powered in suspend. However, if a
display shares its regulator with the touch controller, we may want to
do a power off so that the display and touch controller do not use any
power.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Joao Paulo Goncalves <joao.goncalves@toradex.com>
---
 Documentation/devicetree/bindings/input/atmel,maxtouch.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml b/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
index c40799355ed75..8de5f539b30e3 100644
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.yaml
@@ -87,6 +87,12 @@ properties:
       - 2 # ATMEL_MXT_WAKEUP_GPIO
     default: 0
 
+  atmel,poweroff-sleep:
+    description: |
+      Instead of using the deep sleep feature of the maXTouch controller,
+      poweroff the regulators.
+    type: boolean
+
   wakeup-source:
     type: boolean
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v5 4/4] Input: atmel_mxt_ts - add support for poweroff-sleep
  2024-07-08  7:15 [PATCH v5 0/4] Add a property to turn off the max touch controller if not used Stefan Eichenberger
                   ` (2 preceding siblings ...)
  2024-07-08  7:15 ` [PATCH v5 3/4] dt-bindings: input: atmel,maxtouch: add poweroff-sleep property Stefan Eichenberger
@ 2024-07-08  7:15 ` Stefan Eichenberger
  3 siblings, 0 replies; 5+ messages in thread
From: Stefan Eichenberger @ 2024-07-08  7:15 UTC (permalink / raw)
  To: nick, dmitry.torokhov, robh, krzk+dt, conor+dt, nicolas.ferre,
	alexandre.belloni, claudiu.beznea, linus.walleij,
	francesco.dolcini, joao.goncalves
  Cc: linux-input, devicetree, linux-arm-kernel, linux-kernel,
	Stefan Eichenberger

From: Stefan Eichenberger <stefan.eichenberger@toradex.com>

Add support for poweroff-sleep to the Atmel maXTouch driver. This allows
us to power off the input device entirely and only power it on when it
is opened. This will also automatically power it off when we suspend the
system.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 59 ++++++++++++++++++++++--
 1 file changed, 55 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 85f3c685bf526..3bcdbb58a24e6 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -265,6 +265,7 @@ enum v4l_dbg_inputs {
 enum mxt_suspend_mode {
 	MXT_SUSPEND_DEEP_SLEEP	= 0,
 	MXT_SUSPEND_T9_CTRL	= 1,
+	MXT_SUSPEND_POWEROFF	= 2,
 };
 
 /* Config update context */
@@ -2273,8 +2274,38 @@ static int mxt_configure_objects(struct mxt_data *data,
 
 static void mxt_config_cb(const struct firmware *cfg, void *ctx)
 {
+	struct mxt_data *data = ctx;
+
 	mxt_configure_objects(ctx, cfg);
 	release_firmware(cfg);
+
+	if ((data->suspend_mode == MXT_SUSPEND_POWEROFF) && !data->in_bootloader) {
+		disable_irq(data->irq);
+		mxt_power_off(data);
+	}
+}
+
+static void mxt_initialize_after_resume(struct mxt_data *data)
+{
+	int error;
+
+	error = mxt_power_on(data);
+	if (error) {
+		dev_err(&data->client->dev, "Failed to power on device\n");
+		return;
+	}
+
+	error = mxt_acquire_irq(data);
+	if (error) {
+		dev_err(&data->client->dev, "Failed to acquire IRQ\n");
+		return;
+	}
+
+	error = mxt_configure_objects(data, NULL);
+	if (error) {
+		dev_err(&data->client->dev, "Failed to configure objects\n");
+		return;
+	}
 }
 
 static void mxt_debug_init(struct mxt_data *data);
@@ -3089,6 +3120,12 @@ static ssize_t mxt_update_fw_store(struct device *dev,
 	struct mxt_data *data = dev_get_drvdata(dev);
 	int error;
 
+	if ((data->suspend_mode == MXT_SUSPEND_POWEROFF) && !data->in_bootloader) {
+		error = mxt_power_on(data);
+		if (error)
+			return error;
+	}
+
 	error = mxt_load_fw(dev, MXT_FW_NAME);
 	if (error) {
 		dev_err(dev, "The firmware update failed(%d)\n", error);
@@ -3123,7 +3160,10 @@ static const struct attribute_group mxt_attr_group = {
 
 static void mxt_start(struct mxt_data *data)
 {
-	mxt_wakeup_toggle(data->client, true, false);
+	if (data->suspend_mode == MXT_SUSPEND_POWEROFF)
+		mxt_initialize_after_resume(data);
+	else
+		mxt_wakeup_toggle(data->client, true, false);
 
 	switch (data->suspend_mode) {
 	case MXT_SUSPEND_T9_CTRL:
@@ -3135,6 +3175,7 @@ static void mxt_start(struct mxt_data *data)
 				MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0x83);
 		break;
 
+	case MXT_SUSPEND_POWEROFF:
 	case MXT_SUSPEND_DEEP_SLEEP:
 	default:
 		mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
@@ -3160,7 +3201,12 @@ static void mxt_stop(struct mxt_data *data)
 		break;
 	}
 
-	mxt_wakeup_toggle(data->client, false, false);
+	if (data->suspend_mode == MXT_SUSPEND_POWEROFF) {
+		disable_irq(data->irq);
+		mxt_power_off(data);
+	} else {
+		mxt_wakeup_toggle(data->client, false, false);
+	}
 }
 
 static int mxt_input_open(struct input_dev *dev)
@@ -3357,6 +3403,9 @@ static int mxt_probe(struct i2c_client *client)
 	if (error)
 		return error;
 
+	if (device_property_read_bool(&client->dev, "atmel,poweroff-sleep"))
+		data->suspend_mode = MXT_SUSPEND_POWEROFF;
+
 	/*
 	 * Controllers like mXT1386 have a dedicated WAKE line that could be
 	 * connected to a GPIO or to I2C SCL pin, or permanently asserted low.
@@ -3406,7 +3455,8 @@ static void mxt_remove(struct i2c_client *client)
 	sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
 	mxt_free_input_device(data);
 	mxt_free_object_table(data);
-	mxt_power_off(data);
+	if (!(data->suspend_mode == MXT_SUSPEND_POWEROFF))
+		mxt_power_off(data);
 }
 
 static int mxt_suspend(struct device *dev)
@@ -3439,7 +3489,8 @@ static int mxt_resume(struct device *dev)
 	if (!input_dev)
 		return 0;
 
-	enable_irq(data->irq);
+	if (!(data->suspend_mode == MXT_SUSPEND_POWEROFF))
+		enable_irq(data->irq);
 
 	mutex_lock(&input_dev->mutex);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-07-08  7:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-08  7:15 [PATCH v5 0/4] Add a property to turn off the max touch controller if not used Stefan Eichenberger
2024-07-08  7:15 ` [PATCH v5 1/4] Input: atmel_mxt_ts - add power off and power on functions Stefan Eichenberger
2024-07-08  7:15 ` [PATCH v5 2/4] Input: atmel_mxt_ts - move calls to register the input device to separate function Stefan Eichenberger
2024-07-08  7:15 ` [PATCH v5 3/4] dt-bindings: input: atmel,maxtouch: add poweroff-sleep property Stefan Eichenberger
2024-07-08  7:15 ` [PATCH v5 4/4] Input: atmel_mxt_ts - add support for poweroff-sleep Stefan Eichenberger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).