linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 0/7] Add spi support for CMA3000 driver and new driver CMR3000
@ 2011-10-18 15:47 Ricardo Ribalda Delgado
  2011-10-18 15:48 ` [PATCHv3 1/7] input/cma3000_d0x: Support devices without pdata Ricardo Ribalda Delgado
                   ` (10 more replies)
  0 siblings, 11 replies; 15+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:47 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv
  Cc: Ricardo Ribalda Delgado


The following set of patches add spi and device tree support for the cma3000 driver and also
add support for the cmr3000 gyroscope.

v3 of the set.

Changelog:

  v3: -Support for device tree
      -Separate read/write spi

  v2: -Changes propossed by Jonathan Cameron
      -More fixes for the cma3000 driver

Ricardo Ribalda Delgado (7):
  input/cma3000_d0x: Support devices without pdata
  input/cma3000_d0x: Check silicon version
  input/cma3000_d0x: Keep configuration on poweroff
  input/cma3000_d0x: Add CMA3000 spi support
  Input: add CMR3000 gyrsocope driver
  input/cma3000_d0x: Unwind reverse order of init
  input/cma3000_d0x: Match comment to name of struct

 drivers/input/misc/Kconfig           |   38 ++++-
 drivers/input/misc/Makefile          |    3 +
 drivers/input/misc/cma3000_d0x.c     |  100 ++++++++--
 drivers/input/misc/cma3000_d0x_spi.c |  145 +++++++++++++
 drivers/input/misc/cmr3000_d0x.c     |  382 ++++++++++++++++++++++++++++++++++
 drivers/input/misc/cmr3000_d0x.h     |   45 ++++
 drivers/input/misc/cmr3000_d0x_spi.c |  178 ++++++++++++++++
 include/linux/input/cma3000.h        |    2 +-
 include/linux/input/cmr3000.h        |   54 +++++
 9 files changed, 930 insertions(+), 17 deletions(-)
 create mode 100644 drivers/input/misc/cma3000_d0x_spi.c
 create mode 100644 drivers/input/misc/cmr3000_d0x.c
 create mode 100644 drivers/input/misc/cmr3000_d0x.h
 create mode 100644 drivers/input/misc/cmr3000_d0x_spi.c
 create mode 100644 include/linux/input/cmr3000.h

-- 
1.7.7


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCHv3 1/7] input/cma3000_d0x: Support devices without pdata
  2011-10-18 15:47 [PATCHv3 0/7] Add spi support for CMA3000 driver and new driver CMR3000 Ricardo Ribalda Delgado
@ 2011-10-18 15:48 ` Ricardo Ribalda Delgado
  2011-10-18 15:48 ` [PATCHv3 2/7] input/cma3000_d0x: Check silicon version Ricardo Ribalda Delgado
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:48 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv
  Cc: Ricardo Ribalda Delgado

Architectures based on device-tree does not have platform data
associated to the spi/i2c devices. Instead they can have some of
the options embedded in the device tree.

This patch allows the cma3000  driver to get the configuration
from the platform_data, the device tree, or in the wort case,
just use a default configuration.

---

v3: Fixes suggested by Jonathan Cameron
    -Add support for the device tree

v2: Fixes suggested by Jonathan Cameron
    -Spelling
    -Simplify pdata!=NULL check

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
 drivers/input/misc/cma3000_d0x.c |   84 +++++++++++++++++++++++++++++++++-----
 1 files changed, 73 insertions(+), 11 deletions(-)

diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
index 1633b63..604a32f 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/input/cma3000.h>
+#include <linux/of.h>
 
 #include "cma3000_d0x.h"
 
@@ -62,9 +63,21 @@
 #define BIT_TO_2G  18
 #define BIT_TO_8G  71
 
