2014-11-10 12:44:23

by Daniel Baluta

[permalink] [raw]
Subject: [PATCH v4 0/7] Introduce IIO interface for Android advanced features

This patchset introduces a new interface for supporting some of the composite
sensors in Android [1]. First supported sensors are activity and pedometer.

This is a follow up of the discussion about adding new channels to IIO
initiated some time ago on IIO list [2].

A device that has the activity/pedometer functionality is Freescale's MMA9553L ([3]).

Because we don't have yet the hardware, to demonstrate these new channels we
update iio_dummy kernel module and iio_event_monitor test program. We want
to get an early feedback about extending the IIO interface in the correct
direction.

[1] http://source.android.com/devices/sensors/composite_sensors.html
[2] http://marc.info/?l=linux-iio&m=138374342831057&w=2
[3] http://www.freescale.com/files/sensors/doc/ref_manual/MMA9553LSWRM.pdf

Changes since v3:
* rebased on latest togreg branch (head at 5e62863aea)
* fix typos reported by Hartmut

Changes since v2: (comments from Jonathan and Hartmut)
* dropped the RFC tag
* use int instead of unsigned long for ret in iio_evgen_poke
* remove TRANSITION event and use THRESHOLD instead
* remove IIO_HEIGHT channel and use CALIBHEIGHT mask instead
* adapt iio_dummy modules and iio_event_monitor to reflect IIO
interface changes.

Daniel Baluta (4):
iio: dummy: Add virtual registers for dummy device
iio: core: Introduce IIO_ACTIVITY channel
iio: dummy: Demonstrate the usage of new channel types
iio: event_monitor: Add support for new channel types

Irina Tirdea (3):
iio: core: Introduce IIO_EV_DIR_NONE
iio: core: Introduce STEPS channel, ENABLE mask and INSTANCE event
iio: core: Introduce IIO_CHAN_INFO_CALIBHEIGHT

Documentation/ABI/testing/sysfs-bus-iio | 74 ++++++++
drivers/iio/industrialio-core.c | 8 +
drivers/iio/industrialio-event.c | 13 +-
.../staging/iio/Documentation/iio_event_monitor.c | 23 ++-
drivers/staging/iio/iio_dummy_evgen.c | 17 ++
drivers/staging/iio/iio_dummy_evgen.h | 6 +
drivers/staging/iio/iio_simple_dummy.c | 199 +++++++++++++++++++--
drivers/staging/iio/iio_simple_dummy.h | 7 +
drivers/staging/iio/iio_simple_dummy_events.c | 66 ++++++-
include/linux/iio/iio.h | 2 +
include/linux/iio/types.h | 10 +-
11 files changed, 395 insertions(+), 30 deletions(-)

--
1.9.1


2014-11-10 12:44:27

by Daniel Baluta

[permalink] [raw]
Subject: [PATCH v4 2/7] iio: core: Introduce IIO_ACTIVITY channel

This channel will be used for exposing information about
activity composite sensors. Activities supported so far:
* running
* jogging
* walking
* still

THRESHOLD event is used to signal a change in the activity
state.

We associate a confidence interval for each activity expressed
as a percentage from 0 to 100.
* 0, means the sensor IS NOT reporting that activity.
* 100, means the sensor IS reporting that activity.

Users of this interface have two possible means to gather
information about the ongoing activities.

1. Event based, via event file descriptor
* sensor may report an event when ENTERING an activity or LEAVING
an activity based on a threshold value.
* drivers will wake up applications waiting data on the event fd

2. Polling, by reading the sysfs associated attribute files:
* /sys/bus/iio/devices/iio:device0/in_activity_running_input
expressed as percentage confidence value from 0 to 100.

This will offer an interface for Android significant motion
composite sensor defined here:
http://source.android.com/devices/sensors/composite_sensors.html

Activities listed above are supported by Freescale's MMA9553 sensor:
http://freescale.com/files/sensors/doc/ref_manual/MMA9553LSWRM.pdf

Signed-off-by: Irina Tirdea <[email protected]>
Signed-off-by: Daniel Baluta <[email protected]>
---
Documentation/ABI/testing/sysfs-bus-iio | 44 +++++++++++++++++++++++++++++++++
drivers/iio/industrialio-core.c | 5 ++++
include/linux/iio/types.h | 7 +++++-
3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 117521d..7bf49ad 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -790,6 +790,40 @@ Description:
met before an event is generated. If direction is not
specified then this period applies to both directions.

+What: /sys/.../events/in_activity_still_thresh_rising_en
+What: /sys/.../events/in_activity_still_thresh_falling_en
+What: /sys/.../events/in_activity_walking_thresh_rising_en
+What: /sys/.../events/in_activity_walking_thresh_falling_en
+What: /sys/.../events/in_activity_jogging_thresh_rising_en
+What: /sys/.../events/in_activity_jogging_thresh_falling_en
+What: /sys/.../events/in_activity_running_thresh_rising_en
+What: /sys/.../events/in_activity_running_thresh_falling_en
+KernelVersion: 3.19
+Contact: [email protected]
+Description:
+ Enables or disables activitity events. Depending on direction
+ an event is generated when sensor ENTERS or LEAVES a given state.
+
+What: /sys/.../events/in_activity_still_thresh_rising_value
+What: /sys/.../events/in_activity_still_thresh_falling_value
+What: /sys/.../events/in_activity_walking_thresh_rising_value
+What: /sys/.../events/in_activity_walking_thresh_falling_value
+What: /sys/.../events/in_activity_jogging_thresh_rising_value
+What: /sys/.../events/in_activity_jogging_thresh_falling_value
+What: /sys/.../events/in_activity_running_thresh_rising_value
+What: /sys/.../events/in_activity_running_thresh_falling_value
+KernelVersion: 3.19
+Contact: [email protected]
+Description:
+ Confidence value (in units as percentage) to be used
+ for deciding when an event should be generated. E.g for
+ running: If the confidence value reported by the sensor
+ is greater than in_activity_running_thresh_rising_value
+ then the sensor ENTERS running state. Conversely, if the
+ confidence value reported by the sensor is lower than
+ in_activity_running_thresh_falling_value then the sensor
+ is LEAVING running state.
+
What: /sys/.../iio:deviceX/events/in_accel_mag_en
What: /sys/.../iio:deviceX/events/in_accel_mag_rising_en
What: /sys/.../iio:deviceX/events/in_accel_mag_falling_en
@@ -956,6 +990,16 @@ Description:
and the relevant _type attributes to establish the data storage
format.

+What: /sys/.../iio:deviceX/in_activity_still_input
+What: /sys/.../iio:deviceX/in_activity_walking_input
+What: /sys/.../iio:deviceX/in_activity_jogging_input
+What: /sys/.../iio:deviceX/in_activity_running_input
+KernelVersion: 3.19
+Contact: [email protected]
+Description:
+ This attribute is used to read the confidence for an activity
+ expressed in units as percentage.
+
What: /sys/.../iio:deviceX/in_anglvel_z_quadrature_correction_raw
KernelVersion: 2.6.38
Contact: [email protected]
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index af3e76d..e453ef9 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -70,6 +70,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_CCT] = "cct",
[IIO_PRESSURE] = "pressure",
[IIO_HUMIDITYRELATIVE] = "humidityrelative",
+ [IIO_ACTIVITY] = "activity",
};

