summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen/edt-ft5x06.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/edt-ft5x06.c')
-rw-r--r--drivers/input/touchscreen/edt-ft5x06.c93
1 files changed, 61 insertions, 32 deletions
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 24ab9e9f5b21..bf498bd4dea9 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -32,7 +32,7 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
-#include <asm/unaligned.h>
+#include <linux/unaligned.h>
#define WORK_REGISTER_THRESHOLD 0x00
#define WORK_REGISTER_REPORT_RATE 0x08
@@ -120,7 +120,6 @@ struct edt_ft5x06_ts_data {
struct regmap *regmap;
#if defined(CONFIG_DEBUG_FS)
- struct dentry *debug_dir;
u8 *raw_buffer;
size_t raw_bufsize;
#endif
@@ -431,7 +430,7 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
*field = val;
}
- count = scnprintf(buf, PAGE_SIZE, "%d\n", val);
+ count = sysfs_emit(buf, "%d\n", val);
out:
mutex_unlock(&tsdata->mutex);
return error ?: count;
@@ -580,10 +579,7 @@ static struct attribute *edt_ft5x06_attrs[] = {
&dev_attr_crc_errors.attr,
NULL
};
-
-static const struct attribute_group edt_ft5x06_attr_group = {
- .attrs = edt_ft5x06_attrs,
-};
+ATTRIBUTE_GROUPS(edt_ft5x06);
static void edt_ft5x06_restore_reg_parameters(struct edt_ft5x06_ts_data *tsdata)
{
@@ -818,23 +814,21 @@ static const struct file_operations debugfs_raw_data_fops = {
.read = edt_ft5x06_debugfs_raw_data_read,
};
-static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
- const char *debugfs_name)
+static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata)
{
- tsdata->debug_dir = debugfs_create_dir(debugfs_name, NULL);
+ struct dentry *debug_dir = tsdata->client->debugfs;
- debugfs_create_u16("num_x", S_IRUSR, tsdata->debug_dir, &tsdata->num_x);
- debugfs_create_u16("num_y", S_IRUSR, tsdata->debug_dir, &tsdata->num_y);
+ debugfs_create_u16("num_x", S_IRUSR, debug_dir, &tsdata->num_x);
+ debugfs_create_u16("num_y", S_IRUSR, debug_dir, &tsdata->num_y);
debugfs_create_file("mode", S_IRUSR | S_IWUSR,
- tsdata->debug_dir, tsdata, &debugfs_mode_fops);
+ debug_dir, tsdata, &debugfs_mode_fops);
debugfs_create_file("raw_data", S_IRUSR,
- tsdata->debug_dir, tsdata, &debugfs_raw_data_fops);
+ debug_dir, tsdata, &debugfs_raw_data_fops);
}
static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
{
- debugfs_remove_recursive(tsdata->debug_dir);
kfree(tsdata->raw_buffer);
}
@@ -845,8 +839,7 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
return -ENOSYS;
}
-static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
- const char *debugfs_name)
+static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata)
{
}
@@ -1124,6 +1117,14 @@ static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
}
}
+static void edt_ft5x06_exit_regmap(void *arg)
+{
+ struct edt_ft5x06_ts_data *data = arg;
+
+ if (!IS_ERR_OR_NULL(data->regmap))
+ regmap_exit(data->regmap);
+}
+
static void edt_ft5x06_disable_regulators(void *arg)
{
struct edt_ft5x06_ts_data *data = arg;
@@ -1157,6 +1158,16 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
return PTR_ERR(tsdata->regmap);
}
+ /*
+ * We are not using devm_regmap_init_i2c() and instead install a
+ * custom action because we may replace regmap with M06-specific one
+ * and we need to make sure that it will not be released too early.
+ */
+ error = devm_add_action_or_reset(&client->dev, edt_ft5x06_exit_regmap,
+ tsdata);
+ if (error)
+ return error;
+
chip_data = device_get_match_data(&client->dev);
if (!chip_data)
chip_data = (const struct edt_i2c_chip_data *)id->driver_data;
@@ -1168,13 +1179,9 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
tsdata->max_support_points = chip_data->max_support_points;
tsdata->vcc = devm_regulator_get(&client->dev, "vcc");
- if (IS_ERR(tsdata->vcc)) {
- error = PTR_ERR(tsdata->vcc);
- if (error != -EPROBE_DEFER)
- dev_err(&client->dev,
- "failed to request regulator: %d\n", error);
- return error;
- }
+ if (IS_ERR(tsdata->vcc))
+ return dev_err_probe(&client->dev, PTR_ERR(tsdata->vcc),
+ "failed to request regulator\n");
tsdata->iovcc = devm_regulator_get(&client->dev, "iovcc");
if (IS_ERR(tsdata->iovcc)) {
@@ -1226,7 +1233,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
}
/*
- * Check which sleep modes we can support. Power-off requieres the
+ * Check which sleep modes we can support. Power-off requires the
* reset-pin to ensure correct power-down/power-up behaviour. Start with
* the EDT_PMODE_POWEROFF test since this is the deepest possible sleep
* mode.
@@ -1241,6 +1248,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
if (tsdata->wake_gpio) {
usleep_range(5000, 6000);
gpiod_set_value_cansleep(tsdata->wake_gpio, 1);
+ usleep_range(5000, 6000);
}
if (tsdata->reset_gpio) {
@@ -1333,15 +1341,11 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
return error;
}
- error = devm_device_add_group(&client->dev, &edt_ft5x06_attr_group);
- if (error)
- return error;
-
error = input_register_device(input);
if (error)
return error;
- edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev));
+ edt_ft5x06_ts_prepare_debugfs(tsdata);
dev_dbg(&client->dev,
"EDT FT5x06 initialized: IRQ %d, WAKE pin %d, Reset pin %d.\n",
@@ -1357,7 +1361,6 @@ static void edt_ft5x06_ts_remove(struct i2c_client *client)
struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
edt_ft5x06_ts_teardown_debugfs(tsdata);
- regmap_exit(tsdata->regmap);
}
static int edt_ft5x06_ts_suspend(struct device *dev)
@@ -1472,6 +1475,10 @@ static const struct edt_i2c_chip_data edt_ft5x06_data = {
.max_support_points = 5,
};
+static const struct edt_i2c_chip_data edt_ft5452_data = {
+ .max_support_points = 5,
+};
+
static const struct edt_i2c_chip_data edt_ft5506_data = {
.max_support_points = 10,
};
@@ -1480,12 +1487,28 @@ static const struct edt_i2c_chip_data edt_ft6236_data = {
.max_support_points = 2,
};
+static const struct edt_i2c_chip_data edt_ft8201_data = {
+ .max_support_points = 10,
+};
+
+static const struct edt_i2c_chip_data edt_ft8716_data = {
+ .max_support_points = 10,
+};
+
+static const struct edt_i2c_chip_data edt_ft8719_data = {
+ .max_support_points = 10,
+};
+
static const struct i2c_device_id edt_ft5x06_ts_id[] = {
{ .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },
{ .name = "edt-ft5506", .driver_data = (long)&edt_ft5506_data },
{ .name = "ev-ft5726", .driver_data = (long)&edt_ft5506_data },
+ { .name = "ft5452", .driver_data = (long)&edt_ft5452_data },
/* Note no edt- prefix for compatibility with the ft6236.c driver */
{ .name = "ft6236", .driver_data = (long)&edt_ft6236_data },
+ { .name = "ft8201", .driver_data = (long)&edt_ft8201_data },
+ { .name = "ft8716", .driver_data = (long)&edt_ft8716_data },
+ { .name = "ft8719", .driver_data = (long)&edt_ft8719_data },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
@@ -1496,8 +1519,13 @@ static const struct of_device_id edt_ft5x06_of_match[] = {
{ .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data },
{ .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data },
{ .compatible = "evervision,ev-ft5726", .data = &edt_ft5506_data },
+ { .compatible = "focaltech,ft5426", .data = &edt_ft5506_data },
+ { .compatible = "focaltech,ft5452", .data = &edt_ft5452_data },
/* Note focaltech vendor prefix for compatibility with ft6236.c */
{ .compatible = "focaltech,ft6236", .data = &edt_ft6236_data },
+ { .compatible = "focaltech,ft8201", .data = &edt_ft8201_data },
+ { .compatible = "focaltech,ft8716", .data = &edt_ft8716_data },
+ { .compatible = "focaltech,ft8719", .data = &edt_ft8719_data },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match);
@@ -1505,12 +1533,13 @@ MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match);
static struct i2c_driver edt_ft5x06_ts_driver = {
.driver = {
.name = "edt_ft5x06",
+ .dev_groups = edt_ft5x06_groups,
.of_match_table = edt_ft5x06_of_match,
.pm = pm_sleep_ptr(&edt_ft5x06_ts_pm_ops),
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
.id_table = edt_ft5x06_ts_id,
- .probe_new = edt_ft5x06_ts_probe,
+ .probe = edt_ft5x06_ts_probe,
.remove = edt_ft5x06_ts_remove,
};