* [PATCH RFC v2 1/9] Input: atmel_mxt_ts - improve touchscreen size/orientation handling
2015-12-24 13:49 [PATCH RFC v2 0/8] Input: atmel_mxt_ts - raw data via debugfs Nick Dyer
@ 2015-12-24 13:49 ` Nick Dyer
2016-01-11 23:24 ` Dmitry Torokhov
2015-12-24 13:49 ` [PATCH RFC v2 2/9] Input: atmel_mxt_ts - add diagnostic data retrieval via debugfs Nick Dyer
` (7 subsequent siblings)
8 siblings, 1 reply; 11+ messages in thread
From: Nick Dyer @ 2015-12-24 13:49 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benson Leung, linux-input, linux-kernel, Alan Bowens,
Javier Martinez Canillas, Chris Healy, Nick Dyer
Both T100 and T9 handle range and orientation in a similar fashion.
Reduce duplication between the two implementations.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 68 ++++++++++++--------------------
1 file changed, 26 insertions(+), 42 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index c562205..4a1d218 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -113,8 +113,8 @@ struct t7_config {
#define MXT_T9_DETECT (1 << 7)
struct t9_range {
- u16 x;
- u16 y;
+ __le16 x;
+ __le16 y;
} __packed;
/* MXT_TOUCH_MULTI_T9 orient */
@@ -216,6 +216,7 @@ struct mxt_data {
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
+ bool xy_switch;
bool in_bootloader;
u16 mem_size;
u8 t100_aux_ampl;
@@ -1665,8 +1666,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
if (error)
return error;
- le16_to_cpus(&range.x);
- le16_to_cpus(&range.y);
+ data->max_x = get_unaligned_le16(&range.x);
+ data->max_y = get_unaligned_le16(&range.y);
error = __mxt_read_reg(client,
object->start_address + MXT_T9_ORIENT,
@@ -1674,23 +1675,7 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
if (error)
return error;
- /* Handle default values */
- if (range.x == 0)
- range.x = 1023;
-
- if (range.y == 0)
- range.y = 1023;
-
- if (orient & MXT_T9_ORIENT_SWITCH) {
- data->max_x = range.y;
- data->max_y = range.x;
- } else {
- data->max_x = range.x;
- data->max_y = range.y;
- }
-
- dev_dbg(&client->dev,
- "Touchscreen size X%uY%u\n", data->max_x, data->max_y);
+ data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
return 0;
}
@@ -1708,13 +1693,14 @@ static int mxt_read_t100_config(struct mxt_data *data)
if (!object)
return -EINVAL;
+ /* read touchscreen dimensions */
error = __mxt_read_reg(client,
object->start_address + MXT_T100_XRANGE,
sizeof(range_x), &range_x);
if (error)
return error;
- le16_to_cpus(&range_x);
+ data->max_x = get_unaligned_le16(&range_x);
error = __mxt_read_reg(client,
object->start_address + MXT_T100_YRANGE,
@@ -1722,36 +1708,24 @@ static int mxt_read_t100_config(struct mxt_data *data)
if (error)
return error;
- le16_to_cpus(&range_y);
+ data->max_y = get_unaligned_le16(&range_y);
+ /* read orientation config */
error = __mxt_read_reg(client,
object->start_address + MXT_T100_CFG1,
1, &cfg);
if (error)
return error;
+ data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
+
+ /* allocate aux bytes */
error = __mxt_read_reg(client,
object->start_address + MXT_T100_TCHAUX,
1, &tchaux);
if (error)
return error;
- /* Handle default values */
- if (range_x == 0)
- range_x = 1023;
-
- if (range_y == 0)
- range_y = 1023;
-
- if (cfg & MXT_T100_CFG_SWITCHXY) {
- data->max_x = range_y;
- data->max_y = range_x;
- } else {
- data->max_x = range_x;
- data->max_y = range_y;
- }
-
- /* allocate aux bytes */
aux = 6;
if (tchaux & MXT_T100_TCHAUX_VECT)
@@ -1767,9 +1741,6 @@ static int mxt_read_t100_config(struct mxt_data *data)
"T100 aux mappings vect:%u ampl:%u area:%u\n",
data->t100_aux_vect, data->t100_aux_ampl, data->t100_aux_area);
- dev_info(&client->dev,
- "T100 Touchscreen size X%uY%u\n", data->max_x, data->max_y);
-
return 0;
}
@@ -1828,6 +1799,19 @@ static int mxt_initialize_input_device(struct mxt_data *data)
return -EINVAL;
}
+ /* Handle default values and orientation switch */
+ if (data->max_x == 0)
+ data->max_x = 1023;
+
+ if (data->max_y == 0)
+ data->max_y = 1023;
+
+ if (data->xy_switch)
+ swap(data->max_x, data->max_y);
+
+ dev_info(dev, "Touchscreen size X%uY%u\n", data->max_x, data->max_y);
+
+ /* Register input device */
input_dev = input_allocate_device();
if (!input_dev) {
dev_err(dev, "Failed to allocate memory\n");
--
2.5.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH RFC v2 1/9] Input: atmel_mxt_ts - improve touchscreen size/orientation handling
2015-12-24 13:49 ` [PATCH RFC v2 1/9] Input: atmel_mxt_ts - improve touchscreen size/orientation handling Nick Dyer
@ 2016-01-11 23:24 ` Dmitry Torokhov
0 siblings, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2016-01-11 23:24 UTC (permalink / raw)
To: Nick Dyer
Cc: Benson Leung, linux-input, linux-kernel, Alan Bowens,
Javier Martinez Canillas, Chris Healy
On Thu, Dec 24, 2015 at 01:49:20PM +0000, Nick Dyer wrote:
> Both T100 and T9 handle range and orientation in a similar fashion.
> Reduce duplication between the two implementations.
>
> Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Applied, thank you.
> ---
> drivers/input/touchscreen/atmel_mxt_ts.c | 68 ++++++++++++--------------------
> 1 file changed, 26 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
> index c562205..4a1d218 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -113,8 +113,8 @@ struct t7_config {
> #define MXT_T9_DETECT (1 << 7)
>
> struct t9_range {
> - u16 x;
> - u16 y;
> + __le16 x;
> + __le16 y;
> } __packed;
>
> /* MXT_TOUCH_MULTI_T9 orient */
> @@ -216,6 +216,7 @@ struct mxt_data {
> unsigned int irq;
> unsigned int max_x;
> unsigned int max_y;
> + bool xy_switch;
> bool in_bootloader;
> u16 mem_size;
> u8 t100_aux_ampl;
> @@ -1665,8 +1666,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
> if (error)
> return error;
>
> - le16_to_cpus(&range.x);
> - le16_to_cpus(&range.y);
> + data->max_x = get_unaligned_le16(&range.x);
> + data->max_y = get_unaligned_le16(&range.y);
>
> error = __mxt_read_reg(client,
> object->start_address + MXT_T9_ORIENT,
> @@ -1674,23 +1675,7 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
> if (error)
> return error;
>
> - /* Handle default values */
> - if (range.x == 0)
> - range.x = 1023;
> -
> - if (range.y == 0)
> - range.y = 1023;
> -
> - if (orient & MXT_T9_ORIENT_SWITCH) {
> - data->max_x = range.y;
> - data->max_y = range.x;
> - } else {
> - data->max_x = range.x;
> - data->max_y = range.y;
> - }
> -
> - dev_dbg(&client->dev,
> - "Touchscreen size X%uY%u\n", data->max_x, data->max_y);
> + data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
>
> return 0;
> }
> @@ -1708,13 +1693,14 @@ static int mxt_read_t100_config(struct mxt_data *data)
> if (!object)
> return -EINVAL;
>
> + /* read touchscreen dimensions */
> error = __mxt_read_reg(client,
> object->start_address + MXT_T100_XRANGE,
> sizeof(range_x), &range_x);
> if (error)
> return error;
>
> - le16_to_cpus(&range_x);
> + data->max_x = get_unaligned_le16(&range_x);
>
> error = __mxt_read_reg(client,
> object->start_address + MXT_T100_YRANGE,
> @@ -1722,36 +1708,24 @@ static int mxt_read_t100_config(struct mxt_data *data)
> if (error)
> return error;
>
> - le16_to_cpus(&range_y);
> + data->max_y = get_unaligned_le16(&range_y);
>
> + /* read orientation config */
> error = __mxt_read_reg(client,
> object->start_address + MXT_T100_CFG1,
> 1, &cfg);
> if (error)
> return error;
>
> + data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
> +
> + /* allocate aux bytes */
> error = __mxt_read_reg(client,
> object->start_address + MXT_T100_TCHAUX,
> 1, &tchaux);
> if (error)
> return error;
>
> - /* Handle default values */
> - if (range_x == 0)
> - range_x = 1023;
> -
> - if (range_y == 0)
> - range_y = 1023;
> -
> - if (cfg & MXT_T100_CFG_SWITCHXY) {
> - data->max_x = range_y;
> - data->max_y = range_x;
> - } else {
> - data->max_x = range_x;
> - data->max_y = range_y;
> - }
> -
> - /* allocate aux bytes */
> aux = 6;
>
> if (tchaux & MXT_T100_TCHAUX_VECT)
> @@ -1767,9 +1741,6 @@ static int mxt_read_t100_config(struct mxt_data *data)
> "T100 aux mappings vect:%u ampl:%u area:%u\n",
> data->t100_aux_vect, data->t100_aux_ampl, data->t100_aux_area);
>
> - dev_info(&client->dev,
> - "T100 Touchscreen size X%uY%u\n", data->max_x, data->max_y);
> -
> return 0;
> }
>
> @@ -1828,6 +1799,19 @@ static int mxt_initialize_input_device(struct mxt_data *data)
> return -EINVAL;
> }
>
> + /* Handle default values and orientation switch */
> + if (data->max_x == 0)
> + data->max_x = 1023;
> +
> + if (data->max_y == 0)
> + data->max_y = 1023;
> +
> + if (data->xy_switch)
> + swap(data->max_x, data->max_y);
> +
> + dev_info(dev, "Touchscreen size X%uY%u\n", data->max_x, data->max_y);
> +
> + /* Register input device */
> input_dev = input_allocate_device();
> if (!input_dev) {
> dev_err(dev, "Failed to allocate memory\n");
> --
> 2.5.0
>
--
Dmitry
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH RFC v2 2/9] Input: atmel_mxt_ts - add diagnostic data retrieval via debugfs
2015-12-24 13:49 [PATCH RFC v2 0/8] Input: atmel_mxt_ts - raw data via debugfs Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 1/9] Input: atmel_mxt_ts - improve touchscreen size/orientation handling Nick Dyer
@ 2015-12-24 13:49 ` Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 3/9] Input: atmel_mxt_ts - read touchscreen position in matrix Nick Dyer
` (6 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Nick Dyer @ 2015-12-24 13:49 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benson Leung, linux-input, linux-kernel, Alan Bowens,
Javier Martinez Canillas, Chris Healy, Nick Dyer
Retrieve refs data from the T37 diagnostic data object and expose it via
a binary attribute in debugfs.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 208 +++++++++++++++++++++++++++++++
1 file changed, 208 insertions(+)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 4a1d218..96000f4 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -28,6 +28,7 @@
#include <linux/of.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
+#include <linux/debugfs.h>
/* Firmware files */
#define MXT_FW_NAME "maxtouch.fw"
@@ -124,6 +125,17 @@ struct t9_range {
#define MXT_COMMS_CTRL 0
#define MXT_COMMS_CMD 1
+/* MXT_DEBUG_DIAGNOSTIC_T37 */
+#define MXT_DIAGNOSTIC_PAGEUP 0x01
+#define MXT_DIAGNOSTIC_DELTAS 0x10
+#define MXT_DIAGNOSTIC_SIZE 128
+
+struct t37_debug {
+ u8 mode;
+ u8 page;
+ u8 data[MXT_DIAGNOSTIC_SIZE];
+};
+
/* Define for MXT_GEN_COMMAND_T6 */
#define MXT_BOOT_VALUE 0xa5
#define MXT_RESET_VALUE 0x01
@@ -205,6 +217,18 @@ struct mxt_object {
u8 num_report_ids;
} __packed;
+#ifdef CONFIG_DEBUG_FS
+struct mxt_dbg {
+ u16 t37_address;
+ u16 diag_cmd_address;
+ struct t37_debug *t37_buf;
+ unsigned int t37_pages;
+ unsigned int t37_nodes;
+
+ struct dentry *debugfs_dir;
+};
+#endif
+
/* Each client has this additional data */
struct mxt_data {
struct i2c_client *client;
@@ -233,6 +257,9 @@ struct mxt_data {
u8 num_touchids;
u8 multitouch;
struct t7_config t7_cfg;
+#ifdef CONFIG_DEBUG_FS
+ struct mxt_dbg dbg;
+#endif
/* Cached parameters from object table */
u16 T5_address;
@@ -2043,6 +2070,184 @@ recheck:
return 0;
}
+#ifdef CONFIG_DEBUG_FS
+static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
+ unsigned int y)
+{
+ struct mxt_dbg *dbg = &data->dbg;
+ unsigned int ofs, page;
+
+ ofs = (y + (x * (data->info.matrix_ysize))) * sizeof(u16);
+ page = ofs / MXT_DIAGNOSTIC_SIZE;
+ ofs %= MXT_DIAGNOSTIC_SIZE;
+
+ return get_unaligned_le16(&dbg->t37_buf[page].data[ofs]);
+}
+
+static void mxt_convert_debug_pages(struct seq_file *s, struct mxt_data *data)
+{
+ struct mxt_dbg *dbg = &data->dbg;
+ unsigned int x = 0;
+ unsigned int y = 0;
+ unsigned int i;
+ u16 val;
+
+ for (i = 0; i < dbg->t37_nodes; i++) {
+ val = mxt_get_debug_value(data, x, y);
+ seq_write(s, &val, sizeof(u16));
+
+ /* Next value */
+ if (++x >= data->info.matrix_xsize) {
+ x = 0;
+ y++;
+ }
+ }
+}
+
+static int mxt_read_diagnostic_debug(struct seq_file *s, void *d)
+{
+ struct mxt_data *data = dev_get_drvdata(s->private);
+ struct mxt_dbg *dbg = &data->dbg;
+ int retries = 0;
+ int page;
+ int ret;
+ u8 mode = MXT_DIAGNOSTIC_DELTAS;
+ u8 cmd = mode;
+ struct t37_debug *p;
+
+ for (page = 0; page < dbg->t37_pages; page++) {
+ p = dbg->t37_buf + page;
+
+ ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
+ cmd);
+ if (ret)
+ return ret;
+
+ retries = 0;
+
+ /* Poll until command is actioned */
+ msleep(20);
+wait_cmd:
+ /* Read first two bytes only */
+ ret = __mxt_read_reg(data->client, dbg->t37_address,
+ 2, p);
+ if (ret)
+ return ret;
+
+ if ((p->mode != mode) || (p->page != page)) {
+ if (retries++ > 100)
+ return -EINVAL;
+
+ msleep(20);
+ goto wait_cmd;
+ }
+
+ /* Read entire T37 page */
+ ret = __mxt_read_reg(data->client, dbg->t37_address,
+ sizeof(struct t37_debug), p);
+ if (ret)
+ return ret;
+
+ dev_dbg(&data->client->dev, "%s page:%d retries:%d\n",
+ __func__, page, retries);
+
+ /* For remaining pages, write PAGEUP rather than mode */
+ cmd = MXT_DIAGNOSTIC_PAGEUP;
+ }
+
+ mxt_convert_debug_pages(s, data);
+
+ return 0;
+}
+
+static int mxt_debugfs_data_open(struct inode *inode, struct file *f)
+{
+ struct mxt_data *data = inode->i_private;
+ size_t size = data->dbg.t37_nodes * sizeof(u16);
+
+ return single_open_size(f, mxt_read_diagnostic_debug, data, size);
+}
+
+static const struct file_operations mxt_debugfs_data_ops = {
+ .owner = THIS_MODULE,
+ .open = mxt_debugfs_data_open,
+ .release = single_release,
+ .read = seq_read,
+ .llseek = seq_lseek
+};
+
+static void mxt_debugfs_remove(struct mxt_data *data)
+{
+ debugfs_remove_recursive(data->dbg.debugfs_dir);
+}
+
+static void mxt_debugfs_init(struct mxt_data *data)
+{
+ struct mxt_dbg *dbg = &data->dbg;
+ struct mxt_object *object;
+ char dirname[50];
+ struct dentry *dent;
+
+ object = mxt_get_object(data, MXT_GEN_COMMAND_T6);
+ if (!object)
+ return;
+
+ dbg->diag_cmd_address = object->start_address + MXT_COMMAND_DIAGNOSTIC;
+
+ object = mxt_get_object(data, MXT_DEBUG_DIAGNOSTIC_T37);
+ if (!object)
+ return;
+
+ if (mxt_obj_size(object) != sizeof(struct t37_debug)) {
+ dev_warn(&data->client->dev, "Bad T37 size");
+ return;
+ }
+
+ dbg->t37_address = object->start_address;
+
+ snprintf(dirname, sizeof(dirname), "heatmap-%s-%s",
+ dev_driver_string(&data->client->dev),
+ dev_name(&data->client->dev));
+
+ dbg->debugfs_dir = debugfs_create_dir(dirname, NULL);
+ if (!dbg->debugfs_dir) {
+ dev_err(&data->client->dev, "Error creating debugfs dir\n");
+ return;
+ }
+
+ /* Calculate size of data and allocate buffer */
+ dbg->t37_nodes = data->info.matrix_xsize * data->info.matrix_ysize;
+ dbg->t37_pages = dbg->t37_nodes * sizeof(u16)
+ / sizeof(dbg->t37_buf->data) + 1;
+
+ dbg->t37_buf = devm_kzalloc(&data->client->dev,
+ sizeof(struct t37_debug) * dbg->t37_pages,
+ GFP_KERNEL);
+ if (!dbg->t37_buf)
+ goto error;
+
+ dent = debugfs_create_file("deltas", S_IRUGO,
+ dbg->debugfs_dir, data,
+ &mxt_debugfs_data_ops);
+ if (!dent)
+ goto error;
+
+ return;
+
+error:
+ dev_err(&data->client->dev, "Error creating debugfs entry\n");
+ mxt_debugfs_remove(data);
+}
+#else
+static inline void mxt_debugfs_remove(struct mxt_data *data)
+{
+}
+
+static inline void mxt_debugfs_init(struct mxt_data *data)
+{
+}
+#endif /* CONFIG_DEBUG_FS */
+
static int mxt_configure_objects(struct mxt_data *data,
const struct firmware *cfg)
{
@@ -2070,6 +2275,8 @@ static int mxt_configure_objects(struct mxt_data *data,
dev_warn(dev, "No touch object detected\n");
}
+ mxt_debugfs_init(data);
+
dev_info(dev,
"Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n",
info->family_id, info->variant_id, info->version >> 4,
@@ -2617,6 +2824,7 @@ static int mxt_remove(struct i2c_client *client)
{
struct mxt_data *data = i2c_get_clientdata(client);
+ mxt_debugfs_remove(data);
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
free_irq(data->irq, data);
mxt_free_input_device(data);
--
2.5.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH RFC v2 3/9] Input: atmel_mxt_ts - read touchscreen position in matrix
2015-12-24 13:49 [PATCH RFC v2 0/8] Input: atmel_mxt_ts - raw data via debugfs Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 1/9] Input: atmel_mxt_ts - improve touchscreen size/orientation handling Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 2/9] Input: atmel_mxt_ts - add diagnostic data retrieval via debugfs Nick Dyer
@ 2015-12-24 13:49 ` Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 4/9] Input: atmel_mxt_ts - handle diagnostic data orientation Nick Dyer
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Nick Dyer @ 2015-12-24 13:49 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benson Leung, linux-input, linux-kernel, Alan Bowens,
Javier Martinez Canillas, Chris Healy, Nick Dyer
The touchscreen may have a margin where not all the matrix is used. Read
the parameters from T9 and T100 and take account of the difference.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 41 ++++++++++++++++++++++++++++----
1 file changed, 36 insertions(+), 5 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 96000f4..a177019 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -100,6 +100,8 @@ struct t7_config {
/* MXT_TOUCH_MULTI_T9 field */
#define MXT_T9_CTRL 0
+#define MXT_T9_XSIZE 3
+#define MXT_T9_YSIZE 4
#define MXT_T9_ORIENT 9
#define MXT_T9_RANGE 18
@@ -145,7 +147,9 @@ struct t37_debug {
#define MXT_T100_CTRL 0
#define MXT_T100_CFG1 1
#define MXT_T100_TCHAUX 3
+#define MXT_T100_XSIZE 9
#define MXT_T100_XRANGE 13
+#define MXT_T100_YSIZE 20
#define MXT_T100_YRANGE 24
#define MXT_T100_CFG_SWITCHXY BIT(5)
@@ -241,6 +245,8 @@ struct mxt_data {
unsigned int max_x;
unsigned int max_y;
bool xy_switch;
+ u8 xsize;
+ u8 ysize;
bool in_bootloader;
u16 mem_size;
u8 t100_aux_ampl;
@@ -1688,6 +1694,18 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return -EINVAL;
error = __mxt_read_reg(client,
+ object->start_address + MXT_T9_XSIZE,
+ sizeof(data->xsize), &data->xsize);
+ if (error)
+ return error;
+
+ error = __mxt_read_reg(client,
+ object->start_address + MXT_T9_YSIZE,
+ sizeof(data->ysize), &data->ysize);
+ if (error)
+ return error;
+
+ error = __mxt_read_reg(client,
object->start_address + MXT_T9_RANGE,
sizeof(range), &range);
if (error)
@@ -1737,6 +1755,18 @@ static int mxt_read_t100_config(struct mxt_data *data)
data->max_y = get_unaligned_le16(&range_y);
+ error = __mxt_read_reg(client,
+ object->start_address + MXT_T100_XSIZE,
+ sizeof(data->xsize), &data->xsize);
+ if (error)
+ return error;
+
+ error = __mxt_read_reg(client,
+ object->start_address + MXT_T100_YSIZE,
+ sizeof(data->ysize), &data->ysize);
+ if (error)
+ return error;
+
/* read orientation config */
error = __mxt_read_reg(client,
object->start_address + MXT_T100_CFG1,
@@ -2077,7 +2107,7 @@ static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
struct mxt_dbg *dbg = &data->dbg;
unsigned int ofs, page;
- ofs = (y + (x * (data->info.matrix_ysize))) * sizeof(u16);
+ ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
page = ofs / MXT_DIAGNOSTIC_SIZE;
ofs %= MXT_DIAGNOSTIC_SIZE;
@@ -2097,7 +2127,7 @@ static void mxt_convert_debug_pages(struct seq_file *s, struct mxt_data *data)
seq_write(s, &val, sizeof(u16));
/* Next value */
- if (++x >= data->info.matrix_xsize) {
+ if (++x >= data->xsize) {
x = 0;
y++;
}
@@ -2216,9 +2246,10 @@ static void mxt_debugfs_init(struct mxt_data *data)
}
/* Calculate size of data and allocate buffer */
- dbg->t37_nodes = data->info.matrix_xsize * data->info.matrix_ysize;
- dbg->t37_pages = dbg->t37_nodes * sizeof(u16)
- / sizeof(dbg->t37_buf->data) + 1;
+ dbg->t37_nodes = data->xsize * data->ysize;
+ dbg->t37_pages = ((data->xsize * data->info.matrix_ysize)
+ * sizeof(u16) / sizeof(dbg->t37_buf->data)) + 1;
+
dbg->t37_buf = devm_kzalloc(&data->client->dev,
sizeof(struct t37_debug) * dbg->t37_pages,
--
2.5.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH RFC v2 4/9] Input: atmel_mxt_ts - handle diagnostic data orientation
2015-12-24 13:49 [PATCH RFC v2 0/8] Input: atmel_mxt_ts - raw data via debugfs Nick Dyer
` (2 preceding siblings ...)
2015-12-24 13:49 ` [PATCH RFC v2 3/9] Input: atmel_mxt_ts - read touchscreen position in matrix Nick Dyer
@ 2015-12-24 13:49 ` Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 5/9] Input: atmel_mxt_ts - add diagnostic data support for mXT1386 Nick Dyer
` (4 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Nick Dyer @ 2015-12-24 13:49 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benson Leung, linux-input, linux-kernel, Alan Bowens,
Javier Martinez Canillas, Chris Healy, Nick Dyer
Invert the diagnostic data to match the orientation of the input device.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 30 +++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index a177019..48bf9ec 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -122,6 +122,8 @@ struct t9_range {
/* MXT_TOUCH_MULTI_T9 orient */
#define MXT_T9_ORIENT_SWITCH (1 << 0)
+#define MXT_T9_ORIENT_INVERTX (1 << 1)
+#define MXT_T9_ORIENT_INVERTY (1 << 2)
/* MXT_SPT_COMMSCONFIG_T18 */
#define MXT_COMMS_CTRL 0
@@ -153,6 +155,8 @@ struct t37_debug {
#define MXT_T100_YRANGE 24
#define MXT_T100_CFG_SWITCHXY BIT(5)
+#define MXT_T100_CFG_INVERTY BIT(6)
+#define MXT_T100_CFG_INVERTX BIT(7)
#define MXT_T100_TCHAUX_VECT BIT(0)
#define MXT_T100_TCHAUX_AMPL BIT(1)
@@ -244,7 +248,9 @@ struct mxt_data {
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
- bool xy_switch;
+ bool invertx;
+ bool inverty;
+ bool xyswitch;
u8 xsize;
u8 ysize;
bool in_bootloader;
@@ -1720,7 +1726,9 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
if (error)
return error;
- data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
+ data->xyswitch = orient & MXT_T9_ORIENT_SWITCH;
+ data->invertx = orient & MXT_T9_ORIENT_INVERTX;
+ data->inverty = orient & MXT_T9_ORIENT_INVERTY;
return 0;
}
@@ -1774,7 +1782,9 @@ static int mxt_read_t100_config(struct mxt_data *data)
if (error)
return error;
- data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
+ data->xyswitch = cfg & MXT_T100_CFG_SWITCHXY;
+ data->invertx = cfg & MXT_T100_CFG_INVERTX;
+ data->inverty = cfg & MXT_T100_CFG_INVERTY;
/* allocate aux bytes */
error = __mxt_read_reg(client,
@@ -1863,7 +1873,7 @@ static int mxt_initialize_input_device(struct mxt_data *data)
if (data->max_y == 0)
data->max_y = 1023;
- if (data->xy_switch)
+ if (data->xyswitch)
swap(data->max_x, data->max_y);
dev_info(dev, "Touchscreen size X%uY%u\n", data->max_x, data->max_y);
@@ -2119,15 +2129,21 @@ static void mxt_convert_debug_pages(struct seq_file *s, struct mxt_data *data)
struct mxt_dbg *dbg = &data->dbg;
unsigned int x = 0;
unsigned int y = 0;
- unsigned int i;
+ unsigned int i, rx, ry;
u16 val;
for (i = 0; i < dbg->t37_nodes; i++) {
- val = mxt_get_debug_value(data, x, y);
+ /* Handle orientation */
+ rx = data->xyswitch ? y : x;
+ ry = data->xyswitch ? x : y;
+ rx = data->invertx ? (data->xsize - 1 - rx) : rx;
+ ry = data->inverty ? (data->ysize - 1 - ry) : ry;
+
+ val = mxt_get_debug_value(data, rx, ry);
seq_write(s, &val, sizeof(u16));
/* Next value */
- if (++x >= data->xsize) {
+ if (++x >= (data->xyswitch ? data->ysize : data->xsize)) {
x = 0;
y++;
}
--
2.5.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH RFC v2 5/9] Input: atmel_mxt_ts - add diagnostic data support for mXT1386
2015-12-24 13:49 [PATCH RFC v2 0/8] Input: atmel_mxt_ts - raw data via debugfs Nick Dyer
` (3 preceding siblings ...)
2015-12-24 13:49 ` [PATCH RFC v2 4/9] Input: atmel_mxt_ts - handle diagnostic data orientation Nick Dyer
@ 2015-12-24 13:49 ` Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 6/9] Input: atmel_mxt_ts - add support for reference data Nick Dyer
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Nick Dyer @ 2015-12-24 13:49 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benson Leung, linux-input, linux-kernel, Alan Bowens,
Javier Martinez Canillas, Chris Healy, Nick Dyer
The mXT1386 family of chips have a different architecture which splits
the diagnostic data into 3 columns.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 48bf9ec..a2f11836 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -134,6 +134,10 @@ struct t9_range {
#define MXT_DIAGNOSTIC_DELTAS 0x10
#define MXT_DIAGNOSTIC_SIZE 128
+#define MXT_FAMILY_1386 160
+#define MXT1386_COLUMNS 3
+#define MXT1386_PAGES_PER_COLUMN 8
+
struct t37_debug {
u8 mode;
u8 page;
@@ -2114,13 +2118,27 @@ recheck:
static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
unsigned int y)
{
+ struct mxt_info *info = &data->info;
struct mxt_dbg *dbg = &data->dbg;
unsigned int ofs, page;
+ unsigned int col = 0;
+ unsigned int col_width;
+
+ if (info->family_id == MXT_FAMILY_1386) {
+ col_width = info->matrix_ysize / MXT1386_COLUMNS;
+ col = y / col_width;
+ y = y % col_width;
+ } else {
+ col_width = info->matrix_ysize;
+ }
- ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+ ofs = (y + (x * col_width)) * sizeof(u16);
page = ofs / MXT_DIAGNOSTIC_SIZE;
ofs %= MXT_DIAGNOSTIC_SIZE;
+ if (info->family_id == MXT_FAMILY_1386)
+ page += col * MXT1386_PAGES_PER_COLUMN;
+
return get_unaligned_le16(&dbg->t37_buf[page].data[ofs]);
}
@@ -2229,6 +2247,7 @@ static void mxt_debugfs_remove(struct mxt_data *data)
static void mxt_debugfs_init(struct mxt_data *data)
{
+ struct mxt_info *info = &data->info;
struct mxt_dbg *dbg = &data->dbg;
struct mxt_object *object;
char dirname[50];
@@ -2263,8 +2282,13 @@ static void mxt_debugfs_init(struct mxt_data *data)
/* Calculate size of data and allocate buffer */
dbg->t37_nodes = data->xsize * data->ysize;
- dbg->t37_pages = ((data->xsize * data->info.matrix_ysize)
- * sizeof(u16) / sizeof(dbg->t37_buf->data)) + 1;
+
+ if (info->family_id == MXT_FAMILY_1386)
+ dbg->t37_pages = MXT1386_COLUMNS * MXT1386_PAGES_PER_COLUMN;
+ else
+ dbg->t37_pages = ((data->xsize * info->matrix_ysize)
+ * sizeof(u16) / sizeof(dbg->t37_buf->data))
+ + 1;
dbg->t37_buf = devm_kzalloc(&data->client->dev,
--
2.5.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH RFC v2 6/9] Input: atmel_mxt_ts - add support for reference data
2015-12-24 13:49 [PATCH RFC v2 0/8] Input: atmel_mxt_ts - raw data via debugfs Nick Dyer
` (4 preceding siblings ...)
2015-12-24 13:49 ` [PATCH RFC v2 5/9] Input: atmel_mxt_ts - add diagnostic data support for mXT1386 Nick Dyer
@ 2015-12-24 13:49 ` Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 7/9] Input: atmel_mxt_ts - add metadata to debugfs Nick Dyer
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Nick Dyer @ 2015-12-24 13:49 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benson Leung, linux-input, linux-kernel, Alan Bowens,
Javier Martinez Canillas, Chris Healy, Nick Dyer
There are different datatypes available from a maXTouch chip. Add
support to retrieve reference data as well.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
---
drivers/input/touchscreen/atmel_mxt_ts.c | 75 +++++++++++++++++++++++++-------
1 file changed, 59 insertions(+), 16 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index a2f11836..bccd7bc 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -132,6 +132,7 @@ struct t9_range {
/* MXT_DEBUG_DIAGNOSTIC_T37 */
#define MXT_DIAGNOSTIC_PAGEUP 0x01
#define MXT_DIAGNOSTIC_DELTAS 0x10
+#define MXT_DIAGNOSTIC_REFS 0x11
#define MXT_DIAGNOSTIC_SIZE 128
#define MXT_FAMILY_1386 160
@@ -211,6 +212,8 @@ enum t100_type {
#define MXT_PIXELS_PER_MM 20
+struct mxt_data;
+
struct mxt_info {
u8 family_id;
u8 variant_id;
@@ -230,6 +233,27 @@ struct mxt_object {
} __packed;
#ifdef CONFIG_DEBUG_FS
+struct mxt_debug_datatype {
+ u8 mode;
+ char *name;
+};
+
+struct mxt_debug_entry {
+ struct mxt_data *data;
+ const struct mxt_debug_datatype *datatype;
+};
+
+static const struct mxt_debug_datatype mxt_dbg_datatypes[] = {
+ {
+ .mode = MXT_DIAGNOSTIC_REFS,
+ .name = "refs",
+ },
+ {
+ .mode = MXT_DIAGNOSTIC_DELTAS,
+ .name = "deltas",
+ },
+};
+
struct mxt_dbg {
u16 t37_address;
u16 diag_cmd_address;
@@ -238,6 +262,8 @@ struct mxt_dbg {
unsigned int t37_nodes;
struct dentry *debugfs_dir;
+ struct mxt_debug_entry entries[ARRAY_SIZE(mxt_dbg_datatypes)];
+ struct mutex dbg_mutex;
};
#endif
@@ -2142,7 +2168,7 @@ static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
return get_unaligned_le16(&dbg->t37_buf[page].data[ofs]);
}
-static void mxt_convert_debug_pages(struct seq_file *s, struct mxt_data *data)
+static int mxt_convert_debug_pages(struct seq_file *s, struct mxt_data *data)
{
struct mxt_dbg *dbg = &data->dbg;
unsigned int x = 0;
@@ -2166,26 +2192,31 @@ static void mxt_convert_debug_pages(struct seq_file *s, struct mxt_data *data)
y++;
}
}
+
+ return 0;
}
static int mxt_read_diagnostic_debug(struct seq_file *s, void *d)
{
- struct mxt_data *data = dev_get_drvdata(s->private);
+ struct mxt_debug_entry *e = s->private;
+ struct mxt_data *data = e->data;
struct mxt_dbg *dbg = &data->dbg;
int retries = 0;
int page;
int ret;
- u8 mode = MXT_DIAGNOSTIC_DELTAS;
+ u8 mode = e->datatype->mode;
u8 cmd = mode;
struct t37_debug *p;
+ mutex_lock(&dbg->dbg_mutex);
+
for (page = 0; page < dbg->t37_pages; page++) {
p = dbg->t37_buf + page;
ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
cmd);
if (ret)
- return ret;
+ goto release;
retries = 0;
@@ -2196,7 +2227,7 @@ wait_cmd:
ret = __mxt_read_reg(data->client, dbg->t37_address,
2, p);
if (ret)
- return ret;
+ goto release;
if ((p->mode != mode) || (p->page != page)) {
if (retries++ > 100)
@@ -2210,7 +2241,7 @@ wait_cmd:
ret = __mxt_read_reg(data->client, dbg->t37_address,
sizeof(struct t37_debug), p);
if (ret)
- return ret;
+ goto release;
dev_dbg(&data->client->dev, "%s page:%d retries:%d\n",
__func__, page, retries);
@@ -2219,17 +2250,19 @@ wait_cmd:
cmd = MXT_DIAGNOSTIC_PAGEUP;
}
- mxt_convert_debug_pages(s, data);
+ ret = mxt_convert_debug_pages(s, data);
- return 0;
+release:
+ mutex_unlock(&dbg->dbg_mutex);
+ return ret;
}
static int mxt_debugfs_data_open(struct inode *inode, struct file *f)
{
- struct mxt_data *data = inode->i_private;
- size_t size = data->dbg.t37_nodes * sizeof(u16);
+ struct mxt_debug_entry *e = inode->i_private;
+ size_t size = e->data->dbg.t37_nodes * sizeof(u16);
- return single_open_size(f, mxt_read_diagnostic_debug, data, size);
+ return single_open_size(f, mxt_read_diagnostic_debug, e, size);
}
static const struct file_operations mxt_debugfs_data_ops = {
@@ -2252,6 +2285,8 @@ static void mxt_debugfs_init(struct mxt_data *data)
struct mxt_object *object;
char dirname[50];
struct dentry *dent;
+ struct mxt_debug_entry *e;
+ int i;
object = mxt_get_object(data, MXT_GEN_COMMAND_T6);
if (!object)
@@ -2297,11 +2332,19 @@ static void mxt_debugfs_init(struct mxt_data *data)
if (!dbg->t37_buf)
goto error;
- dent = debugfs_create_file("deltas", S_IRUGO,
- dbg->debugfs_dir, data,
- &mxt_debugfs_data_ops);
- if (!dent)
- goto error;
+ for (i = 0; i < ARRAY_SIZE(mxt_dbg_datatypes); i++) {
+ e = &dbg->entries[i];
+ e->data = data;
+ e->datatype = mxt_dbg_datatypes + i;
+
+ dent = debugfs_create_file(mxt_dbg_datatypes[i].name, S_IRUGO,
+ dbg->debugfs_dir, e,
+ &mxt_debugfs_data_ops);
+ if (!dent)
+ goto error;
+ }
+
+ mutex_init(&dbg->dbg_mutex);
return;
--
2.5.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH RFC v2 7/9] Input: atmel_mxt_ts - add metadata to debugfs
2015-12-24 13:49 [PATCH RFC v2 0/8] Input: atmel_mxt_ts - raw data via debugfs Nick Dyer
` (5 preceding siblings ...)
2015-12-24 13:49 ` [PATCH RFC v2 6/9] Input: atmel_mxt_ts - add support for reference data Nick Dyer
@ 2015-12-24 13:49 ` Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 8/9] Input: atmel_mxt_ts - create debugfs info file Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 9/9] Input: atmel_mxt_ts - single node diagnostic data support Nick Dyer
8 siblings, 0 replies; 11+ messages in thread
From: Nick Dyer @ 2015-12-24 13:49 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benson Leung, linux-input, linux-kernel, Alan Bowens,
Javier Martinez Canillas, Chris Healy, Nick Dyer
Add information to debugfs to allow a generic utility to retrieve
screen parameters and info.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
---
Documentation/ABI/testing/debugfs-heatmap | 60 +++++++++++++++++++++++++++++++
drivers/input/touchscreen/atmel_mxt_ts.c | 48 +++++++++++++++++++++++--
2 files changed, 105 insertions(+), 3 deletions(-)
create mode 100644 Documentation/ABI/testing/debugfs-heatmap
diff --git a/Documentation/ABI/testing/debugfs-heatmap b/Documentation/ABI/testing/debugfs-heatmap
new file mode 100644
index 0000000..9246340
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-heatmap
@@ -0,0 +1,60 @@
+What: /sys/kernel/debug/heatmap-dev_driver_string-dev_name/
+Date:
+KernelVersion:
+Contact:
+Description:
+ A directory will be created under heatmap for each device which
+ provides heatmap data.
+
+What: /sys/kernel/debug/heatmap-dev_driver_string-dev_name/datatype/
+Date:
+KernelVersion:
+Contact:
+Description:
+ The device can have multiple heatmap data types. A directory is created
+ for each one.
+
+What: /sys/kernel/debug/heatmap-xxx/datatype/format
+Date:
+KernelVersion:
+Contact:
+Description:
+ Specifies the type of each data value, one of:
+ uint8
+ uint16
+ uint32
+ int8
+ int16
+ int32
+
+What: /sys/kernel/debug/heatmap-xxx/datatype/width
+Date:
+KernelVersion:
+Contact:
+Description:
+ The width of the data.
+
+What: /sys/kernel/debug/heatmap-xxx/datatype/height
+Date:
+KernelVersion:
+Contact:
+Description:
+ The height of the data.
+
+What: /sys/kernel/debug/heatmap-xxx/datatype/name
+Date:
+KernelVersion:
+Contact:
+Description:
+ Display name for the data.
+
+What: /sys/kernel/debug/heatmap-xxx/datatype/data
+Date:
+KernelVersion:
+Contact:
+Description:
+ Binary attribute for the data.
+
+ The orientation of the data should correspond to the co-ordinates
+ reported to the input layer. Starting at the top left hand corner, rows
+ then columns. The endianness of data values will be as per host cpu.
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index bccd7bc..3f12915 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -236,21 +236,31 @@ struct mxt_object {
struct mxt_debug_datatype {
u8 mode;
char *name;
+ char *desc;
+ char *format;
};
struct mxt_debug_entry {
struct mxt_data *data;
const struct mxt_debug_datatype *datatype;
+ u16 width;
+ u16 height;
+ struct debugfs_blob_wrapper format_wrapper;
+ struct debugfs_blob_wrapper desc_wrapper;
};
static const struct mxt_debug_datatype mxt_dbg_datatypes[] = {
{
.mode = MXT_DIAGNOSTIC_REFS,
.name = "refs",
+ .desc = "Mutual Capacitance References",
+ .format = "uint16",
},
{
.mode = MXT_DIAGNOSTIC_DELTAS,
.name = "deltas",
+ .desc = "Mutual Capacitance Deltas",
+ .format = "int16",
},
};
@@ -2286,6 +2296,7 @@ static void mxt_debugfs_init(struct mxt_data *data)
char dirname[50];
struct dentry *dent;
struct mxt_debug_entry *e;
+ struct dentry *dir;
int i;
object = mxt_get_object(data, MXT_GEN_COMMAND_T6);
@@ -2337,9 +2348,40 @@ static void mxt_debugfs_init(struct mxt_data *data)
e->data = data;
e->datatype = mxt_dbg_datatypes + i;
- dent = debugfs_create_file(mxt_dbg_datatypes[i].name, S_IRUGO,
- dbg->debugfs_dir, e,
- &mxt_debugfs_data_ops);
+ dir = debugfs_create_dir(mxt_dbg_datatypes[i].name,
+ dbg->debugfs_dir);
+ if (!dir)
+ goto error;
+
+ e->width = data->xyswitch ? data->ysize : data->xsize;
+ e->height = data->xyswitch ? data->xsize : data->ysize;
+
+ e->format_wrapper.data = (void *)e->datatype->format;
+ e->format_wrapper.size = strlen(e->datatype->format);
+ dent = debugfs_create_blob("format", S_IRUGO,
+ dir, &e->format_wrapper);
+ if (!dent)
+ goto error;
+
+ e->desc_wrapper.data = (void *)e->datatype->desc;
+ e->desc_wrapper.size = strlen(e->datatype->desc);
+ dent = debugfs_create_blob("name", S_IRUGO,
+ dir, &e->desc_wrapper);
+ if (!dent)
+ goto error;
+
+ dent = debugfs_create_u16("width", S_IRUGO,
+ dir, &e->width);
+ if (!dent)
+ goto error;
+
+ dent = debugfs_create_u16("height", S_IRUGO,
+ dir, &e->height);
+ if (!dent)
+ goto error;
+
+ dent = debugfs_create_file("data", S_IRUGO,
+ dir, e, &mxt_debugfs_data_ops);
if (!dent)
goto error;
}
--
2.5.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH RFC v2 8/9] Input: atmel_mxt_ts - create debugfs info file
2015-12-24 13:49 [PATCH RFC v2 0/8] Input: atmel_mxt_ts - raw data via debugfs Nick Dyer
` (6 preceding siblings ...)
2015-12-24 13:49 ` [PATCH RFC v2 7/9] Input: atmel_mxt_ts - add metadata to debugfs Nick Dyer
@ 2015-12-24 13:49 ` Nick Dyer
2015-12-24 13:49 ` [PATCH RFC v2 9/9] Input: atmel_mxt_ts - single node diagnostic data support Nick Dyer
8 siblings, 0 replies; 11+ messages in thread
From: Nick Dyer @ 2015-12-24 13:49 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benson Leung, linux-input, linux-kernel, Alan Bowens,
Javier Martinez Canillas, Chris Healy, Nick Dyer
Add files in debugfs directory with info about the chip and input device.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
---
Documentation/ABI/testing/debugfs-heatmap | 14 ++++++++++++++
drivers/input/touchscreen/atmel_mxt_ts.c | 22 ++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/Documentation/ABI/testing/debugfs-heatmap b/Documentation/ABI/testing/debugfs-heatmap
index 9246340..95668a5 100644
--- a/Documentation/ABI/testing/debugfs-heatmap
+++ b/Documentation/ABI/testing/debugfs-heatmap
@@ -6,6 +6,13 @@ Description:
A directory will be created under heatmap for each device which
provides heatmap data.
+What: /sys/kernel/debug/heatmap-dev_driver_string-dev_name/info
+Date:
+KernelVersion:
+Contact:
+Description:
+ Info relating to the device, eg hardware/firmware version
+
What: /sys/kernel/debug/heatmap-dev_driver_string-dev_name/datatype/
Date:
KernelVersion:
@@ -48,6 +55,13 @@ Contact:
Description:
Display name for the data.
+What: /sys/kernel/debug/heatmap-xxx/datatype/input_name
+Date:
+KernelVersion:
+Contact:
+Description:
+ The name of the corresponding input device, if relevant.
+
What: /sys/kernel/debug/heatmap-xxx/datatype/data
Date:
KernelVersion:
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 3f12915..05bacc6 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -274,6 +274,9 @@ struct mxt_dbg {
struct dentry *debugfs_dir;
struct mxt_debug_entry entries[ARRAY_SIZE(mxt_dbg_datatypes)];
struct mutex dbg_mutex;
+ struct debugfs_blob_wrapper input_name_wrapper;
+ char info[50];
+ struct debugfs_blob_wrapper info_wrapper;
};
#endif
@@ -2326,6 +2329,18 @@ static void mxt_debugfs_init(struct mxt_data *data)
return;
}
+ dbg->info_wrapper.data = dbg->info;
+ dbg->info_wrapper.size = sizeof(dbg->info);
+ scnprintf(dbg->info, sizeof(dbg->info),
+ "Family: %u Variant: %u Firmware V%u.%u.%02X",
+ info->family_id, info->variant_id, info->version >> 4,
+ info->version & 0xf, info->build);
+
+ dent = debugfs_create_blob("info", S_IRUGO, dbg->debugfs_dir,
+ &dbg->info_wrapper);
+ if (!dent)
+ goto error;
+
/* Calculate size of data and allocate buffer */
dbg->t37_nodes = data->xsize * data->ysize;
@@ -2370,6 +2385,13 @@ static void mxt_debugfs_init(struct mxt_data *data)
if (!dent)
goto error;
+ dbg->input_name_wrapper.data = (void *)data->input_dev->name;
+ dbg->input_name_wrapper.size = strlen(data->input_dev->name);
+ dent = debugfs_create_blob("input_name", S_IRUGO,
+ dir, &dbg->input_name_wrapper);
+ if (!dent)
+ goto error;
+
dent = debugfs_create_u16("width", S_IRUGO,
dir, &e->width);
if (!dent)
--
2.5.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH RFC v2 9/9] Input: atmel_mxt_ts - single node diagnostic data support
2015-12-24 13:49 [PATCH RFC v2 0/8] Input: atmel_mxt_ts - raw data via debugfs Nick Dyer
` (7 preceding siblings ...)
2015-12-24 13:49 ` [PATCH RFC v2 8/9] Input: atmel_mxt_ts - create debugfs info file Nick Dyer
@ 2015-12-24 13:49 ` Nick Dyer
8 siblings, 0 replies; 11+ messages in thread
From: Nick Dyer @ 2015-12-24 13:49 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Benson Leung, linux-input, linux-kernel, Alan Bowens,
Javier Martinez Canillas, Chris Healy, Nick Dyer
Add support for retrieving a single node of data at high rate.
---
drivers/input/touchscreen/atmel_mxt_ts.c | 60 +++++++++++++++++++++++++++++---
1 file changed, 55 insertions(+), 5 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 05bacc6..fd3aaae 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -238,6 +238,7 @@ struct mxt_debug_datatype {
char *name;
char *desc;
char *format;
+ bool single_node;
};
struct mxt_debug_entry {
@@ -262,6 +263,20 @@ static const struct mxt_debug_datatype mxt_dbg_datatypes[] = {
.desc = "Mutual Capacitance Deltas",
.format = "int16",
},
+ {
+ .mode = MXT_DIAGNOSTIC_REFS,
+ .name = "single_node_refs",
+ .desc = "Single Node References",
+ .format = "uint16",
+ .single_node = true,
+ },
+ {
+ .mode = MXT_DIAGNOSTIC_DELTAS,
+ .name = "single_node_deltas",
+ .format = "int16",
+ .desc = "Single Node Deltas",
+ .single_node = true,
+ },
};
struct mxt_dbg {
@@ -270,6 +285,7 @@ struct mxt_dbg {
struct t37_debug *t37_buf;
unsigned int t37_pages;
unsigned int t37_nodes;
+ unsigned int single_node_ofs;
struct dentry *debugfs_dir;
struct mxt_debug_entry entries[ARRAY_SIZE(mxt_dbg_datatypes)];
@@ -2216,14 +2232,16 @@ static int mxt_read_diagnostic_debug(struct seq_file *s, void *d)
struct mxt_dbg *dbg = &data->dbg;
int retries = 0;
int page;
+ int pages = e->datatype->single_node ? 1 : dbg->t37_pages;
int ret;
u8 mode = e->datatype->mode;
u8 cmd = mode;
struct t37_debug *p;
+ u16 val;
mutex_lock(&dbg->dbg_mutex);
- for (page = 0; page < dbg->t37_pages; page++) {
+ for (page = 0; page < pages; page++) {
p = dbg->t37_buf + page;
ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
@@ -2263,7 +2281,14 @@ wait_cmd:
cmd = MXT_DIAGNOSTIC_PAGEUP;
}
- ret = mxt_convert_debug_pages(s, data);
+ if (e->datatype->single_node) {
+ val = get_unaligned_le16(&dbg->t37_buf[0]
+ .data[dbg->single_node_ofs]);
+ seq_write(s, &val, sizeof(u16));
+ ret = 0;
+ } else {
+ ret = mxt_convert_debug_pages(s, data);
+ }
release:
mutex_unlock(&dbg->dbg_mutex);
@@ -2273,7 +2298,12 @@ release:
static int mxt_debugfs_data_open(struct inode *inode, struct file *f)
{
struct mxt_debug_entry *e = inode->i_private;
- size_t size = e->data->dbg.t37_nodes * sizeof(u16);
+ size_t size;
+
+ if (e->datatype->single_node)
+ size = sizeof(u16);
+ else
+ size = e->data->dbg.t37_nodes * sizeof(u16);
return single_open_size(f, mxt_read_diagnostic_debug, e, size);
}
@@ -2291,6 +2321,19 @@ static void mxt_debugfs_remove(struct mxt_data *data)
debugfs_remove_recursive(data->dbg.debugfs_dir);
}
+static void mxt_debugfs_calc_single_node_ofs(struct mxt_data *data)
+{
+ struct mxt_info *info = &data->info;
+ int ofs = data->ysize / 2;
+
+ while ((ofs + info->matrix_ysize) <= (MXT_DIAGNOSTIC_SIZE/sizeof(u16)))
+ ofs += info->matrix_ysize;
+
+ dev_dbg(&data->client->dev, "Single node ofs: %d\n", ofs);
+
+ data->dbg.single_node_ofs = ofs;
+}
+
static void mxt_debugfs_init(struct mxt_data *data)
{
struct mxt_info *info = &data->info;
@@ -2358,6 +2401,8 @@ static void mxt_debugfs_init(struct mxt_data *data)
if (!dbg->t37_buf)
goto error;
+ mxt_debugfs_calc_single_node_ofs(data);
+
for (i = 0; i < ARRAY_SIZE(mxt_dbg_datatypes); i++) {
e = &dbg->entries[i];
e->data = data;
@@ -2368,8 +2413,13 @@ static void mxt_debugfs_init(struct mxt_data *data)
if (!dir)
goto error;
- e->width = data->xyswitch ? data->ysize : data->xsize;
- e->height = data->xyswitch ? data->xsize : data->ysize;
+ if (e->datatype->single_node) {
+ e->width = 1;
+ e->height = 1;
+ } else {
+ e->width = data->xyswitch ? data->ysize : data->xsize;
+ e->height = data->xyswitch ? data->xsize : data->ysize;
+ }
e->format_wrapper.data = (void *)e->datatype->format;
e->format_wrapper.size = strlen(e->datatype->format);
--
2.5.0
^ permalink raw reply related [flat|nested] 11+ messages in thread