static const char * const iio_modifier_names[] = {
@@ -91,6 +92,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_NORTH_TRUE] = "from_north_true",
[IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
[IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
+ [IIO_MOD_RUNNING] = "running",
+ [IIO_MOD_JOGGING] = "jogging",
+ [IIO_MOD_WALKING] = "walking",
+ [IIO_MOD_STILL] = "still",
};

/* relies on pairs of these shared then separate */
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 4a2af8a..b3a241d 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -30,6 +30,7 @@ enum iio_chan_type {
IIO_CCT,
IIO_PRESSURE,
IIO_HUMIDITYRELATIVE,
+ IIO_ACTIVITY,
};

enum iio_modifier {
@@ -59,7 +60,11 @@ enum iio_modifier {
IIO_MOD_NORTH_MAGN,
IIO_MOD_NORTH_TRUE,
IIO_MOD_NORTH_MAGN_TILT_COMP,
- IIO_MOD_NORTH_TRUE_TILT_COMP
+ IIO_MOD_NORTH_TRUE_TILT_COMP,
+ IIO_MOD_RUNNING,
+ IIO_MOD_JOGGING,
+ IIO_MOD_WALKING,
+ IIO_MOD_STILL,
};

enum iio_event_type {
--
1.9.1

2014-11-10 12:44:36

by Daniel Baluta

[permalink] [raw]
Subject: [PATCH v4 6/7] iio: dummy: Demonstrate the usage of new channel types

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 IIO_CHAN_INFO_CALIBHEIGHT mask bit for reading and writing
user's height.

Signed-off-by: Irina Tirdea <[email protected]>
Signed-off-by: Daniel Baluta <[email protected]>
---
drivers/staging/iio/iio_simple_dummy.c | 199 +++++++++++++++++++++++---
drivers/staging/iio/iio_simple_dummy.h | 5 +
drivers/staging/iio/iio_simple_dummy_events.c | 43 ++++++
3 files changed, 229 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index bf78e6f..10a9e08 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_THRESH,
+ .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_THRESH,
+ .dir = IIO_EV_DIR_FALLING,
+ .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
#endif

/*
@@ -215,6 +243,37 @@ 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) |
+ BIT(IIO_CHAN_INFO_CALIBHEIGHT),
+ .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_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 */
+ },
};

/**
@@ -263,24 +322,55 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
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;
+ }
+ break;
case IIO_CHAN_INFO_OFFSET:
/* only single ended adc -> 7 */
*val = 7;
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;
+ 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 +388,27 @@ 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;
+ case IIO_CHAN_INFO_CALIBHEIGHT:
+ switch (chan->type) {
+ case IIO_STEPS:
+ *val = st->height;
+ ret = IIO_VAL_INT;
+ break;
+ default:
+ break;
+ }
+ break;
+
default:
break;
}
@@ -330,14 +441,45 @@ 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;
+ 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,6 +498,24 @@ 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;
+ }
+ case IIO_CHAN_INFO_CALIBHEIGHT:
+ switch (chan->type) {
+ case IIO_STEPS:
+ st->height = val;
+ return 0;
+ default:
+ return -EINVAL;
+ }

default:
return -EINVAL;
@@ -395,6 +555,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 ad89842..3b714b4 100644
--- a/drivers/staging/iio/iio_simple_dummy.h
+++ b/drivers/staging/iio/iio_simple_dummy.h
@@ -34,9 +34,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..ac15a44 100644
--- a/drivers/staging/iio/iio_simple_dummy_events.c
+++ b/drivers/staging/iio/iio_simple_dummy_events.c
@@ -72,6 +72,22 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
st->event_en = state;
else
return -EINVAL;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case IIO_ACTIVITY:
+ switch (type) {
+ case IIO_EV_TYPE_THRESH:
+ 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 +177,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_THRESH,
+ 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_THRESH,
+ 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

2014-11-10 12:44:31

by Daniel Baluta

[permalink] [raw]
Subject: [PATCH v4 4/7] iio: core: Introduce STEPS channel, ENABLE mask and INSTANCE event

From: Irina Tirdea <[email protected]>

These changes are needed to support the functionality of a pedometer.
A pedometer has two basic functionalities: step counter and step detector.

The step counter needs to be enabled and then it will count the steps
in its hardware register. Whenever the application needs to check
the step count, it will read the step counter register. To support the
step counter a new channel type STEPS is added. Since the pedometer needs
to be enabled first so that the hardware can count and store the steps,
we need a specific ENABLE channel info mask.

The step detector will generate an interrupt each time a step is detected.
To support this functionality we add a new event type INSTANCE.

For more information on the Android requirements for step counter and step
detector see:
http://source.android.com/devices/sensors/composite_sensors.html#counter
and http://source.android.com/devices/sensors/composite_sensors.html#detector.

A device that has the pedometer functionality this interface needs to
support is Freescale's MMA9553L:
http://www.freescale.com/files/sensors/doc/ref_manual/MMA9553LSWRM.pdf

Signed-off-by: Irina Tirdea <[email protected]>
Signed-off-by: Daniel Baluta <[email protected]>
---
Documentation/ABI/testing/sysfs-bus-iio | 22 ++++++++++++++++++++++
drivers/iio/industrialio-core.c | 2 ++
drivers/iio/industrialio-event.c | 1 +
include/linux/iio/iio.h | 1 +
include/linux/iio/types.h | 2 ++
5 files changed, 28 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 7bf49ad..c60b0a1 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -856,6 +856,13 @@ Description:
number or direction is not specified, applies to all channels of
this type.

+What: /sys/.../events/in_steps_instance_en
+KernelVersion: 3.19
+Contact: [email protected]
+Description:
+ Enables or disables step detection. Each time the user takes a step an
+ event of this type will be generated.
+
What: /sys/bus/iio/devices/iio:deviceX/trigger/current_trigger
KernelVersion: 2.6.35
Contact: [email protected]
@@ -1095,3 +1102,18 @@ Description:
after application of scale and offset. If no offset or scale is
present, output should be considered as processed with the
unit in milliamps.
+
+What: /sys/.../iio:deviceX/in_steps_en
+KernelVersion: 3.19
+Contact: [email protected]
+Description:
+ Activates the step counter. After activation, the number of steps
+ taken by the user will be counted in hardware and exported through
+ in_steps_input.
+
+What: /sys/.../iio:deviceX/in_steps_input
+KernelVersion: 3.19
+Contact: [email protected]
+Description:
+ This attribute is used to read the number of steps taken by the user
+ since the last reboot while activated.
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index e453ef9..1e060f3 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -71,6 +71,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_PRESSURE] = "pressure",
[IIO_HUMIDITYRELATIVE] = "humidityrelative",
[IIO_ACTIVITY] = "activity",
+ [IIO_STEPS] = "steps",
};

