Adds support for the new channel types in the dummy driver: * a new channel IIO_ACTIVITY * two state transition events (running and walking) * a new channel IIO_STEPS and support for reading and writing pedometer step counter * step detect event * a new channel IIO_HEIGHT and support for reading and writing height Signed-off-by: Irina Tirdea <irina.tirdea@xxxxxxxxx> Signed-off-by: Daniel Baluta <daniel.baluta@xxxxxxxxx> --- drivers/staging/iio/iio_simple_dummy.c | 199 +++++++++++++++++++++++--- drivers/staging/iio/iio_simple_dummy.h | 5 + drivers/staging/iio/iio_simple_dummy_events.c | 38 +++++ 3 files changed, 223 insertions(+), 19 deletions(-) diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index bf78e6f..5430aed 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -69,6 +69,34 @@ static const struct iio_event_spec iio_dummy_event = { .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE), }; +/* + * simple step detect event - triggered when a step is detected + */ +static const struct iio_event_spec step_detect_event = { + .type = IIO_EV_TYPE_INSTANCE, + .dir = IIO_EV_DIR_NONE, + .mask_separate = BIT(IIO_EV_INFO_ENABLE), +}; + +/* + * simple transition event - triggered when the reported running confidence + * value rises above a threshold value + */ +static const struct iio_event_spec iio_running_event = { + .type = IIO_EV_TYPE_TRANSITION, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE), +}; + +/* + * simple transition event - triggered when the reported walking confidence + * value falls under a threshold value + */ +static const struct iio_event_spec iio_walking_event = { + .type = IIO_EV_TYPE_TRANSITION, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE), +}; #endif /* @@ -215,6 +243,42 @@ static const struct iio_chan_spec iio_dummy_channels[] = { .indexed = 1, .channel = 0, }, + { + .type = IIO_STEPS, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_ENABLE), + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + .scan_index = -1, +#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS + .event_spec = &step_detect_event, + .num_event_specs = 1, +#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */ + }, + { + .type = IIO_HEIGHT, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + .scan_index = -1, + }, + { + .type = IIO_ACTIVITY, + .modified = 1, + .channel2 = IIO_MOD_RUNNING, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), +#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS + .event_spec = &iio_running_event, + .num_event_specs = 1, +#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */ + }, + { + .type = IIO_ACTIVITY, + .modified = 1, + .channel2 = IIO_MOD_WALKING, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), +#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS + .event_spec = &iio_walking_event, + .num_event_specs = 1, +#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */ + }, }; /** @@ -259,6 +323,34 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev, *val = st->accel_val; ret = IIO_VAL_INT; break; + case IIO_HEIGHT: + *val = st->height; + ret = IIO_VAL_INT; + break; + default: + break; + } + break; + case IIO_CHAN_INFO_PROCESSED: + switch (chan->type) { + case IIO_STEPS: + *val = st->steps; + ret = IIO_VAL_INT; + break; + case IIO_ACTIVITY: + switch (chan->channel2) { + case IIO_MOD_RUNNING: + *val = st->activity_running; + ret = IIO_VAL_INT; + break; + case IIO_MOD_WALKING: + *val = st->activity_walking; + ret = IIO_VAL_INT; + break; + default: + break; + } + break; default: break; } @@ -269,18 +361,29 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev, ret = IIO_VAL_INT; break; case IIO_CHAN_INFO_SCALE: - switch (chan->differential) { - case 0: - /* only single ended adc -> 0.001333 */ - *val = 0; - *val2 = 1333; - ret = IIO_VAL_INT_PLUS_MICRO; + switch (chan->type) { + case IIO_VOLTAGE: + switch (chan->differential) { + case 0: + /* only single ended adc -> 0.001333 */ + *val = 0; + *val2 = 1333; + ret = IIO_VAL_INT_PLUS_MICRO; + break; + case 1: + /* all differential adc channels -> + * 0.000001344 */ + *val = 0; + *val2 = 1344; + ret = IIO_VAL_INT_PLUS_NANO; + } + break; + case IIO_HEIGHT: + *val = 1; + ret = IIO_VAL_INT; + break; + default: break; - case 1: - /* all differential adc channels -> 0.000001344 */ - *val = 0; - *val2 = 1344; - ret = IIO_VAL_INT_PLUS_NANO; } break; case IIO_CHAN_INFO_CALIBBIAS: @@ -298,6 +401,16 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev, *val2 = 33; ret = IIO_VAL_INT_PLUS_NANO; break; + case IIO_CHAN_INFO_ENABLE: + switch (chan->type) { + case IIO_STEPS: + *val = st->steps_enabled; + ret = IIO_VAL_INT; + break; + default: + break; + } + break; default: break; } @@ -330,14 +443,50 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - if (chan->output == 0) + switch (chan->type) { + case IIO_VOLTAGE: + if (chan->output == 0) + return -EINVAL; + + /* Locking not required as writing single value */ + mutex_lock(&st->lock); + st->dac_val = val; + mutex_unlock(&st->lock); + return 0; + case IIO_HEIGHT: + mutex_lock(&st->lock); + st->height = val; + mutex_unlock(&st->lock); + return 0; + default: return -EINVAL; - - /* Locking not required as writing single value */ - mutex_lock(&st->lock); - st->dac_val = val; - mutex_unlock(&st->lock); - return 0; + } + case IIO_CHAN_INFO_PROCESSED: + switch (chan->type) { + case IIO_STEPS: + mutex_lock(&st->lock); + st->steps = val; + mutex_unlock(&st->lock); + return 0; + case IIO_ACTIVITY: + if (val < 0) + val = 0; + if (val > 100) + val = 100; + switch (chan->channel2) { + case IIO_MOD_RUNNING: + st->activity_running = val; + return 0; + case IIO_MOD_WALKING: + st->activity_walking = val; + return 0; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } case IIO_CHAN_INFO_CALIBSCALE: mutex_lock(&st->lock); /* Compare against table - hard matching here */ @@ -356,7 +505,16 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev, st->accel_calibbias = val; mutex_unlock(&st->lock); return 0; - + case IIO_CHAN_INFO_ENABLE: + switch (chan->type) { + case IIO_STEPS: + mutex_lock(&st->lock); + st->steps_enabled = val; + mutex_unlock(&st->lock); + return 0; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -395,6 +553,9 @@ static int iio_dummy_init_device(struct iio_dev *indio_dev) st->accel_val = 34; st->accel_calibbias = -7; st->accel_calibscale = &dummy_scales[0]; + st->steps = 47; + st->activity_running = 98; + st->activity_walking = 4; return 0; } diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h index 1a74e26..d49aec3 100644 --- a/drivers/staging/iio/iio_simple_dummy.h +++ b/drivers/staging/iio/iio_simple_dummy.h @@ -32,9 +32,14 @@ struct iio_dummy_state { int differential_adc_val[2]; int accel_val; int accel_calibbias; + int activity_running; + int activity_walking; const struct iio_dummy_accel_calibscale *accel_calibscale; struct mutex lock; struct iio_dummy_regs *regs; + int steps_enabled; + int steps; + int height; #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS int event_irq; int event_val; diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c index 719dfa5..ae37620 100644 --- a/drivers/staging/iio/iio_simple_dummy_events.c +++ b/drivers/staging/iio/iio_simple_dummy_events.c @@ -66,12 +66,23 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev, */ switch (chan->type) { case IIO_VOLTAGE: + case IIO_ACTIVITY: switch (type) { case IIO_EV_TYPE_THRESH: if (dir == IIO_EV_DIR_RISING) st->event_en = state; else return -EINVAL; + case IIO_EV_TYPE_TRANSITION: + st->event_en = state; + break; + default: + return -EINVAL; + } + case IIO_STEPS: + switch (type) { + case IIO_EV_TYPE_INSTANCE: + st->event_en = state; break; default: return -EINVAL; @@ -161,6 +172,33 @@ static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private) IIO_EV_TYPE_THRESH, 0, 0, 0), iio_get_time_ns()); break; + case 1: + if (st->activity_running > st->event_val) + iio_push_event(indio_dev, + IIO_EVENT_CODE(IIO_ACTIVITY, 0, + IIO_MOD_RUNNING, + IIO_EV_DIR_RISING, + IIO_EV_TYPE_TRANSITION, + 0, 0, 0), + iio_get_time_ns()); + break; + case 2: + if (st->activity_walking < st->event_val) + iio_push_event(indio_dev, + IIO_EVENT_CODE(IIO_ACTIVITY, 0, + IIO_MOD_WALKING, + IIO_EV_DIR_FALLING, + IIO_EV_TYPE_TRANSITION, + 0, 0, 0), + iio_get_time_ns()); + break; + case 3: + iio_push_event(indio_dev, + IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD, + IIO_EV_DIR_NONE, + IIO_EV_TYPE_INSTANCE, 0, 0, 0), + iio_get_time_ns()); + break; default: break; } -- 1.9.1 -- 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