Skip to content

Commit 36874c7

Browse files
Roger Quadrosdtor
authored andcommitted
Input: pixcir_i2c_ts - support up to 5 fingers and hardware tracking IDs
Some variants of the Pixcir touch controller support up to 5 simultaneous fingers and hardware tracking IDs. Prepare the driver for that. Signed-off-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
1 parent 62e65b7 commit 36874c7

2 files changed

Lines changed: 69 additions & 17 deletions

File tree

drivers/input/touchscreen/pixcir_i2c_ts.c

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,20 @@
2727
#include <linux/input/pixcir_ts.h>
2828
#include <linux/gpio.h>
2929

30-
#define PIXCIR_MAX_SLOTS 2
30+
#define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */
3131

3232
struct pixcir_i2c_ts_data {
3333
struct i2c_client *client;
3434
struct input_dev *input;
35-
const struct pixcir_ts_platform_data *chip;
35+
const struct pixcir_ts_platform_data *pdata;
3636
bool running;
37+
int max_fingers; /* Max fingers supported in this instance */
3738
};
3839

3940
struct pixcir_touch {
4041
int x;
4142
int y;
43+
int id;
4244
};
4345

4446
struct pixcir_report_data {
@@ -49,13 +51,21 @@ struct pixcir_report_data {
4951
static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
5052
struct pixcir_report_data *report)
5153
{
52-
u8 rdbuf[10], wrbuf[1] = { 0 };
54+
u8 rdbuf[2 + PIXCIR_MAX_SLOTS * 5];
55+
u8 wrbuf[1] = { 0 };
5356
u8 *bufptr;
5457
u8 touch;
5558
int ret, i;
59+
int readsize;
60+
const struct pixcir_i2c_chip_data *chip = &tsdata->pdata->chip;
5661

5762
memset(report, 0, sizeof(struct pixcir_report_data));
5863

64+
i = chip->has_hw_ids ? 1 : 0;
65+
readsize = 2 + tsdata->max_fingers * (4 + i);
66+
if (readsize > sizeof(rdbuf))
67+
readsize = sizeof(rdbuf);
68+
5969
ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf));
6070
if (ret != sizeof(wrbuf)) {
6171
dev_err(&tsdata->client->dev,
@@ -64,7 +74,7 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
6474
return;
6575
}
6676

67-
ret = i2c_master_recv(tsdata->client, rdbuf, sizeof(rdbuf));
77+
ret = i2c_master_recv(tsdata->client, rdbuf, readsize);
6878
if (ret != sizeof(rdbuf)) {
6979
dev_err(&tsdata->client->dev,
7080
"%s: i2c_master_recv failed(), ret=%d\n",
@@ -73,8 +83,8 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
7383
}
7484

7585
touch = rdbuf[0] & 0x7;
76-
if (touch > PIXCIR_MAX_SLOTS)
77-
touch = PIXCIR_MAX_SLOTS;
86+
if (touch > tsdata->max_fingers)
87+
touch = tsdata->max_fingers;
7888

7989
report->num_touches = touch;
8090
bufptr = &rdbuf[2];
@@ -83,7 +93,12 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
8393
report->touches[i].x = (bufptr[1] << 8) | bufptr[0];
8494
report->touches[i].y = (bufptr[3] << 8) | bufptr[2];
8595

86-
bufptr = bufptr + 4;
96+
if (chip->has_hw_ids) {
97+
report->touches[i].id = bufptr[4];
98+
bufptr = bufptr + 5;
99+
} else {
100+
bufptr = bufptr + 4;
101+
}
87102
}
88103
}
89104

@@ -95,22 +110,35 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
95110
struct pixcir_touch *touch;
96111
int n, i, slot;
97112
struct device *dev = &ts->client->dev;
113+
const struct pixcir_i2c_chip_data *chip = &ts->pdata->chip;
98114

