Input: pixcir_ts - add support for axis inversion / swapping
authorHans de Goede <hdegoede@redhat.com>
Fri, 15 Jul 2016 21:31:31 +0000 (14:31 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 15 Jul 2016 21:50:57 +0000 (14:50 -0700)
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>
drivers/input/touchscreen/pixcir_i2c_ts.c

index f58784d..d159e14 100644 (file)
@@ -27,9 +27,9 @@
 #include <linux/input/touchscreen.h>
 #include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
-/*#include <linux/of.h>*/
 #include <linux/of_device.h>
 #include <linux/platform_data/pixcir_i2c_ts.h>
+#include <asm/unaligned.h>
 
 #define PIXCIR_MAX_SLOTS       5 /* Max fingers supported by driver */
 
@@ -41,19 +41,15 @@ struct pixcir_i2c_ts_data {
        struct gpio_desc *gpio_enable;
        struct gpio_desc *gpio_wake;
        const struct pixcir_i2c_chip_data *chip;
+       struct touchscreen_properties prop;
        int max_fingers;        /* Max fingers supported in this instance */
        bool running;
 };
 
-struct pixcir_touch {
-       int x;
-       int y;
-       int id;
-};
-
 struct pixcir_report_data {
        int num_touches;
-       struct pixcir_touch touches[PIXCIR_MAX_SLOTS];
+       struct input_mt_pos pos[PIXCIR_MAX_SLOTS];
+       int ids[PIXCIR_MAX_SLOTS];
 };
 
 static 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,
        bufptr = &rdbuf[2];
 
        for (i = 0; i < touch; i++) {
-               report->touches[i].x = (bufptr[1] << 8) | bufptr[0];
-               report->touches[i].y = (bufptr[3] << 8) | bufptr[2];
-
+               touchscreen_set_mt_pos(&report->pos[i], &tsdata->prop,
+                                      get_unaligned_le16(bufptr),
+                                      get_unaligned_le16(bufptr + 2));
                if (chip->has_hw_ids) {
-                       report->touches[i].id = bufptr[4];
+                       report->ids[i] = bufptr[4];
                        bufptr = bufptr + 5;
                } else {
                        bufptr = bufptr + 4;
@@ -113,9 +109,7 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
 static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
                             struct pixcir_report_data *report)
 {
-       struct input_mt_pos pos[PIXCIR_MAX_SLOTS];
        int slots[PIXCIR_MAX_SLOTS];
-       struct pixcir_touch *touch;
        int n, i, slot;
        struct device *dev = &ts->client->dev;
        const struct pixcir_i2c_chip_data *chip = ts->chip;
@@ -124,24 +118,16 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
        if (n > PIXCIR_MAX_SLOTS)
                n = PIXCIR_MAX_SLOTS;
 
-       if (!ts->chip->has_hw_ids) {
-               for (i = 0; i < n; i++) {
-                       touch = &report->touches[i];
-                       pos[i].x = touch->x;
-                       pos[i].y = touch->y;
-               }
-
-               input_mt_assign_slots(ts->input, slots, pos, n, 0);
-       }
+       if (!ts->chip->has_hw_ids)
+               input_mt_assign_slots(ts->input, slots, report->pos, n, 0);
 
        for (i = 0; i < n; i++) {
-               touch = &report->touches[i];
-
                if (chip->has_hw_ids) {
-                       slot = input_mt_get_slot_by_key(ts->input, touch->id);
+                       slot = input_mt_get_slot_by_key(ts->input,
+                                                       report->ids[i]);
                        if (slot < 0) {
                                dev_dbg(dev, "no free slot for id 0x%x\n",
-                                       touch->id);
+                                       report->ids[i]);
                                continue;
                        }
                } else {
@@ -149,14 +135,15 @@ static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts,
                }
 
                input_mt_slot(ts->input, slot);
-               input_mt_report_slot_state(ts->input,
-                                          MT_TOOL_FINGER, true);
+               input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
 
-               input_event(ts->input, EV_ABS, ABS_MT_POSITION_X, touch->x);
-               input_event(ts->input, EV_ABS, ABS_MT_POSITION_Y, touch->y);
+               input_report_abs(ts->input, ABS_MT_POSITION_X,
+                                report->pos[i].x);
+               input_report_abs(ts->input, ABS_MT_POSITION_Y,
+                                report->pos[i].y);
 
                dev_dbg(dev, "%d: slot %d, x %d, y %d\n",
-                       i, slot, touch->x, touch->y);
+                       i, slot, report->pos[i].x, report->pos[i].y);
        }
 
        input_mt_sync_frame(ts->input);
@@ -515,7 +502,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
        } else {
                input_set_capability(input, EV_ABS, ABS_MT_POSITION_X);
                input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y);
-               touchscreen_parse_properties(input, true, NULL);
+               touchscreen_parse_properties(input, true, &tsdata->prop);
                if (!input_abs_get_max(input, ABS_MT_POSITION_X) ||
                    !input_abs_get_max(input, ABS_MT_POSITION_Y)) {
                        dev_err(dev, "Touchscreen size is not specified\n");