From: Christopher Heiny <cheiny@synaptics.com>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Jean Delvare <khali@linux-fr.org>,
Linux Kernel <linux-kernel@vger.kernel.org>,
Linux Input <linux-input@vger.kernel.org>,
Christopher Heiny <cheiny@synaptics.com>,
Allie Xiong <axiong@synaptics.com>,
William Manson <wmanson@synaptics.com>,
Peichen Chang <peichen.chang@synaptics.com>,
Joerie de Gram <j.de.gram@gmail.com>,
Wolfram Sang <w.sang@pengutronix.de>,
Mathieu Poirier <mathieu.poirier@linaro.org>,
Linus Walleij <linus.walleij@stericsson.com>,
Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com>
Subject: [RFC PATCH 8/17] input: RMI4 F09 Built-In Self Test
Date: Fri, 17 Aug 2012 15:17:48 -0700 [thread overview]
Message-ID: <1345241877-16200-9-git-send-email-cheiny@synaptics.com> (raw)
In-Reply-To: <1345241877-16200-1-git-send-email-cheiny@synaptics.com>
Signed-off-by: Christopher Heiny <cheiny@synaptics.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com>
Cc: Joeri de Gram <j.de.gram@gmail.com>
Acked-by: Jean Delvare <khali@linux-fr.org>
---
drivers/input/rmi4/rmi_f09.c | 772 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 772 insertions(+), 0 deletions(-)
diff --git a/drivers/input/rmi4/rmi_f09.c b/drivers/input/rmi4/rmi_f09.c
new file mode 100644
index 0000000..ee3058e
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f09.c
@@ -0,0 +1,772 @@
+/*
+ * Copyright (c) 2011, 2012 Synaptics Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/rmi.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include "rmi_driver.h"
+
+#define QUERY_BASE_INDEX 1
+
+/* data specific to fn $09 that needs to be kept around */
+struct f09_query {
+ u8 limit_register_count;
+ union {
+ struct {
+ u8 result_register_count:3;
+ u8 reserved:3;
+ u8 internal_limits:1;
+ u8 host_test_enable:1;
+ };
+ u8 f09_bist_query1;
+ };
+};
+
+struct f09_control {
+ union {
+ struct {
+ u8 test1_limit_low:8;
+ u8 test1_limit_high:8;
+ u8 test1_limit_diff:8;
+ };
+ u8 f09_control_test1[3];
+ };
+ union {
+ struct {
+ u8 test2_limit_low:8;
+ u8 test2_limit_high:8;
+ u8 test2_limit_diff:8;
+ };
+ u8 f09_control_test2[3];
+ };
+};
+
+struct f09_data {
+ u8 test_number_control;
+ u8 overall_bist_result;
+ u8 test_result1;
+ u8 test_result2;
+ u8 transmitter_number;
+
+ union {
+ struct {
+ u8 receiver_number:6;
+ u8 limit_failure_code:2;
+ };
+ u8 f09_bist_data2;
+ };
+};
+
+struct f09_cmd {
+ union {
+ struct {
+ u8 run_bist:1;
+ };
+ u8 f09_bist_cmd0;
+ };
+};
+
+struct rmi_fn_09_data {
+ struct f09_query query;
+ struct f09_data data;
+ struct f09_cmd cmd;
+ struct f09_control control;
+ signed char status;
+};
+
+
+static ssize_t rmi_f09_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_status_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+static ssize_t rmi_f09_limit_register_count_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_host_test_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_host_test_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+static ssize_t rmi_f09_internal_limits_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_result_register_count_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_overall_bist_result_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_test_number_control_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_test_number_control_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+static ssize_t rmi_f09_run_bist_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_run_bist_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+static ssize_t rmi_f09_test_result1_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_test_result2_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_control_test1_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_control_test1_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+static ssize_t rmi_f09_control_test2_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t rmi_f09_control_test2_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+
+static int rmi_f09_alloc_memory(struct rmi_function_container *fc);
+
+static void rmi_f09_free_memory(struct rmi_function_container *fc);
+
+static int rmi_f09_initialize(struct rmi_function_container *fc);
+
+static int rmi_f09_config(struct rmi_function_container *fc);
+
+static int rmi_f09_reset(struct rmi_function_container *fc);
+
+static int rmi_f09_create_sysfs(struct rmi_function_container *fc);
+
+
+static struct device_attribute attrs[] = {
+ __ATTR(status, RMI_RW_ATTR,
+ rmi_f09_status_show, rmi_f09_status_store),
+ __ATTR(limitRegisterCount, RMI_RO_ATTR,
+ rmi_f09_limit_register_count_show, rmi_store_error),
+ __ATTR(hostTestEnable, RMI_RW_ATTR,
+ rmi_f09_host_test_enable_show, rmi_f09_host_test_enable_store),
+ __ATTR(internalLimits, RMI_RO_ATTR,
+ rmi_f09_internal_limits_show, rmi_store_error),
+ __ATTR(resultRegisterCount, RMI_RO_ATTR,
+ rmi_f09_result_register_count_show, rmi_store_error),
+ __ATTR(overall_bist_result, RMI_RO_ATTR,
+ rmi_f09_overall_bist_result_show, rmi_store_error),
+ __ATTR(test_number_control, RMI_RW_ATTR,
+ rmi_f09_test_number_control_show,
+ rmi_f09_test_number_control_store),
+ __ATTR(test_result1, RMI_RO_ATTR,
+ rmi_f09_test_result1_show, rmi_store_error),
+ __ATTR(test_result2, RMI_RO_ATTR,
+ rmi_f09_test_result2_show, rmi_store_error),
+ __ATTR(run_bist, RMI_RW_ATTR,
+ rmi_f09_run_bist_show, rmi_f09_run_bist_store),
+ __ATTR(f09_control_test1, RMI_RW_ATTR,
+ rmi_f09_control_test1_show, rmi_f09_control_test1_store),
+ __ATTR(f09_control_test2, RMI_RW_ATTR,
+ rmi_f09_control_test2_show, rmi_f09_control_test2_store),
+};
+
+static int rmi_f09_init(struct rmi_function_container *fc)
+{
+ int rc;
+
+ dev_info(&fc->dev, "Intializing F09 values.");
+
+ rc = rmi_f09_alloc_memory(fc);
+ if (rc < 0)
+ goto error_exit;
+
+ rc = rmi_f09_initialize(fc);
+ if (rc < 0)
+ goto error_exit;
+
+ rc = rmi_f09_create_sysfs(fc);
+ if (rc < 0)
+ goto error_exit;
+
+ return 0;
+
+error_exit:
+ rmi_f09_free_memory(fc);
+
+ return rc;
+}
+
+static int rmi_f09_alloc_memory(struct rmi_function_container *fc)
+{
+ struct rmi_fn_09_data *f09;
+
+ f09 = kzalloc(sizeof(struct rmi_fn_09_data), GFP_KERNEL);
+ if (!f09) {
+ dev_err(&fc->dev, "Failed to allocate rmi_fn_09_data.\n");
+ return -ENOMEM;
+ }
+ fc->data = f09;
+
+ return 0;
+}
+
+static void rmi_f09_free_memory(struct rmi_function_container *fc)
+{
+ kfree(fc->data);
+ fc->data = NULL;
+}
+
+static int rmi_f09_initialize(struct rmi_function_container *fc)
+{
+ struct rmi_device *rmi_dev = fc->rmi_dev;
+ struct rmi_device_platform_data *pdata;
+ struct rmi_fn_09_data *f09 = fc->data;
+ u16 query_base_addr;
+ int rc;
+
+
+ pdata = to_rmi_platform_data(rmi_dev);
+ query_base_addr = fc->fd.query_base_addr;
+
+ /* initial all default values for f09 query here */
+ rc = rmi_read_block(rmi_dev, query_base_addr,
+ (u8 *)&f09->query, sizeof(f09->query));
+ if (rc < 0) {
+ dev_err(&fc->dev, "Failed to read query register."
+ " from 0x%04x\n", query_base_addr);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int rmi_f09_create_sysfs(struct rmi_function_container *fc)
+{
+ int attr_count = 0;
+ int rc;
+
+ dev_dbg(&fc->dev, "Creating sysfs files.");
+ /* Set up sysfs device attributes. */
+ for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
+ if (sysfs_create_file
+ (&fc->dev.kobj, &attrs[attr_count].attr) < 0) {
+ dev_err(&fc->dev, "Failed to create sysfs file for %s.",
+ attrs[attr_count].attr.name);
+ rc = -ENODEV;
+ goto err_remove_sysfs;
+ }
+ }
+
+ return 0;
+
+err_remove_sysfs:
+ for (attr_count--; attr_count >= 0; attr_count--)
+ sysfs_remove_file(&fc->dev.kobj,
+ &attrs[attr_count].attr);
+
+ return rc;
+}
+
+static int rmi_f09_config(struct rmi_function_container *fc)
+{
+ /*we do nothing here. instead reset should notify the user.*/
+ return 0;
+}
+
+static int rmi_f09_reset(struct rmi_function_container *fc)
+{
+ struct rmi_fn_09_data *instance_data = fc->data;
+
+ instance_data->status = -ECONNRESET;
+
+ return 0;
+}
+
+static void rmi_f09_remove(struct rmi_function_container *fc)
+{
+ int attr_count;
+
+ for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++)
+ sysfs_remove_file(&fc->dev.kobj,
+ &attrs[attr_count].attr);
+
+ rmi_f09_free_memory(fc);
+}
+
+static int rmi_f09_attention(struct rmi_function_container *fc, u8 *irq_bits)
+{
+ struct rmi_device *rmi_dev = fc->rmi_dev;
+ struct rmi_fn_09_data *data = fc->data;
+ int error;
+ error = rmi_read_block(rmi_dev, fc->fd.command_base_addr,
+ (u8 *)&data->cmd, sizeof(data->cmd));
+
+ if (error < 0) {
+ dev_err(&fc->dev, "Failed to read command register.\n");
+ return error;
+ }
+ /* If the command register is cleared, meaning the value is 0 */
+ if (data->status == ECONNRESET) {
+ dev_warn(&rmi_dev->dev, "RESET occured: %#04x.\n",
+ data->status);
+ } else if (data->cmd.run_bist) {
+ dev_warn(&rmi_dev->dev,
+ "Command register not cleared: %#04x.\n",
+ data->cmd.run_bist);
+ }
+ return 0;
+}
+
+static struct rmi_function_handler function_handler = {
+ .func = 0x09,
+ .init = rmi_f09_init,
+ .config = rmi_f09_config,
+ .attention = rmi_f09_attention,
+ .reset = rmi_f09_reset,
+ .remove = rmi_f09_remove
+};
+
+static int __init rmi_f09_module_init(void)
+{
+ int error;
+
+ error = rmi_register_function_driver(&function_handler);
+ if (error < 0) {
+ pr_err("%s: register failed!\n", __func__);
+ return error;
+ }
+
+ return 0;
+}
+
+static void rmi_f09_module_exit(void)
+{
+ rmi_unregister_function_driver(&function_handler);
+}
+
+static ssize_t rmi_f09_status_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *instance_data;
+
+ fc = to_rmi_function_container(dev);
+ instance_data = fc->data;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", instance_data->status);
+}
+
+static ssize_t rmi_f09_status_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *instance_data;
+
+ fc = to_rmi_function_container(dev);
+ instance_data = fc->data;
+
+ /* any write to status resets 1 */
+ instance_data->status = 0;
+
+ return 0;
+}
+
+static ssize_t rmi_f09_limit_register_count_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data->query.limit_register_count);
+}
+
+static ssize_t rmi_f09_host_test_enable_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data->query.host_test_enable);
+}
+
+static ssize_t rmi_f09_host_test_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+ unsigned int new_value;
+ int result;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ if (sscanf(buf, "%u", &new_value) != 1) {
+ dev_err(dev,
+ "%s: Error - hostTestEnable has an invalid length.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (new_value < 0 || new_value > 1) {
+ dev_err(dev, "%s: Invalid hostTestEnable bit %s.",
+ __func__, buf);
+ return -EINVAL;
+ }
+ data->query.host_test_enable = new_value;
+ result = rmi_write(fc->rmi_dev, fc->fd.query_base_addr,
+ data->query.host_test_enable);
+ if (result < 0) {
+ dev_err(dev, "%s: Could not write hostTestEnable to 0x%x\n",
+ __func__, fc->fd.query_base_addr);
+ return result;
+ }
+
+ return count;
+
+}
+
+static ssize_t rmi_f09_internal_limits_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data->query.internal_limits);
+}
+
+static ssize_t rmi_f09_result_register_count_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data->query.result_register_count);
+}
+
+static ssize_t rmi_f09_overall_bist_result_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data->data.overall_bist_result);
+}
+
+static ssize_t rmi_f09_test_result1_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data->data.test_result1);
+}
+
+static ssize_t rmi_f09_test_result2_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data->data.test_result2);
+}
+
+static ssize_t rmi_f09_run_bist_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data->cmd.run_bist);
+}
+
+static ssize_t rmi_f09_run_bist_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+ unsigned int new_value;
+ int result;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ if (sscanf(buf, "%u", &new_value) != 1) {
+ dev_err(dev,
+ "%s: Error - run_bist_store has an "
+ "invalid len.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (new_value < 0 || new_value > 1) {
+ dev_err(dev, "%s: Invalid run_bist bit %s.", __func__, buf);
+ return -EINVAL;
+ }
+ data->cmd.run_bist = new_value;
+ result = rmi_write(fc->rmi_dev, fc->fd.command_base_addr,
+ data->cmd.run_bist);
+ if (result < 0) {
+ dev_err(dev, "%s : Could not write run_bist_store to 0x%x\n",
+ __func__, fc->fd.command_base_addr);
+ return result;
+ }
+
+ return count;
+
+}
+
+static ssize_t rmi_f09_control_test1_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u %u %u\n",
+ data->control.test1_limit_low,
+ data->control.test1_limit_high,
+ data->control.test1_limit_diff);
+}
+
+static ssize_t rmi_f09_control_test1_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+ unsigned int new_low, new_high, new_diff;
+ int result;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ if (sscanf(buf, "%u %u %u", &new_low, &new_high, &new_diff) != 3) {
+ dev_err(dev,
+ "%s: Error - f09_control_test1_store has an "
+ "invalid len.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (new_low < 0 || new_low > 1 || new_high < 0 || new_high
+ || new_diff < 0 || new_diff) {
+ dev_err(dev, "%s: Invalid f09_control_test1_diff bit %s.",
+ __func__, buf);
+ return -EINVAL;
+ }
+ data->control.test1_limit_low = new_low;
+ data->control.test1_limit_high = new_high;
+ data->control.test1_limit_diff = new_diff;
+ result = rmi_write(fc->rmi_dev, fc->fd.control_base_addr,
+ data->control.test1_limit_low);
+ if (result < 0) {
+ dev_err(dev, "%s : Could not write f09_control_test1_limit_low to 0x%x\n",
+ __func__, fc->fd.control_base_addr);
+ return result;
+ }
+
+ result = rmi_write(fc->rmi_dev, fc->fd.control_base_addr,
+ data->control.test1_limit_high);
+ if (result < 0) {
+ dev_err(dev, "%s : Could not write f09_control_test1_limit_high to 0x%x\n",
+ __func__, fc->fd.control_base_addr);
+ return result;
+ }
+
+ result = rmi_write(fc->rmi_dev, fc->fd.control_base_addr,
+ data->control.test1_limit_diff);
+ if (result < 0) {
+ dev_err(dev, "%s : Could not write f09_control_test1_limit_diff to 0x%x\n",
+ __func__, fc->fd.control_base_addr);
+ return result;
+ }
+
+ return count;
+
+}
+
+static ssize_t rmi_f09_control_test2_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u %u %u\n",
+ data->control.test2_limit_low,
+ data->control.test2_limit_high,
+ data->control.test2_limit_diff);
+}
+
+static ssize_t rmi_f09_control_test2_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+ unsigned int new_low, new_high, new_diff;
+ int result;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ if (sscanf(buf, "%u %u %u", &new_low, &new_high, &new_diff) != 3) {
+ dev_err(dev,
+ "%s: Error - f09_control_test1_store has an "
+ "invalid len.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (new_low < 0 || new_low > 1 || new_high < 0 || new_high > 1 ||
+ new_diff < 0 || new_diff > 1) {
+ dev_err(dev, "%s: Invalid f09_control_test2_diff bit %s.",
+ __func__, buf);
+ return -EINVAL;
+ }
+ data->control.test2_limit_low = new_low;
+ data->control.test2_limit_high = new_high;
+ data->control.test2_limit_diff = new_diff;
+ result = rmi_write(fc->rmi_dev, fc->fd.control_base_addr,
+ data->control.test2_limit_low);
+ if (result < 0) {
+ dev_err(dev, "%s : Could not write f09_control_test2_limit_low to 0x%x\n",
+ __func__, fc->fd.control_base_addr);
+ return result;
+ }
+
+ result = rmi_write(fc->rmi_dev, fc->fd.control_base_addr,
+ data->control.test2_limit_high);
+ if (result < 0) {
+ dev_err(dev, "%s : Could not write f09_control_test2_limit_high to 0x%x\n",
+ __func__, fc->fd.control_base_addr);
+ return result;
+ }
+
+ result = rmi_write(fc->rmi_dev, fc->fd.control_base_addr,
+ data->control.test2_limit_diff);
+ if (result < 0) {
+ dev_err(dev, "%s : Could not write f09_control_test2_limit_diff to 0x%x\n",
+ __func__, fc->fd.control_base_addr);
+ return result;
+ }
+
+ return count;
+
+}
+
+
+static ssize_t rmi_f09_test_number_control_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ data->data.test_number_control);
+}
+
+static ssize_t rmi_f09_test_number_control_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rmi_function_container *fc;
+ struct rmi_fn_09_data *data;
+ unsigned int new_value;
+ int result;
+
+ fc = to_rmi_function_container(dev);
+ data = fc->data;
+ if (sscanf(buf, "%u", &new_value) != 1) {
+ dev_err(dev,
+ "%s: Error - test_number_control_store has an "
+ "invalid len.\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (new_value < 0 || new_value > 1) {
+ dev_err(dev, "%s: Invalid test_number_control bit %s.",
+ __func__, buf);
+ return -EINVAL;
+ }
+ data->data.test_number_control = new_value;
+ result = rmi_write(fc->rmi_dev, fc->fd.control_base_addr,
+ data->data.test_number_control);
+ if (result < 0) {
+ dev_err(dev, "%s : Could not write "
+ "test_number_control_store to 0x%x\n",
+ __func__, fc->fd.data_base_addr);
+ return result;
+ }
+
+ return count;
+}
+
+module_init(rmi_f09_module_init);
+module_exit(rmi_f09_module_exit);
+
+MODULE_AUTHOR("Allie Xiong <axiong@Synaptics.com>");
+MODULE_DESCRIPTION("RMI F09 module");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(RMI_DRIVER_VERSION);
next prev parent reply other threads:[~2012-08-17 23:22 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-17 22:17 [RFC PATCH 00/11] input: Synaptics RMI4 Touchscreen Driver Christopher Heiny
2012-08-17 22:17 ` [RFC PATCH 1/17] input: RMI4 public header file and documentation Christopher Heiny
2012-08-22 19:08 ` Linus Walleij
2012-08-22 21:45 ` Dmitry Torokhov
2012-08-23 0:26 ` Christopher Heiny
2012-08-22 23:35 ` Rafael J. Wysocki
2012-08-17 22:17 ` [RFC PATCH 2/17] input: RMI4 core bus and sensor drivers Christopher Heiny
2012-08-23 8:55 ` Linus Walleij
2012-09-25 23:53 ` Christopher Heiny
2012-09-26 11:39 ` Linus Walleij
2012-08-17 22:17 ` [RFC PATCH 3/17] input: RMI4 physical layer drivers for I2C and SPI Christopher Heiny
2012-08-23 13:21 ` Linus Walleij
2012-08-17 22:17 ` [RFC PATCH 4/17] input: RMI4 configs and makefiles Christopher Heiny
2012-08-27 18:39 ` Linus Walleij
2012-08-17 22:17 ` [RFC PATCH 5/17] input: rmidev character driver for RMI4 sensors Christopher Heiny
2012-08-27 18:49 ` Linus Walleij
2012-09-05 0:26 ` Christopher Heiny
2012-09-05 8:29 ` Linus Walleij
2012-08-17 22:17 ` [RFC PATCH 6/17] input: RMI4 firmware update Christopher Heiny
2012-08-27 21:01 ` Linus Walleij
2012-08-17 22:17 ` [RFC PATCH 7/17] input: RMI4 F01 device control Christopher Heiny
2012-08-27 21:59 ` Linus Walleij
2012-08-17 22:17 ` Christopher Heiny [this message]
2012-08-27 22:07 ` [RFC PATCH 8/17] input: RMI4 F09 Built-In Self Test Linus Walleij
2012-09-05 0:21 ` Christopher Heiny
2012-08-17 22:17 ` [RFC PATCH 9/17] input: RMI4 F11 multitouch sensing Christopher Heiny
2012-08-27 22:50 ` Linus Walleij
2012-08-17 22:17 ` [RFC PATCH 10/17] input: RM4 F17 Pointing sticks Christopher Heiny
2012-08-17 22:17 ` [RFC PATCH 11/17] input: RMI4 F19 capacitive buttons Christopher Heiny
2012-08-17 22:17 ` [RFC PATCH 12/17] input: RMI4 F1A simple " Christopher Heiny
2012-08-17 22:17 ` [RFC PATCH 13/17] input: RMI4 F21 Force sensing Christopher Heiny
2012-08-17 22:17 ` [RFC PATCH 14/17] input: RMI4 F30 GPIO/LED control Christopher Heiny
2012-08-27 22:58 ` Linus Walleij
2012-09-05 0:28 ` Christopher Heiny
2012-08-17 22:17 ` [RFC PATCH 15/17] input: RMI4 F34 device reflash Christopher Heiny
2012-08-17 22:17 ` [RFC PATCH 16/17] input: RMI4 F41 Active pen 2D input Christopher Heiny
2012-08-17 22:17 ` [RFC PATCH 17/17] input: RMI4 F54 analog data reporting Christopher Heiny
2012-08-27 23:01 ` Linus Walleij
2012-09-05 0:38 ` Christopher Heiny
2012-08-22 12:50 ` [RFC PATCH 00/11] input: Synaptics RMI4 Touchscreen Driver Linus Walleij
2012-08-22 21:29 ` Christopher Heiny
2012-08-27 23:20 ` Christopher Heiny
2012-08-28 0:12 ` Linus Walleij
2012-08-27 23:05 ` Linus Walleij
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1345241877-16200-9-git-send-email-cheiny@synaptics.com \
--to=cheiny@synaptics.com \
--cc=axiong@synaptics.com \
--cc=dmitry.torokhov@gmail.com \
--cc=j.de.gram@gmail.com \
--cc=khali@linux-fr.org \
--cc=linus.walleij@stericsson.com \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mathieu.poirier@linaro.org \
--cc=naveen.gaddipati@stericsson.com \
--cc=peichen.chang@synaptics.com \
--cc=w.sang@pengutronix.de \
--cc=wmanson@synaptics.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).