aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/goodix.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/goodix.c')
-rw-r--r--drivers/input/touchscreen/goodix.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index ca196689f025..3af16984d57c 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -23,6 +23,8 @@
23#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/acpi.h>
27#include <linux/of.h>
26#include <asm/unaligned.h> 28#include <asm/unaligned.h>
27 29
28struct goodix_ts_data { 30struct goodix_ts_data {
@@ -48,6 +50,7 @@ struct goodix_ts_data {
48#define GOODIX_REG_VERSION 0x8140 50#define GOODIX_REG_VERSION 0x8140
49 51
50#define RESOLUTION_LOC 1 52#define RESOLUTION_LOC 1
53#define MAX_CONTACTS_LOC 5
51#define TRIGGER_LOC 6 54#define TRIGGER_LOC 6
52 55
53static const unsigned long goodix_irq_flags[] = { 56static const unsigned long goodix_irq_flags[] = {
@@ -99,7 +102,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
99 } 102 }
100 103
101 touch_num = data[0] & 0x0f; 104 touch_num = data[0] & 0x0f;
102 if (touch_num > GOODIX_MAX_CONTACTS) 105 if (touch_num > ts->max_touch_num)
103 return -EPROTO; 106 return -EPROTO;
104 107
105 if (touch_num > 1) { 108 if (touch_num > 1) {
@@ -141,7 +144,7 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
141 */ 144 */
142static void goodix_process_events(struct goodix_ts_data *ts) 145static void goodix_process_events(struct goodix_ts_data *ts)
143{ 146{
144 u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; 147 u8 point_data[1 + GOODIX_CONTACT_SIZE * ts->max_touch_num];
145 int touch_num; 148 int touch_num;
146 int i; 149 int i;
147 150
@@ -202,21 +205,23 @@ static void goodix_read_config(struct goodix_ts_data *ts)
202 ts->abs_x_max = GOODIX_MAX_WIDTH; 205 ts->abs_x_max = GOODIX_MAX_WIDTH;
203 ts->abs_y_max = GOODIX_MAX_HEIGHT; 206 ts->abs_y_max = GOODIX_MAX_HEIGHT;
204 ts->int_trigger_type = GOODIX_INT_TRIGGER; 207 ts->int_trigger_type = GOODIX_INT_TRIGGER;
208 ts->max_touch_num = GOODIX_MAX_CONTACTS;
205 return; 209 return;
206 } 210 }
207 211
208 ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); 212 ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]);
209 ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); 213 ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]);
210 ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; 214 ts->int_trigger_type = config[TRIGGER_LOC] & 0x03;
211 if (!ts->abs_x_max || !ts->abs_y_max) { 215 ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f;
216 if (!ts->abs_x_max || !ts->abs_y_max || !ts->max_touch_num) {
212 dev_err(&ts->client->dev, 217 dev_err(&ts->client->dev,
213 "Invalid config, using defaults\n"); 218 "Invalid config, using defaults\n");
214 ts->abs_x_max = GOODIX_MAX_WIDTH; 219 ts->abs_x_max = GOODIX_MAX_WIDTH;
215 ts->abs_y_max = GOODIX_MAX_HEIGHT; 220 ts->abs_y_max = GOODIX_MAX_HEIGHT;
221 ts->max_touch_num = GOODIX_MAX_CONTACTS;
216 } 222 }
217} 223}
218 224
219
220/** 225/**
221 * goodix_read_version - Read goodix touchscreen version 226 * goodix_read_version - Read goodix touchscreen version
222 * 227 *
@@ -295,7 +300,7 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts)
295 input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); 300 input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
296 input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); 301 input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
297 302
298 input_mt_init_slots(ts->input_dev, GOODIX_MAX_CONTACTS, 303 input_mt_init_slots(ts->input_dev, ts->max_touch_num,
299 INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); 304 INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
300 305
301 ts->input_dev->name = "Goodix Capacitive TouchScreen"; 306 ts->input_dev->name = "Goodix Capacitive TouchScreen";
@@ -372,11 +377,27 @@ static const struct i2c_device_id goodix_ts_id[] = {
372 { } 377 { }
373}; 378};
374 379
380#ifdef CONFIG_ACPI
375static const struct acpi_device_id goodix_acpi_match[] = { 381static const struct acpi_device_id goodix_acpi_match[] = {
376 { "GDIX1001", 0 }, 382 { "GDIX1001", 0 },
377 { } 383 { }
378}; 384};
379MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); 385MODULE_DEVICE_TABLE(acpi, goodix_acpi_match);
386#endif
387
388#ifdef CONFIG_OF
389static const struct of_device_id goodix_of_match[] = {
390 { .compatible = "goodix,gt911" },
391 { .compatible = "goodix,gt9110" },
392 { .compatible = "goodix,gt912" },
393 { .compatible = "goodix,gt927" },
394 { .compatible = "goodix,gt9271" },
395 { .compatible = "goodix,gt928" },
396 { .compatible = "goodix,gt967" },
397 { }
398};
399MODULE_DEVICE_TABLE(of, goodix_of_match);
400#endif
380 401
381static struct i2c_driver goodix_ts_driver = { 402static struct i2c_driver goodix_ts_driver = {
382 .probe = goodix_ts_probe, 403 .probe = goodix_ts_probe,
@@ -384,7 +405,8 @@ static struct i2c_driver goodix_ts_driver = {
384 .driver = { 405 .driver = {
385 .name = "Goodix-TS", 406 .name = "Goodix-TS",
386 .owner = THIS_MODULE, 407 .owner = THIS_MODULE,
387 .acpi_match_table = goodix_acpi_match, 408 .acpi_match_table = ACPI_PTR(goodix_acpi_match),
409 .of_match_table = of_match_ptr(goodix_of_match),
388 }, 410 },
389}; 411};
390module_i2c_driver(goodix_ts_driver); 412module_i2c_driver(goodix_ts_driver);