All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 0/7] Add spi support for CMA3000 driver and new driver CMR3000
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  0 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv, linux-input,
	linux-kernel
  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.

v2 of the set.

Changelog:

   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     |   36 +++-
 drivers/input/misc/cma3000_d0x_spi.c |  178 ++++++++++++++++
 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, 905 insertions(+), 11 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] 31+ messages in thread

* [PATCHv2 0/7] Add spi support for CMA3000 driver and new driver CMR3000
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  0 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 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.

v2 of the set.

Changelog:

   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     |   36 +++-
 drivers/input/misc/cma3000_d0x_spi.c |  178 ++++++++++++++++
 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, 905 insertions(+), 11 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] 31+ messages in thread

* [PATCHv2 1/7] input/cma3000_d0x: Support devices without pdata
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  2011-10-18 12:53   ` Jonathan Cameron
  -1 siblings, 1 reply; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv, linux-input,
	linux-kernel
  Cc: Ricardo Ribalda Delgado

Architectures based on device-tree does not have platform data
associated to the spi/i2c devices.
This patch allows those architectures to use the cma3000 driver with
a default configuration.

---

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 |   20 +++++++++++++++-----
 1 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
index 1633b63..f2e87e3 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -62,6 +62,18 @@
 #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;
@@ -289,13 +301,11 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
 	int rev;
 	int error;
 
-	if (!pdata) {
-		dev_err(dev, "platform data not found\n");
-		error = -EINVAL;
-		goto err_out;
+	if (pdata == NULL) {
+		dev_info(dev, "platform data not found, using default\n");
+		pdata = &cma3000_default_pdata;
 	}
 
-
 	/* if no IRQ return error */
 	if (irq == 0) {
 		error = -EINVAL;
-- 
1.7.7


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

* [PATCHv2 1/7] input/cma3000_d0x: Support devices without pdata
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
  (?)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  -1 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 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.
This patch allows those architectures to use the cma3000 driver with
a default configuration.

---

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 |   20 +++++++++++++++-----
 1 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
index 1633b63..f2e87e3 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -62,6 +62,18 @@
 #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;
@@ -289,13 +301,11 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
 	int rev;
 	int error;
 
-	if (!pdata) {
-		dev_err(dev, "platform data not found\n");
-		error = -EINVAL;
-		goto err_out;
+	if (pdata == NULL) {
+		dev_info(dev, "platform data not found, using default\n");
+		pdata = &cma3000_default_pdata;
 	}
 
-
 	/* if no IRQ return error */
 	if (irq == 0) {
 		error = -EINVAL;
-- 
1.7.7


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

* [PATCHv2 2/7] input/cma3000_d0x: Check silicon version
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (3 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  2011-10-18 12:54   ` Jonathan Cameron
  -1 siblings, 1 reply; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv, linux-input,
	linux-kernel
  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 f2e87e3..3877cbe 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -26,6 +26,8 @@
 
 #include "cma3000_d0x.h"
 
+#define CMA3000_REV         0x10
+
 #define CMA3000_WHOAMI      0x00
 #define CMA3000_REVID       0x01
 #define CMA3000_CTRL        0x02
@@ -366,7 +368,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] 31+ messages in thread

* [PATCHv2 2/7] input/cma3000_d0x: Check silicon version
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (2 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  -1 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 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 f2e87e3..3877cbe 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -26,6 +26,8 @@
 
 #include "cma3000_d0x.h"
 
+#define CMA3000_REV         0x10
+
 #define CMA3000_WHOAMI      0x00
 #define CMA3000_REVID       0x01
 #define CMA3000_CTRL        0x02
@@ -366,7 +368,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] 31+ messages in thread

* [PATCHv2 3/7] input/cma3000_d0x: Keep configuration on poweroff
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (4 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  -1 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv, linux-input,
	linux-kernel
  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 3877cbe..e1d27d0 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -44,6 +44,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)
 
@@ -230,8 +231,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] 31+ messages in thread

* [PATCHv2 3/7] input/cma3000_d0x: Keep configuration on poweroff
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (5 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  -1 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 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 3877cbe..e1d27d0 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -44,6 +44,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)
 
@@ -230,8 +231,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] 31+ messages in thread