static const char * const iio_modifier_names[] = {
@@ -118,6 +119,7 @@ static const char * const iio_chan_info_postfix[] = {
[IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
[IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
[IIO_CHAN_INFO_INT_TIME] = "integration_time",
+ [IIO_CHAN_INFO_ENABLE] = "en",
};

/**
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index 1290290..3f5cee0 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -197,6 +197,7 @@ static const char * const iio_ev_type_text[] = {
[IIO_EV_TYPE_ROC] = "roc",
[IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
[IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
+ [IIO_EV_TYPE_INSTANCE] = "instance",
};

static const char * const iio_ev_dir_text[] = {
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 3642ce7..f45a400 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -38,6 +38,7 @@ enum iio_chan_info_enum {
IIO_CHAN_INFO_HARDWAREGAIN,
IIO_CHAN_INFO_HYSTERESIS,
IIO_CHAN_INFO_INT_TIME,
+ IIO_CHAN_INFO_ENABLE,
};

enum iio_shared_by {
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 52cb532..904dcbb 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -31,6 +31,7 @@ enum iio_chan_type {
IIO_PRESSURE,
IIO_HUMIDITYRELATIVE,
IIO_ACTIVITY,
+ IIO_STEPS,
};

enum iio_modifier {
@@ -73,6 +74,7 @@ enum iio_event_type {
IIO_EV_TYPE_ROC,
IIO_EV_TYPE_THRESH_ADAPTIVE,
IIO_EV_TYPE_MAG_ADAPTIVE,
+ IIO_EV_TYPE_INSTANCE,
};

enum iio_event_info {
--
1.9.1

2014-11-10 12:44:53

by Daniel Baluta

[permalink] [raw]
Subject: [PATCH v4 5/7] iio: core: Introduce IIO_CHAN_INFO_CALIBHEIGHT

From: Irina Tirdea <[email protected]>

Some devices need the height of the user to compute various
parameters. One of this devices is Freescale's MMA9553L
(http://www.freescale.com/files/sensors/doc/ref_manual/MMA9553LSWRM.pdf)
that needs the height of the user to compute the stride length which
is used further to determine distance, speed and activity type.

Signed-off-by: Irina Tirdea <[email protected]>
Signed-off-by: Daniel Baluta <[email protected]>
---
Documentation/ABI/testing/sysfs-bus-iio | 8 ++++++++
drivers/iio/industrialio-core.c | 1 +
include/linux/iio/iio.h | 1 +
3 files changed, 10 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index c60b0a1..4a9e29a 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -323,6 +323,14 @@ Description:
production inaccuracies). If shared across all channels,
<type>_calibscale is used.

+What: /sys/bus/iio/devices/iio:deviceX/in_steps_calibheight
+KernelVersion: 3.19
+Contact: [email protected]
+Description:
+ Height of the user (in centimeters) used by some pedometers
+ to compute the stride length, distance, speed and activity
+ type.
+
What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available
What: /sys/.../iio:deviceX/in_voltageX_scale_available
What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 1e060f3..45bb3a4 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -120,6 +120,7 @@ static const char * const iio_chan_info_postfix[] = {
[IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
[IIO_CHAN_INFO_INT_TIME] = "integration_time",
[IIO_CHAN_INFO_ENABLE] = "en",
+ [IIO_CHAN_INFO_CALIBHEIGHT] = "calibheight",
};

/**
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index f45a400..878d861 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -39,6 +39,7 @@ enum iio_chan_info_enum {
IIO_CHAN_INFO_HYSTERESIS,
IIO_CHAN_INFO_INT_TIME,
IIO_CHAN_INFO_ENABLE,
+ IIO_CHAN_INFO_CALIBHEIGHT,
};

enum iio_shared_by {
--
1.9.1

2014-11-10 12:44:52

by Daniel Baluta

[permalink] [raw]
Subject: [PATCH v4 7/7] iio: event_monitor: Add support for new channel types

We have the following testing scenario:

$ insmod iio_dummy_evgen.ko
$ insmod iio_dummy.ko

./iio_event_monitor /dev/iio:device0
Event: time: 1412786467971335337, type: activity(running), channel: 0,
evtype: thresh, direction: rising
Event: time: 1412786530792974091, type: activity(walking), channel: 0,
evtype: thresh, direction: falling
Event: time: 1412764319184761765, type: steps, channel: 0, evtype: instance

$ echo 1 > /sys/bus/iio/devices/iio_evgen/poke_ev0
$ echo 2 > /sys/bus/iio/devices/iio_evgen/poke_ev0
$ echo 3 > /sys/bus/iio/devices/iio_evgen/poke_ev0

Signed-off-by: Irina Tirdea <[email protected]>
Signed-off-by: Daniel Baluta <[email protected]>
---
.../staging/iio/Documentation/iio_event_monitor.c | 23 +++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c
index 940ed23..def236a 100644
--- a/drivers/staging/iio/Documentation/iio_event_monitor.c
+++ b/drivers/staging/iio/Documentation/iio_event_monitor.c
@@ -49,6 +49,8 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_CCT] = "cct",
[IIO_PRESSURE] = "pressure",
[IIO_HUMIDITYRELATIVE] = "humidityrelative",
+ [IIO_ACTIVITY] = "activity",
+ [IIO_STEPS] = "steps",
};

static const char * const iio_ev_type_text[] = {
@@ -57,6 +59,7 @@ static const char * const iio_ev_type_text[] = {
[IIO_EV_TYPE_ROC] = "roc",
[IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
[IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
+ [IIO_EV_TYPE_INSTANCE] = "instance",
};

static const char * const iio_ev_dir_text[] = {
@@ -92,6 +95,10 @@ static const char * const iio_modifier_names[] = {
[IIO_MOD_NORTH_TRUE] = "from_north_true",
[IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
[IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
+ [IIO_MOD_RUNNING] = "running",
+ [IIO_MOD_JOGGING] = "jogging",
+ [IIO_MOD_WALKING] = "walking",
+ [IIO_MOD_STILL] = "still",
};

static bool event_is_known(struct iio_event_data *event)
@@ -121,6 +128,8 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_CCT:
case IIO_PRESSURE:
case IIO_HUMIDITYRELATIVE:
+ case IIO_ACTIVITY:
+ case IIO_STEPS:
break;
default:
return false;
@@ -154,6 +163,10 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_MOD_NORTH_TRUE:
case IIO_MOD_NORTH_MAGN_TILT_COMP:
case IIO_MOD_NORTH_TRUE_TILT_COMP:
+ case IIO_MOD_RUNNING:
+ case IIO_MOD_JOGGING:
+ case IIO_MOD_WALKING:
+ case IIO_MOD_STILL:
break;
default:
return false;
@@ -165,6 +178,7 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_EV_TYPE_ROC:
case IIO_EV_TYPE_THRESH_ADAPTIVE:
case IIO_EV_TYPE_MAG_ADAPTIVE:
+ case IIO_EV_TYPE_INSTANCE:
break;
default:
return false;
@@ -174,6 +188,7 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_EV_DIR_EITHER:
case IIO_EV_DIR_RISING:
case IIO_EV_DIR_FALLING:
+ case IIO_EV_DIR_NONE:
break;
default:
return false;
@@ -214,9 +229,11 @@ static void print_event(struct iio_event_data *event)
else if (chan >= 0)
printf("channel: %d, ", chan);

- printf("evtype: %s, direction: %s\n",
- iio_ev_type_text[ev_type],
- iio_ev_dir_text[dir]);
+ printf("evtype: %s", iio_ev_type_text[ev_type]);
+
+ if (dir != IIO_EV_DIR_NONE)
+ printf(", direction: %s", iio_ev_dir_text[dir]);
+ printf("\n");
}

int main(int argc, char **argv)
--
1.9.1

2014-11-10 12:45:45

by Daniel Baluta

[permalink] [raw]
Subject: [PATCH v4 3/7] iio: core: Introduce IIO_EV_DIR_NONE

From: Irina Tirdea <[email protected]>

For some events (e.g.: step detector) a direction does not make sense.

Add IIO_EV_DIR_NONE to be used with such events and generate sysfs event
attributes that do not contain direction.

Signed-off-by: Irina Tirdea <[email protected]>
Signed-off-by: Daniel Baluta <[email protected]>
---
drivers/iio/industrialio-event.c | 12 +++++++++---
include/linux/iio/types.h | 1 +
2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index 0c1e37e..1290290 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -327,9 +327,15 @@ static int iio_device_add_event(struct iio_dev *indio_dev,
for_each_set_bit(i, mask, sizeof(*mask)*8) {
if (i >= ARRAY_SIZE(iio_ev_info_text))
return -EINVAL;
- postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
- iio_ev_type_text[type], iio_ev_dir_text[dir],
- iio_ev_info_text[i]);
+ if (dir != IIO_EV_DIR_NONE)
+ postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
+ iio_ev_type_text[type],
+ iio_ev_dir_text[dir],
+ iio_ev_info_text[i]);
+ else
+ postfix = kasprintf(GFP_KERNEL, "%s_%s",
+ iio_ev_type_text[type],
+ iio_ev_info_text[i]);
if (postfix == NULL)
return -ENOMEM;

diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index b3a241d..52cb532 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -86,6 +86,7 @@ enum iio_event_direction {
IIO_EV_DIR_EITHER,
IIO_EV_DIR_RISING,
IIO_EV_DIR_FALLING,
+ IIO_EV_DIR_NONE,
};

#define IIO_VAL_INT 1
--
1.9.1

2014-11-10 12:46:11

by Daniel Baluta

[permalink] [raw]
Subject: [PATCH v4 1/7] iio: dummy: Add virtual registers for dummy device

We need a way to store events generated by iio_dummy_evgen module,
in order to correctly process IRQs in iio_simple_dummy_events.

For the moment, we add two registers:

* id_reg - ID register, stores the source of the event
* id_data - DATA register, stores the type of the event

e.g echo 4 > /sys/bus/iio/devices/iio_evgen/poke2

id_reg 0x02, id_data 0x04

This means, event of type 4 was generated by fake device 2.

We currently use a hardcoded mapping of virtual events to IIO events.

Signed-off-by: Irina Tirdea <[email protected]>
Signed-off-by: Daniel Baluta <[email protected]>
---
drivers/staging/iio/iio_dummy_evgen.c | 17 +++++++++++++++++
drivers/staging/iio/iio_dummy_evgen.h | 6 ++++++
drivers/staging/iio/iio_simple_dummy.h | 2 ++
drivers/staging/iio/iio_simple_dummy_events.c | 23 ++++++++++++++++++-----
4 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c
index 5a804f1..59ad5a3 100644
--- a/drivers/staging/iio/iio_dummy_evgen.c
+++ b/drivers/staging/iio/iio_dummy_evgen.c
@@ -33,6 +33,7 @@
* @base: base of irq range
* @enabled: mask of which irqs are enabled
* @inuse: mask of which irqs are connected
+ * @regs: irq regs we are faking
* @lock: protect the evgen state
*/
struct iio_dummy_eventgen {
@@ -40,6 +41,7 @@ struct iio_dummy_eventgen {
int base;
bool enabled[IIO_EVENTGEN_NO];
bool inuse[IIO_EVENTGEN_NO];
+ struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
struct mutex lock;
};

@@ -136,6 +138,12 @@ int iio_dummy_evgen_release_irq(int irq)
}
EXPORT_SYMBOL_GPL(iio_dummy_evgen_release_irq);

+struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq)
+{
+ return &iio_evgen->regs[irq - iio_evgen->base];
+}
+EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs);
+
static void iio_dummy_evgen_free(void)
{
irq_free_descs(iio_evgen->base, IIO_EVENTGEN_NO);
@@ -153,6 +161,15 @@ static ssize_t iio_evgen_poke(struct device *dev,
size_t len)
{
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ unsigned long event;
+ int ret;
+
+ ret = kstrtoul(buf, 10, &event);
+ if (ret)
+ return ret;
+
+ iio_evgen->regs[this_attr->address].reg_id = this_attr->address;
+ iio_evgen->regs[this_attr->address].reg_data = event;

if (iio_evgen->enabled[this_attr->address])
handle_nested_irq(iio_evgen->base + this_attr->address);
diff --git a/drivers/staging/iio/iio_dummy_evgen.h b/drivers/staging/iio/iio_dummy_evgen.h
index 3a18081..2ac293a 100644
--- a/drivers/staging/iio/iio_dummy_evgen.h
+++ b/drivers/staging/iio/iio_dummy_evgen.h
@@ -1,6 +1,12 @@
#ifndef _IIO_DUMMY_EVGEN_H_
#define _IIO_DUMMY_EVGEN_H_

+struct iio_dummy_regs {
+ u32 reg_id;
+ u32 reg_data;
+};
+
+struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq);
int iio_dummy_evgen_get_irq(void);
int iio_dummy_evgen_release_irq(int irq);

diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h
index 3027aed..ad89842 100644
--- a/drivers/staging/iio/iio_simple_dummy.h
+++ b/drivers/staging/iio/iio_simple_dummy.h
@@ -13,6 +13,7 @@
#include <linux/kernel.h>

struct iio_dummy_accel_calibscale;
+struct iio_dummy_regs;

/**
* struct iio_dummy_state - device instance specific state.
@@ -35,6 +36,7 @@ struct iio_dummy_state {
int accel_calibbias;
const struct iio_dummy_accel_calibscale *accel_calibscale;
struct mutex lock;
+ struct iio_dummy_regs *regs;
#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 64b45b0..719dfa5 100644
--- a/drivers/staging/iio/iio_simple_dummy_events.c
+++ b/drivers/staging/iio/iio_simple_dummy_events.c
@@ -148,12 +148,23 @@ int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private)
{
struct iio_dev *indio_dev = private;
+ struct iio_dummy_state *st = iio_priv(indio_dev);
+
+ dev_dbg(&indio_dev->dev, "id %x event %x\n",
+ st->regs->reg_id, st->regs->reg_data);
+
+ switch (st->regs->reg_data) {
+ case 0:
+ iio_push_event(indio_dev,
+ IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
+ IIO_EV_DIR_RISING,
+ IIO_EV_TYPE_THRESH, 0, 0, 0),
+ iio_get_time_ns());
+ break;
+ default:
+ break;
+ }

- iio_push_event(indio_dev,
- IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
- IIO_EV_DIR_RISING,
- IIO_EV_TYPE_THRESH, 0, 0, 0),
- iio_get_time_ns());
return IRQ_HANDLED;
}

@@ -179,6 +190,8 @@ int iio_simple_dummy_events_register(struct iio_dev *indio_dev)
ret = st->event_irq;
goto error_ret;
}
+ st->regs = iio_dummy_evgen_get_regs(st->event_irq);
+
ret = request_threaded_irq(st->event_irq,
NULL,
&iio_simple_dummy_event_handler,
--
1.9.1

2014-11-22 11:05:19

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v4 6/7] iio: dummy: Demonstrate the usage of new channel types

On 10/11/14 12:45, Daniel Baluta wrote:
> 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 IIO_CHAN_INFO_CALIBHEIGHT mask bit for reading and writing
> user's height.
>
> Signed-off-by: Irina Tirdea <[email protected]>
> Signed-off-by: Daniel Baluta <[email protected]>
The only bit that makes me wonder in here is allowing writing to the steps
and activity _input attributes.

Now I can see that it makes sense from the point of view of testing the
interface and any userspace code, but the question here is whether the
'normal IIO intefaces' of this dummy driver should correspond to real sensors
where writing to input channels isn't ever valid!.

The alternative would be to create some deliberately not standard ABI for
these with a suitably obvious, 'I don't normally exist' naming - which
would then need documenting. Perhaps what you have is the best option.
Pitty there isn't an out_steps_* interface. Human interface control :)
Or even better out_activity_run_* which would be fun...

Upshot is - leave this be. It's our dummy driver afterall and we can
change the ABI as much as we like without anyone having a valid argument
that we broke their system ;)
> ---
> drivers/staging/iio/iio_simple_dummy.c | 199 +++++++++++++++++++++++---
> drivers/staging/iio/iio_simple_dummy.h | 5 +
> drivers/staging/iio/iio_simple_dummy_events.c | 43 ++++++
> 3 files changed, 229 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
> index bf78e6f..10a9e08 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_THRESH,
> + .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_THRESH,
> + .dir = IIO_EV_DIR_FALLING,
> + .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
> +};
> #endif
>
> /*
> @@ -215,6 +243,37 @@ 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) |
> + BIT(IIO_CHAN_INFO_CALIBHEIGHT),
> + .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_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 */
> + },
> };
>
> /**
> @@ -263,24 +322,55 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
> 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;
> + }
> + break;
> case IIO_CHAN_INFO_OFFSET:
> /* only single ended adc -> 7 */
> *val = 7;
> 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;
> + 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 +388,27 @@ 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;
> + case IIO_CHAN_INFO_CALIBHEIGHT:
> + switch (chan->type) {
> + case IIO_STEPS:
> + *val = st->height;
> + ret = IIO_VAL_INT;
> + break;
> + default:
> + break;
> + }
> + break;
> +
> default:
> break;
> }
> @@ -330,14 +441,45 @@ 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;
> + 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,6 +498,24 @@ 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;
> + }
> + case IIO_CHAN_INFO_CALIBHEIGHT:
> + switch (chan->type) {
> + case IIO_STEPS:
> + st->height = val;
> + return 0;
> + default:
> + return -EINVAL;
> + }
>
> default:
> return -EINVAL;
> @@ -395,6 +555,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 ad89842..3b714b4 100644
> --- a/drivers/staging/iio/iio_simple_dummy.h
> +++ b/drivers/staging/iio/iio_simple_dummy.h
> @@ -34,9 +34,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..ac15a44 100644
> --- a/drivers/staging/iio/iio_simple_dummy_events.c
> +++ b/drivers/staging/iio/iio_simple_dummy_events.c
> @@ -72,6 +72,22 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
> st->event_en = state;
> else
> return -EINVAL;
> + default:
> + return -EINVAL;
> + }
> + break;
> + case IIO_ACTIVITY:
> + switch (type) {
> + case IIO_EV_TYPE_THRESH:
> + 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 +177,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_THRESH,
> + 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_THRESH,
> + 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;
> }
>

