All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nick Dyer <nick.dyer@itdev.co.uk>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Yufeng Shen <miletus@google.com>,
	Daniel Kurtz <djkurtz@chromium.org>,
	Henrik Rydberg <rydberg@euromail.se>,
	Joonyoung Shim <jy0922.shim@samsung.com>,
	Alan Bowens <Alan.Bowens@atmel.com>,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	Peter Meerwald <pmeerw@pmeerw.net>,
	Benson Leung <bleung@chromium.org>,
	Olof Johansson <olofj@chromium.org>,
	Nick Dyer <nick.dyer@itdev.co.uk>
Subject: [PATCH 19/22] Input: atmel_mxt_ts - use deep sleep mode when stopped
Date: Mon, 17 Mar 2014 17:26:52 +0000	[thread overview]
Message-ID: <1395077215-10922-20-git-send-email-nick.dyer@itdev.co.uk> (raw)
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

By writing zero to both the active and idle cycle times the maXTouch device
is put into a deep sleep mode when it consumes minimal power. It is
unnecessary to change the configuration of any other objects (for example
to disable T9 touchscreen).

It is counterproductive to reset the chip on resume, it will result in a
long delay. However it is necessary to issue a calibrate command after the
chip has spent any time in deep sleep.

This patch also deals with the situation where the power configuration is
zero on probe, which would mean that the device never wakes up to execute
commands.

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 99 +++++++++++++++++++++++---------
 1 file changed, 73 insertions(+), 26 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index ce88ada..5cd2261 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -89,9 +89,13 @@
 #define MXT_T6_STATUS_RESET	(1 << 7)
 
 /* MXT_GEN_POWER_T7 field */
-#define MXT_POWER_IDLEACQINT	0
-#define MXT_POWER_ACTVACQINT	1
-#define MXT_POWER_ACTV2IDLETO	2
+struct t7_config {
+	u8 idle;
+	u8 active;
+} __packed;
+
+#define MXT_POWER_CFG_RUN		0
+#define MXT_POWER_CFG_DEEPSLEEP		1
 
 /* MXT_GEN_ACQUIRE_T8 field */
 #define MXT_ACQUIRE_CHRGTIME	0
@@ -103,7 +107,6 @@
 #define MXT_ACQUIRE_ATCHCALSTHR	7
 
 /* MXT_TOUCH_MULTI_T9 field */
-#define MXT_TOUCH_CTRL		0
 #define MXT_T9_ORIENT		9
 #define MXT_T9_RANGE		18
 
@@ -242,6 +245,7 @@ struct mxt_data {
 	u32 config_crc;
 	u32 info_crc;
 	u8 bootloader_addr;
+	struct t7_config t7_cfg;
 
 	/* Cached parameters from object table */
 	u8 T6_reportid;
@@ -600,20 +604,6 @@ static int mxt_read_message(struct mxt_data *data,
 			sizeof(struct mxt_message), message);
 }
 
-static int mxt_write_object(struct mxt_data *data,
-				 u8 type, u8 offset, u8 val)
-{
-	struct mxt_object *object;
-	u16 reg;
-
-	object = mxt_get_object(data, type);
-	if (!object || offset >= mxt_obj_size(object))
-		return -EINVAL;
-
-	reg = object->start_address;
-	return mxt_write_reg(data->client, reg + offset, val);
-}
-
 static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
 {
 	struct input_dev *input = data->input_dev;
@@ -1129,6 +1119,60 @@ release:
 	return ret;
 }
 
+static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep)
+{
+	struct device *dev = &data->client->dev;
+	int error;
+	struct t7_config *new_config;
+	struct t7_config deepsleep = { .active = 0, .idle = 0 };
+
+	if (sleep == MXT_POWER_CFG_DEEPSLEEP)
+		new_config = &deepsleep;
+	else
+		new_config = &data->t7_cfg;
+
+	error = __mxt_write_reg(data->client, data->T7_address,
+				sizeof(data->t7_cfg), new_config);
+	if (error)
+		return error;
+
+	dev_dbg(dev, "Set T7 ACTV:%d IDLE:%d\n",
+		new_config->active, new_config->idle);
+
+	return 0;
+}
+
+static int mxt_init_t7_power_cfg(struct mxt_data *data)
+{
+	struct device *dev = &data->client->dev;
+	int error;
+	bool retry = false;
+
+recheck:
+	error = __mxt_read_reg(data->client, data->T7_address,
+				sizeof(data->t7_cfg), &data->t7_cfg);
+	if (error)
+		return error;
+
+	if (data->t7_cfg.active == 0 || data->t7_cfg.idle == 0) {
+		if (!retry) {
+			dev_dbg(dev, "T7 cfg zero, resetting\n");
+			mxt_soft_reset(data);
+			retry = true;
+			goto recheck;
+		} else {
+			dev_dbg(dev, "T7 cfg zero after reset, overriding\n");
+			data->t7_cfg.active = 20;
+			data->t7_cfg.idle = 100;
+			return mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
+		}
+	}
+
+	dev_dbg(dev, "Initialized power cfg: ACTV %d, IDLE %d\n",
+		data->t7_cfg.active, data->t7_cfg.idle);
+	return 0;
+}
+
 static int mxt_make_highchg(struct mxt_data *data)
 {
 	struct device *dev = &data->client->dev;
@@ -1323,6 +1367,12 @@ static int mxt_initialize(struct mxt_data *data)
 		goto err_free_object_table;
 	}
 
