[PATCH v1] iio: accel: kxcjk-1013: Support thresholds

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

 



From: Srinivas Pandruvada <srinivas.pandruvada@xxxxxxxxxxxxxxx>

This chip has a motion detect capability. Using IIO events to
specify thresholds and pushing events.
In addition a new trigger of type any-motion is added, which
pushes data to buffer only when there is any movement.

Change list:
Comments addressed for
Re: [PATCH 5/6] iio: accel: kxcjk-1013: Support thresholds
Date: 07/20/2014

- Both motion detect and data ready can be enabled together
- Sending RISING/FALLING events based on int status
- Separate interrupt configuration for data ready and motion detect

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@xxxxxxxxxxxxxxx>
---
 drivers/iio/accel/kxcjk-1013.c | 499 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 448 insertions(+), 51 deletions(-)

diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index 57c515b..b4d6d7a 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -27,6 +27,7 @@
 #include <linux/iio/sysfs.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/trigger.h>
+#include <linux/iio/events.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/accel/kxcjk_1013.h>
@@ -75,16 +76,30 @@
 
 #define KXCJK1013_SLEEP_DELAY_MS	2000
 
+#define KXCJK1013_REG_INT_SRC2_BIT_ZP	BIT(0)
+#define KXCJK1013_REG_INT_SRC2_BIT_ZN	BIT(1)
+#define KXCJK1013_REG_INT_SRC2_BIT_YP	BIT(2)
+#define KXCJK1013_REG_INT_SRC2_BIT_YN	BIT(3)
+#define KXCJK1013_REG_INT_SRC2_BIT_XP	BIT(4)
+#define KXCJK1013_REG_INT_SRC2_BIT_XN	BIT(5)
+
+#define KXCJK1013_DEFAULT_WAKE_THRES	1
+
 struct kxcjk1013_data {
 	struct i2c_client *client;
-	struct iio_trigger *trig;
-	bool trig_mode;
+	struct iio_trigger *dready_trig;
+	struct iio_trigger *motion_trig;
 	struct mutex mutex;
 	s16 buffer[8];
 	u8 odr_bits;
 	u8 range;
+	int wake_thres;
+	int wake_dur;
 	bool active_high_intr;
-	bool trigger_on;
+	bool dready_trigger_on;
+	int ev_enable_state;
+	bool motion_trigger_on;
+	int64_t timestamp;
 };
 
 enum kxcjk1013_axis {
@@ -131,6 +146,23 @@ static const struct {
 			      {19163, 1, 0},
 			      {38326, 0, 1} };
 
+static const struct {
+	int val;
+	int val2;
+	int odr_bits;
+} wake_odr_data_rate_table[] = { {0, 781000, 0x00},
+				 {1, 563000, 0x01},
+				 {3, 125000, 0x02},
+				 {6, 250000, 0x03},
+				 {12, 500000, 0x04},
+				 {25, 0, 0x05},
+				 {50, 0, 0x06},
+				 {100, 0, 0x06},
+				 {200, 0, 0x06},
+				 {400, 0, 0x06},
+				 {800, 0, 0x06},
+				 {1600, 0, 0x06} };
+
 static int kxcjk1013_set_mode(struct kxcjk1013_data *data,
 			      enum kxcjk1013_mode mode)
 {
@@ -241,7 +273,6 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data)
 
 	data->range = KXCJK1013_RANGE_4G;
 
-
 	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_DATA_CTRL);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error reading reg_data_ctrl\n");
@@ -273,6 +304,8 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data)
 	if (ret < 0)
 		return ret;
 
+	data->wake_thres = KXCJK1013_DEFAULT_WAKE_THRES;
+
 	return 0;
 }
 
@@ -307,8 +340,96 @@ static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
 	return 0;
 }
 
