diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-31 15:59:34 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-31 15:59:34 -0500 |
commit | 7f4054836d811c650c51f9c93088f8ebd61b0020 (patch) | |
tree | 6db556d7ea3f6acdd8b62fd5a2a2331608d898b6 /drivers/input/touchscreen | |
parent | a5cb2366fba7b34da285ef627ee44472235d5bee (diff) |
Revert "Input: atmel_mxt_ts - use deep sleep mode when stopped"
This reverts commit 9d469d033d135d80742a4e39e6bbb4519dd5eee1.
It breaks the Chromebook Pixel touchpad (and touchscreen).
Reported-by: Dirk Hohndel <dirk@hohndel.org>
Bisected-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nick Dyer <nick.dyer@itdev.co.uk>
Cc: Benson Leung <bleung@chromium.org>
Cc: Yufeng Shen <miletus@chromium.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: stable@vger.kernel.org # v3.16+
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 99 |
1 files changed, 26 insertions, 73 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index bb070206223c..95ee92a91bd2 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -99,13 +99,9 @@ | |||
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 | struct t7_config { | 102 | #define MXT_POWER_IDLEACQINT 0 |
103 | u8 idle; | 103 | #define MXT_POWER_ACTVACQINT 1 |
104 | u8 active; | 104 | #define MXT_POWER_ACTV2IDLETO 2 |
105 | } __packed; | ||
106 | |||
107 | #define MXT_POWER_CFG_RUN 0 | ||
108 | #define MXT_POWER_CFG_DEEPSLEEP 1 | ||
109 | 105 | ||
110 | /* MXT_GEN_ACQUIRE_T8 field */ | 106 | /* MXT_GEN_ACQUIRE_T8 field */ |
111 | #define MXT_ACQUIRE_CHRGTIME 0 | 107 | #define MXT_ACQUIRE_CHRGTIME 0 |
@@ -117,6 +113,7 @@ struct t7_config { | |||
117 | #define MXT_ACQUIRE_ATCHCALSTHR 7 | 113 | #define MXT_ACQUIRE_ATCHCALSTHR 7 |
118 | 114 | ||
119 | /* MXT_TOUCH_MULTI_T9 field */ | 115 | /* MXT_TOUCH_MULTI_T9 field */ |
116 | #define MXT_TOUCH_CTRL 0 | ||
120 | #define MXT_T9_ORIENT 9 | 117 | #define MXT_T9_ORIENT 9 |
121 | #define MXT_T9_RANGE 18 | 118 | #define MXT_T9_RANGE 18 |
122 | 119 | ||
@@ -256,7 +253,6 @@ struct mxt_data { | |||
256 | bool update_input; | 253 | bool update_input; |
257 | u8 last_message_count; | 254 | u8 last_message_count; |
258 | u8 num_touchids; | 255 | u8 num_touchids; |
259 | struct t7_config t7_cfg; | ||
260 | 256 | ||
261 | /* Cached parameters from object table */ | 257 | /* Cached parameters from object table */ |
262 | u16 T5_address; | 258 | u16 T5_address; |
@@ -672,6 +668,20 @@ static void mxt_proc_t6_messages(struct mxt_data *data, u8 *msg) | |||
672 | data->t6_status = status; | 668 | data->t6_status = status; |
673 | } | 669 | } |
674 | 670 | ||
671 | static 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 | |||
675 | static void mxt_input_button(struct mxt_data *data, u8 *message) | 685 | static void mxt_input_button(struct mxt_data *data, u8 *message) |
676 | { | 686 | { |
677 | struct input_dev *input = data->input_dev; | 687 | struct input_dev *input = data->input_dev; |
@@ -1742,60 +1752,6 @@ err_free_object_table: | |||
1742 | return error; | 1752 | return error; |
1743 | } | 1753 | } |
1744 | 1754 | ||
1745 | static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep) | ||
1746 | { | ||
1747 | struct device *dev = &data->client->dev; | ||
1748 | int error; | ||
1749 | struct t7_config *new_config; | ||
1750 | struct t7_config deepsleep = { .active = 0, .idle = 0 }; | ||
1751 | |||
1752 | if (sleep == MXT_POWER_CFG_DEEPSLEEP) | ||
1753 | new_config = &deepsleep; | ||
1754 | else | ||
1755 | new_config = &data->t7_cfg; | ||
1756 | |||
1757 | error = __mxt_write_reg(data->client, data->T7_address, | ||
1758 | sizeof(data->t7_cfg), new_config); | ||
1759 | if (error) | ||
1760 | return error; | ||
1761 | |||
1762 | dev_dbg(dev, "Set T7 ACTV:%d IDLE:%d\n", | ||
1763 | new_config->active, new_config->idle); | ||
1764 | |||
1765 | return 0; | ||
1766 | } | ||
1767 | |||
1768 | static int mxt_init_t7_power_cfg(struct mxt_data *data) | ||
1769 | { | ||
1770 | struct device *dev = &data->client->dev; | ||
1771 | int error; | ||
1772 | bool retry = false; | ||
1773 | |||
1774 | recheck: | ||
1775 | error = __mxt_read_reg(data->client, data->T7_address, | ||
1776 | sizeof(data->t7_cfg), &data->t7_cfg); | ||
1777 | if (error) | ||
1778 | return error; | ||
1779 | |||
1780 | if (data->t7_cfg.active == 0 || data->t7_cfg.idle == 0) { | ||
1781 | if (!retry) { | ||
1782 | dev_dbg(dev, "T7 cfg zero, resetting\n"); | ||
1783 | mxt_soft_reset(data); | ||
1784 | retry = true; | ||
1785 | goto recheck; | ||
1786 | } else { | ||
1787 | dev_dbg(dev, "T7 cfg zero after reset, overriding\n"); | ||
1788 | data->t7_cfg.active = 20; | ||
1789 | data->t7_cfg.idle = 100; | ||
1790 | return mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); | ||
1791 | } | ||
1792 | } | ||
1793 | |||
1794 | dev_dbg(dev, "Initialized power cfg: ACTV %d, IDLE %d\n", | ||
1795 | data->t7_cfg.active, data->t7_cfg.idle); | ||
1796 | return 0; | ||
1797 | } | ||
1798 | |||
1799 | static int mxt_configure_objects(struct mxt_data *data, | 1755 | static int mxt_configure_objects(struct mxt_data *data, |
1800 | const struct firmware *cfg) | 1756 | const struct firmware *cfg) |
1801 | { | 1757 | { |
@@ -1809,12 +1765,6 @@ static int mxt_configure_objects(struct mxt_data *data, | |||
1809 | dev_warn(dev, "Error %d updating config\n", error); | 1765 | dev_warn(dev, "Error %d updating config\n", error); |
1810 | } | 1766 | } |
1811 | 1767 | ||
1812 | error = mxt_init_t7_power_cfg(data); | ||
1813 | if (error) { | ||
1814 | dev_err(dev, "Failed to initialize power cfg\n"); | ||
1815 | return error; | ||
1816 | } | ||
1817 | |||
1818 | error = mxt_initialize_t9_input_device(data); | 1768 | error = mxt_initialize_t9_input_device(data); |
1819 | if (error) | 1769 | if (error) |
1820 | return error; | 1770 | return error; |
@@ -2093,15 +2043,16 @@ static const struct attribute_group mxt_attr_group = { | |||
2093 | 2043 | ||
2094 | static void mxt_start(struct mxt_data *data) | 2044 | static void mxt_start(struct mxt_data *data) |
2095 | { | 2045 | { |
2096 | mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); | 2046 | /* Touch enable */ |
2097 | 2047 | mxt_write_object(data, | |
2098 | /* Recalibrate since chip has been in deep sleep */ | 2048 | MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83); |
2099 | mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); | ||
2100 | } | 2049 | } |
2101 | 2050 | ||
2102 | static void mxt_stop(struct mxt_data *data) | 2051 | static void mxt_stop(struct mxt_data *data) |
2103 | { | 2052 | { |
2104 | mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); | 2053 | /* Touch disable */ |
2054 | mxt_write_object(data, | ||
2055 | MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0); | ||
2105 | } | 2056 | } |
2106 | 2057 | ||
2107 | static int mxt_input_open(struct input_dev *dev) | 2058 | static int mxt_input_open(struct input_dev *dev) |
@@ -2266,6 +2217,8 @@ static int __maybe_unused mxt_resume(struct device *dev) | |||
2266 | struct mxt_data *data = i2c_get_clientdata(client); | 2217 | struct mxt_data *data = i2c_get_clientdata(client); |
2267 | struct input_dev *input_dev = data->input_dev; | 2218 | struct input_dev *input_dev = data->input_dev; |
2268 | 2219 | ||
2220 | mxt_soft_reset(data); | ||
2221 | |||
2269 | mutex_lock(&input_dev->mutex); | 2222 | mutex_lock(&input_dev->mutex); |
2270 | 2223 | ||
2271 | if (input_dev->users) | 2224 | if (input_dev->users) |