aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baluta <daniel.baluta@intel.com>2014-11-10 07:45:34 -0500
committerJonathan Cameron <jic23@kernel.org>2014-11-22 06:15:04 -0500
commit3e34e650db19708b1c27421e8d3d749a09adbb0c (patch)
treebb78aca153f7d02dd08f291ce04f5a16a3e49c19
parentbcdf28fb1b8badf3cdba18d349f6251057e36a45 (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.c199
-rw-r--r--drivers/staging/iio/iio_simple_dummy.h5
-rw-r--r--drivers/staging/iio/iio_simple_dummy_events.c43
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 */
75static 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 */
85static 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 */
95static 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 }