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
26static const struct config_item_type iio_dummy_type = {
27 .ct_owner = THIS_MODULE,
28};
29
30
31
32
33
34
35
36struct iio_dummy_accel_calibscale {
37 int val;
38 int val2;
39 int regval;
40};
41
42static 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
54static 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
63static 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
73static 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
83static 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
96static 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
279static 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
422static 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
518static 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
536static 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
563static 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 struct device *parent = NULL;
570
571
572
573
574
575
576
577 swd = kzalloc(sizeof(*swd), GFP_KERNEL);
578 if (!swd) {
579 ret = -ENOMEM;
580 goto error_kzalloc;
581 }
582
583
584
585
586
587
588
589
590 indio_dev = iio_device_alloc(parent, sizeof(*st));
591 if (!indio_dev) {
592 ret = -ENOMEM;
593 goto error_ret;
594 }
595
596 st = iio_priv(indio_dev);
597 mutex_init(&st->lock);
598
599 iio_dummy_init_device(indio_dev);
600
601
602
603
604
605
606
607 swd->device = indio_dev;
608
609
610
611
612
613
614
615
616
617
618 indio_dev->name = kstrdup(name, GFP_KERNEL);
619
620
621 indio_dev->channels = iio_dummy_channels;
622 indio_dev->num_channels = ARRAY_SIZE(iio_dummy_channels);
623
624
625
626
627
628 indio_dev->info = &iio_dummy_info;
629
630
631 indio_dev->modes = INDIO_DIRECT_MODE;
632
633 ret = iio_simple_dummy_events_register(indio_dev);
634 if (ret < 0)
635 goto error_free_device;
636
637 ret = iio_simple_dummy_configure_buffer(indio_dev);
638 if (ret < 0)
639 goto error_unregister_events;
640
641 ret = iio_device_register(indio_dev);
642 if (ret < 0)
643 goto error_unconfigure_buffer;
644
645 iio_swd_group_init_type_name(swd, name, &iio_dummy_type);
646
647 return swd;
648error_unconfigure_buffer:
649 iio_simple_dummy_unconfigure_buffer(indio_dev);
650error_unregister_events:
651 iio_simple_dummy_events_unregister(indio_dev);
652error_free_device:
653 iio_device_free(indio_dev);
654error_ret:
655 kfree(swd);
656error_kzalloc:
657 return ERR_PTR(ret);
658}
659
660
661
662
663
664
665
666static int iio_dummy_remove(struct iio_sw_device *swd)
667{
668
669
670
671
672
673
674 struct iio_dev *indio_dev = swd->device;
675
676
677 iio_device_unregister(indio_dev);
678
679
680
681
682 iio_simple_dummy_unconfigure_buffer(indio_dev);
683
684 iio_simple_dummy_events_unregister(indio_dev);
685
686
687 kfree(indio_dev->name);
688 iio_device_free(indio_dev);
689
690 return 0;
691}
692
693
694
695
696
697
698
699
700
701
702
703static const struct iio_sw_device_ops iio_dummy_device_ops = {
704 .probe = iio_dummy_probe,
705 .remove = iio_dummy_remove,
706};
707
708static struct iio_sw_device_type iio_dummy_device = {
709 .name = "dummy",
710 .owner = THIS_MODULE,
711 .ops = &iio_dummy_device_ops,
712};
713
714module_iio_sw_device_driver(iio_dummy_device);
715
716MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
717MODULE_DESCRIPTION("IIO dummy driver");
718MODULE_LICENSE("GPL v2");
719