+static struct cma3000_platform_data cma3000_default_pdata = {
+	.mdthr = 0x8,
+	.mdfftmr = 0x33,
+	.ffthr = 0x8,
+	.mode = CMAMODE_MEAS400,
+	.g_range = CMARANGE_2G,
+	.fuzz_x = BIT_TO_2G,
+	.fuzz_y = BIT_TO_2G,
+	.fuzz_z = BIT_TO_2G,
+	.irqflags = 0,
+};
+
 struct cma3000_accl_data {
 	const struct cma3000_bus_ops *bus_ops;
-	const struct cma3000_platform_data *pdata;
+	struct cma3000_platform_data pdata;
 
 	struct device *dev;
 	struct input_dev *input_dev;
@@ -182,7 +195,7 @@ static int cma3000_reset(struct cma3000_accl_data *data)
 
 static int cma3000_poweron(struct cma3000_accl_data *data)
 {
-	const struct cma3000_platform_data *pdata = data->pdata;
+	struct cma3000_platform_data *pdata = &data->pdata;
 	u8 ctrl = 0;
 	int ret;
 
@@ -280,22 +293,57 @@ void cma3000_resume(struct cma3000_accl_data *data)
 }
 EXPORT_SYMBOL(cma3000_resume);
 
+#ifdef CONFIG_OF
+void cma3000_get_pdata_of(struct device *dev, struct cma3000_accl_data *data)
+{
+	const __be32 *property;
+	int len;
+
+	property = of_get_property(dev->of_node, "vti,mdthr", &len);
+	if (property && len == sizeof(int))
+		data->pdata.mdthr = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,mdfftmr", &len);
+	if (property && len == sizeof(int))
+		data->pdata.mdfftmr = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,mode", &len);
+	if (property && len == sizeof(int))
+		data->pdata.mode = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,g_range", &len);
+	if (property && len == sizeof(int))
+		data->pdata.g_range = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,fuzz_x", &len);
+	if (property && len == sizeof(int))
+		data->pdata.fuzz_x = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,fuzz_y", &len);
+	if (property && len == sizeof(int))
+		data->pdata.fuzz_y = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,fuzz_z", &len);
+	if (property && len == sizeof(int))
+		data->pdata.fuzz_z = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,irqflags", &len);
+	if (property && len == sizeof(int))
+		data->pdata.irqflags = be32_to_cpup(property);
+
+	return;
+}
+#endif
+
 struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
 				       const struct cma3000_bus_ops *bops)
 {
-	const struct cma3000_platform_data *pdata = dev->platform_data;
+	struct cma3000_platform_data *pdata;
 	struct cma3000_accl_data *data;
 	struct input_dev *input_dev;
 	int rev;
 	int error;
 
-	if (!pdata) {
-		dev_err(dev, "platform data not found\n");
-		error = -EINVAL;
-		goto err_out;
-	}
-
-
 	/* if no IRQ return error */
 	if (irq == 0) {
 		error = -EINVAL;
@@ -309,10 +357,24 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
 		goto err_free_mem;
 	}
 
+	/*Init platform data*/
+	if (dev->platform_data != NULL) {
+		memcpy(&data->pdata, dev->platform_data, sizeof(data->pdata));
+	} else {
+		memcpy(&data->pdata, &cma3000_default_pdata,
+				sizeof(data->pdata));
+		#ifdef CONFIG_OF
+		if (dev->of_node != NULL)
+			cma3000_get_pdata_of(dev, data);
+		 else
+		#endif
+		dev_info(dev, "platform data not found, using default\n");
+	}
+	pdata = &data->pdata;
+
 	data->dev = dev;
 	data->input_dev = input_dev;
 	data->bus_ops = bops;
-	data->pdata = pdata;
 	data->irq = irq;
 	mutex_init(&data->mutex);
 
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv3 2/7] input/cma3000_d0x: Check silicon version
  2011-10-18 15:47 [PATCHv3 0/7] Add spi support for CMA3000 driver and new driver CMR3000 Ricardo Ribalda Delgado
  2011-10-18 15:48 ` [PATCHv3 1/7] input/cma3000_d0x: Support devices without pdata Ricardo Ribalda Delgado
@ 2011-10-18 15:48 ` Ricardo Ribalda Delgado
  2011-10-18 15:48 ` [PATCHv3 3/7] input/cma3000_d0x: Keep configuration on poweroff Ricardo Ribalda Delgado
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:48 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv
  Cc: Ricardo Ribalda Delgado

Improve probing of the cma3000 chip, by checking the revision of the
device.

---

v2: Fixes suggested by Jonathan Cameron
	-Remove WhoamI pr_info

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
 drivers/input/misc/cma3000_d0x.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
index 604a32f..18ac912 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -27,6 +27,8 @@
 
 #include "cma3000_d0x.h"
 
+#define CMA3000_REV         0x10
+
 #define CMA3000_WHOAMI      0x00
 #define CMA3000_REVID       0x01
 #define CMA3000_CTRL        0x02
@@ -418,7 +420,11 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
 		error = rev;
 		goto err_free_mem;
 	}
-
+	if (rev != CMA3000_REV) {
+		error = -EINVAL;
+		pr_err("CMA3000 Accelerometer: Unknown Revision %x\n", rev);
+		goto err_free_mem;
+	}
 	pr_info("CMA3000 Accelerometer: Revision %x\n", rev);
 
 	error = request_threaded_irq(irq, NULL, cma3000_thread_irq,
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv3 3/7] input/cma3000_d0x: Keep configuration on poweroff
  2011-10-18 15:47 [PATCHv3 0/7] Add spi support for CMA3000 driver and new driver CMR3000 Ricardo Ribalda Delgado
  2011-10-18 15:48 ` [PATCHv3 1/7] input/cma3000_d0x: Support devices without pdata Ricardo Ribalda Delgado
  2011-10-18 15:48 ` [PATCHv3 2/7] input/cma3000_d0x: Check silicon version Ricardo Ribalda Delgado
@ 2011-10-18 15:48 ` Ricardo Ribalda Delgado
  2011-10-18 15:48 ` [PATCHv3 4/7] input/cma3000_d0x: Add CMA3000 spi support Ricardo Ribalda Delgado
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:48 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv
  Cc: Ricardo Ribalda Delgado

When the device goes to poweroff keep the spi/i2c configuration.
Otherwhise the device could not wake up if it was in spi mode.

---

v2: Fixes suggested by Jonathan Cameron
    -Code Style

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
 drivers/input/misc/cma3000_d0x.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
index 18ac912..bbda34c 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -45,6 +45,7 @@
 #define CMA3000_RANGE2G    (1 << 7)
 #define CMA3000_RANGE8G    (0 << 7)
 #define CMA3000_BUSI2C     (0 << 4)
+#define CMA3000_BUSSPI     (1 << 4)
 #define CMA3000_MODEMASK   (7 << 1)
 #define CMA3000_GRANGEMASK (1 << 7)
 
@@ -231,8 +232,11 @@ static int cma3000_poweron(struct cma3000_accl_data *data)
 static int cma3000_poweroff(struct cma3000_accl_data *data)
 {
 	int ret;
+	u8 ctrl = CMAMODE_POFF;
 
-	ret = CMA3000_SET(data, CMA3000_CTRL, CMAMODE_POFF, "Mode setting");
+	ctrl |= data->bus_ops->ctrl_mod;
+
+	ret = CMA3000_SET(data, CMA3000_CTRL, ctrl, "Mode setting");
 	msleep(CMA3000_SETDELAY);
 
 	return ret;
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv3 4/7] input/cma3000_d0x: Add CMA3000 spi support
  2011-10-18 15:47 [PATCHv3 0/7] Add spi support for CMA3000 driver and new driver CMR3000 Ricardo Ribalda Delgado
                   ` (2 preceding siblings ...)
  2011-10-18 15:48 ` [PATCHv3 3/7] input/cma3000_d0x: Keep configuration on poweroff Ricardo Ribalda Delgado
@ 2011-10-18 15:48 ` Ricardo Ribalda Delgado
  2011-10-18 15:48 ` [PATCHv3 5/7] Input: add CMR3000 gyrsocope driver Ricardo Ribalda Delgado
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:48 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv
  Cc: Ricardo Ribalda Delgado

Add support for SPI communication.

---

v3: Fixes suggested by Jonathan Cameron
	-Separate write/read commands
	-Do not check 1/0 mask
	-Use spi_w8r8 and spi_write_then_read functions
v2: Fixes suggested by Jonathan Cameron
	-Add filename to based on header
	-Rename set with write
	-Set spi buffers as cache aligned
	-Code Style

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
 drivers/input/misc/Kconfig           |   14 +++-
 drivers/input/misc/Makefile          |    1 +
 drivers/input/misc/cma3000_d0x_spi.c |  145 ++++++++++++++++++++++++++++++++++
 3 files changed, 158 insertions(+), 2 deletions(-)
 create mode 100644 drivers/input/misc/cma3000_d0x_spi.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index c9104bb..b9f2e93 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -496,8 +496,8 @@ config INPUT_CMA3000
 	  Say Y here if you want to use VTI CMA3000_D0x Accelerometer
 	  driver
 
-	  This driver currently only supports I2C interface to the
-	  controller. Also select the I2C method.
+	  This driver supports I2C and SPI interface to the
+	  controller. Also select the I2C method and/or the SPI method.
 
 	  If unsure, say N
 
@@ -514,6 +514,16 @@ config INPUT_CMA3000_I2C
 	  To compile this driver as a module, choose M here: the
 	  module will be called cma3000_d0x_i2c.
 
+config INPUT_CMA3000_SPI
+	tristate "Support SPI bus connection"
+	depends on INPUT_CMA3000 && SPI
+	help
+	  Say Y here if you want to use VTI CMA3000_D0x Accelerometer
+	  through SPI interface.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cma3000_d0x_spi.
+
 config INPUT_XEN_KBDDEV_FRONTEND
 	tristate "Xen virtual keyboard and mouse support"
 	depends on XEN_FBDEV_FRONTEND
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 299ad5e..7305f6f 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_INPUT_BFIN_ROTARY)		+= bfin_rotary.o
 obj-$(CONFIG_INPUT_CM109)		+= cm109.o
 obj-$(CONFIG_INPUT_CMA3000)		+= cma3000_d0x.o
 obj-$(CONFIG_INPUT_CMA3000_I2C)		+= cma3000_d0x_i2c.o
+obj-$(CONFIG_INPUT_CMA3000_SPI)		+= cma3000_d0x_spi.o
 obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
 obj-$(CONFIG_INPUT_DM355EVM)		+= dm355evm_keys.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
diff --git a/drivers/input/misc/cma3000_d0x_spi.c b/drivers/input/misc/cma3000_d0x_spi.c
new file mode 100644
index 0000000..c91a552
--- /dev/null
+++ b/drivers/input/misc/cma3000_d0x_spi.c
@@ -0,0 +1,145 @@
+/*
+ * Implements SPI interface for VTI CMA300_D0x Accelerometer driver
+ *
+ * Copyright (C) 2011 Qtechnology
+ * Author: Ricardo Ribalda <ricardo.ribalda@gmail.com.com>
+ * Based on:
+ *	drivers/input/misc/cma3000_d0x_i2c.c by Hemanth V
+ *	drivers/input/mis/adxl34x-spi.c	by Michael Hennerich
+ *
+ * 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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/input/cma3000.h>
+#include "cma3000_d0x.h"
+
+static int cma3000_spi_write(struct device *dev, u8 reg, u8 val, char *msg)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	int ret;
+	u8 tmp[2];
+
+	tmp[0] = (reg << 2) | 2;
+	tmp[1] = val;
+
+	ret = spi_write_then_read(spi, tmp, sizeof(tmp), NULL, 0);
+	if (ret < 0) {
+		dev_err(dev, "%s failed (%s, %d)\n", __func__, msg, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cma3000_spi_read(struct device *dev, u8 reg, char *msg)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	int ret;
+
+	ret = spi_w8r8(spi, reg << 2);
+	if (ret < 0)
+		dev_err(dev, "%s failed (%s, %d)\n", __func__, msg, ret);
+
+	return ret;
+}
+
+static const struct cma3000_bus_ops cma3000_spi_bops = {
+	.bustype = BUS_SPI,
+#define CMA3000_BUSSPI     (1 << 4)
+	.ctrl_mod = CMA3000_BUSSPI,
+	.read = cma3000_spi_read,
+	.write = cma3000_spi_write,
+};
+
+static int __devinit cma3000_spi_probe(struct spi_device *spi)
+{
+	struct cma3000_accl_data *data;
+
+	data = cma3000_init(&spi->dev, spi->irq, &cma3000_spi_bops);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	spi_set_drvdata(spi, data);
+
+	return 0;
+}
+
+static int __devexit cma3000_spi_remove(struct spi_device *spi)
+{
+	struct cma3000_accl_data *data = dev_get_drvdata(&spi->dev);
+
+	cma3000_exit(data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int cma3000_spi_suspend(struct device *dev)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct cma3000_accl_data *data = dev_get_drvdata(&spi->dev);
+
+	cma3000_suspend(data);
+
+	return 0;
+}
+
+static int cma3000_spi_resume(struct device *dev)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct cma3000_accl_data *data = dev_get_drvdata(&spi->dev);
+
+	cma3000_resume(data);
+
+	return 0;
+}
+
+static const struct dev_pm_ops cma3000_spi_pm_ops = {
+	.suspend = cma3000_spi_suspend,
+	.resume = cma3000_spi_resume,
+};
+#endif
+
+static SIMPLE_DEV_PM_OPS(cma3000_spi_pm, cma3000_spi_suspend,
+			 cma3000_spi_resume);
+
+static struct spi_driver cma3000_driver = {
+	.driver = {
+		   .name = "cma3000_d01",
+		   .bus = &spi_bus_type,
+		   .owner = THIS_MODULE,
+		   .pm = &cma3000_spi_pm,
+		   },
+	.probe = cma3000_spi_probe,
+	.remove = __devexit_p(cma3000_spi_remove),
+};
+
+static int __init cma3000_spi_init(void)
+{
+	return spi_register_driver(&cma3000_driver);
+}
+
+static void __exit cma3000_spi_exit(void)
+{
+	spi_unregister_driver(&cma3000_driver);
+}
+
+module_init(cma3000_spi_init);
+module_exit(cma3000_spi_exit);
+
+MODULE_DESCRIPTION("CMA3000-D0x Accelerometer SPI Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>");
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv3 5/7] Input: add CMR3000 gyrsocope driver
  2011-10-18 15:47 [PATCHv3 0/7] Add spi support for CMA3000 driver and new driver CMR3000 Ricardo Ribalda Delgado
                   ` (3 preceding siblings ...)
  2011-10-18 15:48 ` [PATCHv3 4/7] input/cma3000_d0x: Add CMA3000 spi support Ricardo Ribalda Delgado
@ 2011-10-18 15:48 ` Ricardo Ribalda Delgado
  2011-10-18 15:48 ` [PATCHv3 6/7] input/cma3000_d0x: Unwind reverse order of init Ricardo Ribalda Delgado
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:48 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv
  Cc: Ricardo Ribalda Delgado

Add support for CMR3000 Tri-axis accelerometer. CMR3000 supports both
I2C/SPI bus communication, currently the driver supports SPI
communication, since I have no hardware to test the I2C communication.

---

v3: Fixes suggested by Jonathan Cameron
	-Support DT
	-Cleaner spi read/write

v2: Fixes suggested by Jonathan Cameron
	-Code Stype
	-Check pdata!=NULL
	-SPI align Cacheline
	-More clear based on
	-%s/set/write/
	-%s/accl/gyro/
	-remove READ/SET macros

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
 drivers/input/misc/Kconfig           |   24 ++
 drivers/input/misc/Makefile          |    2 +
 drivers/input/misc/cmr3000_d0x.c     |  426 ++++++++++++++++++++++++++++++++++
 drivers/input/misc/cmr3000_d0x.h     |   45 ++++
 drivers/input/misc/cmr3000_d0x_spi.c |  144 ++++++++++++
 include/linux/input/cmr3000.h        |   54 +++++
 6 files changed, 695 insertions(+), 0 deletions(-)
 create mode 100644 drivers/input/misc/cmr3000_d0x.c
 create mode 100644 drivers/input/misc/cmr3000_d0x.h
 create mode 100644 drivers/input/misc/cmr3000_d0x_spi.c
 create mode 100644 include/linux/input/cmr3000.h

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index b9f2e93..7c56f94 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -524,6 +524,30 @@ config INPUT_CMA3000_SPI
 	  To compile this driver as a module, choose M here: the
 	  module will be called cma3000_d0x_spi.
 
+config INPUT_CMR3000
+	tristate "VTI CMR3000 Tri-axis gyroscope"
+	help
+	  Say Y here if you want to use VTI CMR3000_D0x Gyroscope
+	  driver
+
+	  This driver currently only supports SPI interface to the
+	  controller. Also select the SPI method.
+
+	  If unsure, say N
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cmr3000_d0x.
+
+config INPUT_CMR3000_SPI
+	tristate "Support SPI bus connection"
+	depends on INPUT_CMR3000 && SPI
+	help
+	  Say Y here if you want to use VTI CMR3000_D0x Gyroscope
+	  through SPI interface.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cmr3000_d0x_spi.
+
 config INPUT_XEN_KBDDEV_FRONTEND
 	tristate "Xen virtual keyboard and mouse support"
 	depends on XEN_FBDEV_FRONTEND
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 7305f6f..c7fe09a 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -21,6 +21,8 @@ obj-$(CONFIG_INPUT_CM109)		+= cm109.o
 obj-$(CONFIG_INPUT_CMA3000)		+= cma3000_d0x.o
 obj-$(CONFIG_INPUT_CMA3000_I2C)		+= cma3000_d0x_i2c.o
 obj-$(CONFIG_INPUT_CMA3000_SPI)		+= cma3000_d0x_spi.o
+obj-$(CONFIG_INPUT_CMR3000)		+= cmr3000_d0x.o
+obj-$(CONFIG_INPUT_CMR3000_SPI)		+= cmr3000_d0x_spi.o
 obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
 obj-$(CONFIG_INPUT_DM355EVM)		+= dm355evm_keys.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
diff --git a/drivers/input/misc/cmr3000_d0x.c b/drivers/input/misc/cmr3000_d0x.c
new file mode 100644
index 0000000..7fe672f
--- /dev/null
+++ b/drivers/input/misc/cmr3000_d0x.c
@@ -0,0 +1,426 @@
+/*
+ * VTI CMR3000_D0x Gyroscope driver
+ *
+ * Copyright (C) 2011 Qtechnology
+ * Author: Ricardo Ribalda <ricardo.ribalda@gmail.com>
+ *
+ * Based on:
+ *	drivers/input/misc/cma3000_d0x.c by: Hemanth V
+ *
+ * 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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/cmr3000.h>
+#include <linux/of.h>
+
+#include "cmr3000_d0x.h"
+
+#define CMR3000_REV         0x21
+
+#define CMR3000_WHOAMI      0x00
+#define CMR3000_REVID       0x01
+#define CMR3000_CTRL        0x02
+#define CMR3000_STATUS      0x03
+#define CMR3000_X_LSB       0x0C
+#define CMR3000_X_MSB       0x0D
+#define CMR3000_Y_LSB       0x0E
+#define CMR3000_Y_MSB       0x0F
+#define CMR3000_Z_LSB       0x10
+#define CMR3000_Z_MSB       0x11
+#define CMR3000_I2C_ADDR    0x22
+#define CMR3000_PDR         0x26
+
+#define CMR3000_IRQDIS     (1 << 0)
+#define CMR3000_MODEMASK   (3 << 1)
+#define CMR3000_BUSI2C     (0 << 4)
+#define CMR3000_BUSSPI     (1 << 4)
+#define CMR3000_INTLOW     (1 << 6)
+#define CMR3000_INTHIGH    (0 << 6)
+#define CMR3000_RST        (1 << 7)
+
+#define CMRMODE_SHIFT      1
+#define CMRIRQLEVEL_SHIFT  6
+
+#define CMR3000_STATUS_PERR    (1 << 0)
+#define CMR3000_STATUS_PORST   (1 << 3)
+
+/* Settling time delay in ms */
+#define CMR3000_SETDELAY    30
+
+/*
+ * Bit weights mult/div in dps for bit 0, other bits need
+ * multipy factor 2^n. 11th bit is the sign bit.
+ */
+#define BIT_TO_DPS_MUL  3
+#define BIT_TO_DPS_DIV 32
+
+static struct cmr3000_platform_data cmr3000_default_pdata = {
+	.irq_level = CMR3000_INTHIGH,
+	.mode = CMRMODE_MEAS80,
+	.fuzz_x = 1,
+	.fuzz_y = 1,
+	.fuzz_z = 1,
+	.irqflags = 0,
+};
+
+struct cmr3000_gyro_data {
+	const struct cmr3000_bus_ops *bus_ops;
+	struct cmr3000_platform_data pdata;
+
+	struct device *dev;
+	struct input_dev *input_dev;
+
+	int irq_level;
+	u8 mode;
+
+	int bit_to_mg;
+	int irq;
+
+	struct mutex mutex;
+	bool opened;
+	bool suspended;
+};
+
+static void decode_dps(struct cmr3000_gyro_data *data, int *datax,
+		       int *datay, int *dataz)
+{
+	/* Data in 2's complement, convert to dps */
+	*datax = (((s16) ((*datax) << 2)) * BIT_TO_DPS_MUL) / BIT_TO_DPS_DIV;
+	*datay = (((s16) ((*datay) << 2)) * BIT_TO_DPS_MUL) / BIT_TO_DPS_DIV;
+	*dataz = (((s16) ((*dataz) << 2)) * BIT_TO_DPS_MUL) / BIT_TO_DPS_DIV;
+}
+
+static irqreturn_t cmr3000_thread_irq(int irq, void *dev_id)
+{
+	struct cmr3000_gyro_data *data = dev_id;
+	int datax, datay, dataz;
+	u8 mode, intr_status;
+
+	intr_status = data->bus_ops->read(data->dev, CMR3000_STATUS,
+							"irq status");
+	intr_status = data->bus_ops->read(data->dev, CMR3000_CTRL,
+							"control mode");
+	if (intr_status < 0)
+		return IRQ_NONE;
+
+	/* Interrupt not for this device */
+	if (intr_status & CMR3000_IRQDIS)
+		return IRQ_NONE;
+
+	mode = (intr_status & CMR3000_MODEMASK) >> CMRMODE_SHIFT;
+	if ((mode != CMRMODE_MEAS80)
+	    && (mode != CMRMODE_MEAS20))
+		return IRQ_NONE;
+
+	datax = (data->bus_ops->read(data->dev, CMR3000_X_MSB, "X_MSB")) << 8;
+	datax |= data->bus_ops->read(data->dev, CMR3000_X_LSB, "X_LSB");
+	datay = (data->bus_ops->read(data->dev, CMR3000_Y_MSB, "Y_MSB")) << 8;
+	datay |= data->bus_ops->read(data->dev, CMR3000_Y_LSB, "Y_LSB");
+	dataz = (data->bus_ops->read(data->dev, CMR3000_Z_MSB, "Z_MSB")) << 8;
+	dataz |= data->bus_ops->read(data->dev, CMR3000_Z_LSB, "Z_LSB");
+
+	/* Device closed */
+	if ((data->mode != CMRMODE_MEAS80)
+	    && (data->mode != CMRMODE_MEAS20))
+		return IRQ_NONE;
+
+	/* Decode register values to dps */
+	decode_dps(data, &datax, &datay, &dataz);
+
+	input_report_abs(data->input_dev, ABS_X, datax);
+	input_report_abs(data->input_dev, ABS_Y, datay);
+	input_report_abs(data->input_dev, ABS_Z, dataz);
+	input_sync(data->input_dev);
+
+	return IRQ_HANDLED;
+}
+
+static int cmr3000_poweron(struct cmr3000_gyro_data *data)
+{
+	const struct cmr3000_platform_data *pdata = &data->pdata;
+	u8 ctrl;
+	int ret;
+
+	ctrl = pdata->irq_level << CMRIRQLEVEL_SHIFT;
+	ctrl |= data->mode << CMRMODE_SHIFT;
+	ctrl |= data->bus_ops->ctrl_mod;
+	ret = data->bus_ops->write(data->dev, CMR3000_CTRL, ctrl,
+							"Mode setting");
+	if (ret < 0)
+		return -EIO;
+
+	msleep(CMR3000_SETDELAY);
+
+	return 0;
+}
+
+static int cmr3000_poweroff(struct cmr3000_gyro_data *data)
+{
+	int ret;
+	u8 ctrl = CMRMODE_POFF;
+
+	ctrl |= data->bus_ops->ctrl_mod;
+	ctrl |= CMR3000_IRQDIS;
+
+	ret = data->bus_ops->write(data->dev, CMR3000_CTRL, ctrl,
+							"Mode setting");
+	msleep(CMR3000_SETDELAY);
+
+	return ret;
+}
+
+static int cmr3000_reset(struct cmr3000_gyro_data *data)
+{
+	int val;
+
+	/* Reset chip */
+	data->bus_ops->write(data->dev, CMR3000_CTRL, CMR3000_RST, "Reset");
+	mdelay(2);
+
+	/* Settling time delay */
+	val = data->bus_ops->read(data->dev, CMR3000_STATUS, "Status");
+	if (val < 0) {
+		dev_err(data->dev, "Reset failed\n");
+		return val;
+	}
+
+	if (val & CMR3000_STATUS_PERR) {
+		dev_err(data->dev, "Parity Error\n");
+		return -EIO;
+	}
+
+	return cmr3000_poweroff(data);
+}
+
+static int cmr3000_open(struct input_dev *input_dev)
+{
+	struct cmr3000_gyro_data *data = input_get_drvdata(input_dev);
+
+	mutex_lock(&data->mutex);
+
+	if (!data->suspended)
+		cmr3000_poweron(data);
+
+	data->opened = true;
+
+	mutex_unlock(&data->mutex);
+
+	return 0;
+}
+
+static void cmr3000_close(struct input_dev *input_dev)
+{
+	struct cmr3000_gyro_data *data = input_get_drvdata(input_dev);
+
+	mutex_lock(&data->mutex);
+
+	if (!data->suspended)
+		cmr3000_poweroff(data);
+
+	data->opened = false;
+
+	mutex_unlock(&data->mutex);
+}
+
+void cmr3000_suspend(struct cmr3000_gyro_data *data)
+{
+	mutex_lock(&data->mutex);
+
+	if (!data->suspended && data->opened)
+		cmr3000_poweroff(data);
+
+	data->suspended = true;
+
+	mutex_unlock(&data->mutex);
+}
+EXPORT_SYMBOL(cmr3000_suspend);
+
+void cmr3000_resume(struct cmr3000_gyro_data *data)
+{
+	mutex_lock(&data->mutex);
+
+	if (data->suspended && data->opened)
+		cmr3000_poweron(data);
+
+	data->suspended = false;
+
+	mutex_unlock(&data->mutex);
+}
+EXPORT_SYMBOL(cmr3000_resume);
+
+#ifdef CONFIG_OF
+void cmr3000_get_pdata_of(struct device *dev, struct cmr3000_gyro_data *data)
+{
+	const __be32 *property;
+	int len;
+
+	property = of_get_property(dev->of_node, "vti,irq_level", &len);
+	if (property && len == sizeof(int))
+		data->pdata.irq_level = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,mode", &len);
+	if (property && len == sizeof(int))
+		data->pdata.mode = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,fuzz_x", &len);
+	if (property && len == sizeof(int))
+		data->pdata.fuzz_x = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,fuzz_y", &len);
+	if (property && len == sizeof(int))
+		data->pdata.fuzz_y = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,fuzz_z", &len);
+	if (property && len == sizeof(int))
+		data->pdata.fuzz_z = be32_to_cpup(property);
+
+	property = of_get_property(dev->of_node, "vti,irqflags", &len);
+	if (property && len == sizeof(int))
+		data->pdata.irqflags = be32_to_cpup(property);
+
+	return;
+}
+#endif
+
+struct cmr3000_gyro_data *cmr3000_init(struct device *dev, int irq,
+				       const struct cmr3000_bus_ops *bops)
+{
+	struct cmr3000_platform_data *pdata;
+	struct cmr3000_gyro_data *data;
+	struct input_dev *input_dev;
+	int rev;
+	int error;
+
+	/* if no IRQ return error */
+	if (irq == 0) {
+		error = -EINVAL;
+		goto err_out;
+	}
+
+	data = kzalloc(sizeof(struct cmr3000_gyro_data), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!data || !input_dev) {
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	/*Init platform data*/
+	if (dev->platform_data != NULL) {
+		memcpy(&data->pdata, dev->platform_data, sizeof(data->pdata));
+	} else {
+		memcpy(&data->pdata, &cmr3000_default_pdata,
+				sizeof(data->pdata));
+		#ifdef CONFIG_OF
+		if (dev->of_node != NULL)
+			cmr3000_get_pdata_of(dev, data);
+		 else
+		#endif
+		dev_info(dev, "platform data not found, using default\n");
+	}
+	pdata = &data->pdata;
+
+	data->dev = dev;
+	data->input_dev = input_dev;
+	data->bus_ops = bops;
+	data->irq = irq;
+	mutex_init(&data->mutex);
+
+	data->mode = pdata->mode;
+	if ((data->mode != CMRMODE_MEAS80)
+	    && (data->mode != CMRMODE_MEAS20)) {
+		data->mode = CMRMODE_MEAS80;
+		dev_warn(dev, "Invalid mode specified, assuming 80Hz\n");
+	}
+
+	data->irq_level = pdata->irq_level;
+	if ((data->irq_level != CMR3000_INTLOW)
+	    && (data->irq_level != CMR3000_INTHIGH)) {
+		data->irq_level = CMR3000_INTHIGH;
+		dev_warn(data->dev,
+			 "Invalid int level specified, assuming high\n");
+	}
+
+	input_dev->name = "cmr3000-gyroscope";
+	input_dev->id.bustype = bops->bustype;
+	input_dev->open = cmr3000_open;
+	input_dev->close = cmr3000_close;
+
+	__set_bit(EV_ABS, input_dev->evbit);
+
+	input_set_abs_params(input_dev, ABS_X,
+			     -CMRRANGE, CMRRANGE, pdata->fuzz_x, 0);
+	input_set_abs_params(input_dev, ABS_Y,
+			     -CMRRANGE, CMRRANGE, pdata->fuzz_y, 0);
+	input_set_abs_params(input_dev, ABS_Z,
+			     -CMRRANGE, CMRRANGE, pdata->fuzz_z, 0);
+
+	input_set_drvdata(input_dev, data);
+
+	error = cmr3000_reset(data);
+	if (error)
+		goto err_free_mem;
+
+	rev = data->bus_ops->read(data->dev, CMR3000_REVID, "Revid");
+	if (rev < 0) {
+		error = rev;
+		goto err_free_mem;
+	}
+	if (rev != CMR3000_REV) {
+		error = -EINVAL;
+		pr_err("CMR3000 Gyroscope: Unknown Revision %x\n", rev);
+		goto err_free_mem;
+	}
+	pr_info("CMR3000 Gyroscope: Revision %x\n", rev);
+
+	error = request_threaded_irq(irq, NULL, cmr3000_thread_irq,
+				     pdata->irqflags | IRQF_ONESHOT,
+				     "cmr3000_d0x", data);
+	if (error) {
+		dev_err(dev, "request_threaded_irq failed\n");
+		goto err_free_mem;
+	}
+
+	error = input_register_device(data->input_dev);
+	if (error) {
+		dev_err(dev, "Unable to register input device\n");
+		goto err_free_irq;
+	}
+
+	return data;
+
+err_free_irq:
+	free_irq(irq, data);
+err_free_mem:
+	input_free_device(input_dev);
+	kfree(data);
+err_out:
+	return ERR_PTR(error);
+}
+EXPORT_SYMBOL(cmr3000_init);
+
+void cmr3000_exit(struct cmr3000_gyro_data *data)
+{
+	input_unregister_device(data->input_dev);
+	free_irq(data->irq, data);
+	kfree(data);
+}
+EXPORT_SYMBOL(cmr3000_exit);
+
+MODULE_DESCRIPTION("CMR3000-D0x Gyroscope Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>");
diff --git a/drivers/input/misc/cmr3000_d0x.h b/drivers/input/misc/cmr3000_d0x.h
new file mode 100644
index 0000000..3d0984a
--- /dev/null
+++ b/drivers/input/misc/cmr3000_d0x.h
@@ -0,0 +1,45 @@
+/*
+ * VTI CMR3000_D0x Gyroscpe driver
+ *
+ * Copyright (C) 2011 Qtechnology
+ * Author: Ricardo Ribalda <ricardo.ribalda@gmail.com>
+ *
+ * Based on:
+ *	drivers/input/misc/cma3000_d0x.h by Hemanth V
+ *
+ * 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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _INPUT_CMR3000_H
+#define _INPUT_CMR3000_H
+
+#include <linux/types.h>
+#include <linux/input.h>
+
+struct device;
+struct cmr3000_gyro_data;
+
+struct cmr3000_bus_ops {
+	u16 bustype;
+	u8 ctrl_mod;
+	int (*read) (struct device *, u8, char *);
+	int (*write) (struct device *, u8, u8, char *);
+};
+
+struct cmr3000_gyro_data *cmr3000_init(struct device *dev, int irq,
+				       const struct cmr3000_bus_ops *bops);
+void cmr3000_exit(struct cmr3000_gyro_data *);
+void cmr3000_suspend(struct cmr3000_gyro_data *);
+void cmr3000_resume(struct cmr3000_gyro_data *);
+
+#endif
diff --git a/drivers/input/misc/cmr3000_d0x_spi.c b/drivers/input/misc/cmr3000_d0x_spi.c
new file mode 100644
index 0000000..7f27fa3
--- /dev/null
+++ b/drivers/input/misc/cmr3000_d0x_spi.c
@@ -0,0 +1,144 @@
+/*
+ * Implements SPI interface for VTI CMR300_D0x Accelerometer driver
+ *
+ * Copyright (C) 2011 Qtechnology
+ * Author: Ricardo Ribalda <ricardo.ribalda@gmail.com.com>
+ * Based on:
+ *	drivers/input/misc/cma3000_d0x_i2c.c by Hemanth V
+ *	drivers/input/mis/adxl34x-spi.c	by Michael Hennerich
+ *
+ * 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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/input/cmr3000.h>
+#include "cmr3000_d0x.h"
+
+static int cmr3000_spi_write(struct device *dev, u8 reg, u8 val, char *msg)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	int ret;
+	u8 tmp[2];
+
+	tmp[0] = (reg << 2) | 2;
+	tmp[1] = val;
+
+	ret = spi_write_then_read(spi, tmp, sizeof(tmp), NULL, 0);
+	if (ret < 0) {
+		dev_err(dev, "%s failed (%s, %d)\n", __func__, msg, ret);
+		return ret;
+	}
+	return 0;
+}
+
+static int cmr3000_spi_read(struct device *dev, u8 reg, char *msg)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	int ret;
+
+	ret = spi_w8r8(spi, reg << 2);
+	if (ret < 0)
+		dev_err(dev, "%s failed (%s, %d)\n", __func__, msg, ret);
+
+	return ret;
+}
+
+static const struct cmr3000_bus_ops cmr3000_spi_bops = {
+	.bustype = BUS_SPI,
+#define CMR3000_BUSSPI     (1 << 4)
+	.ctrl_mod = CMR3000_BUSSPI,
+	.read = cmr3000_spi_read,
+	.write = cmr3000_spi_write,
+};
+
+static int __devinit cmr3000_spi_probe(struct spi_device *spi)
+{
+	struct cmr3000_gyro_data *data;
+
+	data = cmr3000_init(&spi->dev, spi->irq, &cmr3000_spi_bops);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	spi_set_drvdata(spi, data);
+
+	return 0;
+}
+
+static int __devexit cmr3000_spi_remove(struct spi_device *spi)
+{
+	struct cmr3000_gyro_data *data = dev_get_drvdata(&spi->dev);
+
+	cmr3000_exit(data);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int cmr3000_spi_suspend(struct device *dev)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct cmr3000_gyro_data *data = dev_get_drvdata(&spi->dev);
+
+	cmr3000_suspend(data);
+
+	return 0;
+}
+
+static int cmr3000_spi_resume(struct device *dev)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct cmr3000_gyro_data *data = dev_get_drvdata(&spi->dev);
+
+	cmr3000_resume(data);
+
+	return 0;
+}
+
+static const struct dev_pm_ops cmr3000_spi_pm_ops = {
+	.suspend = cmr3000_spi_suspend,
+	.resume = cmr3000_spi_resume,
+};
+#endif
+
+static SIMPLE_DEV_PM_OPS(cmr3000_spi_pm, cmr3000_spi_suspend,
+			 cmr3000_spi_resume);
+
+static struct spi_driver cmr3000_driver = {
+	.driver = {
+		   .name = "cmr3000_d01",
+		   .bus = &spi_bus_type,
+		   .owner = THIS_MODULE,
+		   .pm = &cmr3000_spi_pm,
+		   },
+	.probe = cmr3000_spi_probe,
+	.remove = __devexit_p(cmr3000_spi_remove),
+};
+
+static int __init cmr3000_spi_init(void)
+{
+	return spi_register_driver(&cmr3000_driver);
+}
+
+static void __exit cmr3000_spi_exit(void)
+{
+	spi_unregister_driver(&cmr3000_driver);
+}
+
+module_init(cmr3000_spi_init);
+module_exit(cmr3000_spi_exit);
+
+MODULE_DESCRIPTION("CMR3000-D0x Gyroscope SPI Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>");
diff --git a/include/linux/input/cmr3000.h b/include/linux/input/cmr3000.h
new file mode 100644
index 0000000..dfcf9e3
--- /dev/null
+++ b/include/linux/input/cmr3000.h
@@ -0,0 +1,54 @@
+/*
+ * VTI CMR3000_Dxx Gyroscope driver
+ *
+ * Copyright (C) 2011 Qtechnology
+ * Author: Ricardo Ribalda <ricardo.ribalda@gmail.com>
+ *
+ * Based on:
+ *	include/linux/input/cma3000.h by Hemanth V
+ *
+ * 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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _LINUX_CMR3000_H
+#define _LINUX_CMR3000_H
+
+#define CMRMODE_DEFAULT    0
+#define CMRMODE_STANDBY    1
+#define CMRMODE_MEAS20     2
+#define CMRMODE_MEAS80     3
+#define CMRMODE_POFF       0
+
+#define CMRIRQLEVEL_LOW    1
+#define CMRIRQLEVEL_HIGH   0
+
+#define CMRRANGE   3072
+
+/**
+ * struct cmr3000_platform_data - CMR3000 Platform data
+ * @fuzz_x: Noise on X Axis
+ * @fuzz_y: Noise on Y Axis
+ * @fuzz_z: Noise on Z Axis
+ * @mode: Operating mode
+ * @irq_level: Irq level
+ */
+struct cmr3000_platform_data {
+	int fuzz_x;
+	int fuzz_y;
+	int fuzz_z;
+	uint8_t irq_level;
+	uint8_t mode;
+	unsigned long irqflags;
+};
+
+#endif
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv3 6/7] input/cma3000_d0x: Unwind reverse order of init
  2011-10-18 15:47 [PATCHv3 0/7] Add spi support for CMA3000 driver and new driver CMR3000 Ricardo Ribalda Delgado
                   ` (4 preceding siblings ...)
  2011-10-18 15:48 ` [PATCHv3 5/7] Input: add CMR3000 gyrsocope driver Ricardo Ribalda Delgado
@ 2011-10-18 15:48 ` Ricardo Ribalda Delgado
  2011-10-18 15:48 ` [PATCHv3 7/7] input/cma3000_d0x: Match comment to name of struct Ricardo Ribalda Delgado
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:48 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv
  Cc: Ricardo Ribalda Delgado


Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
 drivers/input/misc/cma3000_d0x.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
index bbda34c..96a46d4 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -459,8 +459,8 @@ EXPORT_SYMBOL(cma3000_init);
 
 void cma3000_exit(struct cma3000_accl_data *data)
 {
-	free_irq(data->irq, data);
 	input_unregister_device(data->input_dev);
+	free_irq(data->irq, data);
 	kfree(data);
 }
 EXPORT_SYMBOL(cma3000_exit);
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCHv3 7/7] input/cma3000_d0x: Match comment to name of struct
  2011-10-18 15:47 [PATCHv3 0/7] Add spi support for CMA3000 driver and new driver CMR3000 Ricardo Ribalda Delgado
                   ` (5 preceding siblings ...)
  2011-10-18 15:48 ` [PATCHv3 6/7] input/cma3000_d0x: Unwind reverse order of init Ricardo Ribalda Delgado
@ 2011-10-18 15:48 ` Ricardo Ribalda Delgado
       [not found] ` <1318952886-835-2-git-send-email-ricardo.ribalda@gmail.com>
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:48 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv
  Cc: Ricardo Ribalda Delgado


Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
 include/linux/input/cma3000.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/linux/input/cma3000.h b/include/linux/input/cma3000.h
index cbbaac2..e8c28e8 100644
--- a/include/linux/input/cma3000.h
+++ b/include/linux/input/cma3000.h
@@ -33,7 +33,7 @@
 #define CMARANGE_8G   8000
 
 /**
- * struct cma3000_i2c_platform_data - CMA3000 Platform data
+ * struct cma3000_platform_data - CMA3000 Platform data
  * @fuzz_x: Noise on X Axis
  * @fuzz_y: Noise on Y Axis
  * @fuzz_z: Noise on Z Axis
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCHv3 1/7] input/cma3000_d0x: Support devices without pdata
       [not found] ` <1318952886-835-2-git-send-email-ricardo.ribalda@gmail.com>