* [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (7 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  2011-10-18 13:14   ` Jonathan Cameron
  -1 siblings, 1 reply; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv, linux-input,
	linux-kernel
  Cc: Ricardo Ribalda Delgado

Add support for SPI communication.

---

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 |  178 ++++++++++++++++++++++++++++++++++
 3 files changed, 191 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..1487ecf
--- /dev/null
+++ b/drivers/input/misc/cma3000_d0x_spi.c
@@ -0,0 +1,178 @@
+/*
+ * 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"
+
+enum { DO_READ = 0, DO_WRITE };
+
+static int cma3000_spi_cmd(struct spi_device *spi, u8 reg, u8 * val, int cmd,
+			   char *msg)
+{
+	int ret;
+	unsigned char tx_buf[2] ____cacheline_aligned;
+	unsigned char rx_buf[2] ____cacheline_aligned;
+	struct spi_transfer t = {
+		.rx_buf = rx_buf,
+		.tx_buf = tx_buf,
+		.len = 2,
+	};
+	struct spi_message m;
+
+	if (cmd == DO_WRITE) {
+		tx_buf[0] = (reg << 2) | 2;
+		tx_buf[1] = *val;
+	} else {
+		tx_buf[0] = reg << 2;
+		tx_buf[1] = 0;
+	}
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+	ret = spi_sync(spi, &m);
+	if (ret < 0) {
+		dev_err(&spi->dev, "%s failed (%s, %d)\n", __func__, msg, ret);
+		return ret;
+	}
+	if (cmd == DO_READ)
+		*val = rx_buf[1];
+
+	if (rx_buf[0] & 0xc1)
+		dev_err(&spi->dev,
+			"%s Invalid Zero mask(0x%x)\n", __func__, rx_buf[0]);
+
+	if ((rx_buf[0] & 0x2) != 0x2)
+		dev_err(&spi->dev,
+			"%s Invalid One mask (0x%x)\n", __func__, rx_buf[0]);
+
+	return 0;
+}
+
+static int cma3000_spi_write(struct device *dev, u8 reg, u8 val, char *msg)
+{
+
+	struct spi_device *spi = to_spi_device(dev);
+
+	return cma3000_spi_cmd(spi, reg, &val, DO_WRITE, msg);
+}
+
+static int cma3000_spi_read(struct device *dev, u8 reg, char *msg)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	int ret;
+	u8 val;
+
+	ret = cma3000_spi_cmd(spi, reg, &val, DO_READ, msg);
+	if (ret)
+		return ret;
+	return val;
+}
+
+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] 31+ messages in thread

* [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (6 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  -1 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv
  Cc: Ricardo Ribalda Delgado

Add support for SPI communication.

---

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 |  178 ++++++++++++++++++++++++++++++++++
 3 files changed, 191 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..1487ecf
--- /dev/null
+++ b/drivers/input/misc/cma3000_d0x_spi.c
@@ -0,0 +1,178 @@
+/*
+ * 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"
+
+enum { DO_READ = 0, DO_WRITE };
+
+static int cma3000_spi_cmd(struct spi_device *spi, u8 reg, u8 * val, int cmd,
+			   char *msg)
+{
+	int ret;
+	unsigned char tx_buf[2] ____cacheline_aligned;
+	unsigned char rx_buf[2] ____cacheline_aligned;
+	struct spi_transfer t = {
+		.rx_buf = rx_buf,
+		.tx_buf = tx_buf,
+		.len = 2,
+	};
+	struct spi_message m;
+
+	if (cmd == DO_WRITE) {
+		tx_buf[0] = (reg << 2) | 2;
+		tx_buf[1] = *val;
+	} else {
+		tx_buf[0] = reg << 2;
+		tx_buf[1] = 0;
+	}
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+	ret = spi_sync(spi, &m);
+	if (ret < 0) {
+		dev_err(&spi->dev, "%s failed (%s, %d)\n", __func__, msg, ret);
+		return ret;
+	}
+	if (cmd == DO_READ)
+		*val = rx_buf[1];
+
+	if (rx_buf[0] & 0xc1)
+		dev_err(&spi->dev,
+			"%s Invalid Zero mask(0x%x)\n", __func__, rx_buf[0]);
+
+	if ((rx_buf[0] & 0x2) != 0x2)
+		dev_err(&spi->dev,
+			"%s Invalid One mask (0x%x)\n", __func__, rx_buf[0]);
+
+	return 0;
+}
+
+static int cma3000_spi_write(struct device *dev, u8 reg, u8 val, char *msg)
+{
+
+	struct spi_device *spi = to_spi_device(dev);
+
+	return cma3000_spi_cmd(spi, reg, &val, DO_WRITE, msg);
+}
+
+static int cma3000_spi_read(struct device *dev, u8 reg, char *msg)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	int ret;
+	u8 val;
+
+	ret = cma3000_spi_cmd(spi, reg, &val, DO_READ, msg);
+	if (ret)
+		return ret;
+	return val;
+}
+
+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] 31+ messages in thread

* [PATCHv2 5/7] Input: add CMR3000 gyrsocope driver
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (9 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  -1 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv, linux-input,
	linux-kernel
  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
	-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     |  382 ++++++++++++++++++++++++++++++++++
 drivers/input/misc/cmr3000_d0x.h     |   45 ++++
 drivers/input/misc/cmr3000_d0x_spi.c |  178 ++++++++++++++++
 include/linux/input/cmr3000.h        |   54 +++++
 6 files changed, 685 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..a8b3e8b
--- /dev/null
+++ b/drivers/input/misc/cmr3000_d0x.c
@@ -0,0 +1,382 @@
+/*
+ * 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 "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,
+	.irqflags = 0,
+	.fuzz_x = 1,
+	.fuzz_y = 1,
+	.fuzz_z = 1,
+};
+
+struct cmr3000_gyro_data {
+	const struct cmr3000_bus_ops *bus_ops;
+	const 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);
+
+struct cmr3000_gyro_data *cmr3000_init(struct device *dev, int irq,
+				       const struct cmr3000_bus_ops *bops)
+{
+	const struct cmr3000_platform_data *pdata = dev->platform_data;
+	struct cmr3000_gyro_data *data;
+	struct input_dev *input_dev;
+	int rev;
+	int error;
+
+	if (pdata == NULL) {
+		dev_info(dev, "platform data not found, using default\n");
+		pdata = &cmr3000_default_pdata;
+	}
+
+	/* 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;
+	}
+
+	data->dev = dev;
+	data->input_dev = input_dev;
+	data->bus_ops = bops;
+	data->pdata = pdata;
+	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..6243437
--- /dev/null
+++ b/drivers/input/misc/cmr3000_d0x_spi.c
@@ -0,0 +1,178 @@
+/*
+ * 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"
+
+enum { DO_READ = 0, DO_WRITE };
+
+static int cmr3000_spi_cmd(struct spi_device *spi, u8 reg, u8 * val, int cmd,
+			   char *msg)
+{
+	int ret;
+	unsigned char tx_buf[2];
+	unsigned char rx_buf[2];
+	struct spi_transfer t = {
+		.rx_buf = rx_buf,
+		.tx_buf = tx_buf,
+		.len = 2,
+	};
+	struct spi_message m;
+
+	if (cmd == DO_WRITE) {
+		tx_buf[0] = (reg << 2) | 2;
+		tx_buf[1] = *val;
+	} else {
+		tx_buf[0] = reg << 2;
+		tx_buf[1] = 0;
+	}
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+	ret = spi_sync(spi, &m);
+	if (ret < 0) {
+		dev_err(&spi->dev, "%s failed (%s, %d)\n", __func__, msg, ret);
+		return ret;
+	}
+	if (cmd == DO_READ)
+		*val = rx_buf[1];
+
+	if (rx_buf[0] & 0x41)
+		dev_err(&spi->dev,
+			"%s Invalid Zero mask(0x%x)\n", __func__, rx_buf[0]);
+
+	if ((rx_buf[0] & 0x2) != 0x2)
+		dev_err(&spi->dev,
+			"%s Invalid One mask (0x%x)\n", __func__, rx_buf[0]);
+
+	return 0;
+}
+
+static int cmr3000_spi_write(struct device *dev, u8 reg, u8 val, char *msg)
+{
+
+	struct spi_device *spi = to_spi_device(dev);
+
+	return cmr3000_spi_cmd(spi, reg, &val, DO_WRITE, msg);
+}
+
+static int cmr3000_spi_read(struct device *dev, u8 reg, char *msg)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	int ret;
+	u8 val;
+
+	ret = cmr3000_spi_cmd(spi, reg, &val, DO_READ, msg);
+	if (ret)
+		return ret;
+	return val;
+}
+
+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] 31+ messages in thread

* [PATCHv2 5/7] Input: add CMR3000 gyrsocope driver
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (8 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  -1 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 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
	-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     |  382 ++++++++++++++++++++++++++++++++++
 drivers/input/misc/cmr3000_d0x.h     |   45 ++++
 drivers/input/misc/cmr3000_d0x_spi.c |  178 ++++++++++++++++
 include/linux/input/cmr3000.h        |   54 +++++
 6 files changed, 685 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..a8b3e8b
--- /dev/null
+++ b/drivers/input/misc/cmr3000_d0x.c
@@ -0,0 +1,382 @@
+/*
+ * 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 "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,
+	.irqflags = 0,
+	.fuzz_x = 1,
+	.fuzz_y = 1,
+	.fuzz_z = 1,
+};
+
+struct cmr3000_gyro_data {
+	const struct cmr3000_bus_ops *bus_ops;
+	const 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);
+
+struct cmr3000_gyro_data *cmr3000_init(struct device *dev, int irq,
+				       const struct cmr3000_bus_ops *bops)
+{
+	const struct cmr3000_platform_data *pdata = dev->platform_data;
+	struct cmr3000_gyro_data *data;
+	struct input_dev *input_dev;
+	int rev;
+	int error;
+
+	if (pdata == NULL) {
+		dev_info(dev, "platform data not found, using default\n");
+		pdata = &cmr3000_default_pdata;
+	}
+
+	/* 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;
+	}
+
+	data->dev = dev;
+	data->input_dev = input_dev;
+	data->bus_ops = bops;
+	data->pdata = pdata;
+	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..6243437
--- /dev/null
+++ b/drivers/input/misc/cmr3000_d0x_spi.c
@@ -0,0 +1,178 @@
+/*
+ * 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"
+
+enum { DO_READ = 0, DO_WRITE };
+
+static int cmr3000_spi_cmd(struct spi_device *spi, u8 reg, u8 * val, int cmd,
+			   char *msg)
+{
+	int ret;
+	unsigned char tx_buf[2];
+	unsigned char rx_buf[2];
+	struct spi_transfer t = {
+		.rx_buf = rx_buf,
+		.tx_buf = tx_buf,
+		.len = 2,
+	};
+	struct spi_message m;
+
+	if (cmd == DO_WRITE) {
+		tx_buf[0] = (reg << 2) | 2;
+		tx_buf[1] = *val;
+	} else {
+		tx_buf[0] = reg << 2;
+		tx_buf[1] = 0;
+	}
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+	ret = spi_sync(spi, &m);
+	if (ret < 0) {
+		dev_err(&spi->dev, "%s failed (%s, %d)\n", __func__, msg, ret);
+		return ret;
+	}
+	if (cmd == DO_READ)
+		*val = rx_buf[1];
+
+	if (rx_buf[0] & 0x41)
+		dev_err(&spi->dev,
+			"%s Invalid Zero mask(0x%x)\n", __func__, rx_buf[0]);
+
+	if ((rx_buf[0] & 0x2) != 0x2)
+		dev_err(&spi->dev,
+			"%s Invalid One mask (0x%x)\n", __func__, rx_buf[0]);
+
+	return 0;
+}
+
+static int cmr3000_spi_write(struct device *dev, u8 reg, u8 val, char *msg)
+{
+
+	struct spi_device *spi = to_spi_device(dev);
+
+	return cmr3000_spi_cmd(spi, reg, &val, DO_WRITE, msg);
+}
+
+static int cmr3000_spi_read(struct device *dev, u8 reg, char *msg)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	int ret;
+	u8 val;
+
+	ret = cmr3000_spi_cmd(spi, reg, &val, DO_READ, msg);
+	if (ret)
+		return ret;
+	return val;
+}
+
+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] 31+ messages in thread

* [PATCHv2 6/7] input/cma3000_d0x: Unwind reverse order of init
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (11 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  2011-10-18 13:15   ` Jonathan Cameron
  -1 siblings, 1 reply; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv, linux-input,
	linux-kernel
  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 e1d27d0..9836264 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -407,8 +407,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] 31+ messages in thread

* [PATCHv2 6/7] input/cma3000_d0x: Unwind reverse order of init
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (10 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  -1 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 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 e1d27d0..9836264 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -407,8 +407,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] 31+ messages in thread

* [PATCHv2 7/7] input/cma3000_d0x: Match comment to name of struct
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (12 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  2011-10-18 13:16   ` Jonathan Cameron
  -1 siblings, 1 reply; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 UTC (permalink / raw)
  To: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, jic23, hemanthv, linux-input,
	linux-kernel
  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] 31+ messages in thread

* [PATCHv2 7/7] input/cma3000_d0x: Match comment to name of struct
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
                   ` (13 preceding siblings ...)
  (?)
@ 2011-10-18 12:06 ` Ricardo Ribalda Delgado
  -1 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:06 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] 31+ messages in thread

* Re: [PATCHv2 1/7] input/cma3000_d0x: Support devices without pdata
  2011-10-18 12:06 ` [PATCHv2 1/7] input/cma3000_d0x: Support devices without pdata Ricardo Ribalda Delgado
@ 2011-10-18 12:53   ` Jonathan Cameron
  2011-10-18 12:58       ` Ricardo Ribalda Delgado
  0 siblings, 1 reply; 31+ messages in thread
From: Jonathan Cameron @ 2011-10-18 12:53 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 13:06, Ricardo Ribalda Delgado wrote:
> Architectures based on device-tree does not have platform data
> associated to the spi/i2c devices.
> This patch allows those architectures to use the cma3000 driver with
> a default configuration.
Fine except for this description. Looks to be a perfectly reasonable
way of specifying these in DT.  So fix that and I'm happy.
Whoever wants to pass this in from DT can do a patch for it!
> 
> ---
> 
> v2: Fixes suggested by Jonathan Cameron
>     -Spelling
>     -Simplify pdata!=NULL check
> 
> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/input/misc/cma3000_d0x.c |   20 +++++++++++++++-----
>  1 files changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
> index 1633b63..f2e87e3 100644
> --- a/drivers/input/misc/cma3000_d0x.c
> +++ b/drivers/input/misc/cma3000_d0x.c
> @@ -62,6 +62,18 @@
>  #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;
> @@ -289,13 +301,11 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
>  	int rev;
>  	int error;
>  
> -	if (!pdata) {
> -		dev_err(dev, "platform data not found\n");
> -		error = -EINVAL;
> -		goto err_out;
> +	if (pdata == NULL) {
> +		dev_info(dev, "platform data not found, using default\n");
> +		pdata = &cma3000_default_pdata;
>  	}
>  
> -
>  	/* if no IRQ return error */
>  	if (irq == 0) {
>  		error = -EINVAL;


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

* Re: [PATCHv2 2/7] input/cma3000_d0x: Check silicon version
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
@ 2011-10-18 12:54   ` Jonathan Cameron
  0 siblings, 0 replies; 31+ messages in thread
From: Jonathan Cameron @ 2011-10-18 12:54 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 13:06, Ricardo Ribalda Delgado wrote:
> 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>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  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 f2e87e3..3877cbe 100644
> --- a/drivers/input/misc/cma3000_d0x.c
> +++ b/drivers/input/misc/cma3000_d0x.c
> @@ -26,6 +26,8 @@
>  
>  #include "cma3000_d0x.h"
>  
> +#define CMA3000_REV         0x10
> +
>  #define CMA3000_WHOAMI      0x00
>  #define CMA3000_REVID       0x01
>  #define CMA3000_CTRL        0x02
> @@ -366,7 +368,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] 31+ messages in thread

* Re: [PATCHv2 1/7] input/cma3000_d0x: Support devices without pdata
  2011-10-18 12:53   ` Jonathan Cameron
@ 2011-10-18 12:58       ` Ricardo Ribalda Delgado
  0 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:58 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, hemanthv, linux-input, linux-kernel

Hello Jonathan

I think I am going to do it like ads1015.c. I will check for the
pdata, then for the dt info (if it is there) and finally go for the
default, if all fails. What do you think? Shall I fix it in cma3000
and cmr3000?

 Thanks again

On Tue, Oct 18, 2011 at 14:53, Jonathan Cameron <jic23@cam.ac.uk> wrote:
> On 10/18/11 13:06, Ricardo Ribalda Delgado wrote:
>> Architectures based on device-tree does not have platform data
>> associated to the spi/i2c devices.
>> This patch allows those architectures to use the cma3000 driver with
>> a default configuration.
> Fine except for this description. Looks to be a perfectly reasonable
> way of specifying these in DT.  So fix that and I'm happy.
> Whoever wants to pass this in from DT can do a patch for it!
>>
>> ---
>>
>> v2: Fixes suggested by Jonathan Cameron
>>     -Spelling
>>     -Simplify pdata!=NULL check
>>
>> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
> Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
>> ---
>>  drivers/input/misc/cma3000_d0x.c |   20 +++++++++++++++-----
>>  1 files changed, 15 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
>> index 1633b63..f2e87e3 100644
>> --- a/drivers/input/misc/cma3000_d0x.c
>> +++ b/drivers/input/misc/cma3000_d0x.c
>> @@ -62,6 +62,18 @@
>>  #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;
>> @@ -289,13 +301,11 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
>>       int rev;
>>       int error;
>>
>> -     if (!pdata) {
>> -             dev_err(dev, "platform data not found\n");
>> -             error = -EINVAL;
>> -             goto err_out;
>> +     if (pdata == NULL) {
>> +             dev_info(dev, "platform data not found, using default\n");
>> +             pdata = &cma3000_default_pdata;
>>       }
>>
>> -
>>       /* if no IRQ return error */
>>       if (irq == 0) {
>>               error = -EINVAL;
>
>



-- 
Ricardo Ribalda

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

* Re: [PATCHv2 1/7] input/cma3000_d0x: Support devices without pdata
@ 2011-10-18 12:58       ` Ricardo Ribalda Delgado
  0 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 12:58 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, hemanthv, linux-input, linux-kernel

Hello Jonathan

I think I am going to do it like ads1015.c. I will check for the
pdata, then for the dt info (if it is there) and finally go for the
default, if all fails. What do you think? Shall I fix it in cma3000
and cmr3000?

 Thanks again

On Tue, Oct 18, 2011 at 14:53, Jonathan Cameron <jic23@cam.ac.uk> wrote:
> On 10/18/11 13:06, Ricardo Ribalda Delgado wrote:
>> Architectures based on device-tree does not have platform data
>> associated to the spi/i2c devices.
>> This patch allows those architectures to use the cma3000 driver with
>> a default configuration.
> Fine except for this description. Looks to be a perfectly reasonable
> way of specifying these in DT.  So fix that and I'm happy.
> Whoever wants to pass this in from DT can do a patch for it!
>>
>> ---
>>
>> v2: Fixes suggested by Jonathan Cameron
>>     -Spelling
>>     -Simplify pdata!=NULL check
>>
>> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
> Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
>> ---
>>  drivers/input/misc/cma3000_d0x.c |   20 +++++++++++++++-----
>>  1 files changed, 15 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
>> index 1633b63..f2e87e3 100644
>> --- a/drivers/input/misc/cma3000_d0x.c
>> +++ b/drivers/input/misc/cma3000_d0x.c
>> @@ -62,6 +62,18 @@
>>  #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;
>> @@ -289,13 +301,11 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
>>       int rev;
>>       int error;
>>
>> -     if (!pdata) {
>> -             dev_err(dev, "platform data not found\n");
>> -             error = -EINVAL;
>> -             goto err_out;
>> +     if (pdata == NULL) {
>> +             dev_info(dev, "platform data not found, using default\n");
>> +             pdata = &cma3000_default_pdata;
>>       }
>>
>> -
>>       /* if no IRQ return error */
>>       if (irq == 0) {
>>               error = -EINVAL;
>
>



-- 
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] 31+ messages in thread

* Re: [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
@ 2011-10-18 13:14   ` Jonathan Cameron
  2011-10-18 13:43     ` Ricardo Ribalda Delgado
  0 siblings, 1 reply; 31+ messages in thread
From: Jonathan Cameron @ 2011-10-18 13:14 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 13:06, Ricardo Ribalda Delgado wrote:
> Add support for SPI communication.
> 
> ---

Hi Ricardo.

Nice fast response ;)

Can you either put a clear arguement in for why those zero and one
mask checks in the cmd function make sense, or drop them and move
to the much shorter / cleaner functions I suggest below.

Jonathan
> 
> 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 |  178 ++++++++++++++++++++++++++++++++++
>  3 files changed, 191 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
interfaces
> +	  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..1487ecf
> --- /dev/null
> +++ b/drivers/input/misc/cma3000_d0x_spi.c
> @@ -0,0 +1,178 @@
> +/*
> + * 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
mis->misc
> + *
> + * 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"
> +
> +enum { DO_READ = 0, DO_WRITE };
> +
no space after * before val
> +static int cma3000_spi_cmd(struct spi_device *spi, u8 reg, u8 * val, int cmd,
> +			   char *msg)
> +{
> +	int ret;
> +	unsigned char tx_buf[2] ____cacheline_aligned;
> +	unsigned char rx_buf[2] ____cacheline_aligned;
Doesn't work (at least I'm fairly sure it doesn't).
These must be dynamically assigned.

To make my point about these functions being more complex than needed
in more detail....

If this were two functions and you drop the zero and 1 mask
(which I'm not convinced make any sense. I've also killed the message.
We both agree it is the wrong way to go, so post a patch fixing the i2c
interface as well.

static int cma3000_spi_write(struct spi_device *spi, u8 reg, u8 *val, int cmd)
{
	int ret;
	u8 *tx = kmalloc(2, GFP_KERNEL);
	if (tx == NULL)
	   return -ENOMEM;
	tx[0] = (reg << 2) | 2;
	tx[1] = *val;
	ret = spi_write(spi, rx, 2);
	kfree(tx);
	return ret;
}

static int cma3000_spi_read(struct spi_device *spi, u8 reg, u8 *val, int cmd)
{
	return spi_w8r8(spi, reg, val);	
}


> +	struct spi_transfer t = {
> +		.rx_buf = rx_buf,
> +		.tx_buf = tx_buf,
> +		.len = 2,
> +	};
> +	struct spi_message m;
> +
> +	if (cmd == DO_WRITE) {
> +		tx_buf[0] = (reg << 2) | 2;
> +		tx_buf[1] = *val;
> +	} else {
> +		tx_buf[0] = reg << 2;
> +		tx_buf[1] = 0;
> +	}
> +	spi_message_init(&m);
> +	spi_message_add_tail(&t, &m);
> +	ret = spi_sync(spi, &m);
> +	if (ret < 0) {
> +		dev_err(&spi->dev, "%s failed (%s, %d)\n", __func__, msg, ret);
> +		return ret;
> +	}
> +	if (cmd == DO_READ)
> +		*val = rx_buf[1];
> +
> +	if (rx_buf[0] & 0xc1)
> +		dev_err(&spi->dev,
> +			"%s Invalid Zero mask(0x%x)\n", __func__, rx_buf[0]);
These are still cryptic to any user who sees them.  Have you ever seen this
occur?  Seems a pretty unlikely bus screw up to me...
> +
> +	if ((rx_buf[0] & 0x2) != 0x2)
> +		dev_err(&spi->dev,
> +			"%s Invalid One mask (0x%x)\n", __func__, rx_buf[0]);
Also, does this every actually happen. I am not a great fan of VTI data sheets
but I think this only occurs at power up?  Could we verify this explicitly once
then ignore?  It makes for a lot cleaner code as seen above.
> +
> +	return 0;
> +}
> +
> +static int cma3000_spi_write(struct device *dev, u8 reg, u8 val, char *msg)
> +{
> +
> +	struct spi_device *spi = to_spi_device(dev);
> +
> +	return cma3000_spi_cmd(spi, reg, &val, DO_WRITE, msg);
> +}
> +
> +static int cma3000_spi_read(struct device *dev, u8 reg, char *msg)
> +{
> +	struct spi_device *spi = to_spi_device(dev);
> +	int ret;
> +	u8 val;
> +
> +	ret = cma3000_spi_cmd(spi, reg, &val, DO_READ, msg);
> +	if (ret)
> +		return ret;
> +	return val;
> +}
Obviously, if I have convinced you of the advantage of splitting read and
write it would make sense to roll these into these two wrapper functions.
Handling the error message out here is also cleaner than pushing it on
down anyway.
> +
> +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] 31+ messages in thread

* Re: [PATCHv2 6/7] input/cma3000_d0x: Unwind reverse order of init
  2011-10-18 12:06 ` Ricardo Ribalda Delgado
@ 2011-10-18 13:15   ` Jonathan Cameron
  0 siblings, 0 replies; 31+ messages in thread
From: Jonathan Cameron @ 2011-10-18 13:15 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 13:06, Ricardo Ribalda Delgado 
> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  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 e1d27d0..9836264 100644
> --- a/drivers/input/misc/cma3000_d0x.c
> +++ b/drivers/input/misc/cma3000_d0x.c
> @@ -407,8 +407,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);


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

* Re: [PATCHv2 7/7] input/cma3000_d0x: Match comment to name of struct
  2011-10-18 12:06 ` [PATCHv2 7/7] input/cma3000_d0x: Match comment to name of struct Ricardo Ribalda Delgado
@ 2011-10-18 13:16   ` Jonathan Cameron
  0 siblings, 0 replies; 31+ messages in thread
From: Jonathan Cameron @ 2011-10-18 13:16 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 13:06, Ricardo Ribalda Delgado wrote:
> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  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


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

* Re: [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support
  2011-10-18 13:14   ` Jonathan Cameron
@ 2011-10-18 13:43     ` Ricardo Ribalda Delgado
  2011-10-18 13:50       ` Jonathan Cameron
  0 siblings, 1 reply; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 13:43 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, hemanthv, linux-input, linux-kernel

Hello Jonathan

  First of all, thanks for your messages :).

> To make my point about these functions being more complex than needed
> in more detail....
>
> If this were two functions and you drop the zero and 1 mask
> (which I'm not convinced make any sense. I've also killed the message.
> We both agree it is the wrong way to go, so post a patch fixing the i2c
> interface as well.

Of course your functions are much more simpler and beautiful than the
fat one I wrote, no doubt about it :). Just three comments

- Checking the one mask and the zero mask is the only way we have to
know if the chip is still there, The absense of that reply should
trigger an IO error or at least a retry. As you point out, the
zero/one mask is only violated on startup.  I just wanted to make it
more risk free, but if you believe it is more clear that way, lets
remove it

- I am not very fun of kmallocing data per write, specially when it is
part of the irq handler, and you expect this to be low latency. What
about allocating a buffer on init time, and use it with a mutex?

-I dont like the push error message to the bottom, but that will mean
a rewrite of the cma3000 driver, shall I go for it?


Thanks again, and  I will post the new version when you reply this :)


-- 
Ricardo Ribalda

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

* Re: [PATCHv2 1/7] input/cma3000_d0x: Support devices without pdata
  2011-10-18 12:58       ` Ricardo Ribalda Delgado
  (?)
@ 2011-10-18 13:45       ` Jonathan Cameron
  -1 siblings, 0 replies; 31+ messages in thread
From: Jonathan Cameron @ 2011-10-18 13:45 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 13:58, Ricardo Ribalda Delgado wrote:
> Hello Jonathan
> 
> I think I am going to do it like ads1015.c. I will check for the
> pdata, then for the dt info (if it is there) and finally go for the
> default, if all fails. What do you think? Shall I fix it in cma3000
> and cmr3000?
That sounds like the best plan to me.  Fix them both.
> 
>  Thanks again
> 
> On Tue, Oct 18, 2011 at 14:53, Jonathan Cameron <jic23@cam.ac.uk> wrote:
>> On 10/18/11 13:06, Ricardo Ribalda Delgado wrote:
>>> Architectures based on device-tree does not have platform data
>>> associated to the spi/i2c devices.
>>> This patch allows those architectures to use the cma3000 driver with
>>> a default configuration.
>> Fine except for this description. Looks to be a perfectly reasonable
>> way of specifying these in DT.  So fix that and I'm happy.
>> Whoever wants to pass this in from DT can do a patch for it!
>>>
>>> ---
>>>
>>> v2: Fixes suggested by Jonathan Cameron
>>>     -Spelling
>>>     -Simplify pdata!=NULL check
>>>
>>> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
>> Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
>>> ---
>>>  drivers/input/misc/cma3000_d0x.c |   20 +++++++++++++++-----
>>>  1 files changed, 15 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
>>> index 1633b63..f2e87e3 100644
>>> --- a/drivers/input/misc/cma3000_d0x.c
>>> +++ b/drivers/input/misc/cma3000_d0x.c
>>> @@ -62,6 +62,18 @@
>>>  #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;
>>> @@ -289,13 +301,11 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
>>>       int rev;
>>>       int error;
>>>
>>> -     if (!pdata) {
>>> -             dev_err(dev, "platform data not found\n");
>>> -             error = -EINVAL;
>>> -             goto err_out;
>>> +     if (pdata == NULL) {
>>> +             dev_info(dev, "platform data not found, using default\n");
>>> +             pdata = &cma3000_default_pdata;
>>>       }
>>>
>>> -
>>>       /* if no IRQ return error */
>>>       if (irq == 0) {
>>>               error = -EINVAL;
>>
>>
> 
> 
> 


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

* Re: [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support
  2011-10-18 13:43     ` Ricardo Ribalda Delgado
@ 2011-10-18 13:50       ` Jonathan Cameron
  2011-10-18 15:18           ` Ricardo Ribalda Delgado
  0 siblings, 1 reply; 31+ messages in thread
From: Jonathan Cameron @ 2011-10-18 13:50 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 14:43, Ricardo Ribalda Delgado wrote:
> Hello Jonathan
> 
>   First of all, thanks for your messages :).
> 
>> To make my point about these functions being more complex than needed
>> in more detail....
>>
>> If this were two functions and you drop the zero and 1 mask
>> (which I'm not convinced make any sense. I've also killed the message.
>> We both agree it is the wrong way to go, so post a patch fixing the i2c
>> interface as well.
> 
> Of course your functions are much more simpler and beautiful than the
> fat one I wrote, no doubt about it :). Just three comments
> 
> - Checking the one mask and the zero mask is the only way we have to
> know if the chip is still there, The absense of that reply should
> trigger an IO error or at least a retry. As you point out, the
> zero/one mask is only violated on startup.  I just wanted to make it
> more risk free, but if you believe it is more clear that way, lets
> remove it
It's somewhat unconventional to verify the existence of a chip like this.
Usually you assume that if it was there once it still is unless there
is a very good reason to think otherwise.  Worth doing an initial check
in your spi_probe and indeed verify there against these known bits.
No need to do it every time though.
> 
> - I am not very fun of kmallocing data per write, specially when it is
> part of the irq handler, and you expect this to be low latency. What
> about allocating a buffer on init time, and use it with a mutex?
That's absolutely fine and the right way to do it. You could poke it
into the cma3000_accl_data then use the cachline aligned magic. Its
is tiny so I doubt anyone will mind the overhead for the i2c side of
things.
> 
> -I dont like the push error message to the bottom, but that will mean
> a rewrite of the cma3000 driver, shall I go for it?
I would. Though probably worth getting Hemanth to say if he minds first
given it's his driver!
> 
> 
> Thanks again, and  I will post the new version when you reply this :)
> 
> 


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

* Re: [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support
  2011-10-18 13:50       ` Jonathan Cameron
@ 2011-10-18 15:18           ` Ricardo Ribalda Delgado
  0 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:18 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, hemanthv, linux-input, linux-kernel

Hello Jonathan

 I have separated the read and write commands... but when I was
implementing the spi_write I found that most of the drivers just use
stack variables for spi_write. Like drivers/hwmon/ads7871.c,
drivers/gpio/max7301.c and others... Am I missing something or it is a
general "bug"?

As you say, it is better to not rewrite the cma3000 driver until
Hemanth says so, lets leave it for a future patch.




On Tue, Oct 18, 2011 at 15:50, Jonathan Cameron <jic23@cam.ac.uk> wrote:
> On 10/18/11 14:43, Ricardo Ribalda Delgado wrote:
>> Hello Jonathan
>>
>>   First of all, thanks for your messages :).
>>
>>> To make my point about these functions being more complex than needed
>>> in more detail....
>>>
>>> If this were two functions and you drop the zero and 1 mask
>>> (which I'm not convinced make any sense. I've also killed the message.
>>> We both agree it is the wrong way to go, so post a patch fixing the i2c
>>> interface as well.
>>
>> Of course your functions are much more simpler and beautiful than the
>> fat one I wrote, no doubt about it :). Just three comments
>>
>> - Checking the one mask and the zero mask is the only way we have to
>> know if the chip is still there, The absense of that reply should
>> trigger an IO error or at least a retry. As you point out, the
>> zero/one mask is only violated on startup.  I just wanted to make it
>> more risk free, but if you believe it is more clear that way, lets
>> remove it
> It's somewhat unconventional to verify the existence of a chip like this.
> Usually you assume that if it was there once it still is unless there
> is a very good reason to think otherwise.  Worth doing an initial check
> in your spi_probe and indeed verify there against these known bits.
> No need to do it every time though.
>>
>> - I am not very fun of kmallocing data per write, specially when it is
>> part of the irq handler, and you expect this to be low latency. What
>> about allocating a buffer on init time, and use it with a mutex?
> That's absolutely fine and the right way to do it. You could poke it
> into the cma3000_accl_data then use the cachline aligned magic. Its
> is tiny so I doubt anyone will mind the overhead for the i2c side of
> things.
>>
>> -I dont like the push error message to the bottom, but that will mean
>> a rewrite of the cma3000 driver, shall I go for it?
> I would. Though probably worth getting Hemanth to say if he minds first
> given it's his driver!
>>
>>
>> Thanks again, and  I will post the new version when you reply this :)
>>
>>
>
>



-- 
Ricardo Ribalda

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

* Re: [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support
@ 2011-10-18 15:18           ` Ricardo Ribalda Delgado
  0 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:18 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, hemanthv, linux-input, linux-kernel

Hello Jonathan

 I have separated the read and write commands... but when I was
implementing the spi_write I found that most of the drivers just use
stack variables for spi_write. Like drivers/hwmon/ads7871.c,
drivers/gpio/max7301.c and others... Am I missing something or it is a
general "bug"?

As you say, it is better to not rewrite the cma3000 driver until
Hemanth says so, lets leave it for a future patch.




On Tue, Oct 18, 2011 at 15:50, Jonathan Cameron <jic23@cam.ac.uk> wrote:
> On 10/18/11 14:43, Ricardo Ribalda Delgado wrote:
>> Hello Jonathan
>>
>>   First of all, thanks for your messages :).
>>
>>> To make my point about these functions being more complex than needed
>>> in more detail....
>>>
>>> If this were two functions and you drop the zero and 1 mask
>>> (which I'm not convinced make any sense. I've also killed the message.
>>> We both agree it is the wrong way to go, so post a patch fixing the i2c
>>> interface as well.
>>
>> Of course your functions are much more simpler and beautiful than the
>> fat one I wrote, no doubt about it :). Just three comments
>>
>> - Checking the one mask and the zero mask is the only way we have to
>> know if the chip is still there, The absense of that reply should
>> trigger an IO error or at least a retry. As you point out, the
>> zero/one mask is only violated on startup.  I just wanted to make it
>> more risk free, but if you believe it is more clear that way, lets
>> remove it
> It's somewhat unconventional to verify the existence of a chip like this.
> Usually you assume that if it was there once it still is unless there
> is a very good reason to think otherwise.  Worth doing an initial check
> in your spi_probe and indeed verify there against these known bits.
> No need to do it every time though.
>>
>> - I am not very fun of kmallocing data per write, specially when it is
>> part of the irq handler, and you expect this to be low latency. What
>> about allocating a buffer on init time, and use it with a mutex?
> That's absolutely fine and the right way to do it. You could poke it
> into the cma3000_accl_data then use the cachline aligned magic. Its
> is tiny so I doubt anyone will mind the overhead for the i2c side of
> things.
>>
>> -I dont like the push error message to the bottom, but that will mean
>> a rewrite of the cma3000 driver, shall I go for it?
> I would. Though probably worth getting Hemanth to say if he minds first
> given it's his driver!
>>
>>
>> Thanks again, and  I will post the new version when you reply this :)
>>
>>
>
>



-- 
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] 31+ messages in thread

* Re: [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support
  2011-10-18 15:18           ` Ricardo Ribalda Delgado
  (?)
@ 2011-10-18 15:27           ` Jonathan Cameron
  2011-10-18 15:50               ` Ricardo Ribalda Delgado
  -1 siblings, 1 reply; 31+ messages in thread
From: Jonathan Cameron @ 2011-10-18 15:27 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:18, Ricardo Ribalda Delgado wrote:
> Hello Jonathan
> 
>  I have separated the read and write commands... but when I was
> implementing the spi_write I found that most of the drivers just use
> stack variables for spi_write. Like drivers/hwmon/ads7871.c,
> drivers/gpio/max7301.c and others... Am I missing something or it is a
> general "bug"?
bug unless I am also missing where they prevent dma
transfers.  spi_read_then_write is fine
as it does a copy, but spi_write doesn't. 
Documentation/spi/spi-summary

"Note that there are two types of memory your driver must manage as part
of interacting with SPI devices.

  - I/O buffers use the usual Linux rules, and must be DMA-safe.
    You'd normally allocate them from the heap or free page pool.
    Don't use the stack, or anything that's declared "static".
"

This was an issue many people (including me) weren't aware of until
a year or two ago when it was picked up in reviews of a number of drivers.
It was around that time the ___cacheline_aligned trick was used by
Michael Hennerich and everyone else picked up on that as often the
easiest way of doing this in a driver.

Don't suppose there is anything stopping you doing 
spi_write_then_read(tx, 2, NULL, 0)
and using the buffers helpfully allocated in the spi core?
This'll allocate extra space if someone else is using the core
bounce buffers though...

> 
> As you say, it is better to not rewrite the cma3000 driver until
> Hemanth says so, lets leave it for a future patch.
> 
> 
> 
> 
> On Tue, Oct 18, 2011 at 15:50, Jonathan Cameron <jic23@cam.ac.uk> wrote:
>> On 10/18/11 14:43, Ricardo Ribalda Delgado wrote:
>>> Hello Jonathan
>>>
>>>   First of all, thanks for your messages :).
>>>
>>>> To make my point about these functions being more complex than needed
>>>> in more detail....
>>>>
>>>> If this were two functions and you drop the zero and 1 mask
>>>> (which I'm not convinced make any sense. I've also killed the message.
>>>> We both agree it is the wrong way to go, so post a patch fixing the i2c
>>>> interface as well.
>>>
>>> Of course your functions are much more simpler and beautiful than the
>>> fat one I wrote, no doubt about it :). Just three comments
>>>
>>> - Checking the one mask and the zero mask is the only way we have to
>>> know if the chip is still there, The absense of that reply should
>>> trigger an IO error or at least a retry. As you point out, the
>>> zero/one mask is only violated on startup.  I just wanted to make it
>>> more risk free, but if you believe it is more clear that way, lets
>>> remove it
>> It's somewhat unconventional to verify the existence of a chip like this.
>> Usually you assume that if it was there once it still is unless there
>> is a very good reason to think otherwise.  Worth doing an initial check
>> in your spi_probe and indeed verify there against these known bits.
>> No need to do it every time though.
>>>
>>> - I am not very fun of kmallocing data per write, specially when it is
>>> part of the irq handler, and you expect this to be low latency. What
>>> about allocating a buffer on init time, and use it with a mutex?
>> That's absolutely fine and the right way to do it. You could poke it
>> into the cma3000_accl_data then use the cachline aligned magic. Its
>> is tiny so I doubt anyone will mind the overhead for the i2c side of
>> things.
>>>
>>> -I dont like the push error message to the bottom, but that will mean
>>> a rewrite of the cma3000 driver, shall I go for it?
>> I would. Though probably worth getting Hemanth to say if he minds first
>> given it's his driver!
>>>
>>>
>>> Thanks again, and  I will post the new version when you reply this :)
>>>
>>>
>>
>>
> 
> 
> 


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

* Re: [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support
  2011-10-18 15:27           ` Jonathan Cameron
@ 2011-10-18 15:50               ` Ricardo Ribalda Delgado
  0 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:50 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, hemanthv, linux-input, linux-kernel

Hello Jonathan

 I just send the mail with the latest patch version. I will wait for
hermanthv to see if he wants to replace the msg from the read/write
functions, and I will follow his style for the cmr3000. I have testest
the latest changes on my board and it looks ok.

  Thanks for your feedback, and I hope it is ok now :)

On Tue, Oct 18, 2011 at 17:27, Jonathan Cameron <jic23@cam.ac.uk> wrote:
> On 10/18/11 16:18, Ricardo Ribalda Delgado wrote:
>> Hello Jonathan
>>
>>  I have separated the read and write commands... but when I was
>> implementing the spi_write I found that most of the drivers just use
>> stack variables for spi_write. Like drivers/hwmon/ads7871.c,
>> drivers/gpio/max7301.c and others... Am I missing something or it is a
>> general "bug"?
> bug unless I am also missing where they prevent dma
> transfers.  spi_read_then_write is fine
> as it does a copy, but spi_write doesn't.
> Documentation/spi/spi-summary
>
> "Note that there are two types of memory your driver must manage as part
> of interacting with SPI devices.
>
>  - I/O buffers use the usual Linux rules, and must be DMA-safe.
>    You'd normally allocate them from the heap or free page pool.
>    Don't use the stack, or anything that's declared "static".
> "
>
> This was an issue many people (including me) weren't aware of until
> a year or two ago when it was picked up in reviews of a number of drivers.
> It was around that time the ___cacheline_aligned trick was used by
> Michael Hennerich and everyone else picked up on that as often the
> easiest way of doing this in a driver.
>
> Don't suppose there is anything stopping you doing
> spi_write_then_read(tx, 2, NULL, 0)
> and using the buffers helpfully allocated in the spi core?
> This'll allocate extra space if someone else is using the core
> bounce buffers though...
>
>>
>> As you say, it is better to not rewrite the cma3000 driver until
>> Hemanth says so, lets leave it for a future patch.
>>
>>
>>
>>
>> On Tue, Oct 18, 2011 at 15:50, Jonathan Cameron <jic23@cam.ac.uk> wrote:
>>> On 10/18/11 14:43, Ricardo Ribalda Delgado wrote:
>>>> Hello Jonathan
>>>>
>>>>   First of all, thanks for your messages :).
>>>>
>>>>> To make my point about these functions being more complex than needed
>>>>> in more detail....
>>>>>
>>>>> If this were two functions and you drop the zero and 1 mask
>>>>> (which I'm not convinced make any sense. I've also killed the message.
>>>>> We both agree it is the wrong way to go, so post a patch fixing the i2c
>>>>> interface as well.
>>>>
>>>> Of course your functions are much more simpler and beautiful than the
>>>> fat one I wrote, no doubt about it :). Just three comments
>>>>
>>>> - Checking the one mask and the zero mask is the only way we have to
>>>> know if the chip is still there, The absense of that reply should
>>>> trigger an IO error or at least a retry. As you point out, the
>>>> zero/one mask is only violated on startup.  I just wanted to make it
>>>> more risk free, but if you believe it is more clear that way, lets
>>>> remove it
>>> It's somewhat unconventional to verify the existence of a chip like this.
>>> Usually you assume that if it was there once it still is unless there
>>> is a very good reason to think otherwise.  Worth doing an initial check
>>> in your spi_probe and indeed verify there against these known bits.
>>> No need to do it every time though.
>>>>
>>>> - I am not very fun of kmallocing data per write, specially when it is
>>>> part of the irq handler, and you expect this to be low latency. What
>>>> about allocating a buffer on init time, and use it with a mutex?
>>> That's absolutely fine and the right way to do it. You could poke it
>>> into the cma3000_accl_data then use the cachline aligned magic. Its
>>> is tiny so I doubt anyone will mind the overhead for the i2c side of
>>> things.
>>>>
>>>> -I dont like the push error message to the bottom, but that will mean
>>>> a rewrite of the cma3000 driver, shall I go for it?
>>> I would. Though probably worth getting Hemanth to say if he minds first
>>> given it's his driver!
>>>>
>>>>
>>>> Thanks again, and  I will post the new version when you reply this :)
>>>>
>>>>
>>>
>>>
>>
>>
>>
>
>



-- 
Ricardo Ribalda

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

* Re: [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support
@ 2011-10-18 15:50               ` Ricardo Ribalda Delgado
  0 siblings, 0 replies; 31+ messages in thread
From: Ricardo Ribalda Delgado @ 2011-10-18 15:50 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: dmitry.torokhov, sameo, peter.ujfalusi, aghayal, david,
	Shubhrajyoti, saaguirre, hemanthv, linux-input, linux-kernel

Hello Jonathan

 I just send the mail with the latest patch version. I will wait for
hermanthv to see if he wants to replace the msg from the read/write
functions, and I will follow his style for the cmr3000. I have testest
the latest changes on my board and it looks ok.

  Thanks for your feedback, and I hope it is ok now :)

On Tue, Oct 18, 2011 at 17:27, Jonathan Cameron <jic23@cam.ac.uk> wrote:
> On 10/18/11 16:18, Ricardo Ribalda Delgado wrote:
>> Hello Jonathan
>>
>>  I have separated the read and write commands... but when I was
>> implementing the spi_write I found that most of the drivers just use
>> stack variables for spi_write. Like drivers/hwmon/ads7871.c,
>> drivers/gpio/max7301.c and others... Am I missing something or it is a
>> general "bug"?
> bug unless I am also missing where they prevent dma
> transfers.  spi_read_then_write is fine
> as it does a copy, but spi_write doesn't.
> Documentation/spi/spi-summary
>
> "Note that there are two types of memory your driver must manage as part
> of interacting with SPI devices.
>
>  - I/O buffers use the usual Linux rules, and must be DMA-safe.
>    You'd normally allocate them from the heap or free page pool.
>    Don't use the stack, or anything that's declared "static".
> "
>
> This was an issue many people (including me) weren't aware of until
> a year or two ago when it was picked up in reviews of a number of drivers.
> It was around that time the ___cacheline_aligned trick was used by
> Michael Hennerich and everyone else picked up on that as often the
> easiest way of doing this in a driver.
>
> Don't suppose there is anything stopping you doing
> spi_write_then_read(tx, 2, NULL, 0)
> and using the buffers helpfully allocated in the spi core?
> This'll allocate extra space if someone else is using the core
> bounce buffers though...
>
>>
>> As you say, it is better to not rewrite the cma3000 driver until
>> Hemanth says so, lets leave it for a future patch.
>>
>>
>>
>>
>> On Tue, Oct 18, 2011 at 15:50, Jonathan Cameron <jic23@cam.ac.uk> wrote:
>>> On 10/18/11 14:43, Ricardo Ribalda Delgado wrote:
>>>> Hello Jonathan
>>>>
>>>>   First of all, thanks for your messages :).
>>>>
>>>>> To make my point about these functions being more complex than needed
>>>>> in more detail....
>>>>>
>>>>> If this were two functions and you drop the zero and 1 mask
>>>>> (which I'm not convinced make any sense. I've also killed the message.
>>>>> We both agree it is the wrong way to go, so post a patch fixing the i2c
>>>>> interface as well.
>>>>
>>>> Of course your functions are much more simpler and beautiful than the
>>>> fat one I wrote, no doubt about it :). Just three comments
>>>>
>>>> - Checking the one mask and the zero mask is the only way we have to
>>>> know if the chip is still there, The absense of that reply should
>>>> trigger an IO error or at least a retry. As you point out, the
>>>> zero/one mask is only violated on startup.  I just wanted to make it
>>>> more risk free, but if you believe it is more clear that way, lets
>>>> remove it
>>> It's somewhat unconventional to verify the existence of a chip like this.
>>> Usually you assume that if it was there once it still is unless there
>>> is a very good reason to think otherwise.  Worth doing an initial check
>>> in your spi_probe and indeed verify there against these known bits.
>>> No need to do it every time though.
>>>>
>>>> - I am not very fun of kmallocing data per write, specially when it is
>>>> part of the irq handler, and you expect this to be low latency. What
>>>> about allocating a buffer on init time, and use it with a mutex?
>>> That's absolutely fine and the right way to do it. You could poke it
>>> into the cma3000_accl_data then use the cachline aligned magic. Its
>>> is tiny so I doubt anyone will mind the overhead for the i2c side of
>>> things.
>>>>
>>>> -I dont like the push error message to the bottom, but that will mean
>>>> a rewrite of the cma3000 driver, shall I go for it?
>>> I would. Though probably worth getting Hemanth to say if he minds first
>>> given it's his driver!
>>>>
>>>>
>>>> Thanks again, and  I will post the new version when you reply this :)
>>>>
>>>>
>>>
>>>
>>
>>
>>
>
>



-- 
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] 31+ messages in thread

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

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-18 12:06 [PATCHv2 0/7] Add spi support for CMA3000 driver and new driver CMR3000 Ricardo Ribalda Delgado
2011-10-18 12:06 ` Ricardo Ribalda Delgado
2011-10-18 12:06 ` [PATCHv2 1/7] input/cma3000_d0x: Support devices without pdata Ricardo Ribalda Delgado
2011-10-18 12:53   ` Jonathan Cameron
2011-10-18 12:58     ` Ricardo Ribalda Delgado
2011-10-18 12:58       ` Ricardo Ribalda Delgado
2011-10-18 13:45       ` Jonathan Cameron
2011-10-18 12:06 ` Ricardo Ribalda Delgado
2011-10-18 12:06 ` [PATCHv2 2/7] input/cma3000_d0x: Check silicon version Ricardo Ribalda Delgado
2011-10-18 12:06 ` Ricardo Ribalda Delgado
2011-10-18 12:54   ` Jonathan Cameron
2011-10-18 12:06 ` [PATCHv2 3/7] input/cma3000_d0x: Keep configuration on poweroff Ricardo Ribalda Delgado
2011-10-18 12:06 ` Ricardo Ribalda Delgado
2011-10-18 12:06 ` [PATCHv2 4/7] input/cma3000_d0x: Add CMA3000 spi support Ricardo Ribalda Delgado
2011-10-18 12:06 ` Ricardo Ribalda Delgado
2011-10-18 13:14   ` Jonathan Cameron
2011-10-18 13:43     ` Ricardo Ribalda Delgado
2011-10-18 13:50       ` Jonathan Cameron
2011-10-18 15:18         ` Ricardo Ribalda Delgado
2011-10-18 15:18           ` Ricardo Ribalda Delgado
2011-10-18 15:27           ` Jonathan Cameron
2011-10-18 15:50             ` Ricardo Ribalda Delgado
2011-10-18 15:50               ` Ricardo Ribalda Delgado
2011-10-18 12:06 ` [PATCHv2 5/7] Input: add CMR3000 gyrsocope driver Ricardo Ribalda Delgado
2011-10-18 12:06 ` Ricardo Ribalda Delgado
2011-10-18 12:06 ` [PATCHv2 6/7] input/cma3000_d0x: Unwind reverse order of init Ricardo Ribalda Delgado
2011-10-18 12:06 ` Ricardo Ribalda Delgado
2011-10-18 13:15   ` Jonathan Cameron
2011-10-18 12:06 ` [PATCHv2 7/7] input/cma3000_d0x: Match comment to name of struct Ricardo Ribalda Delgado
2011-10-18 13:16   ` Jonathan Cameron
2011-10-18 12:06 ` Ricardo Ribalda Delgado

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.