Skip to content

Commit a2add51

Browse files
jlabundydtor
authored andcommitted
Input: iqs7222 - preserve system status register
Some register groups reserve a byte at the end of their continuous address space. Depending on the variant of silicon, this field may share the same memory space as the lower byte of the system status register (0x10). In these cases, caching the reserved byte and writing it later may effectively reset the device depending on what happened in between the read and write operations. Solve this problem by avoiding any access to this last byte within offending register groups. This method replaces a workaround which attempted to write the reserved byte with up-to-date contents, but left a small window in which updates by the device could have been clobbered. Now that the driver does not touch these reserved bytes, the order in which the device's registers are written no longer matters, and they can be written in their natural order. The new method is also much more generic, and can be more easily extended to new variants of silicon with different register maps. As part of this change, the register read and write functions must be gently updated to support byte access instead of word access. Fixes: 2e70ef5 ("Input: iqs7222 - acknowledge reset before writing registers") Signed-off-by: Jeff LaBundy <jeff@labundy.com> Link: https://lore.kernel.org/r/Z85Alw+d9EHKXx2e@nixie71 Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
1 parent d85862c commit a2add51

File tree

1 file changed

+22
-28
lines changed

1 file changed

+22
-28
lines changed

drivers/input/misc/iqs7222.c

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,11 @@ enum iqs7222_reg_key_id {
100100

101101
enum iqs7222_reg_grp_id {
102102
IQS7222_REG_GRP_STAT,
103-
IQS7222_REG_GRP_FILT,
104103
IQS7222_REG_GRP_CYCLE,
105104
IQS7222_REG_GRP_GLBL,
106105
IQS7222_REG_GRP_BTN,
107106
IQS7222_REG_GRP_CHAN,
107+
IQS7222_REG_GRP_FILT,
108108
IQS7222_REG_GRP_SLDR,
109109
IQS7222_REG_GRP_TPAD,
110110
IQS7222_REG_GRP_GPIO,
@@ -286,6 +286,7 @@ static const struct iqs7222_event_desc iqs7222_tp_events[] = {
286286

287287
struct iqs7222_reg_grp_desc {
288288
u16 base;
289+
u16 val_len;
289290
int num_row;
290291
int num_col;
291292
};
@@ -342,6 +343,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
342343
},
343344
[IQS7222_REG_GRP_FILT] = {
344345
.base = 0xAC00,
346+
.val_len = 3,
345347
.num_row = 1,
346348
.num_col = 2,
347349
},
@@ -400,6 +402,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
400402
},
401403
[IQS7222_REG_GRP_FILT] = {
402404
.base = 0xAC00,
405+
.val_len = 3,
403406
.num_row = 1,
404407
.num_col = 2,
405408
},
@@ -454,6 +457,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
454457
},
455458
[IQS7222_REG_GRP_FILT] = {
456459
.base = 0xC400,
460+
.val_len = 3,
457461
.num_row = 1,
458462
.num_col = 2,
459463
},
@@ -496,6 +500,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
496500
},
497501
[IQS7222_REG_GRP_FILT] = {
498502
.base = 0xC400,
503+
.val_len = 3,
499504
.num_row = 1,
500505
.num_col = 2,
501506
},
@@ -543,6 +548,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
543548
},
544549
[IQS7222_REG_GRP_FILT] = {
545550
.base = 0xAA00,
551+
.val_len = 3,
546552
.num_row = 1,
547553
.num_col = 2,
548554
},
@@ -600,6 +606,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
600606
},
601607
[IQS7222_REG_GRP_FILT] = {
602608
.base = 0xAA00,
609+
.val_len = 3,
603610
.num_row = 1,
604611
.num_col = 2,
605612
},
@@ -656,6 +663,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
656663
},
657664
[IQS7222_REG_GRP_FILT] = {
658665
.base = 0xAE00,
666+
.val_len = 3,
659667
.num_row = 1,
660668
.num_col = 2,
661669
},
@@ -712,6 +720,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
712720
},
713721
[IQS7222_REG_GRP_FILT] = {
714722
.base = 0xAE00,
723+
.val_len = 3,
715724
.num_row = 1,
716725
.num_col = 2,
717726
},
@@ -768,6 +777,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
768777
},
769778
[IQS7222_REG_GRP_FILT] = {
770779
.base = 0xAE00,
780+
.val_len = 3,
771781
.num_row = 1,
772782
.num_col = 2,
773783
},
@@ -1604,7 +1614,7 @@ static int iqs7222_force_comms(struct iqs7222_private *iqs7222)
16041614
}
16051615

16061616
static int iqs7222_read_burst(struct iqs7222_private *iqs7222,
1607-
u16 reg, void *val, u16 num_val)
1617+
u16 reg, void *val, u16 val_len)
16081618
{
16091619
u8 reg_buf[sizeof(__be16)];
16101620
int ret, i;
@@ -1619,7 +1629,7 @@ static int iqs7222_read_burst(struct iqs7222_private *iqs7222,
16191629
{
16201630
.addr = client->addr,
16211631
.flags = I2C_M_RD,
1622-
.len = num_val * sizeof(__le16),
1632+
.len = val_len,
16231633
.buf = (u8 *)val,
16241634
},
16251635
};
@@ -1675,7 +1685,7 @@ static int iqs7222_read_word(struct iqs7222_private *iqs7222, u16 reg, u16 *val)
16751685
__le16 val_buf;
16761686
int error;
16771687

1678-
error = iqs7222_read_burst(iqs7222, reg, &val_buf, 1);
1688+
error = iqs7222_read_burst(iqs7222, reg, &val_buf, sizeof(val_buf));
16791689
if (error)
16801690
return error;
16811691

@@ -1685,10 +1695,9 @@ static int iqs7222_read_word(struct iqs7222_private *iqs7222, u16 reg, u16 *val)
16851695
}
16861696