@ 2011-10-18 15:59   ` Jonathan Cameron
  0 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2011-10-18 15:59 UTC (permalink / raw)
  To: Ricardo Ribalda Delgado
  Cc: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, hemanthv, linux-input, linux-kernel

On 10/18/11 16:48, Ricardo Ribalda Delgado wrote:
> Architectures based on device-tree does not have platform data
> associated to the spi/i2c devices. Instead they can have some of
> the options embedded in the device tree.
> 
> This patch allows the cma3000  driver to get the configuration
> from the platform_data, the device tree, or in the wort case,
> just use a default configuration.
> 
Looks good to me but you'll need an ack from someone more
familiar with DT.
> ---
> 
> v3: Fixes suggested by Jonathan Cameron
>     -Add support for the device tree
> 
> v2: Fixes suggested by Jonathan Cameron
>     -Spelling
>     -Simplify pdata!=NULL check
> 
> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
> ---
>  drivers/input/misc/cma3000_d0x.c |   84 +++++++++++++++++++++++++++++++++-----
>  1 files changed, 73 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
> index 1633b63..604a32f 100644
> --- a/drivers/input/misc/cma3000_d0x.c
> +++ b/drivers/input/misc/cma3000_d0x.c
> @@ -23,6 +23,7 @@
>  #include <linux/slab.h>
>  #include <linux/input.h>
>  #include <linux/input/cma3000.h>
> +#include <linux/of.h>
>  
>  #include "cma3000_d0x.h"
>  
> @@ -62,9 +63,21 @@
>  #define BIT_TO_2G  18
>  #define BIT_TO_8G  71
>  
> +static struct cma3000_platform_data cma3000_default_pdata = {
> +	.mdthr = 0x8,
> +	.mdfftmr = 0x33,
> +	.ffthr = 0x8,
> +	.mode = CMAMODE_MEAS400,
> +	.g_range = CMARANGE_2G,
> +	.fuzz_x = BIT_TO_2G,
> +	.fuzz_y = BIT_TO_2G,
> +	.fuzz_z = BIT_TO_2G,
> +	.irqflags = 0,
> +};
> +
>  struct cma3000_accl_data {
>  	const struct cma3000_bus_ops *bus_ops;
> -	const struct cma3000_platform_data *pdata;
> +	struct cma3000_platform_data pdata;
>  
>  	struct device *dev;
>  	struct input_dev *input_dev;
> @@ -182,7 +195,7 @@ static int cma3000_reset(struct cma3000_accl_data *data)
>  
>  static int cma3000_poweron(struct cma3000_accl_data *data)
>  {
> -	const struct cma3000_platform_data *pdata = data->pdata;
> +	struct cma3000_platform_data *pdata = &data->pdata;
>  	u8 ctrl = 0;
>  	int ret;
>  
> @@ -280,22 +293,57 @@ void cma3000_resume(struct cma3000_accl_data *data)
>  }
>  EXPORT_SYMBOL(cma3000_resume);
>  
> +#ifdef CONFIG_OF
> +void cma3000_get_pdata_of(struct device *dev, struct cma3000_accl_data *data)
> +{
> +	const __be32 *property;
> +	int len;
> +
> +	property = of_get_property(dev->of_node, "vti,mdthr", &len);
> +	if (property && len == sizeof(int))
> +		data->pdata.mdthr = be32_to_cpup(property);
> +
> +	property = of_get_property(dev->of_node, "vti,mdfftmr", &len);
> +	if (property && len == sizeof(int))
> +		data->pdata.mdfftmr = be32_to_cpup(property);
> +
> +	property = of_get_property(dev->of_node, "vti,mode", &len);
> +	if (property && len == sizeof(int))
> +		data->pdata.mode = be32_to_cpup(property);
> +
> +	property = of_get_property(dev->of_node, "vti,g_range", &len);
> +	if (property && len == sizeof(int))
> +		data->pdata.g_range = be32_to_cpup(property);
> +
> +	property = of_get_property(dev->of_node, "vti,fuzz_x", &len);
> +	if (property && len == sizeof(int))
> +		data->pdata.fuzz_x = be32_to_cpup(property);
> +
> +	property = of_get_property(dev->of_node, "vti,fuzz_y", &len);
> +	if (property && len == sizeof(int))
> +		data->pdata.fuzz_y = be32_to_cpup(property);
> +
> +	property = of_get_property(dev->of_node, "vti,fuzz_z", &len);
> +	if (property && len == sizeof(int))
> +		data->pdata.fuzz_z = be32_to_cpup(property);
> +
> +	property = of_get_property(dev->of_node, "vti,irqflags", &len);
> +	if (property && len == sizeof(int))
> +		data->pdata.irqflags = be32_to_cpup(property);
> +
> +	return;
> +}
> +#endif
> +
>  struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
>  				       const struct cma3000_bus_ops *bops)
>  {
> -	const struct cma3000_platform_data *pdata = dev->platform_data;
> +	struct cma3000_platform_data *pdata;
>  	struct cma3000_accl_data *data;
>  	struct input_dev *input_dev;
>  	int rev;
>  	int error;
>  
> -	if (!pdata) {
> -		dev_err(dev, "platform data not found\n");
> -		error = -EINVAL;
> -		goto err_out;
> -	}
> -
> -
>  	/* if no IRQ return error */
>  	if (irq == 0) {
>  		error = -EINVAL;
> @@ -309,10 +357,24 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
>  		goto err_free_mem;
>  	}
>  
> +	/*Init platform data*/
> +	if (dev->platform_data != NULL) {
> +		memcpy(&data->pdata, dev->platform_data, sizeof(data->pdata));
> +	} else {
> +		memcpy(&data->pdata, &cma3000_default_pdata,
> +				sizeof(data->pdata));
> +		#ifdef CONFIG_OF
> +		if (dev->of_node != NULL)
> +			cma3000_get_pdata_of(dev, data);
> +		 else
Alignment is a little strange here, + for consistency of formatting
I'd just double the next line and use a #else 
> +		#endif
> +		dev_info(dev, "platform data not found, using default\n");
> +	}
> +	pdata = &data->pdata;
> +
>  	data->dev = dev;
>  	data->input_dev = input_dev;
>  	data->bus_ops = bops;
> -	data->pdata = pdata;
>  	data->irq = irq;
>  	mutex_init(&data->mutex);
>  

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv3 2/7] input/cma3000_d0x: Check silicon version
       [not found] ` <1318952886-835-3-git-send-email-ricardo.ribalda@gmail.com>
