summaryrefslogtreecommitdiff
path: root/drivers/mfd/iqs62x.c
diff options
context:
space:
mode:
authorJeff LaBundy <jeff@labundy.com>2021-01-17 21:57:08 -0600
committerLee Jones <lee.jones@linaro.org>2021-02-08 13:54:38 +0000
commit6a8fac01dc1c6508dd7cab876170024070b71039 (patch)
tree6b468f2dad8824cc9b059613f087afc79ece8487 /drivers/mfd/iqs62x.c
parent02e550d5b706f034d24e7e46234eb1982f05a137 (diff)
mfd: iqs62x: Do not change clock frequency during ATI
After a reset event, the device automatically triggers ATI at the default core clock frequency (16 MHz). Soon afterward, the driver loads firmware which may attempt to lower the frequency. If this initial ATI cycle is still in progress when the frequency is changed, however, the device incorrectly reports channels 0, 1 and 2 to be in a state of touch once ATI finally completes. To solve this problem, wait until ATI is complete before lowering the frequency. Because this particular ATI cycle occurs following a reset event, its duration is predictable and a simple delay can suffice. Signed-off-by: Jeff LaBundy <jeff@labundy.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd/iqs62x.c')
-rw-r--r--drivers/mfd/iqs62x.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/mfd/iqs62x.c b/drivers/mfd/iqs62x.c
index 9b5c389ca2c3..d1fc38a78acb 100644
--- a/drivers/mfd/iqs62x.c
+++ b/drivers/mfd/iqs62x.c
@@ -81,6 +81,7 @@
#define IQS62X_FW_REC_TYPE_MASK 3
#define IQS62X_FW_REC_TYPE_DATA 4
+#define IQS62X_ATI_STARTUP_MS 350
#define IQS62X_FILT_SETTLE_MS 250
struct iqs62x_fw_rec {
@@ -111,6 +112,14 @@ static int iqs62x_dev_init(struct iqs62x_core *iqs62x)
int ret;
list_for_each_entry(fw_blk, &iqs62x->fw_blk_head, list) {
+ /*
+ * In case ATI is in progress, wait for it to complete before
+ * lowering the core clock frequency.
+ */
+ if (fw_blk->addr == IQS62X_SYS_SETTINGS &&
+ *fw_blk->data & IQS62X_SYS_SETTINGS_CLK_DIV)
+ msleep(IQS62X_ATI_STARTUP_MS);
+
if (fw_blk->mask)
ret = regmap_update_bits(iqs62x->regmap, fw_blk->addr,
fw_blk->mask, *fw_blk->data);