@@ -2,19 +2,9 @@
* Copyright (c) 2011, 2012 Synaptics Incorporated
* Copyright (c) 2011 Unixphere
*
- * 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.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
*/
#include <linux/kernel.h>
@@ -75,7 +65,8 @@ static struct dentry *rmi_debugfs_root;
static void release_rmidev_device(struct device *dev)
{
- device_unregister(dev);
+ struct rmi_device *rmi_dev = to_rmi_device(dev);
+ kfree(rmi_dev);
}
/**
@@ -110,17 +101,19 @@ int rmi_register_phys_device(struct rmi_phys_device *phys)
dev_dbg(phys->dev, "%s: Registered %s as %s.\n", __func__,
pdata->sensor_name, dev_name(&rmi_dev->dev));
- if (IS_ENABLED(CONFIG_RMI4_DEBUG) && rmi_debugfs_root) {
+#ifdef CONFIG_RMI4_DEBUG
+ if (rmi_debugfs_root) {
rmi_dev->debugfs_root = debugfs_create_dir(
dev_name(&rmi_dev->dev), rmi_debugfs_root);
if (!rmi_dev->debugfs_root)
dev_err(&rmi_dev->dev, "Failed to create debugfs root.\n");
}
+#endif
phys->rmi_dev = rmi_dev;
return device_register(&rmi_dev->dev);
}
-EXPORT_SYMBOL(rmi_register_phys_device);
+EXPORT_SYMBOL_GPL(rmi_register_phys_device);
/**
* rmi_unregister_phys_device - unregister a physical device connection
@@ -131,102 +124,84 @@ void rmi_unregister_phys_device(struct rmi_phys_device *phys)
{
struct rmi_device *rmi_dev = phys->rmi_dev;
- if (IS_ENABLED(CONFIG_RMI4_DEBUG) && rmi_dev->debugfs_root)
+#ifdef CONFIG_RMI4_DEBUG
+ if (rmi_dev->debugfs_root)
debugfs_remove(rmi_dev->debugfs_root);
+#endif
- kfree(rmi_dev);
+ device_unregister(&rmi_dev->dev);
}
-EXPORT_SYMBOL(rmi_unregister_phys_device);
+EXPORT_SYMBOL_GPL(rmi_unregister_phys_device);
-/**
- * rmi_register_function_handler - register a handler for an RMI function
- * @handler: RMI handler that should be registered.
- * @module: pointer to module that implements the handler
- * @mod_name: name of the module implementing the handler
- *
- * This function performs additional setup of RMI function handler and
- * registers it with the RMI core so that it can be bound to
- * RMI function devices.
- */
-int __rmi_register_function_handler(struct rmi_function_handler *handler,
- struct module *owner,
- const char *mod_name)
+static int rmi_bus_match(struct device *dev, struct device_driver *drv)
{
- int error;
+ struct rmi_function_driver *fn_drv;
+ struct rmi_function_dev *fn;
- handler->driver.bus = &rmi_bus_type;
- handler->driver.owner = owner;
- handler->driver.mod_name = mod_name;
+ /*
+ * This seems a little broken to me. It means a system can only ever
+ * have one kind of sensor driver. It'll work for now, but I think in
+ * the long run we need to revisit this.
+ */
+ if (dev->type == &rmi_sensor_type && drv == &rmi_sensor_driver.driver)
+ return 1;
- error = driver_register(&handler->driver);
- if (error) {
- pr_err("driver_register() failed for %s, error: %d\n",
- handler->driver.name, error);
- return error;
- }
+ if (dev->type != &rmi_function_type)
+ return 0;
- return 0;
-}
-EXPORT_SYMBOL(__rmi_register_function_handler);
+ fn = to_rmi_function_dev(dev);
+ fn_drv = to_rmi_function_driver(drv);
-/**
- * rmi_unregister_function_handler - unregister given RMI function handler
- * @handler: RMI handler that should be unregistered.
- *
- * This function unregisters given function handler from RMI core which
- * causes it to be unbound from the function devices.
- */
-void rmi_unregister_function_handler(struct rmi_function_handler *handler)
-{
- driver_unregister(&handler->driver);
+ return fn->fd.function_number == fn_drv->func;
}
-EXPORT_SYMBOL(rmi_unregister_function_handler);
-
-static int rmi_function_match(struct device *dev, struct device_driver *drv)
+static int rmi_function_probe(struct device *dev)
{
- struct rmi_function_handler *handler;
- struct rmi_function *fn;
+ struct rmi_function_driver *fn_drv;
+ struct rmi_function_dev *fn = to_rmi_function_dev(dev);
- if (dev->type != &rmi_function_type)
- return 0;
+ fn_drv = to_rmi_function_driver(dev->driver);
- if (drv == &rmi_sensor_driver.driver)
- return 0;
+ if (fn_drv->probe)
+ return fn_drv->probe(fn);
- fn = to_rmi_function(dev);
- handler = to_rmi_function_handler(drv);
-
- return fn->fd.function_number == handler->func;
+ return 0;
}
-static int rmi_function_probe(struct device *dev)
+static int rmi_function_remove(struct device *dev)
{
- struct rmi_function *fn = to_rmi_function(dev);
- struct rmi_function_handler *handler =
- to_rmi_function_handler(dev->driver);
- int error;
+ struct rmi_function_driver *fn_drv;
+ struct rmi_function_dev *fn = to_rmi_function_dev(dev);
- if (handler->probe) {
- error = handler->probe(fn);
- return error;
- }
+ fn_drv = to_rmi_function_driver(dev->driver);
+
+ if (fn_drv->remove)
+ return fn_drv->remove(fn);
return 0;
}
-static int rmi_function_remove(struct device *dev)
+static int rmi_sensor_remove(struct device *dev)
{
- struct rmi_function *fn = to_rmi_function(dev);
- struct rmi_function_handler *handler =
- to_rmi_function_handler(dev->driver);
+ struct rmi_driver *driver;
+ struct rmi_device *rmi_dev = to_rmi_device(dev);
- if (handler->remove)
- handler->remove(fn);
+ driver = to_rmi_driver(dev->driver);
+ if (!driver->remove)
+ return driver->remove(rmi_dev);
return 0;
}
+static int rmi_bus_remove(struct device *dev)
+{
+ if (dev->type == &rmi_function_type)
+ return rmi_function_remove(dev);
+ else if (dev->type == &rmi_sensor_type)
+ return rmi_sensor_remove(dev);
+ return -EINVAL;
+}
+
#ifdef CONFIG_PM
static int rmi_bus_suspend(struct device *dev)
{
@@ -267,12 +242,58 @@ static SIMPLE_DEV_PM_OPS(rmi_bus_pm_ops,
rmi_bus_suspend, rmi_bus_resume);
struct bus_type rmi_bus_type = {
- .match = rmi_function_match,
- .probe = rmi_function_probe,
- .remove = rmi_function_remove,
.name = "rmi",
+ .match = rmi_bus_match,
+ .remove = rmi_bus_remove,
.pm = &rmi_bus_pm_ops,
};
+EXPORT_SYMBOL_GPL(rmi_bus_type);
+
+/**
+ * rmi_register_function_driver - register a driver for an RMI function
+ * @fn_drv: RMI driver that should be registered.
+ * @module: pointer to module that implements the driver
+ * @mod_name: name of the module implementing the driver
+ *
+ * This function performs additional setup of RMI function driver and
+ * registers it with the RMI core so that it can be bound to
+ * RMI function devices.
+ */
+int __rmi_register_function_driver(struct rmi_function_driver *fn_drv,
+ struct module *owner,
+ const char *mod_name)
+{
+ int error;
+
+ fn_drv->driver.bus = &rmi_bus_type;
+ fn_drv->driver.owner = owner;
+ if (!fn_drv->driver.probe)
+ fn_drv->driver.probe = rmi_function_probe;
+ fn_drv->driver.mod_name = mod_name;
+
+ error = driver_register(&fn_drv->driver);
+ if (error) {
+ pr_err("driver_register() failed for %s, error: %d\n",
+ fn_drv->driver.name, error);
+ return error;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(__rmi_register_function_driver);
+
+/**
+ * rmi_unregister_function_driver - unregister given RMI function driver
+ * @fn_drv: RMI driver that should be unregistered.
+ *
+ * This function unregisters given function driver from RMI core which
+ * causes it to be unbound from the function devices.
+ */
+void rmi_unregister_function_driver(struct rmi_function_driver *fn_drv)
+{
+ driver_unregister(&fn_drv->driver);
+}
+EXPORT_SYMBOL_GPL(rmi_unregister_function_driver);
/**
* rmi_for_each_dev - provides a way for other parts of the system to enumerate
@@ -289,7 +310,7 @@ int rmi_for_each_dev(void *data, int (*func)(struct device *dev, void *data))
mutex_unlock(&rmi_bus_mutex);
return retval;
}
-EXPORT_SYMBOL(rmi_for_each_dev);
+EXPORT_SYMBOL_GPL(rmi_for_each_dev);
static int __init rmi_bus_init(void)
{
@@ -304,9 +325,21 @@ static int __init rmi_bus_init(void)
return error;
}
- error = rmi_register_function_handler(&rmi_f01_handler);
+#ifdef CONFIG_RMI4_DEBUG
+ rmi_debugfs_root = debugfs_create_dir(rmi_bus_type.name, NULL);
+ if (!rmi_debugfs_root)
+ pr_err("%s: Failed to create debugfs root.\n",
+ __func__);
+ else if (IS_ERR(rmi_debugfs_root)) {
+ pr_err("%s: Kernel may not contain debugfs support, code=%ld\n",
+ __func__, PTR_ERR(rmi_debugfs_root));
+ rmi_debugfs_root = NULL;
+ }
+#endif
+
+ error = rmi_register_function_driver(&rmi_f01_driver);
if (error) {
- pr_err("%s: error registering the RMI F01 handler: %d\n",
+ pr_err("%s: error registering the RMI F01 driver: %d\n",
__func__, error);
goto err_unregister_bus;
}
@@ -318,22 +351,10 @@ static int __init rmi_bus_init(void)
goto err_unregister_f01;
}
- if (IS_ENABLED(CONFIG_RMI4_DEBUG)) {
- rmi_debugfs_root = debugfs_create_dir(rmi_bus_type.name, NULL);
- if (!rmi_debugfs_root)
- pr_err("%s: Failed to create debugfs root.\n",
- __func__);
- else if (IS_ERR(rmi_debugfs_root)) {
- pr_err("%s: Kernel may not contain debugfs support, code=%ld\n",
- __func__, PTR_ERR(rmi_debugfs_root));
- rmi_debugfs_root = NULL;
- }
- }
-
return 0;
err_unregister_f01:
- rmi_unregister_function_handler(&rmi_f01_handler);
+ rmi_unregister_function_driver(&rmi_f01_driver);
err_unregister_bus:
bus_unregister(&rmi_bus_type);
return error;
@@ -345,11 +366,12 @@ static void __exit rmi_bus_exit(void)
* We should only ever get here if all drivers are unloaded, so
* all we have to do at this point is unregister ourselves.
*/
- if (IS_ENABLED(CONFIG_RMI4_DEBUG) && rmi_debugfs_root)
+#ifdef CONFIG_RMI4_DEBUG
+ if (rmi_debugfs_root)
debugfs_remove(rmi_debugfs_root);
-
+#endif
rmi_unregister_sensor_driver();
- rmi_unregister_function_handler(&rmi_f01_handler);
+ rmi_unregister_function_driver(&rmi_f01_driver);
bus_unregister(&rmi_bus_type);
}
@@ -1,29 +1,17 @@
/*
- * Copyright (c) 2011, 2012 Synaptics Incorporated
+ * Copyright (c) 2011-2013 Synaptics Incorporated
* Copyright (c) 2011 Unixphere
*
- * This driver adds support for generic RMI4 devices from Synpatics. It
- * implements the mandatory f01 RMI register and depends on the presence of
- * other required RMI functions.
+ * This driver provides the core support for a single RMI4-based device.
*
* The RMI4 specification can be found here (URL split after files/ for
* style reasons):
* http://www.synaptics.com/sites/default/files/
* 511-000136-01-Rev-E-RMI4%20Intrfacing%20Guide.pdf
*
- * 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.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
*/
#include <linux/kernel.h>
@@ -40,7 +28,6 @@
#include <linux/rmi.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
-#include <uapi/linux/input.h>
#include "rmi_driver.h"
#include "rmi_f01.h"
@@ -55,311 +42,6 @@
#define IRQ_DEBUG(data) (IS_ENABLED(CONFIG_RMI4_DEBUG) && data->irq_debug)
-#ifdef CONFIG_RMI4_DEBUG
-struct driver_debugfs_data {
- bool done;
- struct rmi_device *rmi_dev;
-};
-
-static int debug_open(struct inode *inodep, struct file *filp)
-{
- struct driver_debugfs_data *data;
- struct rmi_device *rmi_dev;
-
- rmi_dev = inodep->i_private;
- data = kzalloc(sizeof(struct driver_debugfs_data),
- GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- data->rmi_dev = inodep->i_private;
- filp->private_data = data;
- return 0;
-}
-
-static int debug_release(struct inode *inodep, struct file *filp)
-{
- kfree(filp->private_data);
- return 0;
-}
-
-static ssize_t delay_read(struct file *filp, char __user *buffer, size_t size,
- loff_t *offset) {
- struct driver_debugfs_data *data = filp->private_data;
- struct rmi_device_platform_data *pdata =
- data->rmi_dev->phys->dev->platform_data;
- int retval;
- char *local_buf;
-
- if (data->done)
- return 0;
-
- data->done = 1;
-
- local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
- if (!local_buf)
- return -ENOMEM;
-
- retval = snprintf(local_buf, size, "%d %d %d %d %d\n",
- pdata->spi_data.read_delay_us, pdata->spi_data.write_delay_us,
- pdata->spi_data.block_delay_us,
- pdata->spi_data.pre_delay_us, pdata->spi_data.post_delay_us);
-
- if (retval <= 0 || copy_to_user(buffer, local_buf, retval))
- retval = -EFAULT;
- kfree(local_buf);
-
- return retval;
-}
-
-static ssize_t delay_write(struct file *filp, const char __user *buffer,
- size_t size, loff_t *offset) {
- struct driver_debugfs_data *data = filp->private_data;
- struct rmi_device_platform_data *pdata =
- data->rmi_dev->phys->dev->platform_data;
- int retval;
- char *local_buf;
- unsigned int new_read_delay;
- unsigned int new_write_delay;
- unsigned int new_block_delay;
- unsigned int new_pre_delay;
- unsigned int new_post_delay;
-
- local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
- if (!local_buf)
- return -ENOMEM;
-
- retval = copy_from_user(local_buf, buffer, size);
- if (retval) {
- kfree(local_buf);
- return -EFAULT;
- }
-
- retval = sscanf(local_buf, "%u %u %u %u %u", &new_read_delay,
- &new_write_delay, &new_block_delay,
- &new_pre_delay, &new_post_delay);
- kfree(local_buf);
-
- if (retval != 5) {
- dev_err(&data->rmi_dev->dev,
- "Incorrect number of values provided for delay.");
- return -EINVAL;
- }
- dev_dbg(&data->rmi_dev->dev,
- "Setting delays to %u %u %u %u %u.\n", new_read_delay,
- new_write_delay, new_block_delay, new_pre_delay,
- new_post_delay);
- pdata->spi_data.read_delay_us = new_read_delay;
- pdata->spi_data.write_delay_us = new_write_delay;
- pdata->spi_data.block_delay_us = new_block_delay;
- pdata->spi_data.pre_delay_us = new_pre_delay;
- pdata->spi_data.post_delay_us = new_post_delay;
-
- return size;
-}
-
-static const struct file_operations delay_fops = {
- .owner = THIS_MODULE,
- .open = debug_open,
- .release = debug_release,
- .read = delay_read,
- .write = delay_write,
-};
-
-#define PHYS_NAME "phys"
-
-static ssize_t phys_read(struct file *filp, char __user *buffer, size_t size,
- loff_t *offset) {
- struct driver_debugfs_data *data = filp->private_data;
- struct rmi_phys_info *info = &data->rmi_dev->phys->info;
- int retval;
- char *local_buf;
-
- if (data->done)
- return 0;
-
- local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
- if (!local_buf)
- return -ENOMEM;
-
- data->done = 1;
-
- retval = snprintf(local_buf, size,
- "%-5s %ld %ld %ld %ld %ld %ld\n",
- info->proto ? info->proto : "unk",
- info->tx_count, info->tx_bytes, info->tx_errs,
- info->rx_count, info->rx_bytes, info->rx_errs);
- if (retval <= 0 || copy_to_user(buffer, local_buf, retval))
- retval = -EFAULT;
- kfree(local_buf);
-
- return retval;
-}
-
-static const struct file_operations phys_fops = {
- .owner = THIS_MODULE,
- .open = debug_open,
- .release = debug_release,
- .read = phys_read,
-};
-
-static ssize_t attn_count_read(struct file *filp, char __user *buffer,
- size_t size, loff_t *offset) {
- struct driver_debugfs_data *data = filp->private_data;
- struct rmi_driver_data *rmi_data = dev_get_drvdata(&data->rmi_dev->dev);
- int retval;
- char *local_buf;
-
- if (data->done)
- return 0;
-
- local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
- if (!local_buf)
- return -ENOMEM;
-
- data->done = 1;
-
- retval = snprintf(local_buf, size, "%d\n",
- rmi_data->attn_count.counter);
- if (retval <= 0 || copy_to_user(buffer, local_buf, retval))
- retval = -EFAULT;
- kfree(local_buf);
-
- return retval;
-}
-
-static const struct file_operations attn_count_fops = {
- .owner = THIS_MODULE,
- .open = debug_open,
- .release = debug_release,
- .read = attn_count_read,
-};
-
-static ssize_t irq_debug_read(struct file *filp, char __user *buffer,
- size_t size, loff_t *offset) {
- int retval;
- char *local_buf;
- struct driver_debugfs_data *data = filp->private_data;
- struct rmi_driver_data *rmi_data = dev_get_drvdata(&data->rmi_dev->dev);
-
- if (data->done)
- return 0;
-
- local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
- if (!local_buf)
- return -ENOMEM;
-
- data->done = 1;
-
- retval = snprintf(local_buf, size, "%u\n", rmi_data->irq_debug);
-
- if (retval <= 0 || copy_to_user(buffer, local_buf, retval))
- retval = -EFAULT;
- kfree(local_buf);
-
- return retval;
-}
-
-static ssize_t irq_debug_write(struct file *filp, const char __user *buffer,
- size_t size, loff_t *offset) {
- int retval;
- char *local_buf;
- unsigned int new_value;
- struct driver_debugfs_data *data = filp->private_data;
- struct rmi_driver_data *rmi_data = dev_get_drvdata(&data->rmi_dev->dev);
-
-
- local_buf = kcalloc(size, sizeof(u8), GFP_KERNEL);
- if (!local_buf)
- return -ENOMEM;
- retval = copy_from_user(local_buf, buffer, size);
- if (retval) {
- kfree(local_buf);
- return -EFAULT;
- }
-
- retval = sscanf(local_buf, "%u", &new_value);
- if (retval != 1 || new_value > 1)
- retval = -EINVAL;
- kfree(local_buf);
- rmi_data->irq_debug = new_value;
-
- return size;
-}
-
-static const struct file_operations irq_debug_fops = {
- .owner = THIS_MODULE,
- .open = debug_open,
- .release = debug_release,
- .read = irq_debug_read,
- .write = irq_debug_write,
-};
-
-static int setup_debugfs(struct rmi_device *rmi_dev)
-{
- struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
- struct rmi_phys_info *info = &rmi_dev->phys->info;
- int retval = 0;
-
- if (!rmi_dev->debugfs_root)
- return -ENODEV;
-
- if (IS_ENABLED(CONFIG_RMI4_SPI) && !strncmp("spi", info->proto, 3)) {
- data->debugfs_delay = debugfs_create_file("delay",
- RMI_RW_ATTR, rmi_dev->debugfs_root, rmi_dev,
- &delay_fops);
- if (!data->debugfs_delay || IS_ERR(data->debugfs_delay)) {
- dev_warn(&rmi_dev->dev, "Failed to create debugfs delay.\n");
- data->debugfs_delay = NULL;
- }
- }
-
- data->debugfs_phys = debugfs_create_file(PHYS_NAME, RMI_RO_ATTR,
- rmi_dev->debugfs_root, rmi_dev, &phys_fops);
- if (!data->debugfs_phys || IS_ERR(data->debugfs_phys)) {
- dev_warn(&rmi_dev->dev, "Failed to create debugfs phys.\n");
- data->debugfs_phys = NULL;
- }
-
- data->debugfs_irq = debugfs_create_file("irq_debug",
- RMI_RW_ATTR,
- rmi_dev->debugfs_root,
- rmi_dev, &irq_debug_fops);
- if (!data->debugfs_irq || IS_ERR(data->debugfs_irq)) {
- dev_warn(&rmi_dev->dev, "Failed to create debugfs irq_debug.\n");
- data->debugfs_irq = NULL;
- }
-
- data->debugfs_attn_count = debugfs_create_file("attn_count",
- RMI_RO_ATTR,
- rmi_dev->debugfs_root,
- rmi_dev, &attn_count_fops);
- if (!data->debugfs_phys || IS_ERR(data->debugfs_attn_count)) {
- dev_warn(&rmi_dev->dev, "Failed to create debugfs attn_count.\n");
- data->debugfs_attn_count = NULL;
- }
-
- return retval;
-}
-
-static void teardown_debugfs(struct rmi_device *rmi_dev)
-{
- struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
-
- if (IS_ENABLED(CONFIG_RMI4_SPI) && data->debugfs_delay)
- debugfs_remove(data->debugfs_delay);
- if (data->debugfs_phys)
- debugfs_remove(data->debugfs_phys);
- if (data->debugfs_irq)
- debugfs_remove(data->debugfs_irq);
- if (data->debugfs_attn_count)
- debugfs_remove(data->debugfs_attn_count);
-}
-#else
-#define teardown_debugfs(rmi_dev)
-#define setup_debugfs(rmi_dev) 0
-#endif
-
static irqreturn_t rmi_irq_thread(int irq, void *p)
{
struct rmi_phys_device *phys = p;
@@ -431,7 +113,7 @@ static void disable_polling(struct rmi_device *rmi_dev)
cancel_work_sync(&data->poll_work);
}
-static void disable_sensor(struct rmi_device *rmi_dev)
+void disable_sensor(struct rmi_device *rmi_dev)
{
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
@@ -452,7 +134,7 @@ static void disable_sensor(struct rmi_device *rmi_dev)
data->enabled = false;
}
-static int enable_sensor(struct rmi_device *rmi_dev)
+int enable_sensor(struct rmi_device *rmi_dev)
{
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
struct rmi_phys_device *rmi_phys;
@@ -493,108 +175,9 @@ static int enable_sensor(struct rmi_device *rmi_dev)
return retval;
}
-/* sysfs show and store fns for driver attributes */
-
-static ssize_t rmi_driver_bsr_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct rmi_device *rmi_dev;
- struct rmi_driver_data *data;
- rmi_dev = to_rmi_device(dev);
- data = dev_get_drvdata(&rmi_dev->dev);
-
- return snprintf(buf, PAGE_SIZE, "%u\n", data->bsr);
-}
-
-static ssize_t rmi_driver_bsr_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int retval;
- unsigned long val;
- struct rmi_device *rmi_dev;
- struct rmi_driver_data *data;
-
- rmi_dev = to_rmi_device(dev);
- data = dev_get_drvdata(&rmi_dev->dev);
-
- /* need to convert the string data to an actual value */
- retval = strict_strtoul(buf, 10, &val);
- if (retval < 0 || val > 255) {
- dev_err(dev, "Invalid value '%s' written to BSR.\n", buf);
- return -EINVAL;
- }
-
- retval = rmi_write(rmi_dev, BSR_LOCATION, (u8)val);
- if (retval < 0) {
- dev_err(dev, "%s : failed to write bsr %lu to %#06x\n",
- __func__, val, BSR_LOCATION);
- return retval;
- }
-
- data->bsr = val;
-
- return count;
-}
-
-static ssize_t rmi_driver_enabled_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct rmi_device *rmi_dev;
- struct rmi_driver_data *data;
-
- rmi_dev = to_rmi_device(dev);
- data = dev_get_drvdata(&rmi_dev->dev);
-
- return snprintf(buf, PAGE_SIZE, "%u\n", data->enabled);
-}
-
-static ssize_t rmi_driver_enabled_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int retval;
- int new_value;
- struct rmi_device *rmi_dev;
- struct rmi_driver_data *data;
-
- rmi_dev = to_rmi_device(dev);
- data = dev_get_drvdata(&rmi_dev->dev);
-
- if (sysfs_streq(buf, "0"))
- new_value = false;
- else if (sysfs_streq(buf, "1"))
- new_value = true;
- else
- return -EINVAL;
-
- if (new_value) {
- retval = enable_sensor(rmi_dev);
- if (retval) {
- dev_err(dev, "Failed to enable sensor, code=%d.\n",
- retval);
- return -EIO;
- }
- } else {
- disable_sensor(rmi_dev);
- }
-
- return count;
-}
-
-/** This sysfs attribute is deprecated, and will be removed in a future release.
- */
-static struct device_attribute attrs[] = {
- __ATTR(enabled, RMI_RW_ATTR,
- rmi_driver_enabled_show, rmi_driver_enabled_store),
-};
-
-static struct device_attribute bsr_attribute = __ATTR(bsr, RMI_RW_ATTR,
- rmi_driver_bsr_show, rmi_driver_bsr_store);
-
static void rmi_free_function_list(struct rmi_device *rmi_dev)
{
- struct rmi_function *entry, *n;
+ struct rmi_function_dev *entry, *n;
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
if (!data) {
@@ -602,7 +185,7 @@ static void rmi_free_function_list(struct rmi_device *rmi_dev)
return;
}
- data->f01_container = NULL;
+ data->f01_dev = NULL;
if (list_empty(&data->rmi_functions.list))
return;
@@ -613,44 +196,43 @@ static void rmi_free_function_list(struct rmi_device *rmi_dev)
}
}
-static void release_function_device(struct device *dev)
+static void release_fndev_device(struct device *dev)
{
- dev_dbg(dev, "REMOVING KOBJ!");
kobject_put(&dev->kobj);
}
-static int reset_one_function(struct rmi_function *fn)
+static int reset_one_function(struct rmi_function_dev *fn_dev)
{
- struct rmi_function_handler *fh;
+ struct rmi_function_driver *fn_drv;
int retval = 0;
- if (!fn || !fn->dev.driver)
+ if (!fn_dev || !fn_dev->dev.driver)
return 0;
- fh = to_rmi_function_handler(fn->dev.driver);
- if (fh->reset) {
- retval = fh->reset(fn);
+ fn_drv = to_rmi_function_driver(fn_dev->dev.driver);
+ if (fn_drv->reset) {
+ retval = fn_drv->reset(fn_dev);
if (retval < 0)
- dev_err(&fn->dev, "Reset failed with code %d.\n",
+ dev_err(&fn_dev->dev, "Reset failed with code %d.\n",
retval);
}
return retval;
}
-static int configure_one_function(struct rmi_function *fn)
+static int configure_one_function(struct rmi_function_dev *fn_dev)
{
- struct rmi_function_handler *fh;
+ struct rmi_function_driver *fn_drv;
int retval = 0;
- if (!fn || !fn->dev.driver)
+ if (!fn_dev || !fn_dev->dev.driver)
return 0;
- fh = to_rmi_function_handler(fn->dev.driver);
- if (fh->config) {
- retval = fh->config(fn);
+ fn_drv = to_rmi_function_driver(fn_dev->dev.driver);
+ if (fn_drv->config) {
+ retval = fn_drv->config(fn_dev);
if (retval < 0)
- dev_err(&fn->dev, "Config failed with code %d.\n",
+ dev_err(&fn_dev->dev, "Config failed with code %d.\n",
retval);
}
@@ -660,7 +242,7 @@ static int configure_one_function(struct rmi_function *fn)
static int rmi_driver_process_reset_requests(struct rmi_device *rmi_dev)
{
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
- struct rmi_function *entry;
+ struct rmi_function_dev *entry;
int retval;
if (list_empty(&data->rmi_functions.list))
@@ -678,7 +260,7 @@ static int rmi_driver_process_reset_requests(struct rmi_device *rmi_dev)
static int rmi_driver_process_config_requests(struct rmi_device *rmi_dev)
{
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
- struct rmi_function *entry;
+ struct rmi_function_dev *entry;
int retval;
if (list_empty(&data->rmi_functions.list))
@@ -693,21 +275,21 @@ static int rmi_driver_process_config_requests(struct rmi_device *rmi_dev)
return 0;
}
-static void process_one_interrupt(struct rmi_function *fn,
+static void process_one_interrupt(struct rmi_function_dev *fn_dev,
unsigned long *irq_status, struct rmi_driver_data *data)
{
- struct rmi_function_handler *fh;
+ struct rmi_function_driver *fn_drv;
DECLARE_BITMAP(irq_bits, data->num_of_irq_regs);
- if (!fn || !fn->dev.driver)
+ if (!fn_dev || !fn_dev->dev.driver)
return;
- fh = to_rmi_function_handler(fn->dev.driver);
- if (fn->irq_mask && fh->attention) {
- bitmap_and(irq_bits, irq_status, fn->irq_mask,
+ fn_drv = to_rmi_function_driver(fn_dev->dev.driver);
+ if (fn_dev->irq_mask && fn_drv->attention) {
+ bitmap_and(irq_bits, irq_status, fn_dev->irq_mask,
data->irq_count);
if (!bitmap_empty(irq_bits, data->irq_count))
- fh->attention(fn, irq_bits);
+ fn_drv->attention(fn_dev, irq_bits);
}
}
@@ -715,11 +297,11 @@ static int process_interrupt_requests(struct rmi_device *rmi_dev)
{
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
struct device *dev = &rmi_dev->dev;
- struct rmi_function *entry;
+ struct rmi_function_dev *entry;
int error;
error = rmi_read_block(rmi_dev,
- data->f01_container->fd.data_base_addr + 1,
+ data->f01_dev->fd.data_base_addr + 1,
data->irq_status, data->num_of_irq_regs);
if (error < 0) {
dev_err(dev, "Failed to read irqs, code=%d\n", error);
@@ -743,8 +325,7 @@ static int process_interrupt_requests(struct rmi_device *rmi_dev)
*/
list_for_each_entry(entry, &data->rmi_functions.list, list) {
if (entry->irq_mask)
- process_one_interrupt(entry, data->irq_status,
- data);
+ process_one_interrupt(entry, data->irq_status, data);
}
return 0;
@@ -786,7 +367,7 @@ static int rmi_driver_irq_save(struct rmi_device *rmi_dev,
if (!data->irq_stored) {
/* Save current enabled interrupts */
retval = rmi_read_block(rmi_dev,
- data->f01_container->fd.control_base_addr+1,
+ data->f01_dev->fd.control_base_addr+1,
data->irq_mask_store, data->num_of_irq_regs);
if (retval < 0) {
dev_err(dev, "%s: Failed to read enabled interrupts!",
@@ -800,7 +381,7 @@ static int rmi_driver_irq_save(struct rmi_device *rmi_dev,
* to identify them.
*/
retval = rmi_write_block(rmi_dev,
- data->f01_container->fd.control_base_addr+1,
+ data->f01_dev->fd.control_base_addr+1,
new_ints, data->num_of_irq_regs);
if (retval < 0) {
dev_err(dev, "%s: Failed to change enabled interrupts!",
@@ -829,7 +410,7 @@ static int rmi_driver_irq_restore(struct rmi_device *rmi_dev)
if (data->irq_stored) {
retval = rmi_write_block(rmi_dev,
- data->f01_container->fd.control_base_addr+1,
+ data->f01_dev->fd.control_base_addr+1,
data->irq_mask_store, data->num_of_irq_regs);
if (retval < 0) {
dev_err(dev, "%s: Failed to write enabled interupts!",
@@ -858,7 +439,7 @@ static int rmi_driver_irq_handler(struct rmi_device *rmi_dev, int irq)
/* Can get called before the driver is fully ready to deal with
* interrupts.
*/
- if (!data || !data->f01_container) {
+ if (!data || !data->f01_dev) {
dev_dbg(&rmi_dev->dev,
"Not ready to handle interrupts yet!\n");
return 0;
@@ -875,7 +456,7 @@ static int rmi_driver_reset_handler(struct rmi_device *rmi_dev)
/* Can get called before the driver is fully ready to deal with
* this situation.
*/
- if (!data || !data->f01_container) {
+ if (!data || !data->f01_dev) {
dev_warn(&rmi_dev->dev,
"Not ready to handle reset yet!\n");
return 0;
@@ -903,65 +484,66 @@ static int rmi_driver_reset_handler(struct rmi_device *rmi_dev)
* Construct a function's IRQ mask. This should be called once and stored.
*/
int rmi_driver_irq_get_mask(struct rmi_device *rmi_dev,
- struct rmi_function *fn) {
+ struct rmi_function_dev *fn_dev) {
int i;
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
/* call devm_kcalloc when it will be defined in kernel in future */
- fn->irq_mask = devm_kzalloc(&rmi_dev->dev,
+ fn_dev->irq_mask = devm_kzalloc(&rmi_dev->dev,
BITS_TO_LONGS(data->irq_count)*sizeof(unsigned long),
GFP_KERNEL);
- if (fn->irq_mask) {
- for (i = 0; i < fn->num_of_irqs; i++)
- set_bit(fn->irq_pos+i, fn->irq_mask);
- return 0;
- } else
+ if (!fn_dev->irq_mask)
return -ENOMEM;
+
+ for (i = 0; i < fn_dev->num_of_irqs; i++)
+ set_bit(fn_dev->irq_pos+i, fn_dev->irq_mask);
+ return 0;
}
static int init_function_device(struct rmi_device *rmi_dev,
- struct rmi_function *fn)
+ struct rmi_function_dev *fn_dev)
{
int retval;
/* This memset might not be what we want to do... */
- memset(&fn->dev, 0, sizeof(struct device));
- dev_set_name(&fn->dev, "%s.fn%02x", dev_name(&rmi_dev->dev),
- fn->fd.function_number);
- fn->dev.release = release_function_device;
-
- fn->dev.parent = &rmi_dev->dev;
- fn->dev.type = &rmi_function_type;
- fn->dev.bus = &rmi_bus_type;
- dev_dbg(&rmi_dev->dev, "Register F%02X.\n", fn->fd.function_number);
- retval = device_register(&fn->dev);
- if (retval) {
- dev_err(&rmi_dev->dev, "Failed device_register for F%02X.\n",
- fn->fd.function_number);
- return retval;
- }
+ memset(&(fn_dev->dev), 0, sizeof(struct device));
+ dev_set_name(&(fn_dev->dev), "%s.fn%02x", dev_name(&rmi_dev->dev),
+ fn_dev->fd.function_number);
+ fn_dev->dev.release = release_fndev_device;
+
+ fn_dev->dev.parent = &rmi_dev->dev;
+ fn_dev->dev.type = &rmi_function_type;
+ fn_dev->dev.bus = &rmi_bus_type;
if (IS_ENABLED(CONFIG_RMI4_DEBUG)) {
char dirname[12];
- snprintf(dirname, 12, "F%02X", fn->fd.function_number);
- fn->debugfs_root = debugfs_create_dir(dirname,
+ snprintf(dirname, 12, "F%02X", fn_dev->fd.function_number);
+ fn_dev->debugfs_root = debugfs_create_dir(dirname,
rmi_dev->debugfs_root);
- if (!fn->debugfs_root)
- dev_warn(&fn->dev, "Failed to create debugfs dir.\n");
+ if (!fn_dev->debugfs_root)
+ dev_warn(&fn_dev->dev, "Failed to create debugfs dir.\n");
+ }
+
+ dev_dbg(&rmi_dev->dev, "Register F%02X.\n", fn_dev->fd.function_number);
+ retval = device_register(&fn_dev->dev);
+ if (retval) {
+ dev_err(&rmi_dev->dev, "Failed device_register for F%02X.\n",
+ fn_dev->fd.function_number);
+ return retval;
}
return 0;
}
-static int create_function(struct rmi_device *rmi_dev,
+static int create_function_dev(struct rmi_device *rmi_dev,
struct pdt_entry *pdt_ptr,
int *current_irq_count,
u16 page_start)
{
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
- struct rmi_function *fn = NULL;
+ struct rmi_function_dev *fn_dev = NULL;
int retval = 0;
struct device *dev = &rmi_dev->dev;
struct rmi_device_platform_data *pdata;
@@ -971,41 +553,45 @@ static int create_function(struct rmi_device *rmi_dev,
dev_dbg(dev, "Initializing F%02X for %s.\n", pdt_ptr->function_number,
pdata->sensor_name);
- fn = devm_kzalloc(dev, sizeof(struct rmi_function),
+ fn_dev = devm_kzalloc(dev, sizeof(struct rmi_function_dev),
GFP_KERNEL);
- if (!fn) {
- dev_err(dev, "Failed to allocate F%02X container.\n",
+ if (!fn_dev) {
+ dev_err(dev, "Failed to allocate F%02X device.\n",
pdt_ptr->function_number);
return -ENOMEM;
}
- copy_pdt_entry_to_fd(pdt_ptr, &fn->fd, page_start);
+ copy_pdt_entry_to_fd(pdt_ptr, &fn_dev->fd, page_start);
- fn->rmi_dev = rmi_dev;
- fn->num_of_irqs = pdt_ptr->interrupt_source_count;
+ fn_dev->rmi_dev = rmi_dev;
+ fn_dev->num_of_irqs = pdt_ptr->interrupt_source_count;
+ fn_dev->irq_pos = *current_irq_count;
+ *current_irq_count += fn_dev->num_of_irqs;
- fn->irq_pos = *current_irq_count;
- *current_irq_count += fn->num_of_irqs;
+ retval = rmi_driver_irq_get_mask(rmi_dev, fn_dev);
+ if (retval < 0) {
+ dev_err(dev, "%s: Failed to create irq_mask for F%02X.\n",
+ __func__, pdt_ptr->function_number);
+ return retval;
+ }
- retval = init_function_device(rmi_dev, fn);
+ retval = init_function_device(rmi_dev, fn_dev);
if (retval < 0) {
dev_err(dev, "Failed to initialize F%02X device.\n",
pdt_ptr->function_number);
- goto error_free_data;
+ return retval;
}
- INIT_LIST_HEAD(&fn->list);
+ INIT_LIST_HEAD(&fn_dev->list);
/* we need to ensure that F01 is at the head of the list.
*/
if (pdt_ptr->function_number == 0x01) {
- list_add(&fn->list, &data->rmi_functions.list);
- data->f01_container = fn;
+ list_add(&fn_dev->list, &data->rmi_functions.list);
+ data->f01_dev = fn_dev;
} else
- list_add_tail(&fn->list, &data->rmi_functions.list);
- return 0;
+ list_add_tail(&fn_dev->list, &data->rmi_functions.list);
-error_free_data:
- return retval;
+ return 0;
}
/*
@@ -1031,41 +617,107 @@ static void check_bootloader_mode(struct rmi_device *rmi_dev,
if (device_status.flash_prog)
dev_warn(&rmi_dev->dev,
"WARNING: RMI4 device is in bootloader mode!\n");
+
}
/*
- * Scan the PDT for F01 so we can force a reset before anything else
- * is done. This forces the sensor into a known state, and also
- * forces application of any pending updates from reflashing the
- * firmware or configuration.
- *
- * At this time, we also reflash the device if (a) in kernel reflashing is
+ * We also reflash the device if (a) in kernel reflashing is
* enabled, and (b) the reflash module decides it requires reflashing.
*
* We have to do this before actually building the PDT because the reflash
* might cause various registers to move around.
*/
-static int reset_and_reflash(struct rmi_device *rmi_dev)
+static int rmi_device_reflash(struct rmi_device *rmi_dev)
{
struct pdt_entry pdt_entry;
int page;
struct device *dev = &rmi_dev->dev;
- bool done = false;
+ bool done;
bool has_f01 = false;
bool has_f34 = false;
struct pdt_entry f34_pdt, f01_pdt;
int i;
int retval;
struct rmi_device_platform_data *pdata;
+ struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
- dev_dbg(dev, "Initial reset.\n");
+ dev_dbg(dev, "Initial reflash.\n");
pdata = to_rmi_platform_data(rmi_dev);
- for (page = 0; (page <= RMI4_MAX_PAGE) && !done; page++) {
+ data->f01_bootloader_mode = false;
+ for (page = 0; (page <= RMI4_MAX_PAGE); page++) {
u16 page_start = RMI4_PAGE_SIZE * page;
u16 pdt_start = page_start + PDT_START_SCAN_LOCATION;
u16 pdt_end = page_start + PDT_END_SCAN_LOCATION;
+ done = true;
+ for (i = pdt_start; i >= pdt_end ; i -= sizeof(pdt_entry)) {
+ retval = rmi_read_block(rmi_dev, i, &pdt_entry,
+ sizeof(pdt_entry));
+ if (retval != sizeof(pdt_entry)) {
+ dev_err(dev, "Read PDT entry at %#06x failed, code = %d.\n",
+ i, retval);
+ return retval;
+ }
+
+ if (RMI4_END_OF_PDT(pdt_entry.function_number))
+ break;
+ done = false;
+ if (pdt_entry.function_number == 0x01) {
+ memcpy(&f01_pdt, &pdt_entry, sizeof(pdt_entry));
+ has_f01 = true;
+ check_bootloader_mode(rmi_dev, &pdt_entry,
+ page_start);
+ } else if (pdt_entry.function_number == 0x34) {
+ memcpy(&f34_pdt, &pdt_entry, sizeof(pdt_entry));
+ has_f34 = true;
+ }
+
+ if (has_f01 && has_f34) {
+ done = true;
+ break;
+ }
+ }
+
+ if (data->f01_bootloader_mode || done)
+ break;
+ }
+
+ if (!has_f01) {
+ dev_warn(dev, "WARNING: Failed to find F01 for initial reflash.\n");
+ return -ENODEV;
+ }
+
+ if (has_f34)
+ rmi4_fw_update(rmi_dev, &f01_pdt, &f34_pdt);
+ else
+ dev_warn(dev, "WARNING: No F34 , firmware update will not be done.\n");
+ return 0;
+}
+/*
+ * Scan the PDT for F01 so we can force a reset before anything else
+ * is done. This forces the sensor into a known state, and also
+ * forces application of any pending updates from reflashing the
+ * firmware or configuration.
+ *
+ */
+static int rmi_device_reset(struct rmi_device *rmi_dev)
+{
+ struct pdt_entry pdt_entry;
+ int page;
+ struct device *dev = &rmi_dev->dev;
+ int i;
+ int retval;
+ bool done = false;
+ struct rmi_device_platform_data *pdata;
+
+ dev_dbg(dev, "Initial reset.\n");
+ pdata = to_rmi_platform_data(rmi_dev);
+ for (page = 0; (page <= RMI4_MAX_PAGE) && !done; page++) {
+ u16 page_start = RMI4_PAGE_SIZE * page;
+ u16 pdt_start = page_start + PDT_START_SCAN_LOCATION;
+ u16 pdt_end = page_start + PDT_END_SCAN_LOCATION;
done = true;
+
for (i = pdt_start; i >= pdt_end; i -= sizeof(pdt_entry)) {
retval = rmi_read_block(rmi_dev, i, &pdt_entry,
sizeof(pdt_entry));
@@ -1091,39 +743,16 @@ static int reset_and_reflash(struct rmi_device *rmi_dev)
return retval;
}
mdelay(pdata->reset_delay_ms);
- if (IS_ENABLED(CONFIG_RMI4_FWLIB))
- memcpy(&f01_pdt, &pdt_entry,
- sizeof(pdt_entry));
- else
- done = true;
- has_f01 = true;
- break;
- } else if (IS_ENABLED(CONFIG_RMI4_FWLIB) &&
- pdt_entry.function_number == 0x34) {
- memcpy(&f34_pdt, &pdt_entry, sizeof(pdt_entry));
- has_f34 = true;
+ return 0;
}
}
}
- if (!has_f01) {
- dev_warn(dev, "WARNING: Failed to find F01 for initial reset.\n");
- return -ENODEV;
- }
-
- if (IS_ENABLED(CONFIG_RMI4_FWLIB)) {
- if (has_f34)
- rmi4_fw_update(rmi_dev, &f01_pdt, &f34_pdt);
- else
- dev_warn(dev, "WARNING: No F34, firmware update will not be done.\n");
- }
-
- return 0;
+ return -ENODEV;
}
-
-/* extract product ID */
-void get_prod_id(struct rmi_device *rmi_dev, struct rmi_driver_data *drvdata)
+static void get_prod_id(struct rmi_device *rmi_dev,
+ struct rmi_driver_data *drvdata)
{
struct device *dev = &rmi_dev->dev;
int retval;
@@ -1134,7 +763,7 @@ void get_prod_id(struct rmi_device *rmi_dev, struct rmi_driver_data *drvdata)
u8 product_id[RMI_PRODUCT_ID_LENGTH+1];
retval = rmi_read_block(rmi_dev,
- drvdata->f01_container->fd.query_base_addr+
+ drvdata->f01_dev->fd.query_base_addr+
sizeof(struct f01_basic_queries),
product_id, RMI_PRODUCT_ID_LENGTH);
if (retval < 0) {
@@ -1146,7 +775,7 @@ void get_prod_id(struct rmi_device *rmi_dev, struct rmi_driver_data *drvdata)
for (i = 0; i < sizeof(product_id); i++)
product_id[i] = tolower(product_id[i]);
- for (i = 0; i < sizeof(pattern); i++) {
+ for (i = 0; i < ARRAY_SIZE(pattern); i++) {
retval = sscanf(product_id, pattern[i], &board, &rev);
if (retval)
break;
@@ -1158,6 +787,55 @@ void get_prod_id(struct rmi_device *rmi_dev, struct rmi_driver_data *drvdata)
drvdata->board, drvdata->rev);
}
+static int rmi_count_irqs(struct rmi_device *rmi_dev)
+{
+ struct rmi_driver_data *data;
+ struct pdt_entry pdt_entry;
+ int page;
+ struct device *dev = &rmi_dev->dev;
+ int irq_count = 0;
+ bool done = false;
+ int i;
+ int retval;
+
+ data = dev_get_drvdata(&rmi_dev->dev);
+ mutex_lock(&data->pdt_mutex);
+
+ for (page = 0; (page <= RMI4_MAX_PAGE) && !done; page++) {
+ u16 page_start = RMI4_PAGE_SIZE * page;
+ u16 pdt_start = page_start + PDT_START_SCAN_LOCATION;
+ u16 pdt_end = page_start + PDT_END_SCAN_LOCATION;
+
+ done = true;
+ for (i = pdt_start; i >= pdt_end; i -= sizeof(pdt_entry)) {
+ retval = rmi_read_block(rmi_dev, i, &pdt_entry,
+ sizeof(pdt_entry));
+ if (retval != sizeof(pdt_entry)) {
+ dev_err(dev, "Read of PDT entry at %#06x failed.\n",
+ i);
+ goto error_exit;
+ }
+
+ if (RMI4_END_OF_PDT(pdt_entry.function_number))
+ break;
+ irq_count += pdt_entry.interrupt_source_count;
+ done = false;
+
+ if (pdt_entry.function_number == 0x01)
+ check_bootloader_mode(rmi_dev, &pdt_entry,
+ page_start);
+ }
+ done = done || data->f01_bootloader_mode;
+ }
+ data->irq_count = irq_count;
+ data->num_of_irq_regs = (irq_count + 7) / 8;
+ retval = 0;
+
+error_exit:
+ mutex_unlock(&data->pdt_mutex);
+ return retval;
+}
+
static int rmi_scan_pdt(struct rmi_device *rmi_dev)
{
struct rmi_driver_data *data;
@@ -1201,7 +879,7 @@ static int rmi_scan_pdt(struct rmi_device *rmi_dev)
page_start);
- retval = create_function(rmi_dev,
+ retval = create_function_dev(rmi_dev,
&pdt_entry, &irq_count, page_start);
if (retval)
@@ -1212,8 +890,6 @@ static int rmi_scan_pdt(struct rmi_device *rmi_dev)
}
done = done || data->f01_bootloader_mode;
}
- data->irq_count = irq_count;
- data->num_of_irq_regs = (irq_count + 7) / 8;
dev_dbg(dev, "%s: Done with PDT scan.\n", __func__);
retval = 0;
@@ -1226,23 +902,21 @@ static int f01_notifier_call(struct notifier_block *nb,
unsigned long action, void *data)
{
struct device *dev = data;
- struct rmi_function *fn;
+ struct rmi_function_dev *fn_dev;
if (dev->type != &rmi_function_type)
return 0;
- fn = to_rmi_function(dev);
- if (fn->fd.function_number != 0x01)
+ fn_dev = to_rmi_function_dev(dev);
+ if (fn_dev->fd.function_number != 0x01)
return 0;
switch (action) {
case BUS_NOTIFY_BOUND_DRIVER:
- dev_dbg(dev, "%s: F01 driver bound.\n", __func__);
- enable_sensor(fn->rmi_dev);
+ enable_sensor(fn_dev->rmi_dev);
break;
case BUS_NOTIFY_UNBIND_DRIVER:
- dev_dbg(dev, "%s: F01 driver going away.\n", __func__);
- disable_sensor(fn->rmi_dev);
+ disable_sensor(fn_dev->rmi_dev);
break;
}
return 0;
@@ -1253,20 +927,20 @@ static struct notifier_block rmi_bus_notifier = {
};
#ifdef CONFIG_PM
-static int suspend_one_device(struct rmi_function *fn)
+static int suspend_one_device(struct rmi_function_dev *fn_dev)
{
- struct rmi_function_handler *fh;
+ struct rmi_function_driver *fn_drv;
int retval = 0;
- if (!fn->dev.driver)
+ if (!fn_dev->dev.driver)
return 0;
- fh = to_rmi_function_handler(fn->dev.driver);
+ fn_drv = to_rmi_function_driver(fn_dev->dev.driver);
- if (fh->suspend) {
- retval = fh->suspend(fn);
+ if (fn_drv->suspend) {
+ retval = fn_drv->suspend(fn_dev);
if (retval < 0)
- dev_err(&fn->dev, "Suspend failed, code: %d",
+ dev_err(&fn_dev->dev, "Suspend failed, code: %d",
retval);
}
@@ -1276,7 +950,7 @@ static int suspend_one_device(struct rmi_function *fn)
static int rmi_driver_suspend(struct device *dev)
{
struct rmi_driver_data *data;
- struct rmi_function *entry;
+ struct rmi_function_dev *entry;
int retval = 0;
struct rmi_device *rmi_dev = to_rmi_device(dev);
@@ -1309,20 +983,20 @@ exit:
return retval;
}
-static int resume_one_device(struct rmi_function *fn)
+static int resume_one_device(struct rmi_function_dev *fn_dev)
{
- struct rmi_function_handler *fh;
+ struct rmi_function_driver *fn_drv;
int retval = 0;
- if (!fn->dev.driver)
+ if (!fn_dev->dev.driver)
return 0;
- fh = to_rmi_function_handler(fn->dev.driver);
+ fn_drv = to_rmi_function_driver(fn_dev->dev.driver);
- if (fh->resume) {
- retval = fh->resume(fn);
+ if (fn_drv->resume) {
+ retval = fn_drv->resume(fn_dev);
if (retval < 0)
- dev_err(&fn->dev, "Resume failed, code: %d",
+ dev_err(&fn_dev->dev, "Resume failed, code: %d",
retval);
}
@@ -1332,7 +1006,7 @@ static int resume_one_device(struct rmi_function *fn)
static int rmi_driver_resume(struct device *dev)
{
struct rmi_driver_data *data;
- struct rmi_function *entry;
+ struct rmi_function_dev *entry;
int retval = 0;
struct rmi_device *rmi_dev = to_rmi_device(dev);
@@ -1357,7 +1031,6 @@ static int rmi_driver_resume(struct device *dev)
if (retval)
goto exit;
-
if (data->post_resume) {
retval = data->post_resume(data->pm_data);
if (retval)
@@ -1372,24 +1045,12 @@ exit:
#endif /* CONFIG_PM */
-static int __devexit rmi_driver_remove(struct device *dev)
+static int rmi_driver_remove(struct rmi_device *rmi_dev)
{
- struct rmi_driver_data *data;
- int i;
- struct rmi_device *rmi_dev = to_rmi_device(dev);
-
- data = dev_get_drvdata(&rmi_dev->dev);
-
disable_sensor(rmi_dev);
- if (IS_ENABLED(CONFIG_RMI4_DEBUG))
- teardown_debugfs(rmi_dev);
rmi_free_function_list(rmi_dev);
- for (i = 0; i < ARRAY_SIZE(attrs); i++)
- device_remove_file(&rmi_dev->dev, &attrs[i]);
- if (data->pdt_props.has_bsr)
- device_remove_file(&rmi_dev->dev, &bsr_attribute);
return 0;
}
@@ -1397,22 +1058,17 @@ static int __devinit rmi_driver_probe(struct device *dev)
{
struct rmi_driver *rmi_driver;
struct rmi_driver_data *data = NULL;
- struct rmi_function *fn;
struct rmi_device_platform_data *pdata;
int retval = 0;
- int attr_count = 0;
struct rmi_device *rmi_dev;
- dev_dbg(dev, "%s: Starting probe.\n", __func__);
if (!dev->driver) {
dev_err(dev, "No driver for RMI4 device during probe!\n");
return -ENODEV;
}
- if (dev->type != &rmi_sensor_type) {
- dev_dbg(dev, "Not a sensor device.\n");
- return 1;
- }
+ if (dev->type != &rmi_sensor_type)
+ return -ENODEV;
rmi_dev = to_rmi_device(dev);
rmi_driver = to_rmi_driver(dev->driver);
@@ -1447,32 +1103,13 @@ static int __devinit rmi_driver_probe(struct device *dev)
*/
if (!pdata->reset_delay_ms)
pdata->reset_delay_ms = DEFAULT_RESET_DELAY_MS;
- retval = reset_and_reflash(rmi_dev);
+ retval = rmi_device_reset(rmi_dev);
if (retval)
dev_warn(dev, "RMI initial reset failed! Continuing in spite of this.\n");
-
- retval = rmi_scan_pdt(rmi_dev);
- if (retval) {
- dev_err(dev, "PDT scan for %s failed with code %d.\n",
- pdata->sensor_name, retval);
- goto err_free_data;
- }
-
- if (!data->f01_container) {
- dev_err(dev, "missing F01 container!\n");
- retval = -EINVAL;
- goto err_free_data;
- }
-
- list_for_each_entry(fn, &data->rmi_functions.list, list) {
- retval = rmi_driver_irq_get_mask(rmi_dev, fn);
- if (retval < 0) {
- dev_err(dev, "%s: Failed to create irq_mask.\n",
- __func__);
- goto err_free_data;
- }
- }
+ retval = rmi_device_reflash(rmi_dev);
+ if (retval)
+ dev_warn(dev, "RMI reflash failed! Continuing in spite of this.\n");
retval = rmi_read(rmi_dev, PDT_PROPERTIES_LOCATION, &data->pdt_props);
if (retval < 0) {
@@ -1483,22 +1120,29 @@ static int __devinit rmi_driver_probe(struct device *dev)
PDT_PROPERTIES_LOCATION);
}
- dev_dbg(dev, "%s: Creating sysfs files.", __func__);
- for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
- retval = device_create_file(dev, &attrs[attr_count]);
- if (retval < 0) {
- dev_err(dev, "%s: Failed to create sysfs file %s.\n",
- __func__, attrs[attr_count].attr.name);
- goto err_free_data;
- }
- }
- if (data->pdt_props.has_bsr) {
- retval = device_create_file(dev, &bsr_attribute);
- if (retval < 0) {
- dev_err(dev, "%s: Failed to create sysfs file bsr.\n",
- __func__);
- goto err_free_data;
+ if (pdata->attn_gpio) {
+ data->irq = gpio_to_irq(pdata->attn_gpio);
+ if (pdata->level_triggered) {
+ data->irq_flags = IRQF_ONESHOT |
+ ((pdata->attn_polarity == RMI_ATTN_ACTIVE_HIGH)
+ ? IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW);
+ } else {
+ data->irq_flags =
+ (pdata->attn_polarity == RMI_ATTN_ACTIVE_HIGH)
+ ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
}
+ dev_dbg(dev, "Mapped IRQ %d for GPIO %d.\n",
+ data->irq, pdata->attn_gpio);
+ } else
+ data->poll_interval = ktime_set(0,
+ (pdata->poll_interval_ms ? pdata->poll_interval_ms :
+ DEFAULT_POLL_INTERVAL_MS) * 1000);
+
+ retval = rmi_count_irqs(rmi_dev);
+ if (retval) {
+ dev_err(dev, "IRQ counting for %s failed with code %d.\n",
+ pdata->sensor_name, retval);
+ goto err_free_data;
}
mutex_init(&data->irq_mutex);
@@ -1511,8 +1155,7 @@ static int __devinit rmi_driver_probe(struct device *dev)
goto err_free_data;
}
- data->current_irq_mask = devm_kzalloc(dev,
- data->num_of_irq_regs,
+ data->current_irq_mask = devm_kzalloc(dev, data->num_of_irq_regs,
GFP_KERNEL);
if (!data->current_irq_mask) {
dev_err(dev, "Failed to allocate current_irq_mask.\n");
@@ -1520,15 +1163,6 @@ static int __devinit rmi_driver_probe(struct device *dev)
goto err_free_data;
}
- retval = rmi_read_block(rmi_dev,
- data->f01_container->fd.control_base_addr+1,
- data->current_irq_mask, data->num_of_irq_regs);
- if (retval < 0) {
- dev_err(dev, "%s: Failed to read current IRQ mask.\n",
- __func__);
- goto err_free_data;
- }
-
data->irq_mask_store = devm_kzalloc(dev,
BITS_TO_LONGS(data->irq_count)*sizeof(unsigned long),
GFP_KERNEL);
@@ -1537,6 +1171,29 @@ static int __devinit rmi_driver_probe(struct device *dev)
retval = -ENOMEM;
goto err_free_data;
}
+
+ retval = rmi_scan_pdt(rmi_dev);
+ if (retval) {
+ dev_err(dev, "PDT scan for %s failed with code %d.\n",
+ pdata->sensor_name, retval);
+ goto err_free_data;
+ }
+
+ if (!data->f01_dev) {
+ dev_err(dev, "missing F01 device!\n");
+ retval = -EINVAL;
+ goto err_free_data;
+ }
+
+ retval = rmi_read_block(rmi_dev,
+ data->f01_dev->fd.control_base_addr+1,
+ data->current_irq_mask, data->num_of_irq_regs);
+ if (retval < 0) {
+ dev_err(dev, "%s: Failed to read current IRQ mask.\n",
+ __func__);
+ goto err_free_data;
+ }
+
if (IS_ENABLED(CONFIG_PM)) {
data->pm_data = pdata->pm_data;
data->pre_suspend = pdata->pre_suspend;
@@ -1547,34 +1204,11 @@ static int __devinit rmi_driver_probe(struct device *dev)
mutex_init(&data->suspend_mutex);
}
- if (pdata->attn_gpio) {
- data->irq = gpio_to_irq(pdata->attn_gpio);
- if (pdata->level_triggered) {
- data->irq_flags = IRQF_ONESHOT |
- ((pdata->attn_polarity == RMI_ATTN_ACTIVE_HIGH)
- ? IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW);
- } else {
- data->irq_flags =
- (pdata->attn_polarity == RMI_ATTN_ACTIVE_HIGH)
- ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
- }
- } else
- data->poll_interval = ktime_set(0,
- (pdata->poll_interval_ms ? pdata->poll_interval_ms :
- DEFAULT_POLL_INTERVAL_MS) * 1000);
-
- if (data->f01_container->dev.driver) {
+ if (data->f01_dev->dev.driver) {
/* Driver already bound, so enable ATTN now. */
enable_sensor(rmi_dev);
}
- if (IS_ENABLED(CONFIG_RMI4_DEBUG)) {
- retval = setup_debugfs(rmi_dev);
- if (retval < 0)
- dev_warn(&fn->dev, "Failed to setup debugfs. Code: %d.\n",
- retval);
- }
-
if (IS_ENABLED(CONFIG_RMI4_DEV) && pdata->attn_gpio) {
retval = gpio_export(pdata->attn_gpio, false);
if (retval) {
@@ -1598,10 +1232,6 @@ static int __devinit rmi_driver_probe(struct device *dev)
err_free_data:
rmi_free_function_list(rmi_dev);
- for (attr_count--; attr_count >= 0; attr_count--)
- device_remove_file(dev, &attrs[attr_count]);
- if (data->pdt_props.has_bsr)
- device_remove_file(dev, &bsr_attribute);
return retval;
}
@@ -1615,32 +1245,32 @@ struct rmi_driver rmi_sensor_driver = {
.bus = &rmi_bus_type,
.pm = &rmi_driver_pm,
.probe = rmi_driver_probe,
- .remove = __devexit_p(rmi_driver_remove),
},
.irq_handler = rmi_driver_irq_handler,
.reset_handler = rmi_driver_reset_handler,
.store_irq_mask = rmi_driver_irq_save,
.restore_irq_mask = rmi_driver_irq_restore,
.set_input_params = rmi_driver_set_input_params,
+ .remove = rmi_driver_remove,
};
int __init rmi_register_sensor_driver(void)
{
- int error;
+ int retval;
- error = driver_register(&rmi_sensor_driver.driver);
- if (error) {
+ retval = driver_register(&rmi_sensor_driver.driver);
+ if (retval) {
pr_err("%s: driver register failed, code=%d.\n", __func__,
- error);
- return error;
+ retval);
+ return retval;
}
/* Ask the bus to let us know when drivers are bound to devices. */
- error = bus_register_notifier(&rmi_bus_type, &rmi_bus_notifier);
- if (error) {
+ retval = bus_register_notifier(&rmi_bus_type, &rmi_bus_notifier);
+ if (retval) {
pr_err("%s: failed to register bus notifier, code=%d.\n",
- __func__, error);
- return error;
+ __func__, retval);
+ return retval;
}
return 0;
@@ -2,20 +2,11 @@
* Copyright (c) 2011, 2012 Synaptics Incorporated
* Copyright (c) 2011 Unixphere
*
- * 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.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
*/
+
#ifndef _RMI_DRIVER_H
#define _RMI_DRIVER_H
@@ -23,7 +14,7 @@
#include <linux/hrtimer.h>
#include <linux/ktime.h>
-#define RMI_DRIVER_VERSION "1.6"
+#define RMI_DRIVER_VERSION "1.7"
#define SYNAPTICS_INPUT_DEVICE_NAME "Synaptics RMI4 Touch Sensor"
#define SYNAPTICS_VENDOR_ID 0x06cb
@@ -32,8 +23,6 @@
.attrs = _attrs, \
}
-#define attrify(nm) (&dev_attr_##nm.attr)
-
#define PDT_PROPERTIES_LOCATION 0x00EF
#define BSR_LOCATION 0x00FE
@@ -44,14 +33,14 @@ struct pdt_properties {
} __attribute__((__packed__));
struct rmi_driver_data {
- struct rmi_function rmi_functions;
+ struct rmi_function_dev rmi_functions;
struct rmi_device *rmi_dev;
- struct rmi_function *f01_container;
+ struct rmi_function_dev *f01_dev;
bool f01_bootloader_mode;
atomic_t attn_count;
- bool irq_debug;
+ u32 irq_debug;
int irq;
int irq_flags;
int num_of_irq_regs;
@@ -66,7 +55,6 @@ struct rmi_driver_data {
struct hrtimer poll_timer;
struct work_struct poll_work;
ktime_t poll_interval;
-
struct mutex pdt_mutex;
struct pdt_properties pdt_props;
u8 bsr;
@@ -133,11 +121,11 @@ static inline void copy_pdt_entry_to_fd(struct pdt_entry *pdt,
extern void rmi4_fw_update(struct rmi_device *rmi_dev,
struct pdt_entry *f01_pdt, struct pdt_entry *f34_pdt);
#else
-#define rmi4_fw_update(rmi_dev, f01_pdt, f34_pdt)
+#define rmi4_fw_update(rmi_dev, f01_pdt, f34_pdt) 0
#endif
extern struct rmi_driver rmi_sensor_driver;
-extern struct rmi_function_handler rmi_f01_handler;
+extern struct rmi_function_driver rmi_f01_driver;
int rmi_register_sensor_driver(void);
void rmi_unregister_sensor_driver(void);