@ 2011-10-18 16:01   ` Jonathan Cameron
  0 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2011-10-18 16:01 UTC (permalink / raw)
  To: Ricardo Ribalda Delgado
  Cc: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, hemanthv, linux-input, linux-kernel

On 10/18/11 16:48, Ricardo Ribalda Delgado wrote:
> Improve probing of the cma3000 chip, by checking the revision of the
> device.
Please carry acks forward with new versions if the patch hasn't changed
significantly.
> 
> ---
> 
> v2: Fixes suggested by Jonathan Cameron
> 	-Remove WhoamI pr_info
> 
> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
> ---
>  drivers/input/misc/cma3000_d0x.c |    8 +++++++-
>  1 files changed, 7 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
> index 604a32f..18ac912 100644
> --- a/drivers/input/misc/cma3000_d0x.c
> +++ b/drivers/input/misc/cma3000_d0x.c
> @@ -27,6 +27,8 @@
>  
>  #include "cma3000_d0x.h"
>  
> +#define CMA3000_REV         0x10
> +
>  #define CMA3000_WHOAMI      0x00
>  #define CMA3000_REVID       0x01
>  #define CMA3000_CTRL        0x02
> @@ -418,7 +420,11 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
>  		error = rev;
>  		goto err_free_mem;
>  	}
> -
> +	if (rev != CMA3000_REV) {
> +		error = -EINVAL;
> +		pr_err("CMA3000 Accelerometer: Unknown Revision %x\n", rev);
> +		goto err_free_mem;
> +	}
>  	pr_info("CMA3000 Accelerometer: Revision %x\n", rev);
>  
>  	error = request_threaded_irq(irq, NULL, cma3000_thread_irq,


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv3 4/7] input/cma3000_d0x: Add CMA3000 spi support
       [not found] ` <1318952886-835-5-git-send-email-ricardo.ribalda@gmail.com>