+	error = mxt_init_t7_power_cfg(data);
+	if (error) {
+		dev_err(&client->dev, "Failed to initialize power cfg\n");
+		goto err_free_object_table;
+	}
+
 	error = mxt_read_t9_resolution(data);
 	if (error) {
 		dev_err(&client->dev, "Failed to initialize T9 resolution\n");
@@ -1596,16 +1646,15 @@ static const struct attribute_group mxt_attr_group = {
 
 static void mxt_start(struct mxt_data *data)
 {
-	/* Touch enable */
-	mxt_write_object(data,
-			MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83);
+	mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
+
+	/* Recalibrate since chip has been in deep sleep */
+	mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
 }
 
 static void mxt_stop(struct mxt_data *data)
 {
-	/* Touch disable */
-	mxt_write_object(data,
-			MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0);
+	mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);
 }
 
 static int mxt_input_open(struct input_dev *dev)
@@ -1796,8 +1845,6 @@ static int mxt_resume(struct device *dev)
 	struct mxt_data *data = i2c_get_clientdata(client);
 	struct input_dev *input_dev = data->input_dev;
 
-	mxt_soft_reset(data);
-
 	mutex_lock(&input_dev->mutex);
 
 	if (input_dev->users)
-- 
1.8.3.2


  parent reply	other threads:[~2014-03-17 17:41 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-17 17:26 [PATCH 00/22] atmel_mxt_ts patches, already signed-off Nick Dyer
2014-03-17 17:26 ` [PATCH 01/22] Input: atmel_mxt_ts - remove unnecessary platform data Nick Dyer
2014-03-17 17:26 ` [PATCH 02/22] Input: atmel_mxt_ts - improve T19 GPIO keys handling Nick Dyer
2014-03-17 17:26 ` [PATCH 03/22] Input: atmel_mxt_ts - return IRQ_NONE when interrupt handler fails Nick Dyer
2014-03-17 17:26 ` [PATCH 04/22] Input: atmel_mxt_ts - define helper functions for size and instances Nick Dyer
2014-03-17 17:26 ` [PATCH 05/22] Input: atmel_mxt_ts - select FW_LOADER for firmware code Nick Dyer
2014-03-17 17:26 ` [PATCH 06/22] Input: atmel_mxt_ts - wait for CHG assert in mxt_check_bootloader Nick Dyer
2014-03-17 17:26 ` [PATCH 07/22] Input: atmel_mxt_ts - wait for CHG after bootloader resets Nick Dyer
2014-03-17 17:26 ` [PATCH 08/22] Input: atmel_mxt_ts - make wait-after-reset period compatible with all chips Nick Dyer
2014-03-17 17:26 ` [PATCH 09/22] Input: atmel_mxt_ts - improve error reporting and debug Nick Dyer
2014-03-17 17:26 ` [PATCH 10/22] Input: atmel_mxt_ts - implement CRC check for configuration data Nick Dyer
2014-03-17 17:26 ` [PATCH 11/22] Input: atmel_mxt_ts - download device config using firmware loader Nick Dyer
2014-03-17 17:26 ` [PATCH 12/22] Input: atmel_mxt_ts - calculate and check CRC in config file Nick Dyer
2014-03-17 17:26 ` [PATCH 13/22] Input: atmel_mxt_ts - add additional bootloader addresses Nick Dyer
2014-03-17 17:26 ` [PATCH 14/22] Input: atmel_mxt_ts - read and report bootloader version Nick Dyer
2014-03-17 17:26 ` [PATCH 15/22] Input: atmel_mxt_ts - implement bootloader frame retries Nick Dyer
2014-03-17 17:26 ` [PATCH 16/22] Input: atmel_mxt_ts - improve bootloader progress output Nick Dyer
2014-03-17 17:26 ` [PATCH 17/22] Input: atmel_mxt_ts - add check for incorrect firmware file format Nick Dyer
2014-03-17 17:26 ` [PATCH 18/22] Input: atmel_mxt_ts - read screen config from chip Nick Dyer
2014-03-17 17:26 ` Nick Dyer [this message]
2014-03-17 17:26 ` [PATCH 20/22] Input: atmel_mxt_ts - rename pressure to amplitude to match spec Nick Dyer
2014-03-17 17:26 ` [PATCH 21/22] Input: atmel_mxt_ts - rename touchscreen defines to include T9 Nick Dyer
2014-03-17 17:26 ` [PATCH 22/22] Input: atmel_mxt_ts - handle multiple input reports in one message Nick Dyer
2014-04-03 10:41 ` [PATCH 00/22] atmel_mxt_ts patches, already signed-off Nick Dyer
2014-05-19  6:37   ` Dmitry Torokhov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1395077215-10922-20-git-send-email-nick.dyer@itdev.co.uk \
    --to=nick.dyer@itdev.co.uk \
    --cc=Alan.Bowens@atmel.com \
    --cc=bleung@chromium.org \
    --cc=djkurtz@chromium.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=jy0922.shim@samsung.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miletus@google.com \
    --cc=olofj@chromium.org \
    --cc=pmeerw@pmeerw.net \
    --cc=rydberg@euromail.se \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.