Skip to content

Commit 3689abf

Browse files
jlabundydtor
authored andcommitted
Input: iqs269a - configure device with a single block write
Unless it is being done as part of servicing a soft reset interrupt, configuring channels on-the-fly (as is the case when writing to the ati_trigger attribute) may cause GPIO3 (which reflects the state of touch for a selected channel) to be inadvertently asserted. To solve this problem, follow the vendor's recommendation and write all channel configuration as well as the REDO_ATI register field as part of a single block write. This ensures the device has been told to re-calibrate itself following an I2C stop condition, after which sensing resumes and GPIO3 may be asserted. Fixes: 04e4986 ("Input: add support for Azoteq IQS269A") Signed-off-by: Jeff LaBundy <[email protected]> Reviewed-by: Mattijs Korpershoek <[email protected]> Link: https://lore.kernel.org/r/Y7Rs8GyV7g0nF5Yy@nixie71 Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent e023cc4 commit 3689abf

File tree

1 file changed

+39
-59
lines changed

1 file changed

+39
-59
lines changed

drivers/input/misc/iqs269a.c

Lines changed: 39 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,6 @@
9696
#define IQS269_MISC_B_TRACKING_UI_ENABLE BIT(4)
9797
#define IQS269_MISC_B_FILT_STR_SLIDER GENMASK(1, 0)
9898

99-
#define IQS269_CHx_SETTINGS 0x8C
100-
10199
#define IQS269_CHx_ENG_A_MEAS_CAP_SIZE BIT(15)
102100
#define IQS269_CHx_ENG_A_RX_GND_INACTIVE BIT(13)
103101
#define IQS269_CHx_ENG_A_LOCAL_CAP_SIZE BIT(12)
@@ -245,6 +243,18 @@ struct iqs269_ver_info {
245243
u8 padding;
246244
} __packed;
247245

246+
struct iqs269_ch_reg {
247+
u8 rx_enable;
248+
u8 tx_enable;
249+
__be16 engine_a;
250+
__be16 engine_b;
251+
__be16 ati_comp;
252+
u8 thresh[3];
253+
u8 hyst;
254+
u8 assoc_select;
255+
u8 assoc_weight;
256+
} __packed;
257+
248258
struct iqs269_sys_reg {
249259
__be16 general;
250260
u8 active;
@@ -266,18 +276,7 @@ struct iqs269_sys_reg {
266276
u8 timeout_swipe;
267277
u8 thresh_swipe;
268278
u8 redo_ati;
269-
} __packed;
270-
271-
struct iqs269_ch_reg {
272-
u8 rx_enable;
273-
u8 tx_enable;
274-
__be16 engine_a;
275-
__be16 engine_b;
276-
__be16 ati_comp;
277-
u8 thresh[3];
278-
u8 hyst;
279-
u8 assoc_select;
280-
u8 assoc_weight;
279+
struct iqs269_ch_reg ch_reg[IQS269_NUM_CH];
281280
} __packed;
282281

283282
struct iqs269_flags {
@@ -292,7 +291,6 @@ struct iqs269_private {
292291
struct regmap *regmap;
293292
struct mutex lock;
294293
struct iqs269_switch_desc switches[ARRAY_SIZE(iqs269_events)];
295-
struct iqs269_ch_reg ch_reg[IQS269_NUM_CH];
296294
struct iqs269_sys_reg sys_reg;
297295
struct input_dev *keypad;
298296
struct input_dev *slider[IQS269_NUM_SL];
@@ -307,6 +305,7 @@ struct iqs269_private {
307305
static int iqs269_ati_mode_set(struct iqs269_private *iqs269,
308306
unsigned int ch_num, unsigned int mode)
309307
{
308+
struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
310309
u16 engine_a;
311310

312311
if (ch_num >= IQS269_NUM_CH)
@@ -317,12 +316,12 @@ static int iqs269_ati_mode_set(struct iqs269_private *iqs269,
317316

318317
mutex_lock(&iqs269->lock);
319318

320-
engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a);
319+
engine_a = be16_to_cpu(ch_reg[ch_num].engine_a);
321320

322321
engine_a &= ~IQS269_CHx_ENG_A_ATI_MODE_MASK;
323322
engine_a |= (mode << IQS269_CHx_ENG_A_ATI_MODE_SHIFT);
324323

325-
iqs269->ch_reg[ch_num].engine_a = cpu_to_be16(engine_a);
324+
ch_reg[ch_num].engine_a = cpu_to_be16(engine_a);
326325
iqs269->ati_current = false;
327326

328327
mutex_unlock(&iqs269->lock);
@@ -333,13 +332,14 @@ static int iqs269_ati_mode_set(struct iqs269_private *iqs269,
333332
static int iqs269_ati_mode_get(struct iqs269_private *iqs269,
334333
unsigned int ch_num, unsigned int *mode)
335334
{
335+
struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
336336
u16 engine_a;
337337

338338
if (ch_num >= IQS269_NUM_CH)
339339
return -EINVAL;
340340

341341
mutex_lock(&iqs269->lock);
342-
engine_a = be16_to_cpu(iqs269->ch_reg[ch_num].engine_a);
342+
engine_a = be16_to_cpu(ch_reg[ch_num].engine_a);
343343
mutex_unlock(&iqs269->lock);
344344

345345
engine_a &= IQS269_CHx_ENG_A_ATI_MODE_MASK;
@@ -351,6 +351,7 @@ static int iqs269_ati_mode_get(struct iqs269_private *iqs269,
351351
static int iqs269_ati_base_set(struct iqs269_private *iqs269,
352352
unsigned int ch_num, unsigned int base)
353353
{
354+
struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
354355
u16 engine_b;
355356

356357
if (ch_num >= IQS269_NUM_CH)
@@ -379,12 +380,12 @@ static int iqs269_ati_base_set(struct iqs269_private *iqs269,
379380

380381
mutex_lock(&iqs269->lock);
381382

382-
engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
383+
engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
383384

384385
engine_b &= ~IQS269_CHx_ENG_B_ATI_BASE_MASK;
385386
engine_b |= base;
386387

387-
iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
388+
ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
388389
iqs269->ati_current = false;
389390

390391
mutex_unlock(&iqs269->lock);
@@ -395,13 +396,14 @@ static int iqs269_ati_base_set(struct iqs269_private *iqs269,
395396
static int iqs269_ati_base_get(struct iqs269_private *iqs269,
396397
unsigned int ch_num, unsigned int *base)
397398
{
399+
struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
398400
u16 engine_b;
399401

400402
if (ch_num >= IQS269_NUM_CH)
401403
return -EINVAL;
402404

403405
mutex_lock(&iqs269->lock);
404-
engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
406+
engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
405407
mutex_unlock(&iqs269->lock);
406408

407409
switch (engine_b & IQS269_CHx_ENG_B_ATI_BASE_MASK) {
@@ -429,6 +431,7 @@ static int iqs269_ati_base_get(struct iqs269_private *iqs269,
429431
static int iqs269_ati_target_set(struct iqs269_private *iqs269,
430432
unsigned int ch_num, unsigned int target)
431433
{
434+
struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
432435
u16 engine_b;
433436

434437
if (ch_num >= IQS269_NUM_CH)
@@ -439,12 +442,12 @@ static int iqs269_ati_target_set(struct iqs269_private *iqs269,
439442

440443
mutex_lock(&iqs269->lock);
441444

442-
engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
445+
engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
443446

444447
engine_b &= ~IQS269_CHx_ENG_B_ATI_TARGET_MASK;
445448
engine_b |= target / 32;
446449

447-
iqs269->ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
450+
ch_reg[ch_num].engine_b = cpu_to_be16(engine_b);
448451
iqs269->ati_current = false;
449452

450453
mutex_unlock(&iqs269->lock);
@@ -455,13 +458,14 @@ static int iqs269_ati_target_set(struct iqs269_private *iqs269,
455458
static int iqs269_ati_target_get(struct iqs269_private *iqs269,
456459
unsigned int ch_num, unsigned int *target)
457460
{
461+
struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
458462
u16 engine_b;
459463

460464
if (ch_num >= IQS269_NUM_CH)
461465
return -EINVAL;
462466

463467
mutex_lock(&iqs269->lock);
464-
engine_b = be16_to_cpu(iqs269->ch_reg[ch_num].engine_b);
468+
engine_b = be16_to_cpu(ch_reg[ch_num].engine_b);
465469
mutex_unlock(&iqs269->lock);
466470

467471
*target = (engine_b & IQS269_CHx_ENG_B_ATI_TARGET_MASK) * 32;
@@ -531,13 +535,7 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269,
531535
if (fwnode_property_present(ch_node, "azoteq,slider1-select"))
532536
iqs269->sys_reg.slider_select[1] |= BIT(reg);
533537

534-
ch_reg = &iqs269->ch_reg[reg];
535-
536-
error = regmap_raw_read(iqs269->regmap,
537-
IQS269_CHx_SETTINGS + reg * sizeof(*ch_reg) / 2,
538-
ch_reg, sizeof(*ch_reg));
539-
if (error)
540-
return error;
538+
ch_reg = &iqs269->sys_reg.ch_reg[reg];
541539

542540
error = iqs269_parse_mask(ch_node, "azoteq,rx-enable",
543541
&ch_reg->rx_enable);
@@ -1042,10 +1040,8 @@ static int iqs269_parse_prop(struct iqs269_private *iqs269)
10421040

10431041
static int iqs269_dev_init(struct iqs269_private *iqs269)
10441042
{
1045-
struct iqs269_sys_reg *sys_reg = &iqs269->sys_reg;
1046-
struct iqs269_ch_reg *ch_reg;
10471043
unsigned int val;
1048-
int error, i;
1044+
int error;
10491045

10501046
mutex_lock(&iqs269->lock);
10511047

@@ -1055,27 +1051,8 @@ static int iqs269_dev_init(struct iqs269_private *iqs269)
10551051
if (error)
10561052
goto err_mutex;
10571053

1058-
for (i = 0; i < IQS269_NUM_CH; i++) {
1059-
if (!(sys_reg->active & BIT(i)))
1060-
continue;
1061-
1062-
ch_reg = &iqs269->ch_reg[i];
1063-
1064-
error = regmap_raw_write(iqs269->regmap,
1065-
IQS269_CHx_SETTINGS + i *
1066-
sizeof(*ch_reg) / 2, ch_reg,
1067-
sizeof(*ch_reg));
1068-
if (error)
1069-
goto err_mutex;
1070-
}
1071-
1072-
/*
1073-
* The REDO-ATI and ATI channel selection fields must be written in the
1074-
* same block write, so every field between registers 0x80 through 0x8B
1075-
* (inclusive) must be written as well.
1076-
*/
1077-
error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS, sys_reg,
1078-
sizeof(*sys_reg));
1054+
error = regmap_raw_write(iqs269->regmap, IQS269_SYS_SETTINGS,
1055+
&iqs269->sys_reg, sizeof(iqs269->sys_reg));
10791056
if (error)
10801057
goto err_mutex;
10811058

@@ -1349,6 +1326,7 @@ static ssize_t hall_bin_show(struct device *dev,
13491326
struct device_attribute *attr, char *buf)
13501327
{
13511328
struct iqs269_private *iqs269 = dev_get_drvdata(dev);
1329+
struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
13521330
struct i2c_client *client = iqs269->client;
13531331
unsigned int val;
13541332
int error;
@@ -1363,8 +1341,8 @@ static ssize_t hall_bin_show(struct device *dev,
13631341
if (error)
13641342
return error;
13651343

1366-
switch (iqs269->ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable &
1367-
iqs269->ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) {
1344+
switch (ch_reg[IQS269_CHx_HALL_ACTIVE].rx_enable &
1345+
ch_reg[IQS269_CHx_HALL_INACTIVE].rx_enable) {
13681346
case IQS269_HALL_PAD_R:
13691347
val &= IQS269_CAL_DATA_A_HALL_BIN_R_MASK;
13701348
val >>= IQS269_CAL_DATA_A_HALL_BIN_R_SHIFT;
@@ -1444,16 +1422,18 @@ static ssize_t rx_enable_show(struct device *dev,
14441422
struct device_attribute *attr, char *buf)
14451423
{
14461424
struct iqs269_private *iqs269 = dev_get_drvdata(dev);
1425+
struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
14471426

14481427
return scnprintf(buf, PAGE_SIZE, "%u\n",
1449-
iqs269->ch_reg[iqs269->ch_num].rx_enable);
1428+
ch_reg[iqs269->ch_num].rx_enable);
14501429
}
14511430

14521431
static ssize_t rx_enable_store(struct device *dev,
14531432
struct device_attribute *attr, const char *buf,
14541433
size_t count)
14551434
{
14561435
struct iqs269_private *iqs269 = dev_get_drvdata(dev);
1436+
struct iqs269_ch_reg *ch_reg = iqs269->sys_reg.ch_reg;
14571437
unsigned int val;
14581438
int error;
14591439

@@ -1466,7 +1446,7 @@ static ssize_t rx_enable_store(struct device *dev,
14661446

14671447
mutex_lock(&iqs269->lock);
14681448

1469-
iqs269->ch_reg[iqs269->ch_num].rx_enable = val;
1449+
ch_reg[iqs269->ch_num].rx_enable = val;
14701450
iqs269->ati_current = false;
14711451

14721452
mutex_unlock(&iqs269->lock);

0 commit comments

Comments
 (0)