aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2016-07-15 17:31:31 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2016-07-15 17:50:57 -0400
commit0bb11e969f5367dcb661f9fcc77efd5d58a2c470 (patch)
tree742f78642cedf80f2fb7942e0f3b3b1421291e62
parent50dd9f66e54cb415138695944975d4ee51d8b4a5 (diff)
Input: pixcir_ts - add support for axis inversion / swapping
Add support for axis inversion / swapping using the new touchscreen_parse_properties() and touchscreen_set_mt_pos() functionality. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/touchscreen/pixcir_i2c_ts.c53
1 files changed, 20 insertions, 33 deletions
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index f58784d60cf2..d159e14f4d20 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -27,9 +27,9 @@
27#include <linux/input/touchscreen.h> 27#include <linux/input/touchscreen.h>
28#include <linux/gpio.h> 28#include <linux/gpio.h>
29#include <linux/gpio/consumer.h> 29#include <linux/gpio/consumer.h>
30/*#include <linux/of.h>*/
31#include <linux/of_device.h> 30#include <linux/of_device.h>
32#include <linux/platform_data/pixcir_i2c_ts.h> 31#include <linux/platform_data/pixcir_i2c_ts.h>
32#include <asm/unaligned.h>
33 33
34#define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */ 34#define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */
35 35
@@ -41,19 +41,15 @@ struct pixcir_i2c_ts_data {
41 struct gpio_desc *gpio_enable; 41 struct gpio_desc *gpio_enable;
42 struct gpio_desc *gpio_wake; 42 struct gpio_desc *gpio_wake;
43 const struct pixcir_i2c_chip_data *chip; 43 const struct pixcir_i2c_chip_data *chip;
44 struct touchscreen_properties prop;
44 int max_fingers; /* Max fingers supported in this instance */ 45 int max_fingers; /* Max fingers supported in this instance */
45 bool running; 46 bool running;
46}; 47};
47 48
48struct pixcir_touch {
49 int x;
50 int y;
51 int id;
52};
53
54struct pixcir_report_data { 49struct pixcir_report_data {
55 int num_touches; 50 int num_touches;
56 struct pixcir_touch touches[PIXCIR_MAX_SLOTS]; 51 struct input_mt_pos pos[PIXCIR_MAX_SLOTS];
52 int ids[PIXCIR_MAX_SLOTS];
57}; 53};
58 54
59static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata, 55static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
@@ -98,11 +94,11 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
98 bufptr = &rdbuf[2]; 94 bufptr = &rdbuf[2];
99 95
100 for (i = 0; i < touch; i++) { 96 for (i = 0; i < touch; i++) {
101 report->touches[i].x = (bufptr[1] << 8) | bufptr[0]; 97 touchscreen_set_mt_pos(&report->pos[i], &tsdata->prop,
102 report->touches[i].y = (bufptr[3] << 8) | bufptr[2]; 98 get_unaligned_le16(bufptr),
103 99 get_unaligned_le16(bufptr + 2));
104 if (chip->has_hw_ids) { 100 if (chip->has_hw_ids) {
105 report->touches[i].id = bufptr[4]; 101 report->ids[i] = bufptr[4];
106 bufptr = bufptr + 5; 102 bufptr = bufptr + 5;
107 } else { 103 } else {
108 bufptr = bufptr + 4; 104 bufptr = bufptr + 4;
@@ -113,9 +109,7 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
113static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts, 109static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
114 struct pixcir_report_data *report) 110 struct pixcir_report_data *report)
115{ 111{
116 struct input_mt_pos pos[PIXCIR_MAX_SLOTS];
117 int slots[PIXCIR_MAX_SLOTS]; 112 int slots[PIXCIR_MAX_SLOTS];
118 struct pixcir_touch *touch;
119 int n, i, slot; 113 int n, i, slot;
120 struct device *dev = &ts->client->dev; 114 struct device *dev = &ts->client->dev;
121 const struct pixcir_i2c_chip_data *chip = ts->chip; 115 const struct pixcir_i2c_chip_data *chip = ts->chip;
@@ -124,24 +118,16 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
124 if (n > PIXCIR_MAX_SLOTS) 118 if (n > PIXCIR_MAX_SLOTS)
125 n = PIXCIR_MAX_SLOTS; 119 n = PIXCIR_MAX_SLOTS;
126 120
127 if (!ts->chip->has_hw_ids) { 121 if (!ts->chip->has_hw_ids)
128 for (i = 0; i < n; i++) { 122 input_mt_assign_slots(ts->input, slots, report->pos, n, 0);
129 touch = &report->touches[i];
130 pos[i].x = touch->x;
131 pos[i].y = touch->y;
132 }
133
134 input_mt_assign_slots(ts->input, slots, pos, n, 0);
135 }
136 123
137 for (i = 0; i < n; i++) { 124 for (i = 0; i < n; i++) {
138 touch = &report->touches[i];
139
140 if (chip->has_hw_ids) { 125 if (chip->has_hw_ids) {
141 slot = input_mt_get_slot_by_key(ts->input, touch->id); 126 slot = input_mt_get_slot_by_key(ts->input,
127 report->ids[i]);
142 if (slot < 0) { 128 if (slot < 0) {
143 dev_dbg(dev, "no free slot for id 0x%x\n", 129 dev_dbg(dev, "no free slot for id 0x%x\n",
144 touch->id); 130 report->ids[i]);
145 continue; 131 continue;
146 } 132 }
147 } else { 133 } else {
@@ -149,14 +135,15 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
149 } 135 }
150 136
151 input_mt_slot(ts->input, slot); 137 input_mt_slot(ts->input, slot);
152 input_mt_report_slot_state(ts->input, 138 input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
153 MT_TOOL_FINGER, true);
154 139
155 input_event(ts->input, EV_ABS, ABS_MT_POSITION_X, touch->x); 140 input_report_abs(ts->input, ABS_MT_POSITION_X,
156 input_event(ts->input, EV_ABS, ABS_MT_POSITION_Y, touch->y); 141 report->pos[i].x);
142 input_report_abs(ts->input, ABS_MT_POSITION_Y,
143 report->pos[i].y);
157 144
158 dev_dbg(dev, "%d: slot %d, x %d, y %d\n", 145 dev_dbg(dev, "%d: slot %d, x %d, y %d\n",
159 i, slot, touch->x, touch->y); 146 i, slot, report->pos[i].x, report->pos[i].y);
160 } 147 }
161 148
162 input_mt_sync_frame(ts->input); 149 input_mt_sync_frame(ts->input);
@@ -515,7 +502,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
515 } else { 502 } else {
516 input_set_capability(input, EV_ABS, ABS_MT_POSITION_X); 503 input_set_capability(input, EV_ABS, ABS_MT_POSITION_X);
517 input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y); 504 input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y);
518 touchscreen_parse_properties(input, true, NULL); 505 touchscreen_parse_properties(input, true, &tsdata->prop);
519 if (!input_abs_get_max(input, ABS_MT_POSITION_X) || 506 if (!input_abs_get_max(input, ABS_MT_POSITION_X) ||
520 !input_abs_get_max(input, ABS_MT_POSITION_Y)) { 507 !input_abs_get_max(input, ABS_MT_POSITION_Y)) {
521 dev_err(dev, "Touchscreen size is not specified\n"); 508 dev_err(dev, "Touchscreen size is not specified\n");