2014-11-22 11:07:00

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v4 1/7] iio: dummy: Add virtual registers for dummy device

On 10/11/14 12:45, Daniel Baluta wrote:
> We need a way to store events generated by iio_dummy_evgen module,
> in order to correctly process IRQs in iio_simple_dummy_events.
>
> For the moment, we add two registers:
>
> * id_reg - ID register, stores the source of the event
> * id_data - DATA register, stores the type of the event
>
> e.g echo 4 > /sys/bus/iio/devices/iio_evgen/poke2
>
> id_reg 0x02, id_data 0x04
>
> This means, event of type 4 was generated by fake device 2.
>
> We currently use a hardcoded mapping of virtual events to IIO events.
>
> Signed-off-by: Irina Tirdea <[email protected]>
> Signed-off-by: Daniel Baluta <[email protected]>
Applied to the togreg branch of iio.git - initially push out as testing for
the autobuilders to pick a fight with it.
> ---
> drivers/staging/iio/iio_dummy_evgen.c | 17 +++++++++++++++++
> drivers/staging/iio/iio_dummy_evgen.h | 6 ++++++
> drivers/staging/iio/iio_simple_dummy.h | 2 ++
> drivers/staging/iio/iio_simple_dummy_events.c | 23 ++++++++++++++++++-----
> 4 files changed, 43 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c
> index 5a804f1..59ad5a3 100644
> --- a/drivers/staging/iio/iio_dummy_evgen.c
> +++ b/drivers/staging/iio/iio_dummy_evgen.c
> @@ -33,6 +33,7 @@
> * @base: base of irq range
> * @enabled: mask of which irqs are enabled
> * @inuse: mask of which irqs are connected
> + * @regs: irq regs we are faking
> * @lock: protect the evgen state
> */
> struct iio_dummy_eventgen {
> @@ -40,6 +41,7 @@ struct iio_dummy_eventgen {
> int base;
> bool enabled[IIO_EVENTGEN_NO];
> bool inuse[IIO_EVENTGEN_NO];
> + struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
> struct mutex lock;
> };
>
> @@ -136,6 +138,12 @@ int iio_dummy_evgen_release_irq(int irq)
> }
> EXPORT_SYMBOL_GPL(iio_dummy_evgen_release_irq);
>
> +struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq)
> +{
> + return &iio_evgen->regs[irq - iio_evgen->base];
> +}
> +EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs);
> +
> static void iio_dummy_evgen_free(void)
> {
> irq_free_descs(iio_evgen->base, IIO_EVENTGEN_NO);
> @@ -153,6 +161,15 @@ static ssize_t iio_evgen_poke(struct device *dev,
> size_t len)
> {
> struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
> + unsigned long event;
> + int ret;
> +
> + ret = kstrtoul(buf, 10, &event);
> + if (ret)
> + return ret;
> +
> + iio_evgen->regs[this_attr->address].reg_id = this_attr->address;
> + iio_evgen->regs[this_attr->address].reg_data = event;
>
> if (iio_evgen->enabled[this_attr->address])
> handle_nested_irq(iio_evgen->base + this_attr->address);
> diff --git a/drivers/staging/iio/iio_dummy_evgen.h b/drivers/staging/iio/iio_dummy_evgen.h
> index 3a18081..2ac293a 100644
> --- a/drivers/staging/iio/iio_dummy_evgen.h
> +++ b/drivers/staging/iio/iio_dummy_evgen.h
> @@ -1,6 +1,12 @@
> #ifndef _IIO_DUMMY_EVGEN_H_
> #define _IIO_DUMMY_EVGEN_H_
>
> +struct iio_dummy_regs {
> + u32 reg_id;
> + u32 reg_data;
> +};
> +
> +struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq);
> int iio_dummy_evgen_get_irq(void);
> int iio_dummy_evgen_release_irq(int irq);
>
> diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h
> index 3027aed..ad89842 100644
> --- a/drivers/staging/iio/iio_simple_dummy.h
> +++ b/drivers/staging/iio/iio_simple_dummy.h
> @@ -13,6 +13,7 @@
> #include <linux/kernel.h>
>
> struct iio_dummy_accel_calibscale;
> +struct iio_dummy_regs;
>
> /**
> * struct iio_dummy_state - device instance specific state.
> @@ -35,6 +36,7 @@ struct iio_dummy_state {
> int accel_calibbias;
> const struct iio_dummy_accel_calibscale *accel_calibscale;
> struct mutex lock;
> + struct iio_dummy_regs *regs;
> #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 64b45b0..719dfa5 100644
> --- a/drivers/staging/iio/iio_simple_dummy_events.c
> +++ b/drivers/staging/iio/iio_simple_dummy_events.c
> @@ -148,12 +148,23 @@ int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
> static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private)
> {
> struct iio_dev *indio_dev = private;
> + struct iio_dummy_state *st = iio_priv(indio_dev);
> +
> + dev_dbg(&indio_dev->dev, "id %x event %x\n",
> + st->regs->reg_id, st->regs->reg_data);
> +
> + switch (st->regs->reg_data) {
> + case 0:
> + iio_push_event(indio_dev,
> + IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
> + IIO_EV_DIR_RISING,
> + IIO_EV_TYPE_THRESH, 0, 0, 0),
> + iio_get_time_ns());
> + break;
> + default:
> + break;
> + }
>
> - iio_push_event(indio_dev,
> - IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
> - IIO_EV_DIR_RISING,
> - IIO_EV_TYPE_THRESH, 0, 0, 0),
> - iio_get_time_ns());
> return IRQ_HANDLED;
> }
>
> @@ -179,6 +190,8 @@ int iio_simple_dummy_events_register(struct iio_dev *indio_dev)
> ret = st->event_irq;
> goto error_ret;
> }
> + st->regs = iio_dummy_evgen_get_regs(st->event_irq);
> +
> ret = request_threaded_irq(st->event_irq,
> NULL,
> &iio_simple_dummy_event_handler,
>

2014-11-22 11:13:12

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v4 2/7] iio: core: Introduce IIO_ACTIVITY channel

On 10/11/14 12:45, Daniel Baluta wrote:
> This channel will be used for exposing information about
> activity composite sensors. Activities supported so far:
> * running
> * jogging
> * walking
> * still
>
> THRESHOLD event is used to signal a change in the activity
> state.
>
> We associate a confidence interval for each activity expressed
> as a percentage from 0 to 100.
> * 0, means the sensor IS NOT reporting that activity.
> * 100, means the sensor IS reporting that activity.
>
> Users of this interface have two possible means to gather
> information about the ongoing activities.
>
> 1. Event based, via event file descriptor
> * sensor may report an event when ENTERING an activity or LEAVING
> an activity based on a threshold value.
> * drivers will wake up applications waiting data on the event fd
>
> 2. Polling, by reading the sysfs associated attribute files:
> * /sys/bus/iio/devices/iio:device0/in_activity_running_input
> expressed as percentage confidence value from 0 to 100.
>
> This will offer an interface for Android significant motion
> composite sensor defined here:
> http://source.android.com/devices/sensors/composite_sensors.html
>
> Activities listed above are supported by Freescale's MMA9553 sensor:
> http://freescale.com/files/sensors/doc/ref_manual/MMA9553LSWRM.pdf
>
> Signed-off-by: Irina Tirdea <[email protected]>
> Signed-off-by: Daniel Baluta <[email protected]>
Very happy with this - mind you only time will tell if we have ended up
with a flexible enough interface - particularly as people get better at
distinguishing activities use accelerometry.
(come to think of it I wrote a paper on this once - it was rubbish and got
rejected, so I'd rather not remember it, but that's not the point - I
have some recollection of how hard it is to get terribly accurate!)

Anyhow, applied to the togreg branch of iio.git. testing... autobuilders
etc etc.
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 44 +++++++++++++++++++++++++++++++++
> drivers/iio/industrialio-core.c | 5 ++++
> include/linux/iio/types.h | 7 +++++-
> 3 files changed, 55 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 117521d..7bf49ad 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -790,6 +790,40 @@ Description:
> met before an event is generated. If direction is not
> specified then this period applies to both directions.
>
> +What: /sys/.../events/in_activity_still_thresh_rising_en
> +What: /sys/.../events/in_activity_still_thresh_falling_en
> +What: /sys/.../events/in_activity_walking_thresh_rising_en
> +What: /sys/.../events/in_activity_walking_thresh_falling_en
> +What: /sys/.../events/in_activity_jogging_thresh_rising_en
> +What: /sys/.../events/in_activity_jogging_thresh_falling_en
> +What: /sys/.../events/in_activity_running_thresh_rising_en
> +What: /sys/.../events/in_activity_running_thresh_falling_en
> +KernelVersion: 3.19
> +Contact: [email protected]
> +Description:
> + Enables or disables activitity events. Depending on direction
> + an event is generated when sensor ENTERS or LEAVES a given state.
> +
> +What: /sys/.../events/in_activity_still_thresh_rising_value
> +What: /sys/.../events/in_activity_still_thresh_falling_value
> +What: /sys/.../events/in_activity_walking_thresh_rising_value
> +What: /sys/.../events/in_activity_walking_thresh_falling_value
> +What: /sys/.../events/in_activity_jogging_thresh_rising_value
> +What: /sys/.../events/in_activity_jogging_thresh_falling_value
> +What: /sys/.../events/in_activity_running_thresh_rising_value
> +What: /sys/.../events/in_activity_running_thresh_falling_value
> +KernelVersion: 3.19
> +Contact: [email protected]
> +Description:
> + Confidence value (in units as percentage) to be used
> + for deciding when an event should be generated. E.g for
> + running: If the confidence value reported by the sensor
> + is greater than in_activity_running_thresh_rising_value
> + then the sensor ENTERS running state. Conversely, if the
> + confidence value reported by the sensor is lower than
> + in_activity_running_thresh_falling_value then the sensor
> + is LEAVING running state.
> +
> What: /sys/.../iio:deviceX/events/in_accel_mag_en
> What: /sys/.../iio:deviceX/events/in_accel_mag_rising_en
> What: /sys/.../iio:deviceX/events/in_accel_mag_falling_en
> @@ -956,6 +990,16 @@ Description:
> and the relevant _type attributes to establish the data storage
> format.
>
> +What: /sys/.../iio:deviceX/in_activity_still_input
> +What: /sys/.../iio:deviceX/in_activity_walking_input
> +What: /sys/.../iio:deviceX/in_activity_jogging_input
> +What: /sys/.../iio:deviceX/in_activity_running_input
> +KernelVersion: 3.19
> +Contact: [email protected]
> +Description:
> + This attribute is used to read the confidence for an activity
> + expressed in units as percentage.
> +
> What: /sys/.../iio:deviceX/in_anglvel_z_quadrature_correction_raw
> KernelVersion: 2.6.38
> Contact: [email protected]
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index af3e76d..e453ef9 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -70,6 +70,7 @@ static const char * const iio_chan_type_name_spec[] = {
> [IIO_CCT] = "cct",
> [IIO_PRESSURE] = "pressure",
> [IIO_HUMIDITYRELATIVE] = "humidityrelative",
> + [IIO_ACTIVITY] = "activity",
> };
>
> static const char * const iio_modifier_names[] = {
> @@ -91,6 +92,10 @@ static const char * const iio_modifier_names[] = {
> [IIO_MOD_NORTH_TRUE] = "from_north_true",
> [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
> [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
> + [IIO_MOD_RUNNING] = "running",
> + [IIO_MOD_JOGGING] = "jogging",
> + [IIO_MOD_WALKING] = "walking",
> + [IIO_MOD_STILL] = "still",
> };
>
> /* relies on pairs of these shared then separate */
> diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
> index 4a2af8a..b3a241d 100644
> --- a/include/linux/iio/types.h
> +++ b/include/linux/iio/types.h
> @@ -30,6 +30,7 @@ enum iio_chan_type {
> IIO_CCT,
> IIO_PRESSURE,
> IIO_HUMIDITYRELATIVE,
> + IIO_ACTIVITY,
> };
>
> enum iio_modifier {
> @@ -59,7 +60,11 @@ enum iio_modifier {
> IIO_MOD_NORTH_MAGN,
> IIO_MOD_NORTH_TRUE,
> IIO_MOD_NORTH_MAGN_TILT_COMP,
> - IIO_MOD_NORTH_TRUE_TILT_COMP
> + IIO_MOD_NORTH_TRUE_TILT_COMP,
> + IIO_MOD_RUNNING,
> + IIO_MOD_JOGGING,
> + IIO_MOD_WALKING,
> + IIO_MOD_STILL,
> };
>
> enum iio_event_type {
>

2014-11-22 11:14:01

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v4 3/7] iio: core: Introduce IIO_EV_DIR_NONE

On 10/11/14 12:45, Daniel Baluta wrote:
> From: Irina Tirdea <[email protected]>
>
> For some events (e.g.: step detector) a direction does not make sense.
>
> Add IIO_EV_DIR_NONE to be used with such events and generate sysfs event
> attributes that do not contain direction.
>
> Signed-off-by: Irina Tirdea <[email protected]>
> Signed-off-by: Daniel Baluta <[email protected]>
Applied -> iio.git:togreg, pushed->iio.git:testing.

> ---
> drivers/iio/industrialio-event.c | 12 +++++++++---
> include/linux/iio/types.h | 1 +
> 2 files changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
> index 0c1e37e..1290290 100644
> --- a/drivers/iio/industrialio-event.c
> +++ b/drivers/iio/industrialio-event.c
> @@ -327,9 +327,15 @@ static int iio_device_add_event(struct iio_dev *indio_dev,
> for_each_set_bit(i, mask, sizeof(*mask)*8) {
> if (i >= ARRAY_SIZE(iio_ev_info_text))
> return -EINVAL;
> - postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
> - iio_ev_type_text[type], iio_ev_dir_text[dir],
> - iio_ev_info_text[i]);
> + if (dir != IIO_EV_DIR_NONE)
> + postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
> + iio_ev_type_text[type],
> + iio_ev_dir_text[dir],
> + iio_ev_info_text[i]);
> + else
> + postfix = kasprintf(GFP_KERNEL, "%s_%s",
> + iio_ev_type_text[type],
> + iio_ev_info_text[i]);
> if (postfix == NULL)
> return -ENOMEM;
>
> diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
> index b3a241d..52cb532 100644
> --- a/include/linux/iio/types.h
> +++ b/include/linux/iio/types.h
> @@ -86,6 +86,7 @@ enum iio_event_direction {
> IIO_EV_DIR_EITHER,
> IIO_EV_DIR_RISING,
> IIO_EV_DIR_FALLING,
> + IIO_EV_DIR_NONE,
> };
>
> #define IIO_VAL_INT 1
>

2014-11-22 11:17:01

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v4 4/7] iio: core: Introduce STEPS channel, ENABLE mask and INSTANCE event

On 10/11/14 12:45, Daniel Baluta wrote:
> From: Irina Tirdea <[email protected]>
>
> These changes are needed to support the functionality of a pedometer.
> A pedometer has two basic functionalities: step counter and step detector.
>
> The step counter needs to be enabled and then it will count the steps
> in its hardware register. Whenever the application needs to check
> the step count, it will read the step counter register. To support the
> step counter a new channel type STEPS is added. Since the pedometer needs
> to be enabled first so that the hardware can count and store the steps,
> we need a specific ENABLE channel info mask.
>
> The step detector will generate an interrupt each time a step is detected.
> To support this functionality we add a new event type INSTANCE.
>
> For more information on the Android requirements for step counter and step
> detector see:
> http://source.android.com/devices/sensors/composite_sensors.html#counter
> and http://source.android.com/devices/sensors/composite_sensors.html#detector.
>
> A device that has the pedometer functionality this interface needs to
> support is Freescale's MMA9553L:
> http://www.freescale.com/files/sensors/doc/ref_manual/MMA9553LSWRM.pdf
>
> Signed-off-by: Irina Tirdea <[email protected]>
> Signed-off-by: Daniel Baluta <[email protected]>
Still a little dubious about the specific enable interface - perhaps
we might think about renaming it 'start' or something like that and making
the semantics that it always zeros the counter. Then I guess we'd also
need stop to turn it off and it all gets uggly.

Lets go with enable for now and perhaps revisit when a real driver comes
along and we can see how it is being used in anger.

Applied to the togreg branch of iio.git - initially pushed out as testing.

Thanks

Jonathan
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 22 ++++++++++++++++++++++
> drivers/iio/industrialio-core.c | 2 ++
> drivers/iio/industrialio-event.c | 1 +
> include/linux/iio/iio.h | 1 +
> include/linux/iio/types.h | 2 ++
> 5 files changed, 28 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 7bf49ad..c60b0a1 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -856,6 +856,13 @@ Description:
> number or direction is not specified, applies to all channels of
> this type.
>
> +What: /sys/.../events/in_steps_instance_en
> +KernelVersion: 3.19
> +Contact: [email protected]
> +Description:
> + Enables or disables step detection. Each time the user takes a step an
> + event of this type will be generated.
> +
> What: /sys/bus/iio/devices/iio:deviceX/trigger/current_trigger
> KernelVersion: 2.6.35
> Contact: [email protected]
> @@ -1095,3 +1102,18 @@ Description:
> after application of scale and offset. If no offset or scale is
> present, output should be considered as processed with the
> unit in milliamps.
> +
> +What: /sys/.../iio:deviceX/in_steps_en
> +KernelVersion: 3.19
> +Contact: [email protected]
> +Description:
> + Activates the step counter. After activation, the number of steps
> + taken by the user will be counted in hardware and exported through
> + in_steps_input.
> +
> +What: /sys/.../iio:deviceX/in_steps_input
> +KernelVersion: 3.19
> +Contact: [email protected]
> +Description:
> + This attribute is used to read the number of steps taken by the user
> + since the last reboot while activated.
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index e453ef9..1e060f3 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -71,6 +71,7 @@ static const char * const iio_chan_type_name_spec[] = {
> [IIO_PRESSURE] = "pressure",
> [IIO_HUMIDITYRELATIVE] = "humidityrelative",
> [IIO_ACTIVITY] = "activity",
> + [IIO_STEPS] = "steps",
> };
>
> static const char * const iio_modifier_names[] = {
> @@ -118,6 +119,7 @@ static const char * const iio_chan_info_postfix[] = {
> [IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
> [IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
> [IIO_CHAN_INFO_INT_TIME] = "integration_time",
> + [IIO_CHAN_INFO_ENABLE] = "en",
> };
>
> /**
> diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
> index 1290290..3f5cee0 100644
> --- a/drivers/iio/industrialio-event.c
> +++ b/drivers/iio/industrialio-event.c
> @@ -197,6 +197,7 @@ static const char * const iio_ev_type_text[] = {
> [IIO_EV_TYPE_ROC] = "roc",
> [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
> [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
> + [IIO_EV_TYPE_INSTANCE] = "instance",
> };
>
> static const char * const iio_ev_dir_text[] = {
> diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
> index 3642ce7..f45a400 100644
> --- a/include/linux/iio/iio.h
> +++ b/include/linux/iio/iio.h
> @@ -38,6 +38,7 @@ enum iio_chan_info_enum {
> IIO_CHAN_INFO_HARDWAREGAIN,
> IIO_CHAN_INFO_HYSTERESIS,
> IIO_CHAN_INFO_INT_TIME,
> + IIO_CHAN_INFO_ENABLE,
> };
>
> enum iio_shared_by {
> diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
> index 52cb532..904dcbb 100644
> --- a/include/linux/iio/types.h
> +++ b/include/linux/iio/types.h
> @@ -31,6 +31,7 @@ enum iio_chan_type {
> IIO_PRESSURE,
> IIO_HUMIDITYRELATIVE,
> IIO_ACTIVITY,
> + IIO_STEPS,
> };
>
> enum iio_modifier {
> @@ -73,6 +74,7 @@ enum iio_event_type {
> IIO_EV_TYPE_ROC,
> IIO_EV_TYPE_THRESH_ADAPTIVE,
> IIO_EV_TYPE_MAG_ADAPTIVE,
> + IIO_EV_TYPE_INSTANCE,
> };
>
> enum iio_event_info {
>

2014-11-22 11:17:52

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v4 5/7] iio: core: Introduce IIO_CHAN_INFO_CALIBHEIGHT

On 10/11/14 12:45, Daniel Baluta wrote:
> From: Irina Tirdea <[email protected]>
>
> Some devices need the height of the user to compute various
> parameters. One of this devices is Freescale's MMA9553L
> (http://www.freescale.com/files/sensors/doc/ref_manual/MMA9553LSWRM.pdf)
> that needs the height of the user to compute the stride length which
> is used further to determine distance, speed and activity type.
>
> Signed-off-by: Irina Tirdea <[email protected]>
> Signed-off-by: Daniel Baluta <[email protected]>
Applied to the togreg branch of iio.git pushed out as testing.

What fun ;)

J
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 8 ++++++++
> drivers/iio/industrialio-core.c | 1 +
> include/linux/iio/iio.h | 1 +
> 3 files changed, 10 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index c60b0a1..4a9e29a 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -323,6 +323,14 @@ Description:
> production inaccuracies). If shared across all channels,
> <type>_calibscale is used.
>
> +What: /sys/bus/iio/devices/iio:deviceX/in_steps_calibheight
> +KernelVersion: 3.19
> +Contact: [email protected]
> +Description:
> + Height of the user (in centimeters) used by some pedometers
> + to compute the stride length, distance, speed and activity
> + type.
> +
> What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available
> What: /sys/.../iio:deviceX/in_voltageX_scale_available
> What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available
> diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
> index 1e060f3..45bb3a4 100644
> --- a/drivers/iio/industrialio-core.c
> +++ b/drivers/iio/industrialio-core.c
> @@ -120,6 +120,7 @@ static const char * const iio_chan_info_postfix[] = {
> [IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
> [IIO_CHAN_INFO_INT_TIME] = "integration_time",
> [IIO_CHAN_INFO_ENABLE] = "en",
> + [IIO_CHAN_INFO_CALIBHEIGHT] = "calibheight",
> };
>
> /**
> diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
> index f45a400..878d861 100644
> --- a/include/linux/iio/iio.h
> +++ b/include/linux/iio/iio.h
> @@ -39,6 +39,7 @@ enum iio_chan_info_enum {
> IIO_CHAN_INFO_HYSTERESIS,
> IIO_CHAN_INFO_INT_TIME,
> IIO_CHAN_INFO_ENABLE,
> + IIO_CHAN_INFO_CALIBHEIGHT,
> };
>
> enum iio_shared_by {
>

2014-11-22 11:18:55

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v4 6/7] iio: dummy: Demonstrate the usage of new channel types

On 22/11/14 11:05, Jonathan Cameron wrote:
> On 10/11/14 12:45, Daniel Baluta wrote:
>> 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 IIO_CHAN_INFO_CALIBHEIGHT mask bit for reading and writing
>> user's height.
>>
>> Signed-off-by: Irina Tirdea <[email protected]>
>> Signed-off-by: Daniel Baluta <[email protected]>
> The only bit that makes me wonder in here is allowing writing to the steps
> and activity _input attributes.
>
> Now I can see that it makes sense from the point of view of testing the
> interface and any userspace code, but the question here is whether the
> 'normal IIO intefaces' of this dummy driver should correspond to real sensors
> where writing to input channels isn't ever valid!.
>
> The alternative would be to create some deliberately not standard ABI for
> these with a suitably obvious, 'I don't normally exist' naming - which
> would then need documenting. Perhaps what you have is the best option.
> Pitty there isn't an out_steps_* interface. Human interface control :)
> Or even better out_activity_run_* which would be fun...
>
> Upshot is - leave this be. It's our dummy driver afterall and we can
> change the ABI as much as we like without anyone having a valid argument
> that we broke their system ;)

Applied to the togreg branch of iio.git - initially pushed out as testing.

Nicely done with cc'ing a miss-spelt version of your own email address ;)
>> ---
>> drivers/staging/iio/iio_simple_dummy.c | 199 +++++++++++++++++++++++---
>> drivers/staging/iio/iio_simple_dummy.h | 5 +
>> drivers/staging/iio/iio_simple_dummy_events.c | 43 ++++++
>> 3 files changed, 229 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
>> index bf78e6f..10a9e08 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_THRESH,
>> + .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_THRESH,
>> + .dir = IIO_EV_DIR_FALLING,
>> + .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
>> +};
>> #endif
>>
>> /*
>> @@ -215,6 +243,37 @@ 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) |
>> + BIT(IIO_CHAN_INFO_CALIBHEIGHT),
>> + .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_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 */
>> + },
>> };
>>
>> /**
>> @@ -263,24 +322,55 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
>> 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;
>> + }
>> + break;
>> case IIO_CHAN_INFO_OFFSET:
>> /* only single ended adc -> 7 */
>> *val = 7;
>> 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;
>> + 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 +388,27 @@ 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;
>> + case IIO_CHAN_INFO_CALIBHEIGHT:
>> + switch (chan->type) {
>> + case IIO_STEPS:
>> + *val = st->height;
>> + ret = IIO_VAL_INT;
>> + break;
>> + default:
>> + break;
>> + }
>> + break;
>> +
>> default:
>> break;
>> }
>> @@ -330,14 +441,45 @@ 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;
>> + 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,6 +498,24 @@ 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;
>> + }
>> + case IIO_CHAN_INFO_CALIBHEIGHT:
>> + switch (chan->type) {
>> + case IIO_STEPS:
>> + st->height = val;
>> + return 0;
>> + default:
>> + return -EINVAL;
>> + }
>>
>> default:
>> return -EINVAL;
>> @@ -395,6 +555,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 ad89842..3b714b4 100644
>> --- a/drivers/staging/iio/iio_simple_dummy.h
>> +++ b/drivers/staging/iio/iio_simple_dummy.h
>> @@ -34,9 +34,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..ac15a44 100644
>> --- a/drivers/staging/iio/iio_simple_dummy_events.c
>> +++ b/drivers/staging/iio/iio_simple_dummy_events.c
>> @@ -72,6 +72,22 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
>> st->event_en = state;
>> else
>> return -EINVAL;
>> + default:
>> + return -EINVAL;
>> + }
>> + break;
>> + case IIO_ACTIVITY:
>> + switch (type) {
>> + case IIO_EV_TYPE_THRESH:
>> + 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 +177,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_THRESH,
>> + 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_THRESH,
>> + 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;
>> }
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>