99115
n = report->num_touches;
100116
if (n > PIXCIR_MAX_SLOTS)
101117
n = PIXCIR_MAX_SLOTS;
102118

103-
for (i = 0; i < n; i++) {
104-
touch = &report->touches[i];
105-
pos[i].x = touch->x;
106-
pos[i].y = touch->y;
107-
}
119+
if (!chip->has_hw_ids) {
120+
for (i = 0; i < n; i++) {
121+
touch = &report->touches[i];
122+
pos[i].x = touch->x;
123+
pos[i].y = touch->y;
124+
}
108125

109-
input_mt_assign_slots(ts->input, slots, pos, n);
126+
input_mt_assign_slots(ts->input, slots, pos, n);
127+
}
110128

111129
for (i = 0; i < n; i++) {
112130
touch = &report->touches[i];
113-
slot = slots[i];
131+
132+
if (chip->has_hw_ids) {
133+
slot = input_mt_get_slot_by_key(ts->input, touch->id);
134+
if (slot < 0) {
135+
dev_dbg(dev, "no free slot for id 0x%x\n",
136+
touch->id);
137+
continue;
138+
}
139+
} else {
140+
slot = slots[i];
141+
}
114142

115143
input_mt_slot(ts->input, slot);
116144
input_mt_report_slot_state(ts->input,
@@ -130,7 +158,7 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
130158
static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
131159
{
132160
struct pixcir_i2c_ts_data *tsdata = dev_id;
133-
const struct pixcir_ts_platform_data *pdata = tsdata->chip;
161+
const struct pixcir_ts_platform_data *pdata = tsdata->pdata;
134162
struct pixcir_report_data report;
135163

136164
while (tsdata->running) {
@@ -399,6 +427,11 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
399427
return -EINVAL;
400428
}
401429

430+
if (!pdata->chip.max_fingers) {
431+
dev_err(dev, "Invalid max_fingers in pdata\n");
432+
return -EINVAL;
433+
}
434+
402435
tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
403436
if (!tsdata)
404437
return -ENOMEM;
@@ -411,7 +444,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
411444

412445
tsdata->client = client;
413446
tsdata->input = input;
414-
tsdata->chip = pdata;
447+
tsdata->pdata = pdata;
415448

416449
input->name = client->name;
417450
input->id.bustype = BUS_I2C;
@@ -427,7 +460,14 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
427460
input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
428461
input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0);
429462

430-
error = input_mt_init_slots(input, PIXCIR_MAX_SLOTS,
463+
tsdata->max_fingers = tsdata->pdata->chip.max_fingers;
464+
if (tsdata->max_fingers > PIXCIR_MAX_SLOTS) {
465+
tsdata->max_fingers = PIXCIR_MAX_SLOTS;
466+
dev_info(dev, "Limiting maximum fingers to %d\n",
467+
tsdata->max_fingers);
468+
}
469+
470+
error = input_mt_init_slots(input, tsdata->max_fingers,
431471
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
432472
if (error) {
433473
dev_err(dev, "Error initializing Multi-Touch slots\n");

include/linux/input/pixcir_ts.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,22 @@ enum pixcir_int_mode {
4343
#define PIXCIR_INT_ENABLE (1UL << 3)
4444
#define PIXCIR_INT_POL_HIGH (1UL << 2)
4545

46+
/**
47+
* struct pixcir_irc_chip_data - chip related data
48+
* @max_fingers: Max number of fingers reported simultaneously by h/w
49+
* @has_hw_ids: Hardware supports finger tracking IDs
50+
*
51+
*/
52+
struct pixcir_i2c_chip_data {
53+
u8 max_fingers;
54+
bool has_hw_ids;
55+
};
56+
4657
struct pixcir_ts_platform_data {
4758
int x_max;
4859
int y_max;
4960
int gpio_attb; /* GPIO connected to ATTB line */
61+
struct pixcir_i2c_chip_data chip;
5062
};
5163

5264
#endif

0 commit comments

Comments
 (0)