aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2016-07-15 17:05:29 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2016-07-15 17:50:53 -0400
commited7c9870c9bc6ca50dc0d271a301410bc894f4b9 (patch)
tree06501c64473ffba176cc2746a7ea76e0cbf1afe3
parent345ded8ef489a888f6921c999f872848c96b5af8 (diff)
Input: of_touchscreen - add support for inverted / swapped axes
Extend touchscreen_parse_properties() with support for the touchscreen-inverted-x/y and touchscreen-swapped-x-y properties and add touchscreen_set_mt_pos() and touchscreen_report_pos() helper functions for storing coordinates into a input_mt_pos struct, or directly reporting them, taking these properties into account. This commit also modifies the existing callers of touchscreen_parse_properties() to pass in NULL for the new third argument, keeping the existing behavior. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/touchscreen/ad7879.c2
-rw-r--r--drivers/input/touchscreen/cyttsp_core.c2
-rw-r--r--drivers/input/touchscreen/edt-ft5x06.c2
-rw-r--r--drivers/input/touchscreen/of_touchscreen.c81
-rw-r--r--drivers/input/touchscreen/pixcir_i2c_ts.c2
-rw-r--r--drivers/input/touchscreen/tsc200x-core.c2
-rw-r--r--include/linux/input/touchscreen.h21
7 files changed, 105 insertions, 7 deletions
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index 69d299d5dd00..8a84fd4d9147 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -595,7 +595,7 @@ struct ad7879 *ad7879_probe(struct device *dev, u8 devid, unsigned int irq,
595 } else { 595 } else {
596 input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); 596 input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
597 input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); 597 input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
598 touchscreen_parse_properties(input_dev, false); 598 touchscreen_parse_properties(input_dev, false, NULL);
599 if (!input_abs_get_max(input_dev, ABS_PRESSURE)) { 599 if (!input_abs_get_max(input_dev, ABS_PRESSURE)) {
600 dev_err(dev, "Touchscreen pressure is not specified\n"); 600 dev_err(dev, "Touchscreen pressure is not specified\n");
601 return ERR_PTR(-EINVAL); 601 return ERR_PTR(-EINVAL);
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c
index 91cda8f8119d..79381cc1774a 100644
--- a/drivers/input/touchscreen/cyttsp_core.c
+++ b/drivers/input/touchscreen/cyttsp_core.c
@@ -657,7 +657,7 @@ struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
657 657
658 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X); 658 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
659 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y); 659 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
660 touchscreen_parse_properties(input_dev, true); 660 touchscreen_parse_properties(input_dev, true, NULL);
661 661
662 error = input_mt_init_slots(input_dev, CY_MAX_ID, 0); 662 error = input_mt_init_slots(input_dev, CY_MAX_ID, 0);
663 if (error) { 663 if (error) {
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 23fbe382da8b..e8825e599beb 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -972,7 +972,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
972 input_set_abs_params(input, ABS_MT_POSITION_Y, 972 input_set_abs_params(input, ABS_MT_POSITION_Y,
973 0, tsdata->num_y * 64 - 1, 0, 0); 973 0, tsdata->num_y * 64 - 1, 0, 0);
974 974
975 touchscreen_parse_properties(input, true); 975 touchscreen_parse_properties(input, true, NULL);
976 976
977 error = input_mt_init_slots(input, tsdata->max_support_points, 977 error = input_mt_init_slots(input, tsdata->max_support_points,
978 INPUT_MT_DIRECT); 978 INPUT_MT_DIRECT);
diff --git a/drivers/input/touchscreen/of_touchscreen.c b/drivers/input/touchscreen/of_touchscreen.c
index bb6f2fe14667..8d7f9c8f2771 100644
--- a/drivers/input/touchscreen/of_touchscreen.c
+++ b/drivers/input/touchscreen/of_touchscreen.c
@@ -55,12 +55,16 @@ static void touchscreen_set_params(struct input_dev *dev,
55 * @input: input device that should be parsed 55 * @input: input device that should be parsed
56 * @multitouch: specifies whether parsed properties should be applied to 56 * @multitouch: specifies whether parsed properties should be applied to
57 * single-touch or multi-touch axes 57 * single-touch or multi-touch axes
58 * @prop: pointer to a struct touchscreen_properties into which to store
59 * axis swap and invert info for use with touchscreen_report_x_y();
60 * or %NULL
58 * 61 *
59 * This function parses common DT properties for touchscreens and setups the 62 * This function parses common DT properties for touchscreens and setups the
60 * input device accordingly. The function keeps previously set up default 63 * input device accordingly. The function keeps previously set up default
61 * values if no value is specified via DT. 64 * values if no value is specified via DT.
62 */ 65 */
63void touchscreen_parse_properties(struct input_dev *input, bool multitouch) 66void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
67 struct touchscreen_properties *prop)
64{ 68{
65 struct device *dev = input->dev.parent; 69 struct device *dev = input->dev.parent;
66 unsigned int axis; 70 unsigned int axis;
@@ -104,5 +108,80 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch)
104 &fuzz); 108 &fuzz);
105 if (data_present) 109 if (data_present)
106 touchscreen_set_params(input, axis, maximum, fuzz); 110 touchscreen_set_params(input, axis, maximum, fuzz);
111
112 if (!prop)
113 return;
114
115 axis = multitouch ? ABS_MT_POSITION_X : ABS_X;
116
117 prop->max_x = input_abs_get_max(input, axis);
118 prop->max_y = input_abs_get_max(input, axis + 1);
119 prop->invert_x =
120 device_property_read_bool(dev, "touchscreen-inverted-x");
121 prop->invert_y =
122 device_property_read_bool(dev, "touchscreen-inverted-y");
123 prop->swap_x_y =
124 device_property_read_bool(dev, "touchscreen-swapped-x-y");
125
126 if (prop->swap_x_y)
127 swap(input->absinfo[axis], input->absinfo[axis + 1]);
107} 128}
108EXPORT_SYMBOL(touchscreen_parse_properties); 129EXPORT_SYMBOL(touchscreen_parse_properties);
130
131static void
132touchscreen_apply_prop_to_x_y(const struct touchscreen_properties *prop,
133 unsigned int *x, unsigned int *y)
134{
135 if (prop->invert_x)
136 *x = prop->max_x - *x;
137
138 if (prop->invert_y)
139 *y = prop->max_y - *y;
140
141 if (prop->swap_x_y)
142 swap(*x, *y);
143}
144
145/**
146 * touchscreen_set_mt_pos - Set input_mt_pos coordinates
147 * @pos: input_mt_pos to set coordinates of
148 * @prop: pointer to a struct touchscreen_properties
149 * @x: X coordinate to store in pos
150 * @y: Y coordinate to store in pos
151 *
152 * Adjust the passed in x and y values applying any axis inversion and
153 * swapping requested in the passed in touchscreen_properties and store
154 * the result in a struct input_mt_pos.
155 */
156void touchscreen_set_mt_pos(struct input_mt_pos *pos,
157 const struct touchscreen_properties *prop,
158 unsigned int x, unsigned int y)
159{
160 touchscreen_apply_prop_to_x_y(prop, &x, &y);
161 pos->x = x;
162 pos->y = y;
163}
164EXPORT_SYMBOL(touchscreen_set_mt_pos);
165
166/**
167 * touchscreen_report_pos - Report touchscreen coordinates
168 * @input: input_device to report coordinates for
169 * @prop: pointer to a struct touchscreen_properties
170 * @x: X coordinate to report
171 * @y: Y coordinate to report
172 * @multitouch: Report coordinates on single-touch or multi-touch axes
173 *
174 * Adjust the passed in x and y values applying any axis inversion and
175 * swapping requested in the passed in touchscreen_properties and then
176 * report the resulting coordinates on the input_dev's x and y axis.
177 */
178void touchscreen_report_pos(struct input_dev *input,
179 const struct touchscreen_properties *prop,
180 unsigned int x, unsigned int y,
181 bool multitouch)
182{
183 touchscreen_apply_prop_to_x_y(prop, &x, &y);
184 input_report_abs(input, multitouch ? ABS_MT_POSITION_X : ABS_X, x);
185 input_report_abs(input, multitouch ? ABS_MT_POSITION_Y : ABS_Y, y);
186}
187EXPORT_SYMBOL(touchscreen_report_pos);
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index 09523a3d3f23..f58784d60cf2 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -515,7 +515,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
515 } else { 515 } else {
516 input_set_capability(input, EV_ABS, ABS_MT_POSITION_X); 516 input_set_capability(input, EV_ABS, ABS_MT_POSITION_X);
517 input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y); 517 input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y);
518 touchscreen_parse_properties(input, true); 518 touchscreen_parse_properties(input, true, NULL);
519 if (!input_abs_get_max(input, ABS_MT_POSITION_X) || 519 if (!input_abs_get_max(input, ABS_MT_POSITION_X) ||
520 !input_abs_get_max(input, ABS_MT_POSITION_Y)) { 520 !input_abs_get_max(input, ABS_MT_POSITION_Y)) {
521 dev_err(dev, "Touchscreen size is not specified\n"); 521 dev_err(dev, "Touchscreen size is not specified\n");
diff --git a/drivers/input/touchscreen/tsc200x-core.c b/drivers/input/touchscreen/tsc200x-core.c
index 15240c1ee850..26e81d1bcfa0 100644
--- a/drivers/input/touchscreen/tsc200x-core.c
+++ b/drivers/input/touchscreen/tsc200x-core.c
@@ -559,7 +559,7 @@ int tsc200x_probe(struct device *dev, int irq, __u16 bustype,
559 input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0); 559 input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);
560 560
561 if (np) 561 if (np)
562 touchscreen_parse_properties(input_dev, false); 562 touchscreen_parse_properties(input_dev, false, NULL);
563 563
564 input_dev->open = tsc200x_open; 564 input_dev->open = tsc200x_open;
565 input_dev->close = tsc200x_close; 565 input_dev->close = tsc200x_close;
diff --git a/include/linux/input/touchscreen.h b/include/linux/input/touchscreen.h
index c91e1376132b..09d22ccb9e41 100644
--- a/include/linux/input/touchscreen.h
+++ b/include/linux/input/touchscreen.h
@@ -10,7 +10,26 @@
10#define _TOUCHSCREEN_H 10#define _TOUCHSCREEN_H
11 11
12struct input_dev; 12struct input_dev;
13struct input_mt_pos;
13 14
14void touchscreen_parse_properties(struct input_dev *dev, bool multitouch); 15struct touchscreen_properties {
16 unsigned int max_x;
17 unsigned int max_y;
18 bool invert_x;
19 bool invert_y;
20 bool swap_x_y;
21};
22
23void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
24 struct touchscreen_properties *prop);
25
26void touchscreen_set_mt_pos(struct input_mt_pos *pos,
27 const struct touchscreen_properties *prop,
28 unsigned int x, unsigned int y);
29
30void touchscreen_report_pos(struct input_dev *input,
31 const struct touchscreen_properties *prop,
32 unsigned int x, unsigned int y,
33 bool multitouch);
15 34
16#endif 35#endif