@ 2011-10-18 16:02   ` Jonathan Cameron
  0 siblings, 0 replies; 15+ messages in thread
From: Jonathan Cameron @ 2011-10-18 16:02 UTC (permalink / raw)
  To: Ricardo Ribalda Delgado
  Cc: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, hemanthv, linux-input, linux-kernel

On 10/18/11 16:48, Ricardo Ribalda Delgado wrote:
> Add support for SPI communication.
> 
> ---
> 
> v3: Fixes suggested by Jonathan Cameron
> 	-Separate write/read commands
> 	-Do not check 1/0 mask
> 	-Use spi_w8r8 and spi_write_then_read functions
> v2: Fixes suggested by Jonathan Cameron
> 	-Add filename to based on header
> 	-Rename set with write
> 	-Set spi buffers as cache aligned
> 	-Code Style
> 
> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/input/misc/Kconfig           |   14 +++-
>  drivers/input/misc/Makefile          |    1 +
>  drivers/input/misc/cma3000_d0x_spi.c |  145 ++++++++++++++++++++++++++++++++++
>  3 files changed, 158 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/input/misc/cma3000_d0x_spi.c
> 
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index c9104bb..b9f2e93 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -496,8 +496,8 @@ config INPUT_CMA3000
>  	  Say Y here if you want to use VTI CMA3000_D0x Accelerometer
>  	  driver
>  
> -	  This driver currently only supports I2C interface to the
> -	  controller. Also select the I2C method.
> +	  This driver supports I2C and SPI interface to the
> +	  controller. Also select the I2C method and/or the SPI method.
>  
>  	  If unsure, say N
>  
> @@ -514,6 +514,16 @@ config INPUT_CMA3000_I2C
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called cma3000_d0x_i2c.
>  
> +config INPUT_CMA3000_SPI
> +	tristate "Support SPI bus connection"
> +	depends on INPUT_CMA3000 && SPI
> +	help
> +	  Say Y here if you want to use VTI CMA3000_D0x Accelerometer
> +	  through SPI interface.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called cma3000_d0x_spi.
> +
>  config INPUT_XEN_KBDDEV_FRONTEND
>  	tristate "Xen virtual keyboard and mouse support"
>  	depends on XEN_FBDEV_FRONTEND
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index 299ad5e..7305f6f 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_INPUT_BFIN_ROTARY)		+= bfin_rotary.o
>  obj-$(CONFIG_INPUT_CM109)		+= cm109.o
>  obj-$(CONFIG_INPUT_CMA3000)		+= cma3000_d0x.o
>  obj-$(CONFIG_INPUT_CMA3000_I2C)		+= cma3000_d0x_i2c.o
> +obj-$(CONFIG_INPUT_CMA3000_SPI)		+= cma3000_d0x_spi.o
>  obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
>  obj-$(CONFIG_INPUT_DM355EVM)		+= dm355evm_keys.o
>  obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
> diff --git a/drivers/input/misc/cma3000_d0x_spi.c b/drivers/input/misc/cma3000_d0x_spi.c
> new file mode 100644
> index 0000000..c91a552
> --- /dev/null
> +++ b/drivers/input/misc/cma3000_d0x_spi.c
> @@ -0,0 +1,145 @@
> +/*
> + * Implements SPI interface for VTI CMA300_D0x Accelerometer driver
> + *
> + * Copyright (C) 2011 Qtechnology
> + * Author: Ricardo Ribalda <ricardo.ribalda@gmail.com.com>
> + * Based on:
> + *	drivers/input/misc/cma3000_d0x_i2c.c by Hemanth V
> + *	drivers/input/mis/adxl34x-spi.c	by Michael Hennerich
> + *
> + * 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.
> + *
> + * 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/spi/spi.h>
> +#include <linux/input/cma3000.h>
> +#include "cma3000_d0x.h"
> +
> +static int cma3000_spi_write(struct device *dev, u8 reg, u8 val, char *msg)
> +{
> +	struct spi_device *spi = to_spi_device(dev);
> +	int ret;
> +	u8 tmp[2];
> +
> +	tmp[0] = (reg << 2) | 2;
> +	tmp[1] = val;
> +
> +	ret = spi_write_then_read(spi, tmp, sizeof(tmp), NULL, 0);
> +	if (ret < 0) {
> +		dev_err(dev, "%s failed (%s, %d)\n", __func__, msg, ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int cma3000_spi_read(struct device *dev, u8 reg, char *msg)
> +{
> +	struct spi_device *spi = to_spi_device(dev);
> +	int ret;
> +
> +	ret = spi_w8r8(spi, reg << 2);
> +	if (ret < 0)
> +		dev_err(dev, "%s failed (%s, %d)\n", __func__, msg, ret);
> +
> +	return ret;
> +}
> +
> +static const struct cma3000_bus_ops cma3000_spi_bops = {
> +	.bustype = BUS_SPI,
> +#define CMA3000_BUSSPI     (1 << 4)
> +	.ctrl_mod = CMA3000_BUSSPI,
> +	.read = cma3000_spi_read,
> +	.write = cma3000_spi_write,
> +};
> +
> +static int __devinit cma3000_spi_probe(struct spi_device *spi)
> +{
> +	struct cma3000_accl_data *data;
> +
> +	data = cma3000_init(&spi->dev, spi->irq, &cma3000_spi_bops);
> +	if (IS_ERR(data))
> +		return PTR_ERR(data);
> +
> +	spi_set_drvdata(spi, data);
> +
> +	return 0;
> +}
> +
> +static int __devexit cma3000_spi_remove(struct spi_device *spi)
> +{
> +	struct cma3000_accl_data *data = dev_get_drvdata(&spi->dev);
> +
> +	cma3000_exit(data);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM
> +static int cma3000_spi_suspend(struct device *dev)
> +{
> +	struct spi_device *spi = to_spi_device(dev);
> +	struct cma3000_accl_data *data = dev_get_drvdata(&spi->dev);
> +
> +	cma3000_suspend(data);
> +
> +	return 0;
> +}
> +
> +static int cma3000_spi_resume(struct device *dev)
> +{
> +	struct spi_device *spi = to_spi_device(dev);
> +	struct cma3000_accl_data *data = dev_get_drvdata(&spi->dev);
> +
> +	cma3000_resume(data);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops cma3000_spi_pm_ops = {
> +	.suspend = cma3000_spi_suspend,
> +	.resume = cma3000_spi_resume,
> +};
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(cma3000_spi_pm, cma3000_spi_suspend,
> +			 cma3000_spi_resume);
> +
> +static struct spi_driver cma3000_driver = {
> +	.driver = {
> +		   .name = "cma3000_d01",
> +		   .bus = &spi_bus_type,
> +		   .owner = THIS_MODULE,
> +		   .pm = &cma3000_spi_pm,
> +		   },
> +	.probe = cma3000_spi_probe,
> +	.remove = __devexit_p(cma3000_spi_remove),
> +};
> +
> +static int __init cma3000_spi_init(void)
> +{
> +	return spi_register_driver(&cma3000_driver);
> +}
> +
> +static void __exit cma3000_spi_exit(void)
> +{
> +	spi_unregister_driver(&cma3000_driver);
> +}
> +
> +module_init(cma3000_spi_init);
> +module_exit(cma3000_spi_exit);
> +
> +MODULE_DESCRIPTION("CMA3000-D0x Accelerometer SPI Driver");
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>");


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv3 6/7] input/cma3000_d0x: Unwind reverse order of init
       [not found] ` <1318952886-835-7-git-send-email-ricardo.ribalda@gmail.com>