16871697
static int iqs7222_write_burst(struct iqs7222_private *iqs7222,
1688-
u16 reg, const void *val, u16 num_val)
1698+
u16 reg, const void *val, u16 val_len)
16891699
{
16901700
int reg_len = reg > U8_MAX ? sizeof(reg) : sizeof(u8);
1691-
int val_len = num_val * sizeof(__le16);
16921701
int msg_len = reg_len + val_len;
16931702
int ret, i;
16941703
struct i2c_client *client = iqs7222->client;
@@ -1747,7 +1756,7 @@ static int iqs7222_write_word(struct iqs7222_private *iqs7222, u16 reg, u16 val)
17471756
{
17481757
__le16 val_buf = cpu_to_le16(val);
17491758

1750-
return iqs7222_write_burst(iqs7222, reg, &val_buf, 1);
1759+
return iqs7222_write_burst(iqs7222, reg, &val_buf, sizeof(val_buf));
17511760
}
17521761

17531762
static int iqs7222_ati_trigger(struct iqs7222_private *iqs7222)
@@ -1831,30 +1840,14 @@ static int iqs7222_dev_init(struct iqs7222_private *iqs7222, int dir)
18311840

18321841
/*
18331842
* Acknowledge reset before writing any registers in case the device
1834-
* suffers a spurious reset during initialization. Because this step
1835-
* may change the reserved fields of the second filter beta register,
1836-
* its cache must be updated.
1837-
*
1838-
* Writing the second filter beta register, in turn, may clobber the
1839-
* system status register. As such, the filter beta register pair is
1840-
* written first to protect against this hazard.
1843+
* suffers a spurious reset during initialization.
18411844
*/
18421845
if (dir == WRITE) {
1843-
u16 reg = dev_desc->reg_grps[IQS7222_REG_GRP_FILT].base + 1;
1844-
u16 filt_setup;
1845-
18461846
error = iqs7222_write_word(iqs7222, IQS7222_SYS_SETUP,
18471847
iqs7222->sys_setup[0] |
18481848
IQS7222_SYS_SETUP_ACK_RESET);
18491849
if (error)
18501850
return error;
1851-
1852-
error = iqs7222_read_word(iqs7222, reg, &filt_setup);
1853-
if (error)
1854-
return error;
1855-
1856-
iqs7222->filt_setup[1] &= GENMASK(7, 0);
1857-
iqs7222->filt_setup[1] |= (filt_setup & ~GENMASK(7, 0));
18581851
}
18591852

18601853
/*
@@ -1883,6 +1876,7 @@ static int iqs7222_dev_init(struct iqs7222_private *iqs7222, int dir)
18831876
int num_col = dev_desc->reg_grps[i].num_col;
18841877
u16 reg = dev_desc->reg_grps[i].base;
18851878
__le16 *val_buf;
1879+
u16 val_len = dev_desc->reg_grps[i].val_len ? : num_col * sizeof(*val_buf);
18861880
u16 *val;
18871881

18881882
if (!num_col)
@@ -1900,7 +1894,7 @@ static int iqs7222_dev_init(struct iqs7222_private *iqs7222, int dir)
19001894
switch (dir) {
19011895
case READ:
19021896
error = iqs7222_read_burst(iqs7222, reg,
1903-
val_buf, num_col);
1897+
val_buf, val_len);
19041898
for (k = 0; k < num_col; k++)
19051899
val[k] = le16_to_cpu(val_buf[k]);
19061900
break;
@@ -1909,7 +1903,7 @@ static int iqs7222_dev_init(struct iqs7222_private *iqs7222, int dir)
19091903
for (k = 0; k < num_col; k++)
19101904
val_buf[k] = cpu_to_le16(val[k]);
19111905
error = iqs7222_write_burst(iqs7222, reg,
1912-
val_buf, num_col);
1906+
val_buf, val_len);
19131907
break;
19141908

19151909
default:
@@ -1962,7 +1956,7 @@ static int iqs7222_dev_info(struct iqs7222_private *iqs7222)
19621956
int error, i;
19631957

19641958
error = iqs7222_read_burst(iqs7222, IQS7222_PROD_NUM, dev_id,
1965-
ARRAY_SIZE(dev_id));
1959+
sizeof(dev_id));
19661960
if (error)
19671961
return error;
19681962

@@ -2915,7 +2909,7 @@ static int iqs7222_report(struct iqs7222_private *iqs7222)
29152909
__le16 status[IQS7222_MAX_COLS_STAT];
29162910

29172911
error = iqs7222_read_burst(iqs7222, IQS7222_SYS_STATUS, status,
2918-
num_stat);
2912+
num_stat * sizeof(*status));
29192913
if (error)
29202914
return error;
29212915

0 commit comments

Comments
 (0)