-static int kxcjk1013_chip_setup_interrupt(struct kxcjk1013_data *data,
-					  bool status)
+static int kxcjk1013_chip_update_thresholds(struct kxcjk1013_data *data)
+{
+	int ret;
+
+	ret = i2c_smbus_write_byte_data(data->client,
+					KXCJK1013_REG_WAKE_TIMER,
+					data->wake_dur);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"Error writing reg_wake_timer\n");
+		return ret;
+	}
+
+	ret = i2c_smbus_write_byte_data(data->client,
+					KXCJK1013_REG_WAKE_THRES,
+					data->wake_thres);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_wake_thres\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int kxcjk1013_setup_any_motion_interrupt(struct kxcjk1013_data *data,
+						bool status)
+{
+	int ret;
+	enum kxcjk1013_mode store_mode;
+
+	ret = kxcjk1013_get_mode(data, &store_mode);
+	if (ret < 0)
+		return ret;
+
+	/* This is requirement by spec to change state to STANDBY */
+	ret = kxcjk1013_set_mode(data, STANDBY);
+	if (ret < 0)
+		return ret;
+
+	ret = kxcjk1013_chip_update_thresholds(data);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_CTRL1);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_int_ctrl1\n");
+		return ret;
+	}
+
+	if (status)
+		ret |= KXCJK1013_REG_INT_REG1_BIT_IEN;
+	else
+		ret &= ~KXCJK1013_REG_INT_REG1_BIT_IEN;
+
+	ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_INT_CTRL1,
+					ret);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
+		return ret;
+	}
+
+	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+		return ret;
+	}
+
+	if (status)
+		ret |= KXCJK1013_REG_CTRL1_BIT_WUFE;
+	else
+		ret &= ~KXCJK1013_REG_CTRL1_BIT_WUFE;
+
+	ret = i2c_smbus_write_byte_data(data->client,
+					KXCJK1013_REG_CTRL1, ret);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+		return ret;
+	}
+
+	if (store_mode == OPERATION) {
+		ret = kxcjk1013_set_mode(data, OPERATION);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int kxcjk1013_setup_new_data_interrupt(struct kxcjk1013_data *data,
+					      bool status)
 {
 	int ret;
 	enum kxcjk1013_mode store_mode;
@@ -381,6 +502,20 @@ static int kxcjk1013_convert_freq_to_bit(int val, int val2)
 	return -EINVAL;
 }
 
+static int kxcjk1013_convert_wake_odr_to_bit(int val, int val2)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(wake_odr_data_rate_table); ++i) {
+		if (wake_odr_data_rate_table[i].val == val &&
+			wake_odr_data_rate_table[i].val2 == val2) {
+			return wake_odr_data_rate_table[i].odr_bits;
+		}
+	}
+
+	return -EINVAL;
+}
+
 static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2)
 {
 	int ret;
@@ -409,6 +544,17 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2)
 
 	data->odr_bits = odr_bits;
 
+	odr_bits = kxcjk1013_convert_wake_odr_to_bit(val, val2);
+	if (odr_bits < 0)
+		return odr_bits;
+
+	ret = i2c_smbus_write_byte_data(data->client, KXCJK1013_REG_CTRL2,
+					odr_bits);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_ctrl2\n");
+		return ret;
+	}
+
 	if (store_mode == OPERATION) {
 		ret = kxcjk1013_set_mode(data, OPERATION);
 		if (ret < 0)
@@ -560,12 +706,120 @@ static int kxcjk1013_write_raw(struct iio_dev *indio_dev,
 	return ret;
 }
 
+static int kxcjk1013_read_event(struct iio_dev *indio_dev,
+				   const struct iio_chan_spec *chan,
+				   enum iio_event_type type,
+				   enum iio_event_direction dir,
+				   enum iio_event_info info,
+				   int *val, int *val2)
+{
+	struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+	*val2 = 0;
+	switch (info) {
+	case IIO_EV_INFO_VALUE:
+		*val = data->wake_thres;
+		break;
+	case IIO_EV_INFO_PERIOD:
+		*val = data->wake_dur;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return IIO_VAL_INT;
+}
+
+static int kxcjk1013_write_event(struct iio_dev *indio_dev,
+				    const struct iio_chan_spec *chan,
+				    enum iio_event_type type,
+				    enum iio_event_direction dir,
+				    enum iio_event_info info,
+				    int val, int val2)
+{
+	struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+	if (data->ev_enable_state)
+		return -EBUSY;
+
+	switch (info) {
+	case IIO_EV_INFO_VALUE:
+		data->wake_thres = val;
+		break;
+	case IIO_EV_INFO_PERIOD:
+		data->wake_dur = val;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int kxcjk1013_read_event_config(struct iio_dev *indio_dev,
+					  const struct iio_chan_spec *chan,
+					  enum iio_event_type type,
+					  enum iio_event_direction dir)
+{
+
+	struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+	return data->ev_enable_state;
+}
+
+static int kxcjk1013_write_event_config(struct iio_dev *indio_dev,
+					   const struct iio_chan_spec *chan,
+					   enum iio_event_type type,
+					   enum iio_event_direction dir,
+					   int state)
+{
+	struct kxcjk1013_data *data = iio_priv(indio_dev);
+	int ret;
+
+	if (state && data->ev_enable_state)
+		return 0;
+
+	mutex_lock(&data->mutex);
+
+	if (!state && data->motion_trigger_on) {
+		data->ev_enable_state = 0;
+		mutex_unlock(&data->mutex);
+		return 0;
+	}
+
+	/*
+	 * We will expect the enable and disable to do operation in
+	 * in reverse order. This will happen here anyway as our
+	 * resume operation uses sync mode runtime pm calls, the
+	 * suspend operation will be delayed by autosuspend delay
+	 * So the disable operation will still happen in reverse of
+	 * enable operation. When runtime pm is disabled the mode
+	 * is always on so sequence doesn't matter
+	 */
+	ret = kxcjk1013_set_power_state(data, state);
+	if (ret < 0) {
+		mutex_unlock(&data->mutex);
+		return ret;
+	}
+
+	ret =  kxcjk1013_setup_any_motion_interrupt(data, state);
+	if (ret < 0) {
+		mutex_unlock(&data->mutex);
+		return ret;
+	}
+
+	data->ev_enable_state = state;
+	mutex_unlock(&data->mutex);
+
+	return 0;
+}
+
 static int kxcjk1013_validate_trigger(struct iio_dev *indio_dev,
 				      struct iio_trigger *trig)
 {
 	struct kxcjk1013_data *data = iio_priv(indio_dev);
 
-	if (data->trig != trig)
+	if (data->dready_trig != trig && data->motion_trig != trig)
 		return -EINVAL;
 
 	return 0;
@@ -586,6 +840,14 @@ static const struct attribute_group kxcjk1013_attrs_group = {
 	.attrs = kxcjk1013_attributes,
 };
 
+static const struct iio_event_spec kxcjk1013_event = {
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_RISING | IIO_EV_DIR_FALLING,
+		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
+				 BIT(IIO_EV_INFO_ENABLE) |
+				 BIT(IIO_EV_INFO_PERIOD)
+};
+
 #define KXCJK1013_CHANNEL(_axis) {					\
 	.type = IIO_ACCEL,						\
 	.modified = 1,							\
@@ -601,6 +863,8 @@ static const struct attribute_group kxcjk1013_attrs_group = {
 		.shift = 4,						\
 		.endianness = IIO_CPU,					\
 	},								\
+	.event_spec = &kxcjk1013_event,				\
+	.num_event_specs = 1						\
 }
 
 static const struct iio_chan_spec kxcjk1013_channels[] = {
@@ -614,6 +878,10 @@ static const struct iio_info kxcjk1013_info = {
 	.attrs			= &kxcjk1013_attrs_group,
 	.read_raw		= kxcjk1013_read_raw,
 	.write_raw		= kxcjk1013_write_raw,
+	.read_event_value	= kxcjk1013_read_event,
+	.write_event_value	= kxcjk1013_write_event,
+	.write_event_config	= kxcjk1013_write_event_config,
+	.read_event_config	= kxcjk1013_read_event_config,
 	.validate_trigger	= kxcjk1013_validate_trigger,
 	.driver_module		= THIS_MODULE,
 };
@@ -639,7 +907,7 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p)
 	mutex_unlock(&data->mutex);
 
 	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
-					   pf->timestamp);
+					   data->timestamp);
 err:
 	iio_trigger_notify_done(indio_dev->trig);
 
@@ -668,19 +936,32 @@ static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	struct kxcjk1013_data *data = iio_priv(indio_dev);
 	int ret;
 
-	if (state && data->trigger_on)
+	mutex_lock(&data->mutex);
+
+	if (!state && data->ev_enable_state && data->motion_trigger_on) {
+		data->motion_trigger_on = false;
+		mutex_unlock(&data->mutex);
 		return 0;
+	}
 
-	mutex_lock(&data->mutex);
-	ret = kxcjk1013_chip_setup_interrupt(data, state);
-	if (!ret) {
-		ret = kxcjk1013_set_power_state(data, state);
-		if (ret < 0) {
-			mutex_unlock(&data->mutex);
-			return ret;
-		}
+	ret = kxcjk1013_set_power_state(data, state);
+	if (ret < 0) {
+		mutex_unlock(&data->mutex);
+		return ret;
 	}
-	data->trigger_on = state;
+	if (data->motion_trig == trig)
+		ret = kxcjk1013_setup_any_motion_interrupt(data, state);
+	else
+		ret = kxcjk1013_setup_new_data_interrupt(data, state);
+	if (ret < 0) {
+		mutex_unlock(&data->mutex);
+		return ret;
+	}
+	if (data->motion_trig == trig)
+		data->motion_trigger_on = state;
+	else
+		data->dready_trigger_on = state;
+
 	mutex_unlock(&data->mutex);
 
 	return 0;
@@ -692,6 +973,109 @@ static const struct iio_trigger_ops kxcjk1013_trigger_ops = {
 	.owner = THIS_MODULE,
 };
 
+static irqreturn_t kxcjk1013_event_handler(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct kxcjk1013_data *data = iio_priv(indio_dev);
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_SRC1);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_int_src1\n");
+		goto ack_intr;
+	}
+
+	if (ret & 0x02) {
+		ret = i2c_smbus_read_byte_data(data->client,
+					       KXCJK1013_REG_INT_SRC2);
+		if (ret < 0) {
+			dev_err(&data->client->dev,
+				"Error reading reg_int_src2\n");
+			goto ack_intr;
+		}
+
+		if (ret & KXCJK1013_REG_INT_SRC2_BIT_XN)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_X,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_FALLING),
+				       data->timestamp);
+		if (ret & KXCJK1013_REG_INT_SRC2_BIT_XP)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_X,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_RISING),
+				       data->timestamp);
+
+
+		if (ret & KXCJK1013_REG_INT_SRC2_BIT_YN)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_Y,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_FALLING),
+				       data->timestamp);
+		if (ret & KXCJK1013_REG_INT_SRC2_BIT_YP)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_Y,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_RISING),
+				       data->timestamp);
+
+		if (ret & KXCJK1013_REG_INT_SRC2_BIT_ZN)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_Z,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_FALLING),
+				       data->timestamp);
+		if (ret & KXCJK1013_REG_INT_SRC2_BIT_ZP)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_Z,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_RISING),
+				       data->timestamp);
+	}
+
+ack_intr:
+	if (data->dready_trigger_on)
+		return IRQ_HANDLED;
+
+	ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_REL);
+	if (ret < 0)
+		dev_err(&data->client->dev, "Error reading reg_int_rel\n");
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+	data->timestamp = iio_get_time_ns();
+
+	if (data->dready_trigger_on)
+		iio_trigger_poll(data->dready_trig);
+	else if (data->motion_trigger_on)
+		iio_trigger_poll(data->motion_trig);
+
+	if (data->ev_enable_state)
+		return IRQ_WAKE_THREAD;
+	else
+		return IRQ_HANDLED;
+}
+
 static int kxcjk1013_acpi_gpio_probe(struct i2c_client *client,
 				     struct kxcjk1013_data *data)
 {
@@ -734,7 +1118,6 @@ static int kxcjk1013_probe(struct i2c_client *client,
 {
 	struct kxcjk1013_data *data;
 	struct iio_dev *indio_dev;
-	struct iio_trigger *trig = NULL;
 	struct kxcjk_1013_platform_data *pdata;
 	int ret;
 
@@ -769,33 +1152,47 @@ static int kxcjk1013_probe(struct i2c_client *client,
 		client->irq = kxcjk1013_acpi_gpio_probe(client, data);
 
 	if (client->irq >= 0) {
-		trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
-					 indio_dev->id);
-		if (!trig)
-			return -ENOMEM;
+		ret = devm_request_threaded_irq(
+						&client->dev, client->irq,
+						kxcjk1013_data_rdy_trig_poll,
+						kxcjk1013_event_handler,
+						IRQF_TRIGGER_RISING,
+						KXCJK1013_IRQ_NAME,
+						indio_dev);
+		if (ret)
+			return ret;
 
-		data->trig_mode = true;
+		data->dready_trig = devm_iio_trigger_alloc(&client->dev,
+							   "%s-dev%d",
+							   indio_dev->name,
+							   indio_dev->id);
+		if (!data->dready_trig)
+			return -ENOMEM;
 
-		ret = devm_request_irq(&client->dev, client->irq,
-					iio_trigger_generic_data_rdy_poll,
-					IRQF_TRIGGER_RISING,
-					KXCJK1013_IRQ_NAME,
-					trig);
-		if (ret) {
-			dev_err(&client->dev, "unable to request IRQ\n");
-			goto err_trigger_free;
-		}
+		data->motion_trig = devm_iio_trigger_alloc(&client->dev,
+							  "%s-any-motion-dev%d",
+							  indio_dev->name,
+							  indio_dev->id);
+		if (!data->motion_trig)
+			return -ENOMEM;
 
-		trig->dev.parent = &client->dev;
-		trig->ops = &kxcjk1013_trigger_ops;
-		iio_trigger_set_drvdata(trig, indio_dev);
-		data->trig = trig;
-		indio_dev->trig = trig;
+		data->dready_trig->dev.parent = &client->dev;
+		data->dready_trig->ops = &kxcjk1013_trigger_ops;
+		iio_trigger_set_drvdata(data->dready_trig, indio_dev);
+		indio_dev->trig = data->dready_trig;
 		iio_trigger_get(indio_dev->trig);
-
-		ret = iio_trigger_register(trig);
+		ret = iio_trigger_register(data->dready_trig);
 		if (ret)
-			goto err_trigger_free;
+			return ret;
+
+		data->motion_trig->dev.parent = &client->dev;
+		data->motion_trig->ops = &kxcjk1013_trigger_ops;
+		iio_trigger_set_drvdata(data->motion_trig, indio_dev);
+		ret = iio_trigger_register(data->motion_trig);
+		if (ret) {
+			data->motion_trig = NULL;
+			goto err_trigger_unregister;
+		}
 
 		ret = iio_triggered_buffer_setup(indio_dev,
 						&iio_pollfunc_store_time,
@@ -828,14 +1225,13 @@ static int kxcjk1013_probe(struct i2c_client *client,
 err_iio_unregister:
 	iio_device_unregister(indio_dev);
 err_buffer_cleanup:
-	if (data->trig_mode)
+	if (data->dready_trig)
 		iio_triggered_buffer_cleanup(indio_dev);
 err_trigger_unregister:
-	if (data->trig_mode)
-		iio_trigger_unregister(trig);
-err_trigger_free:
-	if (data->trig_mode)
-		iio_trigger_free(trig);
+	if (data->dready_trig)
+		iio_trigger_unregister(data->dready_trig);
+	if (data->motion_trig)
+		iio_trigger_unregister(data->motion_trig);
 
 	return ret;
 }
@@ -851,10 +1247,10 @@ static int kxcjk1013_remove(struct i2c_client *client)
 
 	iio_device_unregister(indio_dev);
 
-	if (data->trig_mode) {
+	if (data->dready_trig) {
 		iio_triggered_buffer_cleanup(indio_dev);
-		iio_trigger_unregister(data->trig);
-		iio_trigger_free(data->trig);
+		iio_trigger_unregister(data->dready_trig);
+		iio_trigger_unregister(data->motion_trig);
 	}
 
 	mutex_lock(&data->mutex);
@@ -886,7 +1282,8 @@ static int kxcjk1013_resume(struct device *dev)
 
 	mutex_lock(&data->mutex);
 	/* Check, if the suspend occured while active */
-	if (data->trigger_on)
+	if (data->dready_trigger_on || data->motion_trigger_on ||
+							data->ev_enable_state)
 		ret = kxcjk1013_set_mode(data, OPERATION);
 	mutex_unlock(&data->mutex);
 
-- 
1.9.3

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