Skip to content

Commit 74d905d

Browse files
ndyerdtor
authored andcommitted
Input: atmel_mxt_ts - only read messages in mxt_acquire_irq() when necessary
The workaround of reading all messages until an invalid is received is a way of forcing the CHG line high, which means that when using edge-triggered interrupts the interrupt can be acquired. With level-triggered interrupts the workaround is unnecessary. Also, most recent maXTouch chips have a feature called RETRIGEN which, when enabled, reasserts the interrupt line every cycle if there are messages waiting. This also makes the workaround unnecessary. Note: the RETRIGEN feature is only in some firmware versions/chips, it's not valid simply to enable the bit. Signed-off-by: Nick Dyer <[email protected]> Acked-by: Benson Leung <[email protected]> Acked-by: Yufeng Shen <[email protected]> (cherry picked from ndyer/linux/for-upstream commit 1ae4e82) [gdavis: Fix conflicts due to v4.6-rc7 commit eb43335 ("Input: atmel_mxt_ts - use mxt_acquire_irq in mxt_soft_reset").] Signed-off-by: George G. Davis <[email protected]> [jiada: reset use_retrigen_workaround at beginning of mxt_check_retrigen() call mxt_check_retrigen() after mxt_acquire_irq() in mxt_initialize() replace white-spaces with tab for MXT_COMMS_RETRIGEN Changed to check if IRQ is level type] Signed-off-by: Jiada Wang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent bbca4d3 commit 74d905d

File tree

1 file changed

+53
-3
lines changed

1 file changed

+53
-3
lines changed

drivers/input/touchscreen/atmel_mxt_ts.c

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/i2c.h>
2121
#include <linux/input/mt.h>
2222
#include <linux/interrupt.h>
23+
#include <linux/irq.h>
2324
#include <linux/of.h>
2425
#include <linux/property.h>
2526
#include <linux/slab.h>
@@ -129,6 +130,7 @@ struct t9_range {
129130
/* MXT_SPT_COMMSCONFIG_T18 */
130131
#define MXT_COMMS_CTRL 0
131132
#define MXT_COMMS_CMD 1
133+
#define MXT_COMMS_RETRIGEN BIT(6)
132134

133135
/* MXT_DEBUG_DIAGNOSTIC_T37 */
134136
#define MXT_DIAGNOSTIC_PAGEUP 0x01
@@ -308,6 +310,7 @@ struct mxt_data {
308310
struct t7_config t7_cfg;
309311
struct mxt_dbg dbg;
310312
struct gpio_desc *reset_gpio;
313+
bool use_retrigen_workaround;
311314

312315
/* Cached parameters from object table */
313316
u16 T5_address;
@@ -318,6 +321,7 @@ struct mxt_data {
318321
u16 T71_address;
319322
u8 T9_reportid_min;
320323
u8 T9_reportid_max;
324+
u16 T18_address;
321325
u8 T19_reportid;
322326
u16 T44_address;
323327
u8 T100_reportid_min;
@@ -1190,9 +1194,11 @@ static int mxt_acquire_irq(struct mxt_data *data)
11901194

11911195
enable_irq(data->irq);
11921196

1193-
error = mxt_process_messages_until_invalid(data);
1194-
if (error)
1195-
return error;
1197+
if (data->use_retrigen_workaround) {
1198+
error = mxt_process_messages_until_invalid(data);
1199+
if (error)
1200+
return error;
1201+
}
11961202

11971203
return 0;
11981204
}
@@ -1282,6 +1288,38 @@ static u32 mxt_calculate_crc(u8 *base, off_t start_off, off_t end_off)
12821288
return crc;
12831289
}
12841290

1291+
static int mxt_check_retrigen(struct mxt_data *data)
1292+
{
1293+
struct i2c_client *client = data->client;
1294+
int error;
1295+
int val;
1296+
struct irq_data *irqd;
1297+
1298+
data->use_retrigen_workaround = false;
1299+
1300+
irqd = irq_get_irq_data(data->irq);
1301+
if (!irqd)
1302+
return -EINVAL;
1303+
1304+
if (irqd_is_level_type(irqd))
1305+
return 0;
1306+
1307+
if (data->T18_address) {
1308+
error = __mxt_read_reg(client,
1309+
data->T18_address + MXT_COMMS_CTRL,
1310+
1, &val);
1311+
if (error)
1312+
return error;
1313+
1314+
if (val & MXT_COMMS_RETRIGEN)
1315+
return 0;
1316+
}
1317+
1318+
dev_warn(&client->dev, "Enabling RETRIGEN workaround\n");
1319+
data->use_retrigen_workaround = true;
1320+
return 0;
1321+
}
1322+
12851323
static int mxt_prepare_cfg_mem(struct mxt_data *data, struct mxt_cfg *cfg)
12861324
{
12871325
struct device *dev = &data->client->dev;
@@ -1561,6 +1599,10 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
15611599

15621600
mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
15631601

1602+
ret = mxt_check_retrigen(data);
1603+
if (ret)
1604+
goto release_mem;
1605+
15641606
ret = mxt_soft_reset(data);
15651607
if (ret)
15661608
goto release_mem;
@@ -1604,6 +1646,7 @@ static void mxt_free_object_table(struct mxt_data *data)
16041646
data->T71_address = 0;
16051647
data->T9_reportid_min = 0;
16061648
data->T9_reportid_max = 0;
1649+
data->T18_address = 0;
16071650
data->T19_reportid = 0;
16081651
data->T44_address = 0;
16091652
data->T100_reportid_min = 0;
@@ -1678,6 +1721,9 @@ static int mxt_parse_object_table(struct mxt_data *data,
16781721
object->num_report_ids - 1;
16791722
data->num_touchids = object->num_report_ids;
16801723
break;
1724+
case MXT_SPT_COMMSCONFIG_T18:
1725+
data->T18_address = object->start_address;
1726+
break;
16811727
case MXT_SPT_MESSAGECOUNT_T44:
16821728
data->T44_address = object->start_address;
16831729
break;
@@ -2141,6 +2187,10 @@ static int mxt_initialize(struct mxt_data *data)
21412187
if (error)
21422188
return error;
21432189

2190+
error = mxt_check_retrigen(data);
2191+
if (error)
2192+
return error;
2193+
21442194
error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
21452195
&client->dev, GFP_KERNEL, data,
21462196
mxt_config_cb);

0 commit comments

Comments
 (0)