2014-11-22 11:20:47

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v4 7/7] iio: event_monitor: Add support for new channel types

On 10/11/14 12:45, Daniel Baluta wrote:
> We have the following testing scenario:
>
> $ insmod iio_dummy_evgen.ko
> $ insmod iio_dummy.ko
>
> ./iio_event_monitor /dev/iio:device0
> Event: time: 1412786467971335337, type: activity(running), channel: 0,
> evtype: thresh, direction: rising
> Event: time: 1412786530792974091, type: activity(walking), channel: 0,
> evtype: thresh, direction: falling
> Event: time: 1412764319184761765, type: steps, channel: 0, evtype: instance
>
> $ echo 1 > /sys/bus/iio/devices/iio_evgen/poke_ev0
> $ echo 2 > /sys/bus/iio/devices/iio_evgen/poke_ev0
> $ echo 3 > /sys/bus/iio/devices/iio_evgen/poke_ev0
>
> Signed-off-by: Irina Tirdea <[email protected]>
> Signed-off-by: Daniel Baluta <[email protected]>
Good description and a good patch. Nice series all in all - I like
the approach of adding ABI with dummy driver and tool support before
the hardware driver comes along. Not quite the same from working out
how things will be used in anger, but still a clean way to work.

All applied to the togreg branch of iio.git - pushed out as testing - in
this case for the autobuilders to completely ignore the patch...

