[PATCH 3/4] staging:iio:adis16350 Add optional event support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is fairly complex.  The device provides two alarms
which can be configured as rising or falling thresholds
on the magnitude or the rate of change of any channel.

I have made things a little more manageable by restricting
things so you can't set both alarms to the same setting.

This also rolls in some name changes etc to make possible
use of macros for some elements.

Note there is an issue with event codes for ADC channels (there
are now too many of them) that will need fixing before this merges.

Various other minor fixes are also in here.
---
 drivers/staging/iio/adc/adc.h            |    8 +++-
 drivers/staging/iio/gyro/gyro.h          |   31 ++++++++++----
 drivers/staging/iio/imu/Kconfig          |    7 +++
 drivers/staging/iio/imu/Makefile         |    1 +
 drivers/staging/iio/imu/adis16350.h      |   62 ++++++++++++++++++++++++-----
 drivers/staging/iio/imu/adis16350_core.c |   17 ++++++--
 drivers/staging/iio/imu/adis16350_ring.c |   10 ++--
 drivers/staging/iio/sysfs.h              |   17 ++++++++-
 8 files changed, 122 insertions(+), 31 deletions(-)

diff --git a/drivers/staging/iio/adc/adc.h b/drivers/staging/iio/adc/adc.h
index 953b5ce..2cd2ef9 100644
--- a/drivers/staging/iio/adc/adc.h
+++ b/drivers/staging/iio/adc/adc.h
@@ -11,7 +11,7 @@
 
 /* Deprecated */
 #define IIO_DEV_ATTR_ADC(_num, _show, _addr)			\
