From f91cb66b8ea227666dde9f8039b17fa5b7cd9cc7 Mon Sep 17 00:00:00 2001 From: Jing Lin Date: Wed, 2 Nov 2011 15:15:30 -0700 Subject: [PATCH] Input: atmel_mxt_ts: Add a debugfs attribute to show all objects The sysfs attribute show method (mxt_object_show) is limited to show object information up to (PAGE_SIZE - 1) bytes. We need a way to get the complete information of all objects. The object information can be obtained from /atmel_mxt_ts/object. Change-Id: I92fff75b37ba0cba19b137460c2144fe847c6343 Signed-off-by: Jing Lin --- drivers/input/touchscreen/atmel_mxt_ts.c | 77 ++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 578a1794e65..d642c9da58b 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #if defined(CONFIG_HAS_EARLYSUSPEND) @@ -253,6 +255,9 @@ #define MXT_MAX_RW_TRIES 3 #define MXT_BLOCK_SIZE 256 +#define MXT_DEBUGFS_DIR "atmel_mxt_ts" +#define MXT_DEBUGFS_FILE "object" + struct mxt_info { u8 family_id; u8 variant_id; @@ -318,6 +323,8 @@ struct mxt_data { int cfg_version_idx; }; +static struct dentry *debug_base; + static bool mxt_object_readable(unsigned int type) { switch (type) { @@ -1728,6 +1735,72 @@ static const struct dev_pm_ops mxt_pm_ops = { }; #endif +static int mxt_debugfs_object_show(struct seq_file *m, void *v) +{ + struct mxt_data *data = m->private; + struct mxt_object *object; + struct device *dev = &data->client->dev; + int i, j, k; + int error; + int obj_size; + u8 val; + + for (i = 0; i < data->info.object_num; i++) { + object = data->object_table + i; + obj_size = object->size + 1; + + seq_printf(m, "Object[%d] (Type %d)\n", i + 1, object->type); + + for (j = 0; j < object->instances + 1; j++) { + seq_printf(m, "[Instance %d]\n", j); + + for (k = 0; k < obj_size; k++) { + error = mxt_read_object(data, object->type, + j * obj_size + k, &val); + if (error) { + dev_err(dev, + "Failed to read object %d " + "instance %d at offset %d\n", + object->type, j, k); + return error; + } + + seq_printf(m, "Byte %d: 0x%02x (%d)\n", + k, val, val); + } + } + } + + return 0; +} + +static int mxt_debugfs_object_open(struct inode *inode, struct file *file) +{ + return single_open(file, mxt_debugfs_object_show, inode->i_private); +} + +static const struct file_operations mxt_object_fops = { + .owner = THIS_MODULE, + .open = mxt_debugfs_object_open, + .read = seq_read, + .release = single_release, +}; + +static void __init mxt_debugfs_init(struct mxt_data *data) +{ + debug_base = debugfs_create_dir(MXT_DEBUGFS_DIR, NULL); + if (IS_ERR_OR_NULL(debug_base)) + pr_err("atmel_mxt_ts: Failed to create debugfs dir\n"); + if (IS_ERR_OR_NULL(debugfs_create_file(MXT_DEBUGFS_FILE, + 0444, + debug_base, + data, + &mxt_object_fops))) { + pr_err("atmel_mxt_ts: Failed to create object file\n"); + debugfs_remove_recursive(debug_base); + } +} + static int __devinit mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1880,6 +1953,8 @@ static int __devinit mxt_probe(struct i2c_client *client, register_early_suspend(&data->early_suspend); #endif + mxt_debugfs_init(data); + return 0; err_unregister_device: @@ -1941,6 +2016,8 @@ static int __devexit mxt_remove(struct i2c_client *client) kfree(data->object_table); kfree(data); + debugfs_remove_recursive(debug_base); + return 0; }