|
@@ -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);
|