Thanks,

Jonathan
> ---
> .../staging/iio/Documentation/iio_event_monitor.c | 23 +++++++++++++++++++---
> 1 file changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c
> index 940ed23..def236a 100644
> --- a/drivers/staging/iio/Documentation/iio_event_monitor.c
> +++ b/drivers/staging/iio/Documentation/iio_event_monitor.c
> @@ -49,6 +49,8 @@ static const char * const iio_chan_type_name_spec[] = {
> [IIO_CCT] = "cct",
> [IIO_PRESSURE] = "pressure",
> [IIO_HUMIDITYRELATIVE] = "humidityrelative",
> + [IIO_ACTIVITY] = "activity",
> + [IIO_STEPS] = "steps",
> };
>
> static const char * const iio_ev_type_text[] = {
> @@ -57,6 +59,7 @@ static const char * const iio_ev_type_text[] = {
> [IIO_EV_TYPE_ROC] = "roc",
> [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
> [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
> + [IIO_EV_TYPE_INSTANCE] = "instance",
> };
>
> static const char * const iio_ev_dir_text[] = {
> @@ -92,6 +95,10 @@ static const char * const iio_modifier_names[] = {
> [IIO_MOD_NORTH_TRUE] = "from_north_true",
> [IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
> [IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
> + [IIO_MOD_RUNNING] = "running",
> + [IIO_MOD_JOGGING] = "jogging",
> + [IIO_MOD_WALKING] = "walking",
> + [IIO_MOD_STILL] = "still",
> };
>
> static bool event_is_known(struct iio_event_data *event)
> @@ -121,6 +128,8 @@ static bool event_is_known(struct iio_event_data *event)
> case IIO_CCT:
> case IIO_PRESSURE:
> case IIO_HUMIDITYRELATIVE:
> + case IIO_ACTIVITY:
> + case IIO_STEPS:
> break;
> default:
> return false;
> @@ -154,6 +163,10 @@ static bool event_is_known(struct iio_event_data *event)
> case IIO_MOD_NORTH_TRUE:
> case IIO_MOD_NORTH_MAGN_TILT_COMP:
> case IIO_MOD_NORTH_TRUE_TILT_COMP:
> + case IIO_MOD_RUNNING:
> + case IIO_MOD_JOGGING:
> + case IIO_MOD_WALKING:
> + case IIO_MOD_STILL:
> break;
> default:
> return false;
> @@ -165,6 +178,7 @@ static bool event_is_known(struct iio_event_data *event)
> case IIO_EV_TYPE_ROC:
> case IIO_EV_TYPE_THRESH_ADAPTIVE:
> case IIO_EV_TYPE_MAG_ADAPTIVE:
> + case IIO_EV_TYPE_INSTANCE:
> break;
> default:
> return false;
> @@ -174,6 +188,7 @@ static bool event_is_known(struct iio_event_data *event)
> case IIO_EV_DIR_EITHER:
> case IIO_EV_DIR_RISING:
> case IIO_EV_DIR_FALLING:
> + case IIO_EV_DIR_NONE:
> break;
> default:
> return false;
> @@ -214,9 +229,11 @@ static void print_event(struct iio_event_data *event)
> else if (chan >= 0)
> printf("channel: %d, ", chan);
>
> - printf("evtype: %s, direction: %s\n",
> - iio_ev_type_text[ev_type],
> - iio_ev_dir_text[dir]);
> + printf("evtype: %s", iio_ev_type_text[ev_type]);
> +
> + if (dir != IIO_EV_DIR_NONE)
> + printf(", direction: %s", iio_ev_dir_text[dir]);
> + printf("\n");
> }
>
> int main(int argc, char **argv)
>

2014-11-24 12:31:10

by Daniel Baluta

[permalink] [raw]
Subject: Re: [PATCH v4 6/7] iio: dummy: Demonstrate the usage of new channel types

On Sat, Nov 22, 2014 at 1:18 PM, Jonathan Cameron <[email protected]> wrote:
> On 22/11/14 11:05, Jonathan Cameron wrote:
>> On 10/11/14 12:45, Daniel Baluta wrote:
>>> 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 IIO_CHAN_INFO_CALIBHEIGHT mask bit for reading and writing
>>> user's height.
>>>
>>> Signed-off-by: Irina Tirdea <[email protected]>
>>> Signed-off-by: Daniel Baluta <[email protected]>
>> The only bit that makes me wonder in here is allowing writing to the steps
>> and activity _input attributes.
>>
>> Now I can see that it makes sense from the point of view of testing the
>> interface and any userspace code, but the question here is whether the
>> 'normal IIO intefaces' of this dummy driver should correspond to real sensors
>> where writing to input channels isn't ever valid!.
>>
>> The alternative would be to create some deliberately not standard ABI for
>> these with a suitably obvious, 'I don't normally exist' naming - which
>> would then need documenting. Perhaps what you have is the best option.
>> Pitty there isn't an out_steps_* interface. Human interface control :)
>> Or even better out_activity_run_* which would be fun...
>>
>> Upshot is - leave this be. It's our dummy driver afterall and we can
>> change the ABI as much as we like without anyone having a valid argument
>> that we broke their system ;)
>
> Applied to the togreg branch of iio.git - initially pushed out as testing.
>
> Nicely done with cc'ing a miss-spelt version of your own email address ;)

:)), I noticed that when was already too late.

Jonathan, Hartmut thanks for reviews!

Daniel.