aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/touchscreen/pixcir_i2c_ts.c74
-rw-r--r--include/linux/input/pixcir_ts.h12
2 files changed, 69 insertions, 17 deletions
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 0b016814e6b6..eddda520a1a7 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -27,18 +27,20 @@
27#include <linux/input/pixcir_ts.h> 27#include <linux/input/pixcir_ts.h>
28#include <linux/gpio.h> 28#include <linux/gpio.h>
29 29
30#define PIXCIR_MAX_SLOTS 2 30#define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */
31 31
32struct pixcir_i2c_ts_data { 32struct pixcir_i2c_ts_data {
33 struct i2c_client *client; 33 struct i2c_client *client;
34 struct input_dev *input; 34 struct input_dev *input;
35 const struct pixcir_ts_platform_data *chip; 35 const struct pixcir_ts_platform_data *pdata;
36 bool running; 36 bool running;
37 int max_fingers; /* Max fingers supported in this instance */
37}; 38};
38 39
39struct pixcir_touch { 40struct pixcir_touch {
40 int x; 41 int x;
41 int y; 42 int y;
43 int id;
42}; 44};
43 45
44struct pixcir_report_data { 46struct pixcir_report_data {
@@ -49,13 +51,21 @@ struct pixcir_report_data {
49static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata, 51static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
50 struct pixcir_report_data *report) 52 struct pixcir_report_data *report)
51{ 53{
52 u8 rdbuf[10], wrbuf[1] = { 0 }; 54 u8 rdbuf[2 + PIXCIR_MAX_SLOTS * 5];
55 u8 wrbuf[1] = { 0 };
53 u8 *bufptr; 56 u8 *bufptr;
54 u8 touch; 57 u8 touch;
55 int ret, i; 58 int ret, i;
59 int readsize;
60 const struct pixcir_i2c_chip_data *chip = &tsdata->pdata->chip;
56 61
57 memset(report, 0, sizeof(struct pixcir_report_data)); 62 memset(report, 0, sizeof(struct pixcir_report_data));
58 63
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
59 ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf)); 69 ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf));
60 if (ret != sizeof(wrbuf)) { 70 if (ret != sizeof(wrbuf)) {
61 dev_err(&tsdata->client->dev, 71 dev_err(&tsdata->client->dev,
@@ -64,7 +74,7 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
64 return; 74 return;
65 } 75 }
66 76
67 ret = i2c_master_recv(tsdata->client, rdbuf, sizeof(rdbuf)); 77 ret = i2c_master_recv(tsdata->client, rdbuf, readsize);
68 if (ret != sizeof(rdbuf)) { 78 if (ret != sizeof(rdbuf)) {
69 dev_err(&tsdata->client->dev, 79 dev_err(&tsdata->client->dev,
70 "%s: i2c_master_recv failed(), ret=%d\n", 80 "%s: i2c_master_recv failed(), ret=%d\n",
@@ -73,8 +83,8 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
73 } 83 }
74 84
75 touch = rdbuf[0] & 0x7; 85 touch = rdbuf[0] & 0x7;
76 if (touch > PIXCIR_MAX_SLOTS) 86 if (touch > tsdata->max_fingers)
77 touch = PIXCIR_MAX_SLOTS; 87 touch = tsdata->max_fingers;
78 88
79 report->num_touches = touch; 89 report->num_touches = touch;
80 bufptr = &rdbuf[2]; 90 bufptr = &rdbuf[2];
@@ -83,7 +93,12 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
83 report->touches[i].x = (bufptr[1] << 8) | bufptr[0]; 93 report->touches[i].x = (bufptr[1] << 8) | bufptr[0];
84 report->touches[i].y = (bufptr[3] << 8) | bufptr[2]; 94 report->touches[i].y = (bufptr[3] << 8) | bufptr[2];
85 95
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 }
87 } 102 }
88} 103}
89 104
@@ -95,22 +110,35 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
95 struct pixcir_touch *touch; 110 struct pixcir_touch *touch;
96 int n, i, slot; 111 int n, i, slot;
97 struct device *dev = &ts->client->dev; 112 struct device *dev = &ts->client->dev;
113 const struct pixcir_i2c_chip_data *chip = &ts->pdata->chip;
98 114
99 n = report->num_touches; 115 n = report->num_touches;
100 if (n > PIXCIR_MAX_SLOTS) 116 if (n > PIXCIR_MAX_SLOTS)
101 n = PIXCIR_MAX_SLOTS; 117 n = PIXCIR_MAX_SLOTS;
102 118
103 for (i = 0; i < n; i++) { 119 if (!chip->has_hw_ids) {
104 touch = &report->touches[i]; 120 for (i = 0; i < n; i++) {
105 pos[i].x = touch->x; 121 touch = &report->touches[i];
106 pos[i].y = touch->y; 122 pos[i].x = touch->x;
107 } 123 pos[i].y = touch->y;
124 }
108 125
109 input_mt_assign_slots(ts->input, slots, pos, n); 126 input_mt_assign_slots(ts->input, slots, pos, n);
127 }
110 128
111 for (i = 0; i < n; i++) { 129 for (i = 0; i < n; i++) {
112 touch = &report->touches[i]; 130 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 }
114 142
115 input_mt_slot(ts->input, slot); 143 input_mt_slot(ts->input, slot);
116 input_mt_report_slot_state(ts->input, 144 input_mt_report_slot_state(ts->input,
@@ -130,7 +158,7 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
130static irqreturn_t pixcir_ts_isr(int irq, void *dev_id) 158static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
131{ 159{
132 struct pixcir_i2c_ts_data *tsdata = dev_id; 160 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;
134 struct pixcir_report_data report; 162 struct pixcir_report_data report;
135 163
136 while (tsdata->running) { 164 while (tsdata->running) {
@@ -399,6 +427,11 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
399 return -EINVAL; 427 return -EINVAL;
400 } 428 }
401 429
430 if (!pdata->chip.max_fingers) {
431 dev_err(dev, "Invalid max_fingers in pdata\n");
432 return -EINVAL;
433 }
434
402 tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL); 435 tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
403 if (!tsdata) 436 if (!tsdata)
404 return -ENOMEM; 437 return -ENOMEM;
@@ -411,7 +444,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
411 444
412 tsdata->client = client; 445 tsdata->client = client;
413 tsdata->input = input; 446 tsdata->input = input;
414 tsdata->chip = pdata; 447 tsdata->pdata = pdata;
415 448
416 input->name = client->name; 449 input->name = client->name;
417 input->id.bustype = BUS_I2C; 450 input->id.bustype = BUS_I2C;
@@ -427,7 +460,14 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
427 input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0); 460 input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
428 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0); 461 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0);
429 462
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,
431 INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); 471 INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
432 if (error) { 472 if (error) {
433 dev_err(dev, "Error initializing Multi-Touch slots\n"); 473 dev_err(dev, "Error initializing Multi-Touch slots\n");
diff --git a/include/linux/input/pixcir_ts.h b/include/linux/input/pixcir_ts.h
index 160cf353aa39..7bae83b7c396 100644
--- a/include/linux/input/pixcir_ts.h
+++ b/include/linux/input/pixcir_ts.h
@@ -43,10 +43,22 @@ enum pixcir_int_mode {
43#define PIXCIR_INT_ENABLE (1UL << 3) 43#define PIXCIR_INT_ENABLE (1UL << 3)
44#define PIXCIR_INT_POL_HIGH (1UL << 2) 44#define PIXCIR_INT_POL_HIGH (1UL << 2)
45 45
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 */
52struct pixcir_i2c_chip_data {
53 u8 max_fingers;
54 bool has_hw_ids;
55};
56
46struct pixcir_ts_platform_data { 57struct pixcir_ts_platform_data {
47 int x_max; 58 int x_max;
48 int y_max; 59 int y_max;
49 int gpio_attb; /* GPIO connected to ATTB line */ 60 int gpio_attb; /* GPIO connected to ATTB line */
61 struct pixcir_i2c_chip_data chip;
50}; 62};
51 63
52#endif 64#endif