This source file includes following definitions.
- iio_dummy_read_raw
- iio_dummy_write_raw
- iio_dummy_init_device
- iio_dummy_probe
- iio_dummy_remove
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/module.h>
17 #include <linux/string.h>
18
19 #include <linux/iio/iio.h>
20 #include <linux/iio/sysfs.h>
21 #include <linux/iio/events.h>
22 #include <linux/iio/buffer.h>
23 #include <linux/iio/sw_device.h>
24 #include "iio_simple_dummy.h"
25
26 static const struct config_item_type iio_dummy_type = {
27 .ct_owner = THIS_MODULE,
28 };
29
30
31
32
33
34
35
36 struct iio_dummy_accel_calibscale {
37 int val;
38 int val2;
39 int regval;
40 };
41
42 static const struct iio_dummy_accel_calibscale dummy_scales[] = {
43 { 0, 100, 0x8 },
44 { 0, 133, 0x7 },
45 { 733, 13, 0x9 },
46 };
47
48 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
49
50
51
52
53
54 static const struct iio_event_spec iio_dummy_event = {
55 .type = IIO_EV_TYPE_THRESH,
56 .dir = IIO_EV_DIR_RISING,
57 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
58 };
59
60
61
62
63 static const struct iio_event_spec step_detect_event = {
64 .type = IIO_EV_TYPE_CHANGE,
65 .dir = IIO_EV_DIR_NONE,
66 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
67 };
68
69
70
71
72
73 static const struct iio_event_spec iio_running_event = {
74 .type = IIO_EV_TYPE_THRESH,
75 .dir = IIO_EV_DIR_RISING,
76 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
77 };
78
79
80
81
82
83 static const struct iio_event_spec iio_walking_event = {
84 .type = IIO_EV_TYPE_THRESH,
85 .dir = IIO_EV_DIR_FALLING,
86 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
87 };
88 #endif
89
90
91
92
93
94
95
96 static const struct iio_chan_spec iio_dummy_channels[] = {
97
98 {
99 .type = IIO_VOLTAGE,
100
101 .indexed = 1,
102 .channel = 0,
103
104 .info_mask_separate =
105
106
107
108
109
110 BIT(IIO_CHAN_INFO_RAW) |
111
112
113
114
115
116 BIT(IIO_CHAN_INFO_OFFSET) |
117
118
119
120
121
122 BIT(IIO_CHAN_INFO_SCALE),
123
124
125
126
127 .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
128
129 .scan_index = DUMMY_INDEX_VOLTAGE_0,
130 .scan_type = {
131 .sign = 'u',
132 .realbits = 13,
133 .storagebits = 16,
134 .shift = 0,
135 },
136 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
137 .event_spec = &iio_dummy_event,
138 .num_event_specs = 1,
139 #endif
140 },
141
142 {
143 .type = IIO_VOLTAGE,
144 .differential = 1,
145
146
147
148
149 .indexed = 1,
150 .channel = 1,
151 .channel2 = 2,
152
153
154
155
156
157 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
158
159
160
161
162
163 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
164
165
166
167
168 .scan_index = DUMMY_INDEX_DIFFVOLTAGE_1M2,
169 .scan_type = {
170 .sign = 's',
171 .realbits = 12,
172 .storagebits = 16,
173 .shift = 0,
174 },
175 },
176
177 {
178 .type = IIO_VOLTAGE,
179 .differential = 1,
180 .indexed = 1,
181 .channel = 3,
182 .channel2 = 4,
183 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
184 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
185 .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
186 .scan_index = DUMMY_INDEX_DIFFVOLTAGE_3M4,
187 .scan_type = {
188 .sign = 's',
189 .realbits = 11,
190 .storagebits = 16,
191 .shift = 0,
192 },
193 },
194
195
196
197
198 {
199 .type = IIO_ACCEL,
200 .modified = 1,
201
202 .channel2 = IIO_MOD_X,
203 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
204
205
206
207
208
209
210 BIT(IIO_CHAN_INFO_CALIBSCALE) |
211 BIT(IIO_CHAN_INFO_CALIBBIAS),
212 .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
213 .scan_index = DUMMY_INDEX_ACCELX,
214 .scan_type = {
215 .sign = 's',
216 .realbits = 16,
217 .storagebits = 16,
218 .shift = 0,
219 },
220 },
221
222
223
224
225 IIO_CHAN_SOFT_TIMESTAMP(4),
226
227 {
228 .type = IIO_VOLTAGE,
229 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
230 .scan_index = -1,
231 .output = 1,
232 .indexed = 1,
233 .channel = 0,
234 },
235 {
236 .type = IIO_STEPS,
237 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_ENABLE) |
238 BIT(IIO_CHAN_INFO_CALIBHEIGHT),
239 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
240 .scan_index = -1,
241 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
242 .event_spec = &step_detect_event,
243 .num_event_specs = 1,
244 #endif
245 },
246 {
247 .type = IIO_ACTIVITY,
248 .modified = 1,
249 .channel2 = IIO_MOD_RUNNING,
250 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
251 .scan_index = -1,
252 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
253 .event_spec = &iio_running_event,
254 .num_event_specs = 1,
255 #endif
256 },
257 {
258 .type = IIO_ACTIVITY,
259 .modified = 1,
260 .channel2 = IIO_MOD_WALKING,
261 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
262 .scan_index = -1,
263 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
264 .event_spec = &iio_walking_event,
265 .num_event_specs = 1,
266 #endif
267 },
268 };
269
270
271
272
273
274
275
276
277
278
279 static int iio_dummy_read_raw(struct iio_dev *indio_dev,
280 struct iio_chan_spec const *chan,
281 int *val,
282 int *val2,
283 long mask)
284 {
285 struct iio_dummy_state *st = iio_priv(indio_dev);
286 int ret = -EINVAL;
287
288 mutex_lock(&st->lock);
289 switch (mask) {
290 case IIO_CHAN_INFO_RAW:
291 switch (chan->type) {
292 case IIO_VOLTAGE:
293 if (chan->output) {
294
295 *val = st->dac_val;
296 ret = IIO_VAL_INT;
297 } else if (chan->differential) {
298 if (chan->channel == 1)
299 *val = st->differential_adc_val[0];
300 else
301 *val = st->differential_adc_val[1];
302 ret = IIO_VAL_INT;
303 } else {
304 *val = st->single_ended_adc_val;
305 ret = IIO_VAL_INT;
306 }
307 break;
308 case IIO_ACCEL:
309 *val = st->accel_val;
310 ret = IIO_VAL_INT;
311 break;
312 default:
313 break;
314 }
315 break;
316 case IIO_CHAN_INFO_PROCESSED:
317 switch (chan->type) {
318 case IIO_STEPS:
319 *val = st->steps;
320 ret = IIO_VAL_INT;
321 break;
322 case IIO_ACTIVITY:
323 switch (chan->channel2) {
324 case IIO_MOD_RUNNING:
325 *val = st->activity_running;
326 ret = IIO_VAL_INT;
327 break;
328 case IIO_MOD_WALKING:
329 *val = st->activity_walking;
330 ret = IIO_VAL_INT;
331 break;
332 default:
333 break;
334 }
335 break;
336 default:
337 break;
338 }
339 break;
340 case IIO_CHAN_INFO_OFFSET:
341
342 *val = 7;
343 ret = IIO_VAL_INT;
344 break;
345 case IIO_CHAN_INFO_SCALE:
346 switch (chan->type) {
347 case IIO_VOLTAGE:
348 switch (chan->differential) {
349 case 0:
350
351 *val = 0;
352 *val2 = 1333;
353 ret = IIO_VAL_INT_PLUS_MICRO;
354 break;
355 case 1:
356
357 *val = 0;
358 *val2 = 1344;
359 ret = IIO_VAL_INT_PLUS_NANO;
360 }
361 break;
362 default:
363 break;
364 }
365 break;
366 case IIO_CHAN_INFO_CALIBBIAS:
367
368 *val = st->accel_calibbias;
369 ret = IIO_VAL_INT;
370 break;
371 case IIO_CHAN_INFO_CALIBSCALE:
372 *val = st->accel_calibscale->val;
373 *val2 = st->accel_calibscale->val2;
374 ret = IIO_VAL_INT_PLUS_MICRO;
375 break;
376 case IIO_CHAN_INFO_SAMP_FREQ:
377 *val = 3;
378 *val2 = 33;
379 ret = IIO_VAL_INT_PLUS_NANO;
380 break;
381 case IIO_CHAN_INFO_ENABLE:
382 switch (chan->type) {
383 case IIO_STEPS:
384 *val = st->steps_enabled;
385 ret = IIO_VAL_INT;
386 break;
387 default:
388 break;
389 }
390 break;
391 case IIO_CHAN_INFO_CALIBHEIGHT:
392 switch (chan->type) {
393 case IIO_STEPS:
394 *val = st->height;
395 ret = IIO_VAL_INT;
396 break;
397 default:
398 break;
399 }
400 break;
401
402 default:
403 break;
404 }
405 mutex_unlock(&st->lock);
406 return ret;
407 }
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422 static int iio_dummy_write_raw(struct iio_dev *indio_dev,
423 struct iio_chan_spec const *chan,
424 int val,
425 int val2,
426 long mask)
427 {
428 int i;
429 int ret = 0;
430 struct iio_dummy_state *st = iio_priv(indio_dev);
431
432 switch (mask) {
433 case IIO_CHAN_INFO_RAW:
434 switch (chan->type) {
435 case IIO_VOLTAGE:
436 if (chan->output == 0)
437 return -EINVAL;
438
439
440 mutex_lock(&st->lock);
441 st->dac_val = val;
442 mutex_unlock(&st->lock);
443 return 0;
444 default:
445 return -EINVAL;
446 }
447 case IIO_CHAN_INFO_PROCESSED:
448 switch (chan->type) {
449 case IIO_STEPS:
450 mutex_lock(&st->lock);
451 st->steps = val;
452 mutex_unlock(&st->lock);
453 return 0;
454 case IIO_ACTIVITY:
455 if (val < 0)
456 val = 0;
457 if (val > 100)
458 val = 100;
459 switch (chan->channel2) {
460 case IIO_MOD_RUNNING:
461 st->activity_running = val;
462 return 0;
463 case IIO_MOD_WALKING:
464 st->activity_walking = val;
465 return 0;
466 default:
467 return -EINVAL;
468 }
469 break;
470 default:
471 return -EINVAL;
472 }
473 case IIO_CHAN_INFO_CALIBSCALE:
474 mutex_lock(&st->lock);
475
476 for (i = 0; i < ARRAY_SIZE(dummy_scales); i++)
477 if (val == dummy_scales[i].val &&
478 val2 == dummy_scales[i].val2)
479 break;
480 if (i == ARRAY_SIZE(dummy_scales))
481 ret = -EINVAL;
482 else
483 st->accel_calibscale = &dummy_scales[i];
484 mutex_unlock(&st->lock);
485 return ret;
486 case IIO_CHAN_INFO_CALIBBIAS:
487 mutex_lock(&st->lock);
488 st->accel_calibbias = val;
489 mutex_unlock(&st->lock);
490 return 0;
491 case IIO_CHAN_INFO_ENABLE:
492 switch (chan->type) {
493 case IIO_STEPS:
494 mutex_lock(&st->lock);
495 st->steps_enabled = val;
496 mutex_unlock(&st->lock);
497 return 0;
498 default:
499 return -EINVAL;
500 }
501 case IIO_CHAN_INFO_CALIBHEIGHT:
502 switch (chan->type) {
503 case IIO_STEPS:
504 st->height = val;
505 return 0;
506 default:
507 return -EINVAL;
508 }
509
510 default:
511 return -EINVAL;
512 }
513 }
514
515
516
517
518 static const struct iio_info iio_dummy_info = {
519 .read_raw = &iio_dummy_read_raw,
520 .write_raw = &iio_dummy_write_raw,
521 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
522 .read_event_config = &iio_simple_dummy_read_event_config,
523 .write_event_config = &iio_simple_dummy_write_event_config,
524 .read_event_value = &iio_simple_dummy_read_event_value,
525 .write_event_value = &iio_simple_dummy_write_event_value,
526 #endif
527 };
528
529
530
531
532
533
534
535
536 static int iio_dummy_init_device(struct iio_dev *indio_dev)
537 {
538 struct iio_dummy_state *st = iio_priv(indio_dev);
539
540 st->dac_val = 0;
541 st->single_ended_adc_val = 73;
542 st->differential_adc_val[0] = 33;
543 st->differential_adc_val[1] = -34;
544 st->accel_val = 34;
545 st->accel_calibbias = -7;
546 st->accel_calibscale = &dummy_scales[0];
547 st->steps = 47;
548 st->activity_running = 98;
549 st->activity_walking = 4;
550
551 return 0;
552 }
553
554
555
556
557
558
559
560
561
562
563 static struct iio_sw_device *iio_dummy_probe(const char *name)
564 {
565 int ret;
566 struct iio_dev *indio_dev;
567 struct iio_dummy_state *st;
568 struct iio_sw_device *swd;
569
570 swd = kzalloc(sizeof(*swd), GFP_KERNEL);
571 if (!swd) {
572 ret = -ENOMEM;
573 goto error_kzalloc;
574 }
575
576
577
578
579
580
581
582
583 indio_dev = iio_device_alloc(sizeof(*st));
584 if (!indio_dev) {
585 ret = -ENOMEM;
586 goto error_ret;
587 }
588
589 st = iio_priv(indio_dev);
590 mutex_init(&st->lock);
591
592 iio_dummy_init_device(indio_dev);
593
594
595
596
597
598
599
600
601
602
603
604
605 swd->device = indio_dev;
606
607
608
609
610
611
612
613
614
615
616 indio_dev->name = kstrdup(name, GFP_KERNEL);
617
618
619 indio_dev->channels = iio_dummy_channels;
620 indio_dev->num_channels = ARRAY_SIZE(iio_dummy_channels);
621
622
623
624
625
626 indio_dev->info = &iio_dummy_info;
627
628
629 indio_dev->modes = INDIO_DIRECT_MODE;
630
631 ret = iio_simple_dummy_events_register(indio_dev);
632 if (ret < 0)
633 goto error_free_device;
634
635 ret = iio_simple_dummy_configure_buffer(indio_dev);
636 if (ret < 0)
637 goto error_unregister_events;
638
639 ret = iio_device_register(indio_dev);
640 if (ret < 0)
641 goto error_unconfigure_buffer;
642
643 iio_swd_group_init_type_name(swd, name, &iio_dummy_type);
644
645 return swd;
646 error_unconfigure_buffer:
647 iio_simple_dummy_unconfigure_buffer(indio_dev);
648 error_unregister_events:
649 iio_simple_dummy_events_unregister(indio_dev);
650 error_free_device:
651 iio_device_free(indio_dev);
652 error_ret:
653 kfree(swd);
654 error_kzalloc:
655 return ERR_PTR(ret);
656 }
657
658
659
660
661
662
663
664 static int iio_dummy_remove(struct iio_sw_device *swd)
665 {
666
667
668
669
670
671
672 struct iio_dev *indio_dev = swd->device;
673
674
675 iio_device_unregister(indio_dev);
676
677
678
679
680 iio_simple_dummy_unconfigure_buffer(indio_dev);
681
682 iio_simple_dummy_events_unregister(indio_dev);
683
684
685 kfree(indio_dev->name);
686 iio_device_free(indio_dev);
687
688 return 0;
689 }
690
691
692
693
694
695
696
697
698
699
700 static const struct iio_sw_device_ops iio_dummy_device_ops = {
701 .probe = iio_dummy_probe,
702 .remove = iio_dummy_remove,
703 };
704
705 static struct iio_sw_device_type iio_dummy_device = {
706 .name = "dummy",
707 .owner = THIS_MODULE,
708 .ops = &iio_dummy_device_ops,
709 };
710
711 module_iio_sw_device_driver(iio_dummy_device);
712
713 MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
714 MODULE_DESCRIPTION("IIO dummy driver");
715 MODULE_LICENSE("GPL v2");