diff options
author | Daniel Baluta <daniel.baluta@intel.com> | 2014-11-10 07:45:34 -0500 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2014-11-22 06:15:04 -0500 |
commit | 3e34e650db19708b1c27421e8d3d749a09adbb0c (patch) | |
tree | bb78aca153f7d02dd08f291ce04f5a16a3e49c19 | |
parent | bcdf28fb1b8badf3cdba18d349f6251057e36a45 (diff) |
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 <irina.tirdea@intel.com>
Signed-off-by: Daniel Baluta <daniel.baluta@intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r-- | drivers/staging/iio/iio_simple_dummy.c | 199 | ||||
-rw-r--r-- | drivers/staging/iio/iio_simple_dummy.h | 5 | ||||
-rw-r--r-- | 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 bf78e6f0311f..10a9e0882bbc 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 = { | |||
69 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE), | 69 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE), |
70 | }; | 70 | }; |
71 | 71 | ||
72 | /* | ||
73 | * simple step detect event - triggered when a step is detected | ||
74 | */ | ||
75 | static const struct iio_event_spec step_detect_event = { | ||
76 | .type = IIO_EV_TYPE_INSTANCE, | ||
77 | .dir = IIO_EV_DIR_NONE, | ||
78 | .mask_separate = BIT(IIO_EV_INFO_ENABLE), | ||
79 | }; | ||
80 | |||
81 | /* | ||
82 | * simple transition event - triggered when the reported running confidence | ||
83 | * value rises above a threshold value | ||
84 | */ | ||
85 | static const struct iio_event_spec iio_running_event = { | ||
86 | .type = IIO_EV_TYPE_THRESH, | ||
87 | .dir = IIO_EV_DIR_RISING, | ||
88 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE), | ||
89 | }; | ||
90 | |||
91 | /* | ||
92 | * simple transition event - triggered when the reported walking confidence | ||
93 | * value falls under a threshold value | ||
94 | */ | ||
95 | static const struct iio_event_spec iio_walking_event = { | ||
96 | .type = IIO_EV_TYPE_THRESH, | ||
97 | .dir = IIO_EV_DIR_FALLING, | ||
98 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE), | ||
99 | }; | ||
72 | #endif | 100 | #endif |
73 | 101 | ||
74 | /* | 102 | /* |
@@ -215,6 +243,37 @@ static const struct iio_chan_spec iio_dummy_channels[] = { | |||
215 | .indexed = 1, | 243 | .indexed = 1, |
216 | .channel = 0, | 244 | .channel = 0, |
217 | }, | 245 | }, |
246 | { | ||
247 | .type = IIO_STEPS, | ||
248 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_ENABLE) | | ||
249 | BIT(IIO_CHAN_INFO_CALIBHEIGHT), | ||
250 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | ||
251 | .scan_index = -1, | ||
252 | #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS | ||
253 | .event_spec = &step_detect_event, | ||
254 | .num_event_specs = 1, | ||
255 | #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */ | ||
256 | }, | ||
257 | { | ||
258 | .type = IIO_ACTIVITY, | ||
259 | .modified = 1, | ||
260 | .channel2 = IIO_MOD_RUNNING, | ||
261 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | ||
262 | #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS | ||
263 | .event_spec = &iio_running_event, | ||
264 | .num_event_specs = 1, | ||
265 | #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */ | ||
266 | }, | ||
267 | { | ||
268 | .type = IIO_ACTIVITY, | ||
269 | .modified = 1, | ||
270 | .channel2 = IIO_MOD_WALKING, | ||
271 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), | ||
272 | #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS | ||
273 | .event_spec = &iio_walking_event, | ||
274 | .num_event_specs = 1, | ||
275 | #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */ | ||
276 | }, | ||
218 | }; | 277 | }; |
219 | 278 | ||
220 | /** | 279 | /** |
@@ -263,24 +322,55 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev, | |||
263 | break; | 322 | break; |
264 | } | 323 | } |
265 | break; | 324 | break; |
325 | case IIO_CHAN_INFO_PROCESSED: | ||
326 | switch (chan->type) { | ||
327 | case IIO_STEPS: | ||
328 | *val = st->steps; | ||
329 | ret = IIO_VAL_INT; | ||
330 | break; | ||
331 | case IIO_ACTIVITY: | ||
332 | switch (chan->channel2) { | ||
333 | case IIO_MOD_RUNNING: | ||
334 | *val = st->activity_running; | ||
335 | ret = IIO_VAL_INT; | ||
336 | break; | ||
337 | case IIO_MOD_WALKING: | ||
338 | *val = st->activity_walking; | ||
339 | ret = IIO_VAL_INT; | ||
340 | break; | ||
341 | default: | ||
342 | break; | ||
343 | } | ||
344 | break; | ||
345 | default: | ||
346 | break; | ||
347 | } | ||
348 | break; | ||
266 | case IIO_CHAN_INFO_OFFSET: | 349 | case IIO_CHAN_INFO_OFFSET: |
267 | /* only single ended adc -> 7 */ | 350 | /* only single ended adc -> 7 */ |
268 | *val = 7; | 351 | *val = 7; |
269 | ret = IIO_VAL_INT; | 352 | ret = IIO_VAL_INT; |
270 | break; | 353 | break; |
271 | case IIO_CHAN_INFO_SCALE: | 354 | case IIO_CHAN_INFO_SCALE: |
272 | switch (chan->differential) { | 355 | switch (chan->type) { |
273 | case 0: | 356 | case IIO_VOLTAGE: |
274 | /* only single ended adc -> 0.001333 */ | 357 | switch (chan->differential) { |
275 | *val = 0; | 358 | case 0: |
276 | *val2 = 1333; | 359 | /* only single ended adc -> 0.001333 */ |
277 | ret = IIO_VAL_INT_PLUS_MICRO; | 360 | *val = 0; |
361 | *val2 = 1333; | ||
362 | ret = IIO_VAL_INT_PLUS_MICRO; | ||
363 | break; | ||
364 | case 1: | ||
365 | /* all differential adc channels -> | ||
366 | * 0.000001344 */ | ||
367 | *val = 0; | ||
368 | *val2 = 1344; | ||
369 | ret = IIO_VAL_INT_PLUS_NANO; | ||
370 | } | ||
371 | break; | ||
372 | default: | ||
278 | break; | 373 | break; |
279 | case 1: | ||
280 | /* all differential adc channels -> 0.000001344 */ | ||
281 | *val = 0; | ||
282 | *val2 = 1344; | ||
283 | ret = IIO_VAL_INT_PLUS_NANO; | ||
284 | } | 374 | } |
285 | break; | 375 | break; |
286 | case IIO_CHAN_INFO_CALIBBIAS: | 376 | case IIO_CHAN_INFO_CALIBBIAS: |
@@ -298,6 +388,27 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev, | |||
298 | *val2 = 33; | 388 | *val2 = 33; |
299 | ret = IIO_VAL_INT_PLUS_NANO; | 389 | ret = IIO_VAL_INT_PLUS_NANO; |
300 | break; | 390 | break; |
391 | case IIO_CHAN_INFO_ENABLE: | ||
392 | switch (chan->type) { | ||
393 | case IIO_STEPS: | ||
394 | *val = st->steps_enabled; | ||
395 | ret = IIO_VAL_INT; | ||
396 | break; | ||
397 | default: | ||
398 | break; | ||
399 | } | ||
400 | break; | ||
401 | case IIO_CHAN_INFO_CALIBHEIGHT: | ||
402 | switch (chan->type) { | ||
403 | case IIO_STEPS: | ||
404 | *val = st->height; | ||
405 | ret = IIO_VAL_INT; | ||
406 | break; | ||
407 | default: | ||
408 | break; | ||
409 | } | ||
410 | break; | ||
411 | |||
301 | default: | 412 | default: |
302 | break; | 413 | break; |
303 | } | 414 | } |
@@ -330,14 +441,45 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev, | |||
330 | 441 | ||
331 | switch (mask) { | 442 | switch (mask) { |
332 | case IIO_CHAN_INFO_RAW: | 443 | case IIO_CHAN_INFO_RAW: |
333 | if (chan->output == 0) | 444 | switch (chan->type) { |
445 | case IIO_VOLTAGE: | ||
446 | if (chan->output == 0) | ||
447 | return -EINVAL; | ||
448 | |||
449 | /* Locking not required as writing single value */ | ||
450 | mutex_lock(&st->lock); | ||
451 | st->dac_val = val; | ||
452 | mutex_unlock(&st->lock); | ||
453 | return 0; | ||
454 | default: | ||
334 | return -EINVAL; | 455 | return -EINVAL; |
335 | 456 | } | |
336 | /* Locking not required as writing single value */ | 457 | case IIO_CHAN_INFO_PROCESSED: |
337 | mutex_lock(&st->lock); | 458 | switch (chan->type) { |
338 | st->dac_val = val; | 459 | case IIO_STEPS: |
339 | mutex_unlock(&st->lock); | 460 | mutex_lock(&st->lock); |
340 | return 0; | 461 | st->steps = val; |
462 | mutex_unlock(&st->lock); | ||
463 | return 0; | ||
464 | case IIO_ACTIVITY: | ||
465 | if (val < 0) | ||
466 | val = 0; | ||
467 | if (val > 100) | ||
468 | val = 100; | ||
469 | switch (chan->channel2) { | ||
470 | case IIO_MOD_RUNNING: | ||
471 | st->activity_running = val; | ||
472 | return 0; | ||
473 | case IIO_MOD_WALKING: | ||
474 | st->activity_walking = val; | ||
475 | return 0; | ||
476 | default: | ||
477 | return -EINVAL; | ||
478 | } | ||
479 | break; | ||
480 | default: | ||
481 | return -EINVAL; | ||
482 | } | ||
341 | case IIO_CHAN_INFO_CALIBSCALE: | 483 | case IIO_CHAN_INFO_CALIBSCALE: |
342 | mutex_lock(&st->lock); | 484 | mutex_lock(&st->lock); |
343 | /* Compare against table - hard matching here */ | 485 | /* Compare against table - hard matching here */ |
@@ -356,6 +498,24 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev, | |||
356 | st->accel_calibbias = val; | 498 | st->accel_calibbias = val; |
357 | mutex_unlock(&st->lock); | 499 | mutex_unlock(&st->lock); |
358 | return 0; | 500 | return 0; |
501 | case IIO_CHAN_INFO_ENABLE: | ||
502 | switch (chan->type) { | ||
503 | case IIO_STEPS: | ||
504 | mutex_lock(&st->lock); | ||
505 | st->steps_enabled = val; | ||
506 | mutex_unlock(&st->lock); | ||
507 | return 0; | ||
508 | default: | ||
509 | return -EINVAL; | ||
510 | } | ||
511 | case IIO_CHAN_INFO_CALIBHEIGHT: | ||
512 | switch (chan->type) { | ||
513 | case IIO_STEPS: | ||
514 | st->height = val; | ||
515 | return 0; | ||
516 | default: | ||
517 | return -EINVAL; | ||
518 | } | ||
359 | 519 | ||
360 | default: | 520 | default: |
361 | return -EINVAL; | 521 | return -EINVAL; |
@@ -395,6 +555,9 @@ static int iio_dummy_init_device(struct iio_dev *indio_dev) | |||
395 | st->accel_val = 34; | 555 | st->accel_val = 34; |
396 | st->accel_calibbias = -7; | 556 | st->accel_calibbias = -7; |
397 | st->accel_calibscale = &dummy_scales[0]; | 557 | st->accel_calibscale = &dummy_scales[0]; |
558 | st->steps = 47; | ||
559 | st->activity_running = 98; | ||
560 | st->activity_walking = 4; | ||
398 | 561 | ||
399 | return 0; | 562 | return 0; |
400 | } | 563 | } |
diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h index ad898424d9bd..3b714b486f5e 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 { | |||
34 | int differential_adc_val[2]; | 34 | int differential_adc_val[2]; |
35 | int accel_val; | 35 | int accel_val; |
36 | int accel_calibbias; | 36 | int accel_calibbias; |
37 | int activity_running; | ||
38 | int activity_walking; | ||
37 | const struct iio_dummy_accel_calibscale *accel_calibscale; | 39 | const struct iio_dummy_accel_calibscale *accel_calibscale; |
38 | struct mutex lock; | 40 | struct mutex lock; |
39 | struct iio_dummy_regs *regs; | 41 | struct iio_dummy_regs *regs; |
42 | int steps_enabled; | ||
43 | int steps; | ||
44 | int height; | ||
40 | #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS | 45 | #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS |
41 | int event_irq; | 46 | int event_irq; |
42 | int event_val; | 47 | int event_val; |
diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c index 719dfa5ae7df..ac15a44ba271 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, | |||
72 | st->event_en = state; | 72 | st->event_en = state; |
73 | else | 73 | else |
74 | return -EINVAL; | 74 | return -EINVAL; |
75 | default: | ||
76 | return -EINVAL; | ||
77 | } | ||
78 | break; | ||
79 | case IIO_ACTIVITY: | ||
80 | switch (type) { | ||
81 | case IIO_EV_TYPE_THRESH: | ||
82 | st->event_en = state; | ||
83 | break; | ||
84 | default: | ||
85 | return -EINVAL; | ||
86 | } | ||
87 | case IIO_STEPS: | ||
88 | switch (type) { | ||
89 | case IIO_EV_TYPE_INSTANCE: | ||
90 | st->event_en = state; | ||
75 | break; | 91 | break; |
76 | default: | 92 | default: |
77 | return -EINVAL; | 93 | return -EINVAL; |
@@ -161,6 +177,33 @@ static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private) | |||
161 | IIO_EV_TYPE_THRESH, 0, 0, 0), | 177 | IIO_EV_TYPE_THRESH, 0, 0, 0), |
162 | iio_get_time_ns()); | 178 | iio_get_time_ns()); |
163 | break; | 179 | break; |
180 | case 1: | ||
181 | if (st->activity_running > st->event_val) | ||
182 | iio_push_event(indio_dev, | ||
183 | IIO_EVENT_CODE(IIO_ACTIVITY, 0, | ||
184 | IIO_MOD_RUNNING, | ||
185 | IIO_EV_DIR_RISING, | ||
186 | IIO_EV_TYPE_THRESH, | ||
187 | 0, 0, 0), | ||
188 | iio_get_time_ns()); | ||
189 | break; | ||
190 | case 2: | ||
191 | if (st->activity_walking < st->event_val) | ||
192 | iio_push_event(indio_dev, | ||
193 | IIO_EVENT_CODE(IIO_ACTIVITY, 0, | ||
194 | IIO_MOD_WALKING, | ||
195 | IIO_EV_DIR_FALLING, | ||
196 | IIO_EV_TYPE_THRESH, | ||
197 | 0, 0, 0), | ||
198 | iio_get_time_ns()); | ||
199 | break; | ||
200 | case 3: | ||
201 | iio_push_event(indio_dev, | ||
202 | IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD, | ||
203 | IIO_EV_DIR_NONE, | ||
204 | IIO_EV_TYPE_INSTANCE, 0, 0, 0), | ||
205 | iio_get_time_ns()); | ||
206 | break; | ||
164 | default: | 207 | default: |
165 | break; | 208 | break; |
166 | } | 209 | } |