@ 2011-10-18 16:53   ` Dmitry Torokhov
  2011-10-18 16:57     ` Ricardo Ribalda Delgado
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry Torokhov @ 2011-10-18 16:53 UTC (permalink / raw)
  To: Ricardo Ribalda Delgado
  Cc: sameo, peter.ujfalusi, aghayal, david, Shubhrajyoti, saaguirre,
	jic23, hemanthv, linux-input, linux-kernel

On Tuesday, October 18, 2011 08:48:05 AM Ricardo Ribalda Delgado wrote:
> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
> ---
>  drivers/input/misc/cma3000_d0x.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/input/misc/cma3000_d0x.c
> b/drivers/input/misc/cma3000_d0x.c index bbda34c..96a46d4 100644
> --- a/drivers/input/misc/cma3000_d0x.c
> +++ b/drivers/input/misc/cma3000_d0x.c
> @@ -459,8 +459,8 @@ EXPORT_SYMBOL(cma3000_init);
> 
>  void cma3000_exit(struct cma3000_accl_data *data)
>  {
> -	free_irq(data->irq, data);
>  	input_unregister_device(data->input_dev);
> +	free_irq(data->irq, data);
>  	kfree(data);
>  }
>  EXPORT_SYMBOL(cma3000_exit);

No, the original is much safer. Unless you 110% sure you won't get
an interrupt between unregistering device (which is most likely
will free the associated data structure) and freeing irq it is
better to leave it as is.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv3 6/7] input/cma3000_d0x: Unwind reverse order of init
  2011-10-18 16:53   ` [PATCHv3 6/7] input/cma3000_d0x: Unwind reverse order of init Dmitry Torokhov
@ 2011-10-18 16:57     ` Ricardo Ribalda Delgado
  2011-10-18 17:03       ` Dmitry Torokhov
  0 siblings, 1 reply; 15+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 16:57 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: sameo, peter.ujfalusi, aghayal, david, Shubhrajyoti, saaguirre,
	jic23, hemanthv, linux-input, linux-kernel

Hello Dmitry

 You are right, and also could be a good idea to init the irq, only
after the input device has been registered. Dont you think so?

  Thanks

On Tue, Oct 18, 2011 at 18:53, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> On Tuesday, October 18, 2011 08:48:05 AM Ricardo Ribalda Delgado wrote:
>> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
>> ---
>>  drivers/input/misc/cma3000_d0x.c |    2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/drivers/input/misc/cma3000_d0x.c
>> b/drivers/input/misc/cma3000_d0x.c index bbda34c..96a46d4 100644
>> --- a/drivers/input/misc/cma3000_d0x.c
>> +++ b/drivers/input/misc/cma3000_d0x.c
>> @@ -459,8 +459,8 @@ EXPORT_SYMBOL(cma3000_init);
>>
>>  void cma3000_exit(struct cma3000_accl_data *data)
>>  {
>> -     free_irq(data->irq, data);
>>       input_unregister_device(data->input_dev);
>> +     free_irq(data->irq, data);
>>       kfree(data);
>>  }
>>  EXPORT_SYMBOL(cma3000_exit);
>
> No, the original is much safer. Unless you 110% sure you won't get
> an interrupt between unregistering device (which is most likely
> will free the associated data structure) and freeing irq it is
> better to leave it as is.
>
> Thanks.
>
> --
> Dmitry
>



-- 
Ricardo Ribalda
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv3 6/7] input/cma3000_d0x: Unwind reverse order of init
  2011-10-18 16:57     ` Ricardo Ribalda Delgado
