summaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2019-02-09 11:49:38 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2019-02-09 12:01:13 -0500
commitf67cc3e927d8414ad3872e046764534ea1f5db0d (patch)
tree8d1f9c24745cbca503cbf95672b3b06dd0e66374 /drivers/input
parent320f07b4a92216aa313680e3c7c7d325d8642715 (diff)
Input: ili210x - fetch touchscreen geometry from DT
Fetching the geometry from the ILI251x registers seems unreliable and sometimes returns all zeroes. Add support for fetching the geometry and axis inversion from DT instead. Signed-off-by: Marek Vasut <marex@denx.de> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/ili210x.c51
1 files changed, 11 insertions, 40 deletions
diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index af1dd9cff12a..9169aa03958a 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -4,6 +4,7 @@
4#include <linux/slab.h> 4#include <linux/slab.h>
5#include <linux/input.h> 5#include <linux/input.h>
6#include <linux/input/mt.h> 6#include <linux/input/mt.h>
7#include <linux/input/touchscreen.h>
7#include <linux/delay.h> 8#include <linux/delay.h>
8#include <linux/workqueue.h> 9#include <linux/workqueue.h>
9#include <linux/gpio/consumer.h> 10#include <linux/gpio/consumer.h>
@@ -20,15 +21,6 @@
20#define REG_FIRMWARE_VERSION 0x40 21#define REG_FIRMWARE_VERSION 0x40
21#define REG_CALIBRATE 0xcc 22#define REG_CALIBRATE 0xcc
22 23
23struct panel_info {
24 u8 x_low;
25 u8 x_high;
26 u8 y_low;
27 u8 y_high;
28 u8 xchannel_num;
29 u8 ychannel_num;
30} __packed;
31
32struct firmware_version { 24struct firmware_version {
33 u8 id; 25 u8 id;
34 u8 major; 26 u8 major;
@@ -46,6 +38,7 @@ struct ili210x {
46 unsigned int poll_period; 38 unsigned int poll_period;
47 struct delayed_work dwork; 39 struct delayed_work dwork;
48 struct gpio_desc *reset_gpio; 40 struct gpio_desc *reset_gpio;
41 struct touchscreen_properties prop;
49 enum ili2xxx_model model; 42 enum ili2xxx_model model;
50 unsigned int max_touches; 43 unsigned int max_touches;
51}; 44};
@@ -149,8 +142,6 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
149 unsigned int x = 0, y = 0; 142 unsigned int x = 0, y = 0;
150 143
151 for (i = 0; i < priv->max_touches; i++) { 144 for (i = 0; i < priv->max_touches; i++) {
152 input_mt_slot(input, i);
153
154 if (priv->model == MODEL_ILI210X) { 145 if (priv->model == MODEL_ILI210X) {
155 touch = ili210x_touchdata_to_coords(priv, touchdata, 146 touch = ili210x_touchdata_to_coords(priv, touchdata,
156 i, &x, &y); 147 i, &x, &y);
@@ -161,11 +152,12 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
161 contact = true; 152 contact = true;
162 } 153 }
163 154
155 input_mt_slot(input, i);
164 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); 156 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
165 if (touch) { 157 if (!touch)
166 input_report_abs(input, ABS_MT_POSITION_X, x); 158 continue;
167 input_report_abs(input, ABS_MT_POSITION_Y, y); 159 touchscreen_report_pos(input, &priv->prop, x, y,
168 } 160 true);
169 } 161 }
170 162
171 input_mt_report_pointer_emulation(input, false); 163 input_mt_report_pointer_emulation(input, false);
@@ -274,10 +266,8 @@ static int ili210x_i2c_probe(struct i2c_client *client,
274 struct ili210x *priv; 266 struct ili210x *priv;
275 struct gpio_desc *reset_gpio; 267 struct gpio_desc *reset_gpio;
276 struct input_dev *input; 268 struct input_dev *input;
277 struct panel_info panel;
278 struct firmware_version firmware; 269 struct firmware_version firmware;
279 enum ili2xxx_model model; 270 enum ili2xxx_model model;
280 int xmax, ymax;
281 int error; 271 int error;
282 272
283 model = (enum ili2xxx_model)id->driver_data; 273 model = (enum ili2xxx_model)id->driver_data;
@@ -334,35 +324,16 @@ static int ili210x_i2c_probe(struct i2c_client *client,
334 return error; 324 return error;
335 } 325 }
336 326
337 /* get panel info */
338 error = ili210x_read_reg(client, REG_PANEL_INFO, &panel, sizeof(panel));
339 if (error) {
340 dev_err(dev, "Failed to get panel information, err: %d\n",
341 error);
342 return error;
343 }
344
345 xmax = panel.x_low | (panel.x_high << 8);
346 ymax = panel.y_low | (panel.y_high << 8);
347
348 /* Setup input device */ 327 /* Setup input device */
349 input->name = "ILI210x Touchscreen"; 328 input->name = "ILI210x Touchscreen";
350 input->id.bustype = BUS_I2C; 329 input->id.bustype = BUS_I2C;
351 input->dev.parent = dev; 330 input->dev.parent = dev;
352 331
353 __set_bit(EV_SYN, input->evbit);
354 __set_bit(EV_KEY, input->evbit);
355 __set_bit(EV_ABS, input->evbit);
356 __set_bit(BTN_TOUCH, input->keybit);
357
358 /* Single touch */
359 input_set_abs_params(input, ABS_X, 0, xmax, 0, 0);
360 input_set_abs_params(input, ABS_Y, 0, ymax, 0, 0);
361
362 /* Multi touch */ 332 /* Multi touch */
363 input_mt_init_slots(input, priv->max_touches, 0); 333 input_set_abs_params(input, ABS_MT_POSITION_X, 0, 0xffff, 0, 0);
364 input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0); 334 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 0xffff, 0, 0);
365 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0); 335 touchscreen_parse_properties(input, true, &priv->prop);
336 input_mt_init_slots(input, priv->max_touches, INPUT_MT_DIRECT);
366 337
367 error = devm_add_action(dev, ili210x_cancel_work, priv); 338 error = devm_add_action(dev, ili210x_cancel_work, priv);
368 if (error) 339 if (error)