0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/kernel.h>
0015 #include <linux/slab.h>
0016 #include <linux/module.h>
0017 #include <linux/string.h>
0018
0019 #include <linux/iio/iio.h>
0020 #include <linux/iio/sysfs.h>
0021 #include <linux/iio/events.h>
0022 #include <linux/iio/buffer.h>
0023 #include <linux/iio/sw_device.h>
0024 #include "iio_simple_dummy.h"
0025
0026 static const struct config_item_type iio_dummy_type = {
0027 .ct_owner = THIS_MODULE,
0028 };
0029
0030
0031
0032
0033
0034
0035
0036 struct iio_dummy_accel_calibscale {
0037 int val;
0038 int val2;
0039 int regval;
0040 };
0041
0042 static const struct iio_dummy_accel_calibscale dummy_scales[] = {
0043 { 0, 100, 0x8 },
0044 { 0, 133, 0x7 },
0045 { 733, 13, 0x9 },
0046 };
0047
0048 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
0049
0050
0051
0052
0053
0054 static const struct iio_event_spec iio_dummy_event = {
0055 .type = IIO_EV_TYPE_THRESH,
0056 .dir = IIO_EV_DIR_RISING,
0057 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
0058 };
0059
0060
0061
0062
0063 static const struct iio_event_spec step_detect_event = {
0064 .type = IIO_EV_TYPE_CHANGE,
0065 .dir = IIO_EV_DIR_NONE,
0066 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
0067 };
0068
0069
0070
0071
0072
0073 static const struct iio_event_spec iio_running_event = {
0074 .type = IIO_EV_TYPE_THRESH,
0075 .dir = IIO_EV_DIR_RISING,
0076 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
0077 };
0078
0079
0080
0081
0082
0083 static const struct iio_event_spec iio_walking_event = {
0084 .type = IIO_EV_TYPE_THRESH,
0085 .dir = IIO_EV_DIR_FALLING,
0086 .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
0087 };
0088 #endif
0089
0090
0091
0092
0093
0094
0095
0096 static const struct iio_chan_spec iio_dummy_channels[] = {
0097
0098 {
0099 .type = IIO_VOLTAGE,
0100
0101 .indexed = 1,
0102 .channel = 0,
0103
0104 .info_mask_separate =
0105
0106
0107
0108
0109
0110 BIT(IIO_CHAN_INFO_RAW) |
0111
0112
0113
0114
0115
0116 BIT(IIO_CHAN_INFO_OFFSET) |
0117
0118
0119
0120
0121
0122 BIT(IIO_CHAN_INFO_SCALE),
0123
0124
0125
0126
0127 .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0128
0129 .scan_index = DUMMY_INDEX_VOLTAGE_0,
0130 .scan_type = {
0131 .sign = 'u',
0132 .realbits = 13,
0133 .storagebits = 16,
0134 .shift = 0,
0135 },
0136 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
0137 .event_spec = &iio_dummy_event,
0138 .num_event_specs = 1,
0139 #endif
0140 },
0141
0142 {
0143 .type = IIO_VOLTAGE,
0144 .differential = 1,
0145
0146
0147
0148
0149 .indexed = 1,
0150 .channel = 1,
0151 .channel2 = 2,
0152
0153
0154
0155
0156
0157 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0158
0159
0160
0161
0162
0163 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
0164
0165
0166
0167
0168 .scan_index = DUMMY_INDEX_DIFFVOLTAGE_1M2,
0169 .scan_type = {
0170 .sign = 's',
0171 .realbits = 12,
0172 .storagebits = 16,
0173 .shift = 0,
0174 },
0175 },
0176
0177 {
0178 .type = IIO_VOLTAGE,
0179 .differential = 1,
0180 .indexed = 1,
0181 .channel = 3,
0182 .channel2 = 4,
0183 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0184 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
0185 .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0186 .scan_index = DUMMY_INDEX_DIFFVOLTAGE_3M4,
0187 .scan_type = {
0188 .sign = 's',
0189 .realbits = 11,
0190 .storagebits = 16,
0191 .shift = 0,
0192 },
0193 },
0194
0195
0196
0197
0198 {
0199 .type = IIO_ACCEL,
0200 .modified = 1,
0201
0202 .channel2 = IIO_MOD_X,
0203 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0204
0205
0206
0207
0208
0209
0210 BIT(IIO_CHAN_INFO_CALIBSCALE) |
0211 BIT(IIO_CHAN_INFO_CALIBBIAS),
0212 .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0213 .scan_index = DUMMY_INDEX_ACCELX,
0214 .scan_type = {
0215 .sign = 's',
0216 .realbits = 16,
0217 .storagebits = 16,
0218 .shift = 0,
0219 },
0220 },
0221
0222
0223
0224
0225 IIO_CHAN_SOFT_TIMESTAMP(4),
0226
0227 {
0228 .type = IIO_VOLTAGE,
0229 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0230 .scan_index = -1,
0231 .output = 1,
0232 .indexed = 1,
0233 .channel = 0,
0234 },
0235 {
0236 .type = IIO_STEPS,
0237 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_ENABLE) |
0238 BIT(IIO_CHAN_INFO_CALIBHEIGHT),
0239 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
0240 .scan_index = -1,
0241 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
0242 .event_spec = &step_detect_event,
0243 .num_event_specs = 1,
0244 #endif
0245 },
0246 {
0247 .type = IIO_ACTIVITY,
0248 .modified = 1,
0249 .channel2 = IIO_MOD_RUNNING,
0250 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
0251 .scan_index = -1,
0252 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
0253 .event_spec = &iio_running_event,
0254 .num_event_specs = 1,
0255 #endif
0256 },
0257 {
0258 .type = IIO_ACTIVITY,
0259 .modified = 1,
0260 .channel2 = IIO_MOD_WALKING,
0261 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
0262 .scan_index = -1,
0263 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
0264 .event_spec = &iio_walking_event,
0265 .num_event_specs = 1,
0266 #endif
0267 },
0268 };
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 static int iio_dummy_read_raw(struct iio_dev *indio_dev,
0280 struct iio_chan_spec const *chan,
0281 int *val,
0282 int *val2,
0283 long mask)
0284 {
0285 struct iio_dummy_state *st = iio_priv(indio_dev);
0286 int ret = -EINVAL;
0287
0288 mutex_lock(&st->lock);
0289 switch (mask) {
0290 case IIO_CHAN_INFO_RAW:
0291 switch (chan->type) {
0292 case IIO_VOLTAGE:
0293 if (chan->output) {
0294
0295 *val = st->dac_val;
0296 ret = IIO_VAL_INT;
0297 } else if (chan->differential) {
0298 if (chan->channel == 1)
0299 *val = st->differential_adc_val[0];
0300 else
0301 *val = st->differential_adc_val[1];
0302 ret = IIO_VAL_INT;
0303 } else {
0304 *val = st->single_ended_adc_val;
0305 ret = IIO_VAL_INT;
0306 }
0307 break;
0308 case IIO_ACCEL:
0309 *val = st->accel_val;
0310 ret = IIO_VAL_INT;
0311 break;
0312 default:
0313 break;
0314 }
0315 break;
0316 case IIO_CHAN_INFO_PROCESSED:
0317 switch (chan->type) {
0318 case IIO_STEPS:
0319 *val = st->steps;
0320 ret = IIO_VAL_INT;
0321 break;
0322 case IIO_ACTIVITY:
0323 switch (chan->channel2) {
0324 case IIO_MOD_RUNNING:
0325 *val = st->activity_running;
0326 ret = IIO_VAL_INT;
0327 break;
0328 case IIO_MOD_WALKING:
0329 *val = st->activity_walking;
0330 ret = IIO_VAL_INT;
0331 break;
0332 default:
0333 break;
0334 }
0335 break;
0336 default:
0337 break;
0338 }
0339 break;
0340 case IIO_CHAN_INFO_OFFSET:
0341
0342 *val = 7;
0343 ret = IIO_VAL_INT;
0344 break;
0345 case IIO_CHAN_INFO_SCALE:
0346 switch (chan->type) {
0347 case IIO_VOLTAGE:
0348 switch (chan->differential) {
0349 case 0:
0350
0351 *val = 0;
0352 *val2 = 1333;
0353 ret = IIO_VAL_INT_PLUS_MICRO;
0354 break;
0355 case 1:
0356
0357 *val = 0;
0358 *val2 = 1344;
0359 ret = IIO_VAL_INT_PLUS_NANO;
0360 }
0361 break;
0362 default:
0363 break;
0364 }
0365 break;
0366 case IIO_CHAN_INFO_CALIBBIAS:
0367
0368 *val = st->accel_calibbias;
0369 ret = IIO_VAL_INT;
0370 break;
0371 case IIO_CHAN_INFO_CALIBSCALE:
0372 *val = st->accel_calibscale->val;
0373 *val2 = st->accel_calibscale->val2;
0374 ret = IIO_VAL_INT_PLUS_MICRO;
0375 break;
0376 case IIO_CHAN_INFO_SAMP_FREQ:
0377 *val = 3;
0378 *val2 = 33;
0379 ret = IIO_VAL_INT_PLUS_NANO;
0380 break;
0381 case IIO_CHAN_INFO_ENABLE:
0382 switch (chan->type) {
0383 case IIO_STEPS:
0384 *val = st->steps_enabled;
0385 ret = IIO_VAL_INT;
0386 break;
0387 default:
0388 break;
0389 }
0390 break;
0391 case IIO_CHAN_INFO_CALIBHEIGHT:
0392 switch (chan->type) {
0393 case IIO_STEPS:
0394 *val = st->height;
0395 ret = IIO_VAL_INT;
0396 break;
0397 default:
0398 break;
0399 }
0400 break;
0401
0402 default:
0403 break;
0404 }
0405 mutex_unlock(&st->lock);
0406 return ret;
0407 }
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422 static int iio_dummy_write_raw(struct iio_dev *indio_dev,
0423 struct iio_chan_spec const *chan,
0424 int val,
0425 int val2,
0426 long mask)
0427 {
0428 int i;
0429 int ret = 0;
0430 struct iio_dummy_state *st = iio_priv(indio_dev);
0431
0432 switch (mask) {
0433 case IIO_CHAN_INFO_RAW:
0434 switch (chan->type) {
0435 case IIO_VOLTAGE:
0436 if (chan->output == 0)
0437 return -EINVAL;
0438
0439
0440 mutex_lock(&st->lock);
0441 st->dac_val = val;
0442 mutex_unlock(&st->lock);
0443 return 0;
0444 default:
0445 return -EINVAL;
0446 }
0447 case IIO_CHAN_INFO_PROCESSED:
0448 switch (chan->type) {
0449 case IIO_STEPS:
0450 mutex_lock(&st->lock);
0451 st->steps = val;
0452 mutex_unlock(&st->lock);
0453 return 0;
0454 case IIO_ACTIVITY:
0455 if (val < 0)
0456 val = 0;
0457 if (val > 100)
0458 val = 100;
0459 switch (chan->channel2) {
0460 case IIO_MOD_RUNNING:
0461 st->activity_running = val;
0462 return 0;
0463 case IIO_MOD_WALKING:
0464 st->activity_walking = val;
0465 return 0;
0466 default:
0467 return -EINVAL;
0468 }
0469 break;
0470 default:
0471 return -EINVAL;
0472 }
0473 case IIO_CHAN_INFO_CALIBSCALE:
0474 mutex_lock(&st->lock);
0475
0476 for (i = 0; i < ARRAY_SIZE(dummy_scales); i++)
0477 if (val == dummy_scales[i].val &&
0478 val2 == dummy_scales[i].val2)
0479 break;
0480 if (i == ARRAY_SIZE(dummy_scales))
0481 ret = -EINVAL;
0482 else
0483 st->accel_calibscale = &dummy_scales[i];
0484 mutex_unlock(&st->lock);
0485 return ret;
0486 case IIO_CHAN_INFO_CALIBBIAS:
0487 mutex_lock(&st->lock);
0488 st->accel_calibbias = val;
0489 mutex_unlock(&st->lock);
0490 return 0;
0491 case IIO_CHAN_INFO_ENABLE:
0492 switch (chan->type) {
0493 case IIO_STEPS:
0494 mutex_lock(&st->lock);
0495 st->steps_enabled = val;
0496 mutex_unlock(&st->lock);
0497 return 0;
0498 default:
0499 return -EINVAL;
0500 }
0501 case IIO_CHAN_INFO_CALIBHEIGHT:
0502 switch (chan->type) {
0503 case IIO_STEPS:
0504 st->height = val;
0505 return 0;
0506 default:
0507 return -EINVAL;
0508 }
0509
0510 default:
0511 return -EINVAL;
0512 }
0513 }
0514
0515
0516
0517
0518 static const struct iio_info iio_dummy_info = {
0519 .read_raw = &iio_dummy_read_raw,
0520 .write_raw = &iio_dummy_write_raw,
0521 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
0522 .read_event_config = &iio_simple_dummy_read_event_config,
0523 .write_event_config = &iio_simple_dummy_write_event_config,
0524 .read_event_value = &iio_simple_dummy_read_event_value,
0525 .write_event_value = &iio_simple_dummy_write_event_value,
0526 #endif
0527 };
0528
0529
0530
0531
0532
0533
0534
0535
0536 static int iio_dummy_init_device(struct iio_dev *indio_dev)
0537 {
0538 struct iio_dummy_state *st = iio_priv(indio_dev);
0539
0540 st->dac_val = 0;
0541 st->single_ended_adc_val = 73;
0542 st->differential_adc_val[0] = 33;
0543 st->differential_adc_val[1] = -34;
0544 st->accel_val = 34;
0545 st->accel_calibbias = -7;
0546 st->accel_calibscale = &dummy_scales[0];
0547 st->steps = 47;
0548 st->activity_running = 98;
0549 st->activity_walking = 4;
0550
0551 return 0;
0552 }
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563 static struct iio_sw_device *iio_dummy_probe(const char *name)
0564 {
0565 int ret;
0566 struct iio_dev *indio_dev;
0567 struct iio_dummy_state *st;
0568 struct iio_sw_device *swd;
0569 struct device *parent = NULL;
0570
0571
0572
0573
0574
0575
0576
0577 swd = kzalloc(sizeof(*swd), GFP_KERNEL);
0578 if (!swd)
0579 return ERR_PTR(-ENOMEM);
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589 indio_dev = iio_device_alloc(parent, sizeof(*st));
0590 if (!indio_dev) {
0591 ret = -ENOMEM;
0592 goto error_free_swd;
0593 }
0594
0595 st = iio_priv(indio_dev);
0596 mutex_init(&st->lock);
0597
0598 iio_dummy_init_device(indio_dev);
0599
0600
0601
0602
0603
0604
0605
0606 swd->device = indio_dev;
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617 indio_dev->name = kstrdup(name, GFP_KERNEL);
0618 if (!indio_dev->name) {
0619 ret = -ENOMEM;
0620 goto error_free_device;
0621 }
0622
0623
0624 indio_dev->channels = iio_dummy_channels;
0625 indio_dev->num_channels = ARRAY_SIZE(iio_dummy_channels);
0626
0627
0628
0629
0630
0631 indio_dev->info = &iio_dummy_info;
0632
0633
0634 indio_dev->modes = INDIO_DIRECT_MODE;
0635
0636 ret = iio_simple_dummy_events_register(indio_dev);
0637 if (ret < 0)
0638 goto error_free_name;
0639
0640 ret = iio_simple_dummy_configure_buffer(indio_dev);
0641 if (ret < 0)
0642 goto error_unregister_events;
0643
0644 ret = iio_device_register(indio_dev);
0645 if (ret < 0)
0646 goto error_unconfigure_buffer;
0647
0648 iio_swd_group_init_type_name(swd, name, &iio_dummy_type);
0649
0650 return swd;
0651 error_unconfigure_buffer:
0652 iio_simple_dummy_unconfigure_buffer(indio_dev);
0653 error_unregister_events:
0654 iio_simple_dummy_events_unregister(indio_dev);
0655 error_free_name:
0656 kfree(indio_dev->name);
0657 error_free_device:
0658 iio_device_free(indio_dev);
0659 error_free_swd:
0660 kfree(swd);
0661 return ERR_PTR(ret);
0662 }
0663
0664
0665
0666
0667
0668
0669
0670 static int iio_dummy_remove(struct iio_sw_device *swd)
0671 {
0672
0673
0674
0675
0676
0677
0678 struct iio_dev *indio_dev = swd->device;
0679
0680
0681 iio_device_unregister(indio_dev);
0682
0683
0684
0685
0686 iio_simple_dummy_unconfigure_buffer(indio_dev);
0687
0688 iio_simple_dummy_events_unregister(indio_dev);
0689
0690
0691 kfree(indio_dev->name);
0692 iio_device_free(indio_dev);
0693
0694 return 0;
0695 }
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707 static const struct iio_sw_device_ops iio_dummy_device_ops = {
0708 .probe = iio_dummy_probe,
0709 .remove = iio_dummy_remove,
0710 };
0711
0712 static struct iio_sw_device_type iio_dummy_device = {
0713 .name = "dummy",
0714 .owner = THIS_MODULE,
0715 .ops = &iio_dummy_device_ops,
0716 };
0717
0718 module_iio_sw_device_driver(iio_dummy_device);
0719
0720 MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
0721 MODULE_DESCRIPTION("IIO dummy driver");
0722 MODULE_LICENSE("GPL v2");