diff options
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r-- | drivers/input/touchscreen/edt-ft5x06.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index a76bc486936c..98766f2a8c4f 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -38,8 +38,7 @@ #include <linux/gpio/consumer.h> #include <linux/input/mt.h> #include <linux/input/touchscreen.h> - -#define MAX_SUPPORT_POINTS 5 +#include <linux/of_device.h> #define WORK_REGISTER_THRESHOLD 0x00 #define WORK_REGISTER_REPORT_RATE 0x08 @@ -105,6 +104,7 @@ struct edt_ft5x06_ts_data { int gain; int offset; int report_rate; + int max_support_points; char name[EDT_NAME_LEN]; @@ -112,6 +112,10 @@ struct edt_ft5x06_ts_data { enum edt_ver version; }; +struct edt_i2c_chip_data { + int max_support_points; +}; + static int edt_ft5x06_ts_readwrite(struct i2c_client *client, u16 wr_len, u8 *wr_buf, u16 rd_len, u8 *rd_buf) @@ -193,7 +197,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id) } memset(rdbuf, 0, sizeof(rdbuf)); - datalen = tplen * MAX_SUPPORT_POINTS + offset + crclen; + datalen = tplen * tsdata->max_support_points + offset + crclen; error = edt_ft5x06_ts_readwrite(tsdata->client, sizeof(cmd), &cmd, @@ -218,7 +222,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id) goto out; } - for (i = 0; i < MAX_SUPPORT_POINTS; i++) { + for (i = 0; i < tsdata->max_support_points; i++) { u8 *buf = &rdbuf[i * tplen + offset]; bool down; @@ -874,6 +878,7 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata) static int edt_ft5x06_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { + const struct edt_i2c_chip_data *chip_data; struct edt_ft5x06_ts_data *tsdata; struct input_dev *input; unsigned long irq_flags; @@ -888,6 +893,16 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, return -ENOMEM; } + chip_data = of_device_get_match_data(&client->dev); + if (!chip_data) + chip_data = (const struct edt_i2c_chip_data *)id->driver_data; + if (!chip_data || !chip_data->max_support_points) { + dev_err(&client->dev, "invalid or missing chip data\n"); + return -EINVAL; + } + + tsdata->max_support_points = chip_data->max_support_points; + tsdata->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(tsdata->reset_gpio)) { @@ -953,7 +968,8 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, touchscreen_parse_properties(input, true); - error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, INPUT_MT_DIRECT); + error = input_mt_init_slots(input, tsdata->max_support_points, + INPUT_MT_DIRECT); if (error) { dev_err(&client->dev, "Unable to init MT slots.\n"); return error; @@ -1032,17 +1048,21 @@ static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops, edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume); +static const struct edt_i2c_chip_data edt_ft5x06_data = { + .max_support_points = 5, +}; + static const struct i2c_device_id edt_ft5x06_ts_id[] = { - { "edt-ft5x06", 0, }, + { .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id); #ifdef CONFIG_OF static const struct of_device_id edt_ft5x06_of_match[] = { - { .compatible = "edt,edt-ft5206", }, - { .compatible = "edt,edt-ft5306", }, - { .compatible = "edt,edt-ft5406", }, + { .compatible = "edt,edt-ft5206", .data = &edt_ft5x06_data }, + { .compatible = "edt,edt-ft5306", .data = &edt_ft5x06_data }, + { .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match); |