@ 2011-10-18 17:03       ` Dmitry Torokhov
  2011-10-18 17:10         ` Ricardo Ribalda Delgado
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry Torokhov @ 2011-10-18 17:03 UTC (permalink / raw)
  To: Ricardo Ribalda Delgado
  Cc: sameo, peter.ujfalusi, aghayal, david, Shubhrajyoti, saaguirre,
	jic23, hemanthv, linux-input, linux-kernel

On Tuesday, October 18, 2011 09:57:24 AM Ricardo Ribalda Delgado wrote:
> Hello Dmitry
> 
>  You are right, and also could be a good idea to init the irq, only
> after the input device has been registered. Dont you think so?

Input core is constructed in such way that it is safe to call
input_report_*() and input_event() on properly allocated input device,
even if it has not been registered yet, the events will simply be
dropped.

So no, it is not necessary and doing so is quite often complicates
error handling in probe() routines.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCHv3 6/7] input/cma3000_d0x: Unwind reverse order of init
  2011-10-18 17:03       ` Dmitry Torokhov
@ 2011-10-18 17:10         ` Ricardo Ribalda Delgado
  0 siblings, 0 replies; 15+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 17:10 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: sameo, peter.ujfalusi, aghayal, david, Shubhrajyoti, saaguirre,
	jic23, hemanthv, linux-input, linux-kernel

