aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Dyer <nick.dyer@itdev.co.uk>2014-07-28 13:14:34 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-28 13:26:29 -0400
commit9d469d033d135d80742a4e39e6bbb4519dd5eee1 (patch)
tree347632dc1343950e8ad504d42fb03c164df3ff6c
parentf048615efc34035e217af148ebdde8ce6efd8af9 (diff)
Input: atmel_mxt_ts - use deep sleep mode when stopped
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>
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c99
1 files changed, 73 insertions, 26 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index c6dfd0af6365..03b85711cb70 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -99,9 +99,13 @@
99#define MXT_T6_STATUS_COMSERR (1 << 2) 99#define MXT_T6_STATUS_COMSERR (1 << 2)
100 100
101/* MXT_GEN_POWER_T7 field */ 101/* MXT_GEN_POWER_T7 field */
102#define MXT_POWER_IDLEACQINT 0 102struct t7_config {
103#define MXT_POWER_ACTVACQINT 1 103 u8 idle;
104#define MXT_POWER_ACTV2IDLETO 2 104 u8 active;
105} __packed;
106
107#define MXT_POWER_CFG_RUN 0
108#define MXT_POWER_CFG_DEEPSLEEP 1
105 109
106/* MXT_GEN_ACQUIRE_T8 field */ 110/* MXT_GEN_ACQUIRE_T8 field */
107#define MXT_ACQUIRE_CHRGTIME 0 111#define MXT_ACQUIRE_CHRGTIME 0
@@ -113,7 +117,6 @@
113#define MXT_ACQUIRE_ATCHCALSTHR 7 117#define MXT_ACQUIRE_ATCHCALSTHR 7
114 118
115/* MXT_TOUCH_MULTI_T9 field */ 119/* MXT_TOUCH_MULTI_T9 field */
116#define MXT_TOUCH_CTRL 0
117#define MXT_T9_ORIENT 9 120#define MXT_T9_ORIENT 9
118#define MXT_T9_RANGE 18 121#define MXT_T9_RANGE 18
119 122
@@ -253,6 +256,7 @@ struct mxt_data {
253 bool update_input; 256 bool update_input;
254 u8 last_message_count; 257 u8 last_message_count;
255 u8 num_touchids; 258 u8 num_touchids;
259 struct t7_config t7_cfg;
256 260
257 /* Cached parameters from object table */ 261 /* Cached parameters from object table */
258 u16 T5_address; 262 u16 T5_address;
@@ -668,20 +672,6 @@ static void mxt_proc_t6_messages(struct mxt_data *data, u8 *msg)
668 data->t6_status = status; 672 data->t6_status = status;
669} 673}
670 674
671static int mxt_write_object(struct mxt_data *data,
672 u8 type, u8 offset, u8 val)
673{
674 struct mxt_object *object;
675 u16 reg;
676
677 object = mxt_get_object(data, type);
678 if (!object || offset >= mxt_obj_size(object))
679 return -EINVAL;
680
681 reg = object->start_address;
682 return mxt_write_reg(data->client, reg + offset, val);
683}
684
685static void mxt_input_button(struct mxt_data *data, u8 *message) 675static void mxt_input_button(struct mxt_data *data, u8 *message)
686{ 676{
687 struct input_dev *input = data->input_dev; 677 struct input_dev *input = data->input_dev;
@@ -1712,6 +1702,60 @@ err_free_object_table:
1712 return error; 1702 return error;
1713} 1703}
1714 1704
1705static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep)
1706{
1707 struct device *dev = &data->client->dev;
1708 int error;
1709 struct t7_config *new_config;
1710 struct t7_config deepsleep = { .active = 0, .idle = 0 };
1711
1712 if (sleep == MXT_POWER_CFG_DEEPSLEEP)
1713 new_config = &deepsleep;
1714 else
1715 new_config = &data->t7_cfg;
1716
1717 error = __mxt_write_reg(data->client, data->T7_address,
1718 sizeof(data->t7_cfg), new_config);
1719 if (error)
1720 return error;
1721
1722 dev_dbg(dev, "Set T7 ACTV:%d IDLE:%d\n",
1723 new_config->active, new_config->idle);
1724
1725 return 0;
1726}
1727
1728static int mxt_init_t7_power_cfg(struct mxt_data *data)
1729{
1730 struct device *dev = &data->client->dev;
1731 int error;
1732 bool retry = false;
1733
1734recheck:
1735 error = __mxt_read_reg(data->client, data->T7_address,
1736 sizeof(data->t7_cfg), &data->t7_cfg);
1737 if (error)
1738 return error;
1739
1740 if (data->t7_cfg.active == 0 || data->t7_cfg.idle == 0) {
1741 if (!retry) {
1742 dev_dbg(dev, "T7 cfg zero, resetting\n");
1743 mxt_soft_reset(data);
1744 retry = true;
1745 goto recheck;
1746 } else {
1747 dev_dbg(dev, "T7 cfg zero after reset, overriding\n");
1748 data->t7_cfg.active = 20;
1749 data->t7_cfg.idle = 100;
1750 return mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
1751 }
1752 }
1753
1754 dev_dbg(dev, "Initialized power cfg: ACTV %d, IDLE %d\n",
1755 data->t7_cfg.active, data->t7_cfg.idle);
1756 return 0;
1757}
1758
1715static int mxt_configure_objects(struct mxt_data *data, 1759static int mxt_configure_objects(struct mxt_data *data,
1716 const struct firmware *cfg) 1760 const struct firmware *cfg)
1717{ 1761{
@@ -1725,6 +1769,12 @@ static int mxt_configure_objects(struct mxt_data *data,
1725 dev_warn(dev, "Error %d updating config\n", error); 1769 dev_warn(dev, "Error %d updating config\n", error);
1726 } 1770 }
1727 1771
1772 error = mxt_init_t7_power_cfg(data);
1773 if (error) {
1774 dev_err(dev, "Failed to initialize power cfg\n");
1775 return error;
1776 }
1777
1728 error = mxt_initialize_t9_input_device(data); 1778 error = mxt_initialize_t9_input_device(data);
1729 if (error) 1779 if (error)
1730 return error; 1780 return error;
@@ -2001,16 +2051,15 @@ static const struct attribute_group mxt_attr_group = {
2001 2051
2002static void mxt_start(struct mxt_data *data) 2052static void mxt_start(struct mxt_data *data)
2003{ 2053{
2004 /* Touch enable */ 2054 mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
2005 mxt_write_object(data, 2055
2006 MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83); 2056 /* Recalibrate since chip has been in deep sleep */
2057 mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
2007} 2058}
2008 2059
2009static void mxt_stop(struct mxt_data *data) 2060static void mxt_stop(struct mxt_data *data)
2010{ 2061{
2011 /* Touch disable */ 2062 mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);
2012 mxt_write_object(data,
2013 MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0);
2014} 2063}
2015 2064
2016static int mxt_input_open(struct input_dev *dev) 2065static int mxt_input_open(struct input_dev *dev)
@@ -2175,8 +2224,6 @@ static int mxt_resume(struct device *dev)
2175 struct mxt_data *data = i2c_get_clientdata(client); 2224 struct mxt_data *data = i2c_get_clientdata(client);
2176 struct input_dev *input_dev = data->input_dev; 2225 struct input_dev *input_dev = data->input_dev;
2177 2226
2178 mxt_soft_reset(data);
2179
2180 mutex_lock(&input_dev->mutex); 2227 mutex_lock(&input_dev->mutex);
2181 2228
2182 if (input_dev->users) 2229 if (input_dev->users)