diff options
author | Hans de Goede <hdegoede@redhat.com> | 2016-07-15 17:05:29 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2016-07-15 17:50:53 -0400 |
commit | ed7c9870c9bc6ca50dc0d271a301410bc894f4b9 (patch) | |
tree | 06501c64473ffba176cc2746a7ea76e0cbf1afe3 | |
parent | 345ded8ef489a888f6921c999f872848c96b5af8 (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.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp_core.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/edt-ft5x06.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/of_touchscreen.c | 81 | ||||
-rw-r--r-- | drivers/input/touchscreen/pixcir_i2c_ts.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/tsc200x-core.c | 2 | ||||
-rw-r--r-- | include/linux/input/touchscreen.h | 21 |
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 | */ |
63 | void touchscreen_parse_properties(struct input_dev *input, bool multitouch) | 66 | void 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 | } |
108 | EXPORT_SYMBOL(touchscreen_parse_properties); | 129 | EXPORT_SYMBOL(touchscreen_parse_properties); |
130 | |||
131 | static void | ||
132 | touchscreen_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 | */ | ||
156 | void 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 | } | ||
164 | EXPORT_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 | */ | ||
178 | void 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 | } | ||
187 | EXPORT_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 | ||
12 | struct input_dev; | 12 | struct input_dev; |
13 | struct input_mt_pos; | ||
13 | 14 | ||
14 | void touchscreen_parse_properties(struct input_dev *dev, bool multitouch); | 15 | struct 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 | |||
23 | void touchscreen_parse_properties(struct input_dev *input, bool multitouch, | ||
24 | struct touchscreen_properties *prop); | ||
25 | |||
26 | void touchscreen_set_mt_pos(struct input_mt_pos *pos, | ||
27 | const struct touchscreen_properties *prop, | ||
28 | unsigned int x, unsigned int y); | ||
29 | |||
30 | void 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 |