Ok,

 I remove that patch and fix it for the new cmr3000 driver


    Thanks!

On Tue, Oct 18, 2011 at 19:03, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> On Tuesday, October 18, 2011 09:57:24 AM Ricardo Ribalda Delgado wrote:
>> Hello Dmitry
>>
>>  You are right, and also could be a good idea to init the irq, only
>> after the input device has been registered. Dont you think so?
>
> Input core is constructed in such way that it is safe to call
> input_report_*() and input_event() on properly allocated input device,
> even if it has not been registered yet, the events will simply be
> dropped.
>
> So no, it is not necessary and doing so is quite often complicates
> error handling in probe() routines.
>
> Thanks.
>
> --
> Dmitry
>



-- 
Ricardo Ribalda
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2011-10-18 17:10 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-18 15:47 [PATCHv3 0/7] Add spi support for CMA3000 driver and new driver CMR3000 Ricardo Ribalda Delgado
2011-10-18 15:48 ` [PATCHv3 1/7] input/cma3000_d0x: Support devices without pdata Ricardo Ribalda Delgado
2011-10-18 15:48 ` [PATCHv3 2/7] input/cma3000_d0x: Check silicon version Ricardo Ribalda Delgado
2011-10-18 15:48 ` [PATCHv3 3/7] input/cma3000_d0x: Keep configuration on poweroff Ricardo Ribalda Delgado
2011-10-18 15:48 ` [PATCHv3 4/7] input/cma3000_d0x: Add CMA3000 spi support Ricardo Ribalda Delgado
2011-10-18 15:48 ` [PATCHv3 5/7] Input: add CMR3000 gyrsocope driver Ricardo Ribalda Delgado
2011-10-18 15:48 ` [PATCHv3 6/7] input/cma3000_d0x: Unwind reverse order of init Ricardo Ribalda Delgado
2011-10-18 15:48 ` [PATCHv3 7/7] input/cma3000_d0x: Match comment to name of struct Ricardo Ribalda Delgado
     [not found] ` <1318952886-835-2-git-send-email-ricardo.ribalda@gmail.com>
2011-10-18 15:59   ` [PATCHv3 1/7] input/cma3000_d0x: Support devices without pdata Jonathan Cameron
     [not found] ` <1318952886-835-3-git-send-email-ricardo.ribalda@gmail.com>
2011-10-18 16:01   ` [PATCHv3 2/7] input/cma3000_d0x: Check silicon version Jonathan Cameron
     [not found] ` <1318952886-835-5-git-send-email-ricardo.ribalda@gmail.com>
2011-10-18 16:02   ` [PATCHv3 4/7] input/cma3000_d0x: Add CMA3000 spi support Jonathan Cameron
     [not found] ` <1318952886-835-7-git-send-email-ricardo.ribalda@gmail.com>
2011-10-18 16:53   ` [PATCHv3 6/7] input/cma3000_d0x: Unwind reverse order of init Dmitry Torokhov
2011-10-18 16:57     ` Ricardo Ribalda Delgado
2011-10-18 17:03       ` Dmitry Torokhov
2011-10-18 17:10         ` Ricardo Ribalda Delgado

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).