-  IIO_DEVICE_ATTR(adc_##_num, S_IRUGO, _show, NULL, _addr)
+	IIO_DEVICE_ATTR(adc_##_num, S_IRUGO, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_IN_RAW(_num, _show, _addr)				\
 	IIO_DEVICE_ATTR(in##_num##_raw, S_IRUGO, _show, NULL, _addr)
@@ -36,3 +36,9 @@
 
 #define IIO_EVENT_CODE_IN_HIGH_THRESH(a) (IIO_EVENT_CODE_ADC_BASE  + a)
 #define IIO_EVENT_CODE_IN_LOW_THRESH(a) (IIO_EVENT_CODE_ADC_BASE  + a + 32)
+#define IIO_EVENT_CODE_IN_HIGH_ROC(a) (IIO_EVENT_CODE_ADC_BASE  + a + 64)
+#define IIO_EVENT_CODE_IN_LOW_ROC(a) (IIO_EVENT_CODE_ADC_BASE  + a + 96)
+#define IIO_EVENT_CODE_IN_SUPPLY_HIGH (IIO_EVENT_CODE_ADC_BASE + 97)
+#define IIO_EVENT_CODE_IN_SUPPLY_LOW (IIO_EVENT_CODE_ADC_BASE + 98)
+#define IIO_EVENT_CODE_IN_SUPPLY_ROC_HIGH (IIO_EVENT_CODE_ADC_BASE + 99)
+#define IIO_EVENT_CODE_IN_SUPPLY_ROC_LOW (IIO_EVENT_CODE_ADC_BASE + 100)
diff --git a/drivers/staging/iio/gyro/gyro.h b/drivers/staging/iio/gyro/gyro.h
index 98b837b..7cda511 100644
--- a/drivers/staging/iio/gyro/gyro.h
+++ b/drivers/staging/iio/gyro/gyro.h
@@ -33,31 +33,31 @@
 #define IIO_DEV_ATTR_GYRO_Z_SCALE(_mode, _show, _store, _addr)		\
 	IIO_DEVICE_ATTR(gyro_z_scale, _mode, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_GYRO_CALIBBIAS(_mode, _show, _store, _addr)		\
+#define IIO_DEV_ATTR_GYRO_CALIBBIAS(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(gyro_calibbias, S_IRUGO, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_GYRO_X_CALIBBIAS(_mode, _show, _store, _addr)		\
+#define IIO_DEV_ATTR_GYRO_X_CALIBBIAS(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(gyro_x_calibbias, _mode, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_GYRO_Y_CALIBBIAS(_mode, _show, _store, _addr)		\
+#define IIO_DEV_ATTR_GYRO_Y_CALIBBIAS(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(gyro_y_calibbias, _mode, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(_mode, _show, _store, _addr)		\
+#define IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(gyro_z_calibbias, _mode, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_GYRO_CALIBSCALE(_mode, _show, _store, _addr)		\
+#define IIO_DEV_ATTR_GYRO_CALIBSCALE(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(gyro_calibscale, S_IRUGO, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_GYRO_X_CALIBSCALE(_mode, _show, _store, _addr)		\
+#define IIO_DEV_ATTR_GYRO_X_CALIBSCALE(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(gyro_x_calibscale, _mode, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_GYRO_Y_CALIBSCALE(_mode, _show, _store, _addr)		\
+#define IIO_DEV_ATTR_GYRO_Y_CALIBSCALE(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(gyro_y_calibscale, _mode, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_GYRO_Z_CALIBSCALE(_mode, _show, _store, _addr)		\
+#define IIO_DEV_ATTR_GYRO_Z_CALIBSCALE(_mode, _show, _store, _addr)	\
 	IIO_DEVICE_ATTR(gyro_z_calibscale, _mode, _show, _store, _addr)
 
-#define IIO_DEV_ATTR_GYRO(_show, _addr)			\
+#define IIO_DEV_ATTR_GYRO(_show, _addr)				\
 	IIO_DEVICE_ATTR(gyro_raw, S_IRUGO, _show, NULL, _addr)
 
 #define IIO_DEV_ATTR_GYRO_X(_show, _addr)			\
@@ -71,3 +71,16 @@
 
 #define IIO_DEV_ATTR_ANGL(_show, _addr)                         \
 	IIO_DEVICE_ATTR(angl_raw, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_EVENT_CODE_GYRO_X_HIGH (IIO_EVENT_CODE_GYRO_BASE)
+#define IIO_EVENT_CODE_GYRO_X_LOW (IIO_EVENT_CODE_GYRO_BASE + 1)
+#define IIO_EVENT_CODE_GYRO_X_ROC_HIGH (IIO_EVENT_CODE_GYRO_BASE + 2)
+#define IIO_EVENT_CODE_GYRO_X_ROC_LOW (IIO_EVENT_CODE_GYRO_BASE + 3)
+#define IIO_EVENT_CODE_GYRO_Y_HIGH (IIO_EVENT_CODE_GYRO_BASE + 4)
+#define IIO_EVENT_CODE_GYRO_Y_LOW (IIO_EVENT_CODE_GYRO_BASE + 5)
+#define IIO_EVENT_CODE_GYRO_Y_ROC_HIGH (IIO_EVENT_CODE_GYRO_BASE + 6)
+#define IIO_EVENT_CODE_GYRO_Y_ROC_LOW (IIO_EVENT_CODE_GYRO_BASE + 7)
+#define IIO_EVENT_CODE_GYRO_Z_HIGH (IIO_EVENT_CODE_GYRO_BASE+ 8)
+#define IIO_EVENT_CODE_GYRO_Z_LOW (IIO_EVENT_CODE_GYRO_BASE + 9)
+#define IIO_EVENT_CODE_GYRO_Z_ROC_HIGH (IIO_EVENT_CODE_GYRO_BASE + 10)
+#define IIO_EVENT_CODE_GYRO_Z_ROC_LOW (IIO_EVENT_CODE_GYRO_BASE + 11)
diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig
index 31a6233..11a4984 100644
--- a/drivers/staging/iio/imu/Kconfig
+++ b/drivers/staging/iio/imu/Kconfig
@@ -21,6 +21,13 @@ config ADIS16350
 	  Say yes here to build support for Analog Devices adis16350/54/55/60/62/64/65
 	  high precision tri-axis inertial sensor.
 
+if ADIS16350
+config ADIS16350_EVENT
+       bool "Enable events on the ADIS16350"
+       help
+	 Threshold and rate of change events for all channels.
+endif #ADIS16350
+
 config ADIS16400
 	tristate "Analog Devices ADIS16400/5 IMU SPI driver"
 	depends on SPI
diff --git a/drivers/staging/iio/imu/Makefile b/drivers/staging/iio/imu/Makefile
index f3b450b..551a20f 100644
--- a/drivers/staging/iio/imu/Makefile
+++ b/drivers/staging/iio/imu/Makefile
@@ -7,6 +7,7 @@ adis16300-$(CONFIG_IIO_RING_BUFFER) += adis16300_ring.o adis16300_trigger.o
 obj-$(CONFIG_ADIS16300) += adis16300.o
 
 adis16350-y             := adis16350_core.o
+adis16350-$(CONFIG_ADIS16350_EVENT) += adis16350_event.o
 adis16350-$(CONFIG_IIO_RING_BUFFER) += adis16350_ring.o adis16350_trigger.o
 obj-$(CONFIG_ADIS16350) += adis16350.o
 
diff --git a/drivers/staging/iio/imu/adis16350.h b/drivers/staging/iio/imu/adis16350.h
index 07d3eeb..948fe75 100644
--- a/drivers/staging/iio/imu/adis16350.h
+++ b/drivers/staging/iio/imu/adis16350.h
@@ -108,6 +108,13 @@
  * @rx:			recieve buffer
  * @buf_lock:		mutex to protect tx and rx
  * @burst_available:	does the device support burst reading
+ * @event_lock:		protect event state
+ * @event_irq:		irq for event line
+ * @event_timestamp:	local store for time of last event
+ * @work_event:		work struct for event bh
+ * @thresh_cache:	cache of thresholds for all the various alarms
+ * @smpl_cache:		cache of sample period for ROC alarms
+ * @active_alarms:	which alarms are on (in terms of attribute mask)
  **/
 struct adis16350_state {
 	struct spi_device		*us;
@@ -119,23 +126,56 @@ struct adis16350_state {
 	u8				*rx;
 	struct mutex			buf_lock;
 	unsigned int			burst_available:1;
+#ifdef CONFIG_ADIS16350_EVENT
+	struct mutex			event_lock;
+	int				event_irq;
+	s64				event_timestamp;
+	struct work_struct		work_event;
+	s16				thresh_cache[44];
+	u8				smpl_cache[22];
+	int				active_alarms[2];
+	unsigned int			oldest_alarm:1;
+	u8				alarm_on[2];
+#endif
 };
 
 int adis16350_set_irq(struct device *dev, bool enable);
 
+int adis16350_spi_read_reg_16(struct device *dev,
+			u8 lower_reg_address,
+			u16 *val);
+
+int adis16350_spi_write_reg_16(struct device *dev,
+			u8 lower_reg_address,
+			u16 value);
+
+#ifdef CONFIG_ADIS16350_EVENT
+int adis16350_configure_event_line(struct adis16350_state *st,
+				int interrupt);
+void adis16350_unconfigure_event_line(struct adis16350_state *st);
+#else
+static inline int adis16350_configure_event_line(struct adis16350_state *st,
+						int interrupt)
+{
+	return 0;
+}
+static inline void adis16350_unconfigure_event_line(struct adis16350_state *st)
+{
+}
+#endif
 #ifdef CONFIG_IIO_RING_BUFFER
 
-#define ADIS16350_SCAN_SUPPLY	0
-#define ADIS16350_SCAN_GYRO_X	1
-#define ADIS16350_SCAN_GYRO_Y	2
-#define ADIS16350_SCAN_GYRO_Z	3
-#define ADIS16350_SCAN_ACC_X	4
-#define ADIS16350_SCAN_ACC_Y	5
-#define ADIS16350_SCAN_ACC_Z	6
-#define ADIS16350_SCAN_TEMP_X	7
-#define ADIS16350_SCAN_TEMP_Y	8
-#define ADIS16350_SCAN_TEMP_Z	9
-#define ADIS16350_SCAN_ADC_0	10
+#define ADIS16350_SCAN_IN_SUPPLY	0
+#define ADIS16350_SCAN_GYRO_X		1
+#define ADIS16350_SCAN_GYRO_Y		2
+#define ADIS16350_SCAN_GYRO_Z		3
+#define ADIS16350_SCAN_ACCEL_X		4
+#define ADIS16350_SCAN_ACCEL_Y		5
+#define ADIS16350_SCAN_ACCEL_Z		6
+#define ADIS16350_SCAN_TEMP_X		7
+#define ADIS16350_SCAN_TEMP_Y		8
+#define ADIS16350_SCAN_TEMP_Z		9
+#define ADIS16350_SCAN_IN0		10
 
 void adis16350_remove_trigger(struct iio_dev *indio_dev);
 int adis16350_probe_trigger(struct iio_dev *indio_dev);
diff --git a/drivers/staging/iio/imu/adis16350_core.c b/drivers/staging/iio/imu/adis16350_core.c
index e500a5c..8480dc2 100644
--- a/drivers/staging/iio/imu/adis16350_core.c
+++ b/drivers/staging/iio/imu/adis16350_core.c
@@ -62,7 +62,7 @@ static int adis16350_spi_write_reg_8(struct device *dev,
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16350_spi_write_reg_16(struct device *dev,
+int adis16350_spi_write_reg_16(struct device *dev,
 		u8 lower_reg_address,
 		u16 value)
 {
@@ -108,7 +108,7 @@ static int adis16350_spi_write_reg_16(struct device *dev,
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16350_spi_read_reg_16(struct device *dev,
+int adis16350_spi_read_reg_16(struct device *dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
@@ -641,13 +641,22 @@ static int __devinit adis16350_probe(struct spi_device *spi)
 		if (ret)
 			goto error_uninitialize_ring;
 	}
-
+	/* The event irq */
+	if (spi->dev.platform_data) {
+		ret = adis16350_configure_event_line(st,
+						*(int *)spi->dev.platform_data);
+ 		if (ret)
+			goto error_remove_trigger;
+ 	}
 	/* Get the device into a sane initial state */
 	ret = adis16350_initial_setup(st);
 	if (ret)
-		goto error_remove_trigger;
+		goto error_unregister_event_line;
+
 	return 0;
 
+error_unregister_event_line:
+	adis16350_unconfigure_event_line(st);
 error_remove_trigger:
 	if (spi->irq)
 		adis16350_remove_trigger(st->indio_dev);
diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
index 1970247..9af0345 100644
--- a/drivers/staging/iio/imu/adis16350_ring.c
+++ b/drivers/staging/iio/imu/adis16350_ring.c
@@ -17,7 +17,7 @@
 #include "../trigger.h"
 #include "adis16350.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16350_SCAN_SUPPLY, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in_supply, ADIS16350_SCAN_IN_SUPPLY, IIO_UNSIGNED(12),
 		ADIS16350_SUPPLY_OUT, NULL);
 
 static IIO_SCAN_EL_C(gyro_x, ADIS16350_SCAN_GYRO_X, IIO_SIGNED(14),
@@ -27,11 +27,11 @@ static IIO_SCAN_EL_C(gyro_y, ADIS16350_SCAN_GYRO_Y, IIO_SIGNED(14),
 static IIO_SCAN_EL_C(gyro_z, ADIS16350_SCAN_GYRO_Z, IIO_SIGNED(14),
 		ADIS16350_ZGYRO_OUT, NULL);
 
-static IIO_SCAN_EL_C(accel_x, ADIS16350_SCAN_ACC_X, IIO_SIGNED(14),
+static IIO_SCAN_EL_C(accel_x, ADIS16350_SCAN_ACCEL_X, IIO_SIGNED(14),
 		ADIS16350_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16350_SCAN_ACC_Y, IIO_SIGNED(14),
+static IIO_SCAN_EL_C(accel_y, ADIS16350_SCAN_ACCEL_Y, IIO_SIGNED(14),
 		ADIS16350_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_z, ADIS16350_SCAN_ACC_Z, IIO_SIGNED(14),
+static IIO_SCAN_EL_C(accel_z, ADIS16350_SCAN_ACCEL_Z, IIO_SIGNED(14),
 		ADIS16350_ZACCL_OUT, NULL);
 
 static IIO_SCAN_EL_C(temp_x, ADIS16350_SCAN_TEMP_X, IIO_SIGNED(12),
@@ -41,7 +41,7 @@ static IIO_SCAN_EL_C(temp_y, ADIS16350_SCAN_TEMP_Y, IIO_SIGNED(12),
 static IIO_SCAN_EL_C(temp_z, ADIS16350_SCAN_TEMP_Z, IIO_SIGNED(12),
 		ADIS16350_ZTEMP_OUT, NULL);
 
-static IIO_SCAN_EL_C(in0, ADIS16350_SCAN_ADC_0, IIO_UNSIGNED(12),
+static IIO_SCAN_EL_C(in0, ADIS16350_SCAN_IN0, IIO_UNSIGNED(12),
 		ADIS16350_AUX_ADC, NULL);
 
 static IIO_SCAN_EL_TIMESTAMP(11);
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
index b531dc1..bd3edd4 100644
--- a/drivers/staging/iio/sysfs.h
+++ b/drivers/staging/iio/sysfs.h
@@ -63,7 +63,7 @@ struct iio_const_attr {
 	container_of(_dev_attr, struct iio_const_attr, dev_attr)
 
 /* Some attributes will be hard coded (device dependent) and not require an
-   address, in these cases pass a negative */
+ * address, in these cases pass a negative */
 #define IIO_ATTR(_name, _mode, _show, _store, _addr)		\
 	{ .dev_attr = __ATTR(_name, _mode, _show, _store),	\
 	  .address = _addr }
@@ -256,8 +256,23 @@ struct iio_const_attr {
 #define IIO_EVENT_CODE_ADC_BASE		500
 #define IIO_EVENT_CODE_MISC_BASE	600
 #define IIO_EVENT_CODE_LIGHT_BASE	700
+#define IIO_EVENT_CODE_TEMP_BASE	800
 
 #define IIO_EVENT_CODE_DEVICE_SPECIFIC	1000
+/* Can we make these a little more predictable rather than
+ * just adding new ones when they turn up? */
+#define IIO_EVENT_CODE_TEMP_X_HIGH (IIO_EVENT_CODE_TEMP_BASE)
+#define IIO_EVENT_CODE_TEMP_X_LOW (IIO_EVENT_CODE_TEMP_BASE + 1)
+#define IIO_EVENT_CODE_TEMP_X_ROC_HIGH (IIO_EVENT_CODE_TEMP_BASE + 2)
+#define IIO_EVENT_CODE_TEMP_X_ROC_LOW (IIO_EVENT_CODE_TEMP_BASE + 3)
+#define IIO_EVENT_CODE_TEMP_Y_HIGH (IIO_EVENT_CODE_TEMP_BASE + 4)
+#define IIO_EVENT_CODE_TEMP_Y_LOW (IIO_EVENT_CODE_TEMP_BASE + 5)
+#define IIO_EVENT_CODE_TEMP_Y_ROC_HIGH (IIO_EVENT_CODE_TEMP_BASE + 6)
+#define IIO_EVENT_CODE_TEMP_Y_ROC_LOW (IIO_EVENT_CODE_TEMP_BASE + 7)
+#define IIO_EVENT_CODE_TEMP_Z_HIGH (IIO_EVENT_CODE_TEMP_BASE + 8)
+#define IIO_EVENT_CODE_TEMP_Z_LOW (IIO_EVENT_CODE_TEMP_BASE + 9)
+#define IIO_EVENT_CODE_TEMP_Z_ROC_HIGH (IIO_EVENT_CODE_TEMP_BASE + 10)
+#define IIO_EVENT_CODE_TEMP_Z_ROC_LOW (IIO_EVENT_CODE_TEMP_BASE + 11)
 
 /**
  * IIO_EVENT_ATTR_RING_50_FULL - ring buffer event to indicate 50% full
-- 
1.7.0.4

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


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux