Skip to content

Commit 2e70ef5

Browse files
jlabundydtor
authored andcommitted
Input: iqs7222 - acknowledge reset before writing registers
If the device suffers a spurious reset while reacting to a previous spurious reset, the second reset interrupt is preempted because the ACK_RESET bit is written last. To solve this problem, write the ACK_RESET bit prior to writing any other registers. This ensures that any registers written before the second spurious reset will be rewritten. Last but not least, the order in which the ACK_RESET bit is written relative to the second filter beta register is important for select variants of silicon. Enforce the correct order so as to not clobber the system status register. Fixes: e505eda ("Input: add support for Azoteq IQS7222A/B/C") Signed-off-by: Jeff LaBundy <jeff@labundy.com> Link: https://lore.kernel.org/r/20220626072412.475211-5-jeff@labundy.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
1 parent 1e4189d commit 2e70ef5

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

drivers/input/misc/iqs7222.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ enum iqs7222_reg_key_id {
9494

9595
enum iqs7222_reg_grp_id {
9696
IQS7222_REG_GRP_STAT,
97+
IQS7222_REG_GRP_FILT,
9798
IQS7222_REG_GRP_CYCLE,
9899
IQS7222_REG_GRP_GLBL,
99100
IQS7222_REG_GRP_BTN,
100101
IQS7222_REG_GRP_CHAN,
101-
IQS7222_REG_GRP_FILT,
102102
IQS7222_REG_GRP_SLDR,
103103
IQS7222_REG_GRP_GPIO,
104104
IQS7222_REG_GRP_SYS,
@@ -1348,6 +1348,34 @@ static int iqs7222_dev_init(struct iqs7222_private *iqs7222, int dir)
13481348
int comms_offset = dev_desc->comms_offset;
13491349
int error, i, j, k;
13501350

1351+
/*
1352+
* Acknowledge reset before writing any registers in case the device
1353+
* suffers a spurious reset during initialization. Because this step
1354+
* may change the reserved fields of the second filter beta register,
1355+
* its cache must be updated.
1356+
*
1357+
* Writing the second filter beta register, in turn, may clobber the
1358+
* system status register. As such, the filter beta register pair is
1359+
* written first to protect against this hazard.
1360+
*/
1361+
if (dir == WRITE) {
1362+
u16 reg = dev_desc->reg_grps[IQS7222_REG_GRP_FILT].base + 1;
1363+
u16 filt_setup;
1364+
1365+
error = iqs7222_write_word(iqs7222, IQS7222_SYS_SETUP,
1366+
iqs7222->sys_setup[0] |
1367+
IQS7222_SYS_SETUP_ACK_RESET);
1368+
if (error)
1369+
return error;
1370+
1371+
error = iqs7222_read_word(iqs7222, reg, &filt_setup);
1372+
if (error)
1373+
return error;
1374+
1375+
iqs7222->filt_setup[1] &= GENMASK(7, 0);
1376+
iqs7222->filt_setup[1] |= (filt_setup & ~GENMASK(7, 0));
1377+
}
1378+
13511379
/*
13521380
* Take advantage of the stop-bit disable function, if available, to
13531381
* save the trouble of having to reopen a communication window after
@@ -2254,8 +2282,6 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
22542282
return error;
22552283
}
22562284

2257-
sys_setup[0] |= IQS7222_SYS_SETUP_ACK_RESET;
2258-
22592285
return iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_SYS,
22602286
IQS7222_REG_KEY_NONE);
22612287
}

0 commit comments

Comments
 (0)