* [PATCH v1] iio: accel: kxcjk-1013: Support thresholds
@ 2014-08-22 19:01 Srinivas Pandruvada
2014-08-26 20:02 ` Jonathan Cameron
0 siblings, 1 reply; 3+ messages in thread
From: Srinivas Pandruvada @ 2014-08-22 19:01 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, Srinivas Pandruvada
From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
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@linux.intel.com>
---
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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v1] iio: accel: kxcjk-1013: Support thresholds
2014-08-22 19:01 [PATCH v1] iio: accel: kxcjk-1013: Support thresholds Srinivas Pandruvada
@ 2014-08-26 20:02 ` Jonathan Cameron
2014-08-26 20:07 ` Pandruvada, Srinivas
0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Cameron @ 2014-08-26 20:02 UTC (permalink / raw)
To: Srinivas Pandruvada; +Cc: linux-iio, Srinivas Pandruvada
On 22/08/14 20:01, Srinivas Pandruvada wrote:
> From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
>
> 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@linux.intel.com>
Looks good - a couple of idle thoughts inline.
Applied to the togreg branch of iio.git.
Thanks,
Jonathan
> ---
> 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;
> + }
> +
Could do this whole set as a combination of for_each_set_bit and
a lookup table for the event codes (or the elements used to build
them). Would make it a little more apparent that this is really
picking between constant values...
Mind you, might well prove more complex than what we have here!
> + 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(
Why the new line before the arguements?
> + &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);
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v1] iio: accel: kxcjk-1013: Support thresholds
2014-08-26 20:02 ` Jonathan Cameron
@ 2014-08-26 20:07 ` Pandruvada, Srinivas
0 siblings, 0 replies; 3+ messages in thread
From: Pandruvada, Srinivas @ 2014-08-26 20:07 UTC (permalink / raw)
To: jic23@kernel.org; +Cc: linux-iio@vger.kernel.org
T24gVHVlLCAyMDE0LTA4LTI2IGF0IDIxOjAyICswMTAwLCBKb25hdGhhbiBDYW1lcm9uIHdyb3Rl
Og0KPiBPbiAyMi8wOC8xNCAyMDowMSwgU3Jpbml2YXMgUGFuZHJ1dmFkYSB3cm90ZToNCj4gPiBG
cm9tOiBTcmluaXZhcyBQYW5kcnV2YWRhIDxzcmluaXZhcy5wYW5kcnV2YWRhQGxpbnV4LmludGVs
LmNvbT4NCj4gPiANCj4gPiBUaGlzIGNoaXAgaGFzIGEgbW90aW9uIGRldGVjdCBjYXBhYmlsaXR5
LiBVc2luZyBJSU8gZXZlbnRzIHRvDQo+ID4gc3BlY2lmeSB0aHJlc2hvbGRzIGFuZCBwdXNoaW5n
IGV2ZW50cy4NCj4gPiBJbiBhZGRpdGlvbiBhIG5ldyB0cmlnZ2VyIG9mIHR5cGUgYW55LW1vdGlv
biBpcyBhZGRlZCwgd2hpY2gNCj4gPiBwdXNoZXMgZGF0YSB0byBidWZmZXIgb25seSB3aGVuIHRo
ZXJlIGlzIGFueSBtb3ZlbWVudC4NCj4gPiANCj4gPiBDaGFuZ2UgbGlzdDoNCj4gPiBDb21tZW50
cyBhZGRyZXNzZWQgZm9yDQo+ID4gUmU6IFtQQVRDSCA1LzZdIGlpbzogYWNjZWw6IGt4Y2prLTEw
MTM6IFN1cHBvcnQgdGhyZXNob2xkcw0KPiA+IERhdGU6IDA3LzIwLzIwMTQNCj4gPiANCj4gPiAt
IEJvdGggbW90aW9uIGRldGVjdCBhbmQgZGF0YSByZWFkeSBjYW4gYmUgZW5hYmxlZCB0b2dldGhl
cg0KPiA+IC0gU2VuZGluZyBSSVNJTkcvRkFMTElORyBldmVudHMgYmFzZWQgb24gaW50IHN0YXR1
cw0KPiA+IC0gU2VwYXJhdGUgaW50ZXJydXB0IGNvbmZpZ3VyYXRpb24gZm9yIGRhdGEgcmVhZHkg
YW5kIG1vdGlvbiBkZXRlY3QNCj4gPiANCj4gPiBTaWduZWQtb2ZmLWJ5OiBTcmluaXZhcyBQYW5k
cnV2YWRhIDxzcmluaXZhcy5wYW5kcnV2YWRhQGxpbnV4LmludGVsLmNvbT4NCj4gTG9va3MgZ29v
ZCAtIGEgY291cGxlIG9mIGlkbGUgdGhvdWdodHMgaW5saW5lLg0KPiANCkkgd2lsbCBjaGVjayBv
biB0aG9zZS4NCg0KVGhhbmtzLA0KU3Jpbml2YXMNCj4gQXBwbGllZCB0byB0aGUgdG9ncmVnIGJy
YW5jaCBvZiBpaW8uZ2l0Lg0KPiANCj4gVGhhbmtzLA0KPiANCj4gSm9uYXRoYW4NCj4gPiAtLS0N
Cj4gPiAgZHJpdmVycy9paW8vYWNjZWwva3hjamstMTAxMy5jIHwgNDk5ICsrKysrKysrKysrKysr
KysrKysrKysrKysrKysrKysrKysrKy0tLS0tDQo+ID4gIDEgZmlsZSBjaGFuZ2VkLCA0NDggaW5z
ZXJ0aW9ucygrKSwgNTEgZGVsZXRpb25zKC0pDQo+ID4gDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZl
cnMvaWlvL2FjY2VsL2t4Y2prLTEwMTMuYyBiL2RyaXZlcnMvaWlvL2FjY2VsL2t4Y2prLTEwMTMu
Yw0KPiA+IGluZGV4IDU3YzUxNWIuLmI0ZDZkN2EgMTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVycy9p
aW8vYWNjZWwva3hjamstMTAxMy5jDQo+ID4gKysrIGIvZHJpdmVycy9paW8vYWNjZWwva3hjamst
MTAxMy5jDQo+ID4gQEAgLTI3LDYgKzI3LDcgQEANCj4gPiAgI2luY2x1ZGUgPGxpbnV4L2lpby9z
eXNmcy5oPg0KPiA+ICAjaW5jbHVkZSA8bGludXgvaWlvL2J1ZmZlci5oPg0KPiA+ICAjaW5jbHVk
ZSA8bGludXgvaWlvL3RyaWdnZXIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2lpby9ldmVudHMu
aD4NCj4gPiAgI2luY2x1ZGUgPGxpbnV4L2lpby90cmlnZ2VyX2NvbnN1bWVyLmg+DQo+ID4gICNp
bmNsdWRlIDxsaW51eC9paW8vdHJpZ2dlcmVkX2J1ZmZlci5oPg0KPiA+ICAjaW5jbHVkZSA8bGlu
dXgvaWlvL2FjY2VsL2t4Y2prXzEwMTMuaD4NCj4gPiBAQCAtNzUsMTYgKzc2LDMwIEBADQo+ID4g
IA0KPiA+ICAjZGVmaW5lIEtYQ0pLMTAxM19TTEVFUF9ERUxBWV9NUwkyMDAwDQo+ID4gIA0KPiA+
ICsjZGVmaW5lIEtYQ0pLMTAxM19SRUdfSU5UX1NSQzJfQklUX1pQCUJJVCgwKQ0KPiA+ICsjZGVm
aW5lIEtYQ0pLMTAxM19SRUdfSU5UX1NSQzJfQklUX1pOCUJJVCgxKQ0KPiA+ICsjZGVmaW5lIEtY
Q0pLMTAxM19SRUdfSU5UX1NSQzJfQklUX1lQCUJJVCgyKQ0KPiA+ICsjZGVmaW5lIEtYQ0pLMTAx
M19SRUdfSU5UX1NSQzJfQklUX1lOCUJJVCgzKQ0KPiA+ICsjZGVmaW5lIEtYQ0pLMTAxM19SRUdf
SU5UX1NSQzJfQklUX1hQCUJJVCg0KQ0KPiA+ICsjZGVmaW5lIEtYQ0pLMTAxM19SRUdfSU5UX1NS
QzJfQklUX1hOCUJJVCg1KQ0KPiA+ICsNCj4gPiArI2RlZmluZSBLWENKSzEwMTNfREVGQVVMVF9X
QUtFX1RIUkVTCTENCj4gPiArDQo+ID4gIHN0cnVjdCBreGNqazEwMTNfZGF0YSB7DQo+ID4gIAlz
dHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50Ow0KPiA+IC0Jc3RydWN0IGlpb190cmlnZ2VyICp0cmln
Ow0KPiA+IC0JYm9vbCB0cmlnX21vZGU7DQo+ID4gKwlzdHJ1Y3QgaWlvX3RyaWdnZXIgKmRyZWFk
eV90cmlnOw0KPiA+ICsJc3RydWN0IGlpb190cmlnZ2VyICptb3Rpb25fdHJpZzsNCj4gPiAgCXN0
cnVjdCBtdXRleCBtdXRleDsNCj4gPiAgCXMxNiBidWZmZXJbOF07DQo+ID4gIAl1OCBvZHJfYml0
czsNCj4gPiAgCXU4IHJhbmdlOw0KPiA+ICsJaW50IHdha2VfdGhyZXM7DQo+ID4gKwlpbnQgd2Fr
ZV9kdXI7DQo+ID4gIAlib29sIGFjdGl2ZV9oaWdoX2ludHI7DQo+ID4gLQlib29sIHRyaWdnZXJf
b247DQo+ID4gKwlib29sIGRyZWFkeV90cmlnZ2VyX29uOw0KPiA+ICsJaW50IGV2X2VuYWJsZV9z
dGF0ZTsNCj4gPiArCWJvb2wgbW90aW9uX3RyaWdnZXJfb247DQo+ID4gKwlpbnQ2NF90IHRpbWVz
dGFtcDsNCj4gPiAgfTsNCj4gPiAgDQo+ID4gIGVudW0ga3hjamsxMDEzX2F4aXMgew0KPiA+IEBA
IC0xMzEsNiArMTQ2LDIzIEBAIHN0YXRpYyBjb25zdCBzdHJ1Y3Qgew0KPiA+ICAJCQkgICAgICB7
MTkxNjMsIDEsIDB9LA0KPiA+ICAJCQkgICAgICB7MzgzMjYsIDAsIDF9IH07DQo+ID4gIA0KPiA+
ICtzdGF0aWMgY29uc3Qgc3RydWN0IHsNCj4gPiArCWludCB2YWw7DQo+ID4gKwlpbnQgdmFsMjsN
Cj4gPiArCWludCBvZHJfYml0czsNCj4gPiArfSB3YWtlX29kcl9kYXRhX3JhdGVfdGFibGVbXSA9
IHsgezAsIDc4MTAwMCwgMHgwMH0sDQo+ID4gKwkJCQkgezEsIDU2MzAwMCwgMHgwMX0sDQo+ID4g
KwkJCQkgezMsIDEyNTAwMCwgMHgwMn0sDQo+ID4gKwkJCQkgezYsIDI1MDAwMCwgMHgwM30sDQo+
ID4gKwkJCQkgezEyLCA1MDAwMDAsIDB4MDR9LA0KPiA+ICsJCQkJIHsyNSwgMCwgMHgwNX0sDQo+
ID4gKwkJCQkgezUwLCAwLCAweDA2fSwNCj4gPiArCQkJCSB7MTAwLCAwLCAweDA2fSwNCj4gPiAr
CQkJCSB7MjAwLCAwLCAweDA2fSwNCj4gPiArCQkJCSB7NDAwLCAwLCAweDA2fSwNCj4gPiArCQkJ
CSB7ODAwLCAwLCAweDA2fSwNCj4gPiArCQkJCSB7MTYwMCwgMCwgMHgwNn0gfTsNCj4gPiArDQo+
ID4gIHN0YXRpYyBpbnQga3hjamsxMDEzX3NldF9tb2RlKHN0cnVjdCBreGNqazEwMTNfZGF0YSAq
ZGF0YSwNCj4gPiAgCQkJICAgICAgZW51bSBreGNqazEwMTNfbW9kZSBtb2RlKQ0KPiA+ICB7DQo+
ID4gQEAgLTI0MSw3ICsyNzMsNiBAQCBzdGF0aWMgaW50IGt4Y2prMTAxM19jaGlwX2luaXQoc3Ry
dWN0IGt4Y2prMTAxM19kYXRhICpkYXRhKQ0KPiA+ICANCj4gPiAgCWRhdGEtPnJhbmdlID0gS1hD
SksxMDEzX1JBTkdFXzRHOw0KPiA+ICANCj4gPiAtDQo+ID4gIAlyZXQgPSBpMmNfc21idXNfcmVh
ZF9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LCBLWENKSzEwMTNfUkVHX0RBVEFfQ1RSTCk7DQo+ID4g
IAlpZiAocmV0IDwgMCkgew0KPiA+ICAJCWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2LCAiRXJy
b3IgcmVhZGluZyByZWdfZGF0YV9jdHJsXG4iKTsNCj4gPiBAQCAtMjczLDYgKzMwNCw4IEBAIHN0
YXRpYyBpbnQga3hjamsxMDEzX2NoaXBfaW5pdChzdHJ1Y3Qga3hjamsxMDEzX2RhdGEgKmRhdGEp
DQo+ID4gIAlpZiAocmV0IDwgMCkNCj4gPiAgCQlyZXR1cm4gcmV0Ow0KPiA+ICANCj4gPiArCWRh
dGEtPndha2VfdGhyZXMgPSBLWENKSzEwMTNfREVGQVVMVF9XQUtFX1RIUkVTOw0KPiA+ICsNCj4g
PiAgCXJldHVybiAwOw0KPiA+ICB9DQo+ID4gIA0KPiA+IEBAIC0zMDcsOCArMzQwLDk2IEBAIHN0
YXRpYyBpbnQga3hjamsxMDEzX3NldF9wb3dlcl9zdGF0ZShzdHJ1Y3Qga3hjamsxMDEzX2RhdGEg
KmRhdGEsIGJvb2wgb24pDQo+ID4gIAlyZXR1cm4gMDsNCj4gPiAgfQ0KPiA+ICANCj4gPiAtc3Rh
dGljIGludCBreGNqazEwMTNfY2hpcF9zZXR1cF9pbnRlcnJ1cHQoc3RydWN0IGt4Y2prMTAxM19k
YXRhICpkYXRhLA0KPiA+IC0JCQkJCSAgYm9vbCBzdGF0dXMpDQo+ID4gK3N0YXRpYyBpbnQga3hj
amsxMDEzX2NoaXBfdXBkYXRlX3RocmVzaG9sZHMoc3RydWN0IGt4Y2prMTAxM19kYXRhICpkYXRh
KQ0KPiA+ICt7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiArCXJldCA9IGkyY19zbWJ1c193
cml0ZV9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ICsJCQkJCUtYQ0pLMTAxM19SRUdfV0FL
RV9USU1FUiwNCj4gPiArCQkJCQlkYXRhLT53YWtlX2R1cik7DQo+ID4gKwlpZiAocmV0IDwgMCkg
ew0KPiA+ICsJCWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2LA0KPiA+ICsJCQkiRXJyb3Igd3Jp
dGluZyByZWdfd2FrZV90aW1lclxuIik7DQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArCX0NCj4g
PiArDQo+ID4gKwlyZXQgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwN
Cj4gPiArCQkJCQlLWENKSzEwMTNfUkVHX1dBS0VfVEhSRVMsDQo+ID4gKwkJCQkJZGF0YS0+d2Fr
ZV90aHJlcyk7DQo+ID4gKwlpZiAocmV0IDwgMCkgew0KPiA+ICsJCWRldl9lcnIoJmRhdGEtPmNs
aWVudC0+ZGV2LCAiRXJyb3Igd3JpdGluZyByZWdfd2FrZV90aHJlc1xuIik7DQo+ID4gKwkJcmV0
dXJuIHJldDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsN
Cj4gPiArc3RhdGljIGludCBreGNqazEwMTNfc2V0dXBfYW55X21vdGlvbl9pbnRlcnJ1cHQoc3Ry
dWN0IGt4Y2prMTAxM19kYXRhICpkYXRhLA0KPiA+ICsJCQkJCQlib29sIHN0YXR1cykNCj4gPiAr
ew0KPiA+ICsJaW50IHJldDsNCj4gPiArCWVudW0ga3hjamsxMDEzX21vZGUgc3RvcmVfbW9kZTsN
Cj4gPiArDQo+ID4gKwlyZXQgPSBreGNqazEwMTNfZ2V0X21vZGUoZGF0YSwgJnN0b3JlX21vZGUp
Ow0KPiA+ICsJaWYgKHJldCA8IDApDQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwkv
KiBUaGlzIGlzIHJlcXVpcmVtZW50IGJ5IHNwZWMgdG8gY2hhbmdlIHN0YXRlIHRvIFNUQU5EQlkg
Ki8NCj4gPiArCXJldCA9IGt4Y2prMTAxM19zZXRfbW9kZShkYXRhLCBTVEFOREJZKTsNCj4gPiAr
CWlmIChyZXQgPCAwKQ0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKw0KPiA+ICsJcmV0ID0ga3hj
amsxMDEzX2NoaXBfdXBkYXRlX3RocmVzaG9sZHMoZGF0YSk7DQo+ID4gKwlpZiAocmV0IDwgMCkN
Cj4gPiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsNCj4gPiArCXJldCA9IGkyY19zbWJ1c19yZWFkX2J5
dGVfZGF0YShkYXRhLT5jbGllbnQsIEtYQ0pLMTAxM19SRUdfSU5UX0NUUkwxKTsNCj4gPiArCWlm
IChyZXQgPCAwKSB7DQo+ID4gKwkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciBy
ZWFkaW5nIHJlZ19pbnRfY3RybDFcbiIpOw0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+
ID4gKw0KPiA+ICsJaWYgKHN0YXR1cykNCj4gPiArCQlyZXQgfD0gS1hDSksxMDEzX1JFR19JTlRf
UkVHMV9CSVRfSUVOOw0KPiA+ICsJZWxzZQ0KPiA+ICsJCXJldCAmPSB+S1hDSksxMDEzX1JFR19J
TlRfUkVHMV9CSVRfSUVOOw0KPiA+ICsNCj4gPiArCXJldCA9IGkyY19zbWJ1c193cml0ZV9ieXRl
X2RhdGEoZGF0YS0+Y2xpZW50LCBLWENKSzEwMTNfUkVHX0lOVF9DVFJMMSwNCj4gPiArCQkJCQly
ZXQpOw0KPiA+ICsJaWYgKHJldCA8IDApIHsNCj4gPiArCQlkZXZfZXJyKCZkYXRhLT5jbGllbnQt
PmRldiwgIkVycm9yIHdyaXRpbmcgcmVnX2ludF9jdHJsMVxuIik7DQo+ID4gKwkJcmV0dXJuIHJl
dDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXQgPSBpMmNfc21idXNfcmVhZF9ieXRlX2RhdGEo
ZGF0YS0+Y2xpZW50LCBLWENKSzEwMTNfUkVHX0NUUkwxKTsNCj4gPiArCWlmIChyZXQgPCAwKSB7
DQo+ID4gKwkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciByZWFkaW5nIHJlZ19j
dHJsMVxuIik7DQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlpZiAo
c3RhdHVzKQ0KPiA+ICsJCXJldCB8PSBLWENKSzEwMTNfUkVHX0NUUkwxX0JJVF9XVUZFOw0KPiA+
ICsJZWxzZQ0KPiA+ICsJCXJldCAmPSB+S1hDSksxMDEzX1JFR19DVFJMMV9CSVRfV1VGRTsNCj4g
PiArDQo+ID4gKwlyZXQgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwN
Cj4gPiArCQkJCQlLWENKSzEwMTNfUkVHX0NUUkwxLCByZXQpOw0KPiA+ICsJaWYgKHJldCA8IDAp
IHsNCj4gPiArCQlkZXZfZXJyKCZkYXRhLT5jbGllbnQtPmRldiwgIkVycm9yIHdyaXRpbmcgcmVn
X2N0cmwxXG4iKTsNCj4gPiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCWlm
IChzdG9yZV9tb2RlID09IE9QRVJBVElPTikgew0KPiA+ICsJCXJldCA9IGt4Y2prMTAxM19zZXRf
bW9kZShkYXRhLCBPUEVSQVRJT04pOw0KPiA+ICsJCWlmIChyZXQgPCAwKQ0KPiA+ICsJCQlyZXR1
cm4gcmV0Ow0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0K
PiA+ICtzdGF0aWMgaW50IGt4Y2prMTAxM19zZXR1cF9uZXdfZGF0YV9pbnRlcnJ1cHQoc3RydWN0
IGt4Y2prMTAxM19kYXRhICpkYXRhLA0KPiA+ICsJCQkJCSAgICAgIGJvb2wgc3RhdHVzKQ0KPiA+
ICB7DQo+ID4gIAlpbnQgcmV0Ow0KPiA+ICAJZW51bSBreGNqazEwMTNfbW9kZSBzdG9yZV9tb2Rl
Ow0KPiA+IEBAIC0zODEsNiArNTAyLDIwIEBAIHN0YXRpYyBpbnQga3hjamsxMDEzX2NvbnZlcnRf
ZnJlcV90b19iaXQoaW50IHZhbCwgaW50IHZhbDIpDQo+ID4gIAlyZXR1cm4gLUVJTlZBTDsNCj4g
PiAgfQ0KPiA+ICANCj4gPiArc3RhdGljIGludCBreGNqazEwMTNfY29udmVydF93YWtlX29kcl90
b19iaXQoaW50IHZhbCwgaW50IHZhbDIpDQo+ID4gK3sNCj4gPiArCWludCBpOw0KPiA+ICsNCj4g
PiArCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKHdha2Vfb2RyX2RhdGFfcmF0ZV90YWJsZSk7
ICsraSkgew0KPiA+ICsJCWlmICh3YWtlX29kcl9kYXRhX3JhdGVfdGFibGVbaV0udmFsID09IHZh
bCAmJg0KPiA+ICsJCQl3YWtlX29kcl9kYXRhX3JhdGVfdGFibGVbaV0udmFsMiA9PSB2YWwyKSB7
DQo+ID4gKwkJCXJldHVybiB3YWtlX29kcl9kYXRhX3JhdGVfdGFibGVbaV0ub2RyX2JpdHM7DQo+
ID4gKwkJfQ0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldHVybiAtRUlOVkFMOw0KPiA+ICt9DQo+
ID4gKw0KPiA+ICBzdGF0aWMgaW50IGt4Y2prMTAxM19zZXRfb2RyKHN0cnVjdCBreGNqazEwMTNf
ZGF0YSAqZGF0YSwgaW50IHZhbCwgaW50IHZhbDIpDQo+ID4gIHsNCj4gPiAgCWludCByZXQ7DQo+
ID4gQEAgLTQwOSw2ICs1NDQsMTcgQEAgc3RhdGljIGludCBreGNqazEwMTNfc2V0X29kcihzdHJ1
Y3Qga3hjamsxMDEzX2RhdGEgKmRhdGEsIGludCB2YWwsIGludCB2YWwyKQ0KPiA+ICANCj4gPiAg
CWRhdGEtPm9kcl9iaXRzID0gb2RyX2JpdHM7DQo+ID4gIA0KPiA+ICsJb2RyX2JpdHMgPSBreGNq
azEwMTNfY29udmVydF93YWtlX29kcl90b19iaXQodmFsLCB2YWwyKTsNCj4gPiArCWlmIChvZHJf
Yml0cyA8IDApDQo+ID4gKwkJcmV0dXJuIG9kcl9iaXRzOw0KPiA+ICsNCj4gPiArCXJldCA9IGky
Y19zbWJ1c193cml0ZV9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LCBLWENKSzEwMTNfUkVHX0NUUkwy
LA0KPiA+ICsJCQkJCW9kcl9iaXRzKTsNCj4gPiArCWlmIChyZXQgPCAwKSB7DQo+ID4gKwkJZGV2
X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB3cml0aW5nIHJlZ19jdHJsMlxuIik7DQo+
ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArCX0NCj4gPiArDQo+ID4gIAlpZiAoc3RvcmVfbW9kZSA9
PSBPUEVSQVRJT04pIHsNCj4gPiAgCQlyZXQgPSBreGNqazEwMTNfc2V0X21vZGUoZGF0YSwgT1BF
UkFUSU9OKTsNCj4gPiAgCQlpZiAocmV0IDwgMCkNCj4gPiBAQCAtNTYwLDEyICs3MDYsMTIwIEBA
IHN0YXRpYyBpbnQga3hjamsxMDEzX3dyaXRlX3JhdyhzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2
LA0KPiA+ICAJcmV0dXJuIHJldDsNCj4gPiAgfQ0KPiA+ICANCj4gPiArc3RhdGljIGludCBreGNq
azEwMTNfcmVhZF9ldmVudChzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2LA0KPiA+ICsJCQkJICAg
Y29uc3Qgc3RydWN0IGlpb19jaGFuX3NwZWMgKmNoYW4sDQo+ID4gKwkJCQkgICBlbnVtIGlpb19l
dmVudF90eXBlIHR5cGUsDQo+ID4gKwkJCQkgICBlbnVtIGlpb19ldmVudF9kaXJlY3Rpb24gZGly
LA0KPiA+ICsJCQkJICAgZW51bSBpaW9fZXZlbnRfaW5mbyBpbmZvLA0KPiA+ICsJCQkJICAgaW50
ICp2YWwsIGludCAqdmFsMikNCj4gPiArew0KPiA+ICsJc3RydWN0IGt4Y2prMTAxM19kYXRhICpk
YXRhID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsNCj4gPiArDQo+ID4gKwkqdmFsMiA9IDA7DQo+ID4g
Kwlzd2l0Y2ggKGluZm8pIHsNCj4gPiArCWNhc2UgSUlPX0VWX0lORk9fVkFMVUU6DQo+ID4gKwkJ
KnZhbCA9IGRhdGEtPndha2VfdGhyZXM7DQo+ID4gKwkJYnJlYWs7DQo+ID4gKwljYXNlIElJT19F
Vl9JTkZPX1BFUklPRDoNCj4gPiArCQkqdmFsID0gZGF0YS0+d2FrZV9kdXI7DQo+ID4gKwkJYnJl
YWs7DQo+ID4gKwlkZWZhdWx0Og0KPiA+ICsJCXJldHVybiAtRUlOVkFMOw0KPiA+ICsJfQ0KPiA+
ICsNCj4gPiArCXJldHVybiBJSU9fVkFMX0lOVDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGlj
IGludCBreGNqazEwMTNfd3JpdGVfZXZlbnQoc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiwNCj4g
PiArCQkJCSAgICBjb25zdCBzdHJ1Y3QgaWlvX2NoYW5fc3BlYyAqY2hhbiwNCj4gPiArCQkJCSAg
ICBlbnVtIGlpb19ldmVudF90eXBlIHR5cGUsDQo+ID4gKwkJCQkgICAgZW51bSBpaW9fZXZlbnRf
ZGlyZWN0aW9uIGRpciwNCj4gPiArCQkJCSAgICBlbnVtIGlpb19ldmVudF9pbmZvIGluZm8sDQo+
ID4gKwkJCQkgICAgaW50IHZhbCwgaW50IHZhbDIpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBreGNq
azEwMTNfZGF0YSAqZGF0YSA9IGlpb19wcml2KGluZGlvX2Rldik7DQo+ID4gKw0KPiA+ICsJaWYg
KGRhdGEtPmV2X2VuYWJsZV9zdGF0ZSkNCj4gPiArCQlyZXR1cm4gLUVCVVNZOw0KPiA+ICsNCj4g
PiArCXN3aXRjaCAoaW5mbykgew0KPiA+ICsJY2FzZSBJSU9fRVZfSU5GT19WQUxVRToNCj4gPiAr
CQlkYXRhLT53YWtlX3RocmVzID0gdmFsOw0KPiA+ICsJCWJyZWFrOw0KPiA+ICsJY2FzZSBJSU9f
RVZfSU5GT19QRVJJT0Q6DQo+ID4gKwkJZGF0YS0+d2FrZV9kdXIgPSB2YWw7DQo+ID4gKwkJYnJl
YWs7DQo+ID4gKwlkZWZhdWx0Og0KPiA+ICsJCXJldHVybiAtRUlOVkFMOw0KPiA+ICsJfQ0KPiA+
ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IGt4Y2pr
MTAxM19yZWFkX2V2ZW50X2NvbmZpZyhzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2LA0KPiA+ICsJ
CQkJCSAgY29uc3Qgc3RydWN0IGlpb19jaGFuX3NwZWMgKmNoYW4sDQo+ID4gKwkJCQkJICBlbnVt
IGlpb19ldmVudF90eXBlIHR5cGUsDQo+ID4gKwkJCQkJICBlbnVtIGlpb19ldmVudF9kaXJlY3Rp
b24gZGlyKQ0KPiA+ICt7DQo+ID4gKw0KPiA+ICsJc3RydWN0IGt4Y2prMTAxM19kYXRhICpkYXRh
ID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gZGF0YS0+ZXZfZW5h
YmxlX3N0YXRlOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IGt4Y2prMTAxM193cml0
ZV9ldmVudF9jb25maWcoc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiwNCj4gPiArCQkJCQkgICBj
b25zdCBzdHJ1Y3QgaWlvX2NoYW5fc3BlYyAqY2hhbiwNCj4gPiArCQkJCQkgICBlbnVtIGlpb19l
dmVudF90eXBlIHR5cGUsDQo+ID4gKwkJCQkJICAgZW51bSBpaW9fZXZlbnRfZGlyZWN0aW9uIGRp
ciwNCj4gPiArCQkJCQkgICBpbnQgc3RhdGUpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBreGNqazEw
MTNfZGF0YSAqZGF0YSA9IGlpb19wcml2KGluZGlvX2Rldik7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+
ICsNCj4gPiArCWlmIChzdGF0ZSAmJiBkYXRhLT5ldl9lbmFibGVfc3RhdGUpDQo+ID4gKwkJcmV0
dXJuIDA7DQo+ID4gKw0KPiA+ICsJbXV0ZXhfbG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ICsNCj4g
PiArCWlmICghc3RhdGUgJiYgZGF0YS0+bW90aW9uX3RyaWdnZXJfb24pIHsNCj4gPiArCQlkYXRh
LT5ldl9lbmFibGVfc3RhdGUgPSAwOw0KPiA+ICsJCW11dGV4X3VubG9jaygmZGF0YS0+bXV0ZXgp
Ow0KPiA+ICsJCXJldHVybiAwOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCS8qDQo+ID4gKwkgKiBX
ZSB3aWxsIGV4cGVjdCB0aGUgZW5hYmxlIGFuZCBkaXNhYmxlIHRvIGRvIG9wZXJhdGlvbiBpbg0K
PiA+ICsJICogaW4gcmV2ZXJzZSBvcmRlci4gVGhpcyB3aWxsIGhhcHBlbiBoZXJlIGFueXdheSBh
cyBvdXINCj4gPiArCSAqIHJlc3VtZSBvcGVyYXRpb24gdXNlcyBzeW5jIG1vZGUgcnVudGltZSBw
bSBjYWxscywgdGhlDQo+ID4gKwkgKiBzdXNwZW5kIG9wZXJhdGlvbiB3aWxsIGJlIGRlbGF5ZWQg
YnkgYXV0b3N1c3BlbmQgZGVsYXkNCj4gPiArCSAqIFNvIHRoZSBkaXNhYmxlIG9wZXJhdGlvbiB3
aWxsIHN0aWxsIGhhcHBlbiBpbiByZXZlcnNlIG9mDQo+ID4gKwkgKiBlbmFibGUgb3BlcmF0aW9u
LiBXaGVuIHJ1bnRpbWUgcG0gaXMgZGlzYWJsZWQgdGhlIG1vZGUNCj4gPiArCSAqIGlzIGFsd2F5
cyBvbiBzbyBzZXF1ZW5jZSBkb2Vzbid0IG1hdHRlcg0KPiA+ICsJICovDQo+ID4gKwlyZXQgPSBr
eGNqazEwMTNfc2V0X3Bvd2VyX3N0YXRlKGRhdGEsIHN0YXRlKTsNCj4gPiArCWlmIChyZXQgPCAw
KSB7DQo+ID4gKwkJbXV0ZXhfdW5sb2NrKCZkYXRhLT5tdXRleCk7DQo+ID4gKwkJcmV0dXJuIHJl
dDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXQgPSAga3hjamsxMDEzX3NldHVwX2FueV9tb3Rp
b25faW50ZXJydXB0KGRhdGEsIHN0YXRlKTsNCj4gPiArCWlmIChyZXQgPCAwKSB7DQo+ID4gKwkJ
bXV0ZXhfdW5sb2NrKCZkYXRhLT5tdXRleCk7DQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArCX0N
Cj4gPiArDQo+ID4gKwlkYXRhLT5ldl9lbmFibGVfc3RhdGUgPSBzdGF0ZTsNCj4gPiArCW11dGV4
X3VubG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ICsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+
ID4gKw0KPiA+ICBzdGF0aWMgaW50IGt4Y2prMTAxM192YWxpZGF0ZV90cmlnZ2VyKHN0cnVjdCBp
aW9fZGV2ICppbmRpb19kZXYsDQo+ID4gIAkJCQkgICAgICBzdHJ1Y3QgaWlvX3RyaWdnZXIgKnRy
aWcpDQo+ID4gIHsNCj4gPiAgCXN0cnVjdCBreGNqazEwMTNfZGF0YSAqZGF0YSA9IGlpb19wcml2
KGluZGlvX2Rldik7DQo+ID4gIA0KPiA+IC0JaWYgKGRhdGEtPnRyaWcgIT0gdHJpZykNCj4gPiAr
CWlmIChkYXRhLT5kcmVhZHlfdHJpZyAhPSB0cmlnICYmIGRhdGEtPm1vdGlvbl90cmlnICE9IHRy
aWcpDQo+ID4gIAkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gIA0KPiA+ICAJcmV0dXJuIDA7DQo+ID4g
QEAgLTU4Niw2ICs4NDAsMTQgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAg
a3hjamsxMDEzX2F0dHJzX2dyb3VwID0gew0KPiA+ICAJLmF0dHJzID0ga3hjamsxMDEzX2F0dHJp
YnV0ZXMsDQo+ID4gIH07DQo+ID4gIA0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGlpb19ldmVu
dF9zcGVjIGt4Y2prMTAxM19ldmVudCA9IHsNCj4gPiArCQkudHlwZSA9IElJT19FVl9UWVBFX1RI
UkVTSCwNCj4gPiArCQkuZGlyID0gSUlPX0VWX0RJUl9SSVNJTkcgfCBJSU9fRVZfRElSX0ZBTExJ
TkcsDQo+ID4gKwkJLm1hc2tfc2VwYXJhdGUgPSBCSVQoSUlPX0VWX0lORk9fVkFMVUUpIHwNCj4g
PiArCQkJCSBCSVQoSUlPX0VWX0lORk9fRU5BQkxFKSB8DQo+ID4gKwkJCQkgQklUKElJT19FVl9J
TkZPX1BFUklPRCkNCj4gPiArfTsNCj4gPiArDQo+ID4gICNkZWZpbmUgS1hDSksxMDEzX0NIQU5O
RUwoX2F4aXMpIHsJCQkJCVwNCj4gPiAgCS50eXBlID0gSUlPX0FDQ0VMLAkJCQkJCVwNCj4gPiAg
CS5tb2RpZmllZCA9IDEsCQkJCQkJCVwNCj4gPiBAQCAtNjAxLDYgKzg2Myw4IEBAIHN0YXRpYyBj
b25zdCBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIGt4Y2prMTAxM19hdHRyc19ncm91cCA9IHsNCj4g
PiAgCQkuc2hpZnQgPSA0LAkJCQkJCVwNCj4gPiAgCQkuZW5kaWFubmVzcyA9IElJT19DUFUsCQkJ
CQlcDQo+ID4gIAl9LAkJCQkJCQkJXA0KPiA+ICsJLmV2ZW50X3NwZWMgPSAma3hjamsxMDEzX2V2
ZW50LAkJCQlcDQo+ID4gKwkubnVtX2V2ZW50X3NwZWNzID0gMQkJCQkJCVwNCj4gPiAgfQ0KPiA+
ICANCj4gPiAgc3RhdGljIGNvbnN0IHN0cnVjdCBpaW9fY2hhbl9zcGVjIGt4Y2prMTAxM19jaGFu
bmVsc1tdID0gew0KPiA+IEBAIC02MTQsNiArODc4LDEwIEBAIHN0YXRpYyBjb25zdCBzdHJ1Y3Qg
aWlvX2luZm8ga3hjamsxMDEzX2luZm8gPSB7DQo+ID4gIAkuYXR0cnMJCQk9ICZreGNqazEwMTNf
YXR0cnNfZ3JvdXAsDQo+ID4gIAkucmVhZF9yYXcJCT0ga3hjamsxMDEzX3JlYWRfcmF3LA0KPiA+
ICAJLndyaXRlX3JhdwkJPSBreGNqazEwMTNfd3JpdGVfcmF3LA0KPiA+ICsJLnJlYWRfZXZlbnRf
dmFsdWUJPSBreGNqazEwMTNfcmVhZF9ldmVudCwNCj4gPiArCS53cml0ZV9ldmVudF92YWx1ZQk9
IGt4Y2prMTAxM193cml0ZV9ldmVudCwNCj4gPiArCS53cml0ZV9ldmVudF9jb25maWcJPSBreGNq
azEwMTNfd3JpdGVfZXZlbnRfY29uZmlnLA0KPiA+ICsJLnJlYWRfZXZlbnRfY29uZmlnCT0ga3hj
amsxMDEzX3JlYWRfZXZlbnRfY29uZmlnLA0KPiA+ICAJLnZhbGlkYXRlX3RyaWdnZXIJPSBreGNq
azEwMTNfdmFsaWRhdGVfdHJpZ2dlciwNCj4gPiAgCS5kcml2ZXJfbW9kdWxlCQk9IFRISVNfTU9E
VUxFLA0KPiA+ICB9Ow0KPiA+IEBAIC02MzksNyArOTA3LDcgQEAgc3RhdGljIGlycXJldHVybl90
IGt4Y2prMTAxM190cmlnZ2VyX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqcCkNCj4gPiAgCW11dGV4
X3VubG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ICANCj4gPiAgCWlpb19wdXNoX3RvX2J1ZmZlcnNf
d2l0aF90aW1lc3RhbXAoaW5kaW9fZGV2LCBkYXRhLT5idWZmZXIsDQo+ID4gLQkJCQkJICAgcGYt
PnRpbWVzdGFtcCk7DQo+ID4gKwkJCQkJICAgZGF0YS0+dGltZXN0YW1wKTsNCj4gPiAgZXJyOg0K
PiA+ICAJaWlvX3RyaWdnZXJfbm90aWZ5X2RvbmUoaW5kaW9fZGV2LT50cmlnKTsNCj4gPiAgDQo+
ID4gQEAgLTY2OCwxOSArOTM2LDMyIEBAIHN0YXRpYyBpbnQga3hjamsxMDEzX2RhdGFfcmR5X3Ry
aWdnZXJfc2V0X3N0YXRlKHN0cnVjdCBpaW9fdHJpZ2dlciAqdHJpZywNCj4gPiAgCXN0cnVjdCBr
eGNqazEwMTNfZGF0YSAqZGF0YSA9IGlpb19wcml2KGluZGlvX2Rldik7DQo+ID4gIAlpbnQgcmV0
Ow0KPiA+ICANCj4gPiAtCWlmIChzdGF0ZSAmJiBkYXRhLT50cmlnZ2VyX29uKQ0KPiA+ICsJbXV0
ZXhfbG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ICsNCj4gPiArCWlmICghc3RhdGUgJiYgZGF0YS0+
ZXZfZW5hYmxlX3N0YXRlICYmIGRhdGEtPm1vdGlvbl90cmlnZ2VyX29uKSB7DQo+ID4gKwkJZGF0
YS0+bW90aW9uX3RyaWdnZXJfb24gPSBmYWxzZTsNCj4gPiArCQltdXRleF91bmxvY2soJmRhdGEt
Pm11dGV4KTsNCj4gPiAgCQlyZXR1cm4gMDsNCj4gPiArCX0NCj4gPiAgDQo+ID4gLQltdXRleF9s
b2NrKCZkYXRhLT5tdXRleCk7DQo+ID4gLQlyZXQgPSBreGNqazEwMTNfY2hpcF9zZXR1cF9pbnRl
cnJ1cHQoZGF0YSwgc3RhdGUpOw0KPiA+IC0JaWYgKCFyZXQpIHsNCj4gPiAtCQlyZXQgPSBreGNq
azEwMTNfc2V0X3Bvd2VyX3N0YXRlKGRhdGEsIHN0YXRlKTsNCj4gPiAtCQlpZiAocmV0IDwgMCkg
ew0KPiA+IC0JCQltdXRleF91bmxvY2soJmRhdGEtPm11dGV4KTsNCj4gPiAtCQkJcmV0dXJuIHJl
dDsNCj4gPiAtCQl9DQo+ID4gKwlyZXQgPSBreGNqazEwMTNfc2V0X3Bvd2VyX3N0YXRlKGRhdGEs
IHN0YXRlKTsNCj4gPiArCWlmIChyZXQgPCAwKSB7DQo+ID4gKwkJbXV0ZXhfdW5sb2NrKCZkYXRh
LT5tdXRleCk7DQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiAgCX0NCj4gPiAtCWRhdGEtPnRyaWdn
ZXJfb24gPSBzdGF0ZTsNCj4gPiArCWlmIChkYXRhLT5tb3Rpb25fdHJpZyA9PSB0cmlnKQ0KPiA+
ICsJCXJldCA9IGt4Y2prMTAxM19zZXR1cF9hbnlfbW90aW9uX2ludGVycnVwdChkYXRhLCBzdGF0
ZSk7DQo+ID4gKwllbHNlDQo+ID4gKwkJcmV0ID0ga3hjamsxMDEzX3NldHVwX25ld19kYXRhX2lu
dGVycnVwdChkYXRhLCBzdGF0ZSk7DQo+ID4gKwlpZiAocmV0IDwgMCkgew0KPiA+ICsJCW11dGV4
X3VubG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4g
KwlpZiAoZGF0YS0+bW90aW9uX3RyaWcgPT0gdHJpZykNCj4gPiArCQlkYXRhLT5tb3Rpb25fdHJp
Z2dlcl9vbiA9IHN0YXRlOw0KPiA+ICsJZWxzZQ0KPiA+ICsJCWRhdGEtPmRyZWFkeV90cmlnZ2Vy
X29uID0gc3RhdGU7DQo+ID4gKw0KPiA+ICAJbXV0ZXhfdW5sb2NrKCZkYXRhLT5tdXRleCk7DQo+
ID4gIA0KPiA+ICAJcmV0dXJuIDA7DQo+ID4gQEAgLTY5Miw2ICs5NzMsMTA5IEBAIHN0YXRpYyBj
b25zdCBzdHJ1Y3QgaWlvX3RyaWdnZXJfb3BzIGt4Y2prMTAxM190cmlnZ2VyX29wcyA9IHsNCj4g
PiAgCS5vd25lciA9IFRISVNfTU9EVUxFLA0KPiA+ICB9Ow0KPiA+ICANCj4gPiArc3RhdGljIGly
cXJldHVybl90IGt4Y2prMTAxM19ldmVudF9oYW5kbGVyKGludCBpcnEsIHZvaWQgKnByaXZhdGUp
DQo+ID4gK3sNCj4gPiArCXN0cnVjdCBpaW9fZGV2ICppbmRpb19kZXYgPSBwcml2YXRlOw0KPiA+
ICsJc3RydWN0IGt4Y2prMTAxM19kYXRhICpkYXRhID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsNCj4g
PiArCWludCByZXQ7DQo+ID4gKw0KPiA+ICsJcmV0ID0gaTJjX3NtYnVzX3JlYWRfYnl0ZV9kYXRh
KGRhdGEtPmNsaWVudCwgS1hDSksxMDEzX1JFR19JTlRfU1JDMSk7DQo+ID4gKwlpZiAocmV0IDwg
MCkgew0KPiA+ICsJCWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2LCAiRXJyb3IgcmVhZGluZyBy
ZWdfaW50X3NyYzFcbiIpOw0KPiA+ICsJCWdvdG8gYWNrX2ludHI7DQo+ID4gKwl9DQo+ID4gKw0K
PiA+ICsJaWYgKHJldCAmIDB4MDIpIHsNCj4gPiArCQlyZXQgPSBpMmNfc21idXNfcmVhZF9ieXRl
X2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ICsJCQkJCSAgICAgICBLWENKSzEwMTNfUkVHX0lOVF9T
UkMyKTsNCj4gPiArCQlpZiAocmV0IDwgMCkgew0KPiA+ICsJCQlkZXZfZXJyKCZkYXRhLT5jbGll
bnQtPmRldiwNCj4gPiArCQkJCSJFcnJvciByZWFkaW5nIHJlZ19pbnRfc3JjMlxuIik7DQo+ID4g
KwkJCWdvdG8gYWNrX2ludHI7DQo+ID4gKwkJfQ0KPiA+ICsNCj4gQ291bGQgZG8gdGhpcyB3aG9s
ZSBzZXQgYXMgYSBjb21iaW5hdGlvbiBvZiBmb3JfZWFjaF9zZXRfYml0IGFuZA0KPiBhIGxvb2t1
cCB0YWJsZSBmb3IgdGhlIGV2ZW50IGNvZGVzIChvciB0aGUgZWxlbWVudHMgdXNlZCB0byBidWls
ZA0KPiB0aGVtKS4gIFdvdWxkIG1ha2UgaXQgYSBsaXR0bGUgbW9yZSBhcHBhcmVudCB0aGF0IHRo
aXMgaXMgcmVhbGx5DQo+IHBpY2tpbmcgYmV0d2VlbiBjb25zdGFudCB2YWx1ZXMuLi4NCj4gDQo+
IE1pbmQgeW91LCBtaWdodCB3ZWxsIHByb3ZlIG1vcmUgY29tcGxleCB0aGFuIHdoYXQgd2UgaGF2
ZSBoZXJlIQ0KPiANCj4gPiArCQlpZiAocmV0ICYgS1hDSksxMDEzX1JFR19JTlRfU1JDMl9CSVRf
WE4pDQo+ID4gKwkJCWlpb19wdXNoX2V2ZW50KGluZGlvX2RldiwNCj4gPiArCQkJCSAgICAgICBJ
SU9fTU9EX0VWRU5UX0NPREUoSUlPX0FDQ0VMLA0KPiA+ICsJCQkJICAgICAgIDAsDQo+ID4gKwkJ
CQkgICAgICAgSUlPX01PRF9YLA0KPiA+ICsJCQkJICAgICAgIElJT19FVl9UWVBFX1RIUkVTSCwN
Cj4gPiArCQkJCSAgICAgICBJSU9fRVZfRElSX0ZBTExJTkcpLA0KPiA+ICsJCQkJICAgICAgIGRh
dGEtPnRpbWVzdGFtcCk7DQo+ID4gKwkJaWYgKHJldCAmIEtYQ0pLMTAxM19SRUdfSU5UX1NSQzJf
QklUX1hQKQ0KPiA+ICsJCQlpaW9fcHVzaF9ldmVudChpbmRpb19kZXYsDQo+ID4gKwkJCQkgICAg
ICAgSUlPX01PRF9FVkVOVF9DT0RFKElJT19BQ0NFTCwNCj4gPiArCQkJCSAgICAgICAwLA0KPiA+
ICsJCQkJICAgICAgIElJT19NT0RfWCwNCj4gPiArCQkJCSAgICAgICBJSU9fRVZfVFlQRV9USFJF
U0gsDQo+ID4gKwkJCQkgICAgICAgSUlPX0VWX0RJUl9SSVNJTkcpLA0KPiA+ICsJCQkJICAgICAg
IGRhdGEtPnRpbWVzdGFtcCk7DQo+ID4gKw0KPiA+ICsNCj4gPiArCQlpZiAocmV0ICYgS1hDSksx
MDEzX1JFR19JTlRfU1JDMl9CSVRfWU4pDQo+ID4gKwkJCWlpb19wdXNoX2V2ZW50KGluZGlvX2Rl
diwNCj4gPiArCQkJCSAgICAgICBJSU9fTU9EX0VWRU5UX0NPREUoSUlPX0FDQ0VMLA0KPiA+ICsJ
CQkJICAgICAgIDAsDQo+ID4gKwkJCQkgICAgICAgSUlPX01PRF9ZLA0KPiA+ICsJCQkJICAgICAg
IElJT19FVl9UWVBFX1RIUkVTSCwNCj4gPiArCQkJCSAgICAgICBJSU9fRVZfRElSX0ZBTExJTkcp
LA0KPiA+ICsJCQkJICAgICAgIGRhdGEtPnRpbWVzdGFtcCk7DQo+ID4gKwkJaWYgKHJldCAmIEtY
Q0pLMTAxM19SRUdfSU5UX1NSQzJfQklUX1lQKQ0KPiA+ICsJCQlpaW9fcHVzaF9ldmVudChpbmRp
b19kZXYsDQo+ID4gKwkJCQkgICAgICAgSUlPX01PRF9FVkVOVF9DT0RFKElJT19BQ0NFTCwNCj4g
PiArCQkJCSAgICAgICAwLA0KPiA+ICsJCQkJICAgICAgIElJT19NT0RfWSwNCj4gPiArCQkJCSAg
ICAgICBJSU9fRVZfVFlQRV9USFJFU0gsDQo+ID4gKwkJCQkgICAgICAgSUlPX0VWX0RJUl9SSVNJ
TkcpLA0KPiA+ICsJCQkJICAgICAgIGRhdGEtPnRpbWVzdGFtcCk7DQo+ID4gKw0KPiA+ICsJCWlm
IChyZXQgJiBLWENKSzEwMTNfUkVHX0lOVF9TUkMyX0JJVF9aTikNCj4gPiArCQkJaWlvX3B1c2hf
ZXZlbnQoaW5kaW9fZGV2LA0KPiA+ICsJCQkJICAgICAgIElJT19NT0RfRVZFTlRfQ09ERShJSU9f
QUNDRUwsDQo+ID4gKwkJCQkgICAgICAgMCwNCj4gPiArCQkJCSAgICAgICBJSU9fTU9EX1osDQo+
ID4gKwkJCQkgICAgICAgSUlPX0VWX1RZUEVfVEhSRVNILA0KPiA+ICsJCQkJICAgICAgIElJT19F
Vl9ESVJfRkFMTElORyksDQo+ID4gKwkJCQkgICAgICAgZGF0YS0+dGltZXN0YW1wKTsNCj4gPiAr
CQlpZiAocmV0ICYgS1hDSksxMDEzX1JFR19JTlRfU1JDMl9CSVRfWlApDQo+ID4gKwkJCWlpb19w
dXNoX2V2ZW50KGluZGlvX2RldiwNCj4gPiArCQkJCSAgICAgICBJSU9fTU9EX0VWRU5UX0NPREUo
SUlPX0FDQ0VMLA0KPiA+ICsJCQkJICAgICAgIDAsDQo+ID4gKwkJCQkgICAgICAgSUlPX01PRF9a
LA0KPiA+ICsJCQkJICAgICAgIElJT19FVl9UWVBFX1RIUkVTSCwNCj4gPiArCQkJCSAgICAgICBJ
SU9fRVZfRElSX1JJU0lORyksDQo+ID4gKwkJCQkgICAgICAgZGF0YS0+dGltZXN0YW1wKTsNCj4g
PiArCX0NCj4gPiArDQo+ID4gK2Fja19pbnRyOg0KPiA+ICsJaWYgKGRhdGEtPmRyZWFkeV90cmln
Z2VyX29uKQ0KPiA+ICsJCXJldHVybiBJUlFfSEFORExFRDsNCj4gPiArDQo+ID4gKwlyZXQgPSBp
MmNfc21idXNfcmVhZF9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LCBLWENKSzEwMTNfUkVHX0lOVF9S
RUwpOw0KPiA+ICsJaWYgKHJldCA8IDApDQo+ID4gKwkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5k
ZXYsICJFcnJvciByZWFkaW5nIHJlZ19pbnRfcmVsXG4iKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4g
SVJRX0hBTkRMRUQ7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpcnFyZXR1cm5fdCBreGNq
azEwMTNfZGF0YV9yZHlfdHJpZ19wb2xsKGludCBpcnEsIHZvaWQgKnByaXZhdGUpDQo+ID4gK3sN
Cj4gPiArCXN0cnVjdCBpaW9fZGV2ICppbmRpb19kZXYgPSBwcml2YXRlOw0KPiA+ICsJc3RydWN0
IGt4Y2prMTAxM19kYXRhICpkYXRhID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsNCj4gPiArDQo+ID4g
KwlkYXRhLT50aW1lc3RhbXAgPSBpaW9fZ2V0X3RpbWVfbnMoKTsNCj4gPiArDQo+ID4gKwlpZiAo
ZGF0YS0+ZHJlYWR5X3RyaWdnZXJfb24pDQo+ID4gKwkJaWlvX3RyaWdnZXJfcG9sbChkYXRhLT5k
cmVhZHlfdHJpZyk7DQo+ID4gKwllbHNlIGlmIChkYXRhLT5tb3Rpb25fdHJpZ2dlcl9vbikNCj4g
PiArCQlpaW9fdHJpZ2dlcl9wb2xsKGRhdGEtPm1vdGlvbl90cmlnKTsNCj4gPiArDQo+ID4gKwlp
ZiAoZGF0YS0+ZXZfZW5hYmxlX3N0YXRlKQ0KPiA+ICsJCXJldHVybiBJUlFfV0FLRV9USFJFQUQ7
DQo+ID4gKwllbHNlDQo+ID4gKwkJcmV0dXJuIElSUV9IQU5ETEVEOw0KPiA+ICt9DQo+ID4gKw0K
PiA+ICBzdGF0aWMgaW50IGt4Y2prMTAxM19hY3BpX2dwaW9fcHJvYmUoc3RydWN0IGkyY19jbGll
bnQgKmNsaWVudCwNCj4gPiAgCQkJCSAgICAgc3RydWN0IGt4Y2prMTAxM19kYXRhICpkYXRhKQ0K
PiA+ICB7DQo+ID4gQEAgLTczNCw3ICsxMTE4LDYgQEAgc3RhdGljIGludCBreGNqazEwMTNfcHJv
YmUoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCwNCj4gPiAgew0KPiA+ICAJc3RydWN0IGt4Y2pr
MTAxM19kYXRhICpkYXRhOw0KPiA+ICAJc3RydWN0IGlpb19kZXYgKmluZGlvX2RldjsNCj4gPiAt
CXN0cnVjdCBpaW9fdHJpZ2dlciAqdHJpZyA9IE5VTEw7DQo+ID4gIAlzdHJ1Y3Qga3hjamtfMTAx
M19wbGF0Zm9ybV9kYXRhICpwZGF0YTsNCj4gPiAgCWludCByZXQ7DQo+ID4gIA0KPiA+IEBAIC03
NjksMzMgKzExNTIsNDcgQEAgc3RhdGljIGludCBreGNqazEwMTNfcHJvYmUoc3RydWN0IGkyY19j
bGllbnQgKmNsaWVudCwNCj4gPiAgCQljbGllbnQtPmlycSA9IGt4Y2prMTAxM19hY3BpX2dwaW9f
cHJvYmUoY2xpZW50LCBkYXRhKTsNCj4gPiAgDQo+ID4gIAlpZiAoY2xpZW50LT5pcnEgPj0gMCkg
ew0KPiA+IC0JCXRyaWcgPSBpaW9fdHJpZ2dlcl9hbGxvYygiJXMtZGV2JWQiLCBpbmRpb19kZXYt
Pm5hbWUsDQo+ID4gLQkJCQkJIGluZGlvX2Rldi0+aWQpOw0KPiA+IC0JCWlmICghdHJpZykNCj4g
PiAtCQkJcmV0dXJuIC1FTk9NRU07DQo+ID4gKwkJcmV0ID0gZGV2bV9yZXF1ZXN0X3RocmVhZGVk
X2lycSgNCj4gV2h5IHRoZSBuZXcgbGluZSBiZWZvcmUgdGhlIGFyZ3VlbWVudHM/DQo+ID4gKwkJ
CQkJCSZjbGllbnQtPmRldiwgY2xpZW50LT5pcnEsDQo+ID4gKwkJCQkJCWt4Y2prMTAxM19kYXRh
X3JkeV90cmlnX3BvbGwsDQo+ID4gKwkJCQkJCWt4Y2prMTAxM19ldmVudF9oYW5kbGVyLA0KPiA+
ICsJCQkJCQlJUlFGX1RSSUdHRVJfUklTSU5HLA0KPiA+ICsJCQkJCQlLWENKSzEwMTNfSVJRX05B
TUUsDQo+ID4gKwkJCQkJCWluZGlvX2Rldik7DQo+ID4gKwkJaWYgKHJldCkNCj4gPiArCQkJcmV0
dXJuIHJldDsNCj4gPiAgDQo+ID4gLQkJZGF0YS0+dHJpZ19tb2RlID0gdHJ1ZTsNCj4gPiArCQlk
YXRhLT5kcmVhZHlfdHJpZyA9IGRldm1faWlvX3RyaWdnZXJfYWxsb2MoJmNsaWVudC0+ZGV2LA0K
PiA+ICsJCQkJCQkJICAgIiVzLWRldiVkIiwNCj4gPiArCQkJCQkJCSAgIGluZGlvX2Rldi0+bmFt
ZSwNCj4gPiArCQkJCQkJCSAgIGluZGlvX2Rldi0+aWQpOw0KPiA+ICsJCWlmICghZGF0YS0+ZHJl
YWR5X3RyaWcpDQo+ID4gKwkJCXJldHVybiAtRU5PTUVNOw0KPiA+ICANCj4gPiAtCQlyZXQgPSBk
ZXZtX3JlcXVlc3RfaXJxKCZjbGllbnQtPmRldiwgY2xpZW50LT5pcnEsDQo+ID4gLQkJCQkJaWlv
X3RyaWdnZXJfZ2VuZXJpY19kYXRhX3JkeV9wb2xsLA0KPiA+IC0JCQkJCUlSUUZfVFJJR0dFUl9S
SVNJTkcsDQo+ID4gLQkJCQkJS1hDSksxMDEzX0lSUV9OQU1FLA0KPiA+IC0JCQkJCXRyaWcpOw0K
PiA+IC0JCWlmIChyZXQpIHsNCj4gPiAtCQkJZGV2X2VycigmY2xpZW50LT5kZXYsICJ1bmFibGUg
dG8gcmVxdWVzdCBJUlFcbiIpOw0KPiA+IC0JCQlnb3RvIGVycl90cmlnZ2VyX2ZyZWU7DQo+ID4g
LQkJfQ0KPiA+ICsJCWRhdGEtPm1vdGlvbl90cmlnID0gZGV2bV9paW9fdHJpZ2dlcl9hbGxvYygm
Y2xpZW50LT5kZXYsDQo+ID4gKwkJCQkJCQkgICIlcy1hbnktbW90aW9uLWRldiVkIiwNCj4gPiAr
CQkJCQkJCSAgaW5kaW9fZGV2LT5uYW1lLA0KPiA+ICsJCQkJCQkJICBpbmRpb19kZXYtPmlkKTsN
Cj4gPiArCQlpZiAoIWRhdGEtPm1vdGlvbl90cmlnKQ0KPiA+ICsJCQlyZXR1cm4gLUVOT01FTTsN
Cj4gPiAgDQo+ID4gLQkJdHJpZy0+ZGV2LnBhcmVudCA9ICZjbGllbnQtPmRldjsNCj4gPiAtCQl0
cmlnLT5vcHMgPSAma3hjamsxMDEzX3RyaWdnZXJfb3BzOw0KPiA+IC0JCWlpb190cmlnZ2VyX3Nl
dF9kcnZkYXRhKHRyaWcsIGluZGlvX2Rldik7DQo+ID4gLQkJZGF0YS0+dHJpZyA9IHRyaWc7DQo+
ID4gLQkJaW5kaW9fZGV2LT50cmlnID0gdHJpZzsNCj4gPiArCQlkYXRhLT5kcmVhZHlfdHJpZy0+
ZGV2LnBhcmVudCA9ICZjbGllbnQtPmRldjsNCj4gPiArCQlkYXRhLT5kcmVhZHlfdHJpZy0+b3Bz
ID0gJmt4Y2prMTAxM190cmlnZ2VyX29wczsNCj4gPiArCQlpaW9fdHJpZ2dlcl9zZXRfZHJ2ZGF0
YShkYXRhLT5kcmVhZHlfdHJpZywgaW5kaW9fZGV2KTsNCj4gPiArCQlpbmRpb19kZXYtPnRyaWcg
PSBkYXRhLT5kcmVhZHlfdHJpZzsNCj4gPiAgCQlpaW9fdHJpZ2dlcl9nZXQoaW5kaW9fZGV2LT50
cmlnKTsNCj4gPiAtDQo+ID4gLQkJcmV0ID0gaWlvX3RyaWdnZXJfcmVnaXN0ZXIodHJpZyk7DQo+
ID4gKwkJcmV0ID0gaWlvX3RyaWdnZXJfcmVnaXN0ZXIoZGF0YS0+ZHJlYWR5X3RyaWcpOw0KPiA+
ICAJCWlmIChyZXQpDQo+ID4gLQkJCWdvdG8gZXJyX3RyaWdnZXJfZnJlZTsNCj4gPiArCQkJcmV0
dXJuIHJldDsNCj4gPiArDQo+ID4gKwkJZGF0YS0+bW90aW9uX3RyaWctPmRldi5wYXJlbnQgPSAm
Y2xpZW50LT5kZXY7DQo+ID4gKwkJZGF0YS0+bW90aW9uX3RyaWctPm9wcyA9ICZreGNqazEwMTNf
dHJpZ2dlcl9vcHM7DQo+ID4gKwkJaWlvX3RyaWdnZXJfc2V0X2RydmRhdGEoZGF0YS0+bW90aW9u
X3RyaWcsIGluZGlvX2Rldik7DQo+ID4gKwkJcmV0ID0gaWlvX3RyaWdnZXJfcmVnaXN0ZXIoZGF0
YS0+bW90aW9uX3RyaWcpOw0KPiA+ICsJCWlmIChyZXQpIHsNCj4gPiArCQkJZGF0YS0+bW90aW9u
X3RyaWcgPSBOVUxMOw0KPiA+ICsJCQlnb3RvIGVycl90cmlnZ2VyX3VucmVnaXN0ZXI7DQo+ID4g
KwkJfQ0KPiA+ICANCj4gPiAgCQlyZXQgPSBpaW9fdHJpZ2dlcmVkX2J1ZmZlcl9zZXR1cChpbmRp
b19kZXYsDQo+ID4gIAkJCQkJCSZpaW9fcG9sbGZ1bmNfc3RvcmVfdGltZSwNCj4gPiBAQCAtODI4
LDE0ICsxMjI1LDEzIEBAIHN0YXRpYyBpbnQga3hjamsxMDEzX3Byb2JlKHN0cnVjdCBpMmNfY2xp
ZW50ICpjbGllbnQsDQo+ID4gIGVycl9paW9fdW5yZWdpc3RlcjoNCj4gPiAgCWlpb19kZXZpY2Vf
dW5yZWdpc3RlcihpbmRpb19kZXYpOw0KPiA+ICBlcnJfYnVmZmVyX2NsZWFudXA6DQo+ID4gLQlp
ZiAoZGF0YS0+dHJpZ19tb2RlKQ0KPiA+ICsJaWYgKGRhdGEtPmRyZWFkeV90cmlnKQ0KPiA+ICAJ
CWlpb190cmlnZ2VyZWRfYnVmZmVyX2NsZWFudXAoaW5kaW9fZGV2KTsNCj4gPiAgZXJyX3RyaWdn
ZXJfdW5yZWdpc3RlcjoNCj4gPiAtCWlmIChkYXRhLT50cmlnX21vZGUpDQo+ID4gLQkJaWlvX3Ry
aWdnZXJfdW5yZWdpc3Rlcih0cmlnKTsNCj4gPiAtZXJyX3RyaWdnZXJfZnJlZToNCj4gPiAtCWlm
IChkYXRhLT50cmlnX21vZGUpDQo+ID4gLQkJaWlvX3RyaWdnZXJfZnJlZSh0cmlnKTsNCj4gPiAr
CWlmIChkYXRhLT5kcmVhZHlfdHJpZykNCj4gPiArCQlpaW9fdHJpZ2dlcl91bnJlZ2lzdGVyKGRh
dGEtPmRyZWFkeV90cmlnKTsNCj4gPiArCWlmIChkYXRhLT5tb3Rpb25fdHJpZykNCj4gPiArCQlp
aW9fdHJpZ2dlcl91bnJlZ2lzdGVyKGRhdGEtPm1vdGlvbl90cmlnKTsNCj4gPiAgDQo+ID4gIAly
ZXR1cm4gcmV0Ow0KPiA+ICB9DQo+ID4gQEAgLTg1MSwxMCArMTI0NywxMCBAQCBzdGF0aWMgaW50
IGt4Y2prMTAxM19yZW1vdmUoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCkNCj4gPiAgDQo+ID4g
IAlpaW9fZGV2aWNlX3VucmVnaXN0ZXIoaW5kaW9fZGV2KTsNCj4gPiAgDQo+ID4gLQlpZiAoZGF0
YS0+dHJpZ19tb2RlKSB7DQo+ID4gKwlpZiAoZGF0YS0+ZHJlYWR5X3RyaWcpIHsNCj4gPiAgCQlp
aW9fdHJpZ2dlcmVkX2J1ZmZlcl9jbGVhbnVwKGluZGlvX2Rldik7DQo+ID4gLQkJaWlvX3RyaWdn
ZXJfdW5yZWdpc3RlcihkYXRhLT50cmlnKTsNCj4gPiAtCQlpaW9fdHJpZ2dlcl9mcmVlKGRhdGEt
PnRyaWcpOw0KPiA+ICsJCWlpb190cmlnZ2VyX3VucmVnaXN0ZXIoZGF0YS0+ZHJlYWR5X3RyaWcp
Ow0KPiA+ICsJCWlpb190cmlnZ2VyX3VucmVnaXN0ZXIoZGF0YS0+bW90aW9uX3RyaWcpOw0KPiA+
ICAJfQ0KPiA+ICANCj4gPiAgCW11dGV4X2xvY2soJmRhdGEtPm11dGV4KTsNCj4gPiBAQCAtODg2
LDcgKzEyODIsOCBAQCBzdGF0aWMgaW50IGt4Y2prMTAxM19yZXN1bWUoc3RydWN0IGRldmljZSAq
ZGV2KQ0KPiA+ICANCj4gPiAgCW11dGV4X2xvY2soJmRhdGEtPm11dGV4KTsNCj4gPiAgCS8qIENo
ZWNrLCBpZiB0aGUgc3VzcGVuZCBvY2N1cmVkIHdoaWxlIGFjdGl2ZSAqLw0KPiA+IC0JaWYgKGRh
dGEtPnRyaWdnZXJfb24pDQo+ID4gKwlpZiAoZGF0YS0+ZHJlYWR5X3RyaWdnZXJfb24gfHwgZGF0
YS0+bW90aW9uX3RyaWdnZXJfb24gfHwNCj4gPiArCQkJCQkJCWRhdGEtPmV2X2VuYWJsZV9zdGF0
ZSkNCj4gPiAgCQlyZXQgPSBreGNqazEwMTNfc2V0X21vZGUoZGF0YSwgT1BFUkFUSU9OKTsNCj4g
PiAgCW11dGV4X3VubG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ICANCj4gPiANCg0K
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-08-26 20:07 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-22 19:01 [PATCH v1] iio: accel: kxcjk-1013: Support thresholds Srinivas Pandruvada
2014-08-26 20:02 ` Jonathan Cameron
2014-08-26 20:07 ` Pandruvada, Srinivas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).