Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
iio_simple_dummy.c
Go to the documentation of this file.
1 
17 #include <linux/kernel.h>
18 #include <linux/slab.h>
19 #include <linux/module.h>
20 #include <linux/moduleparam.h>
21 
22 #include <linux/iio/iio.h>
23 #include <linux/iio/sysfs.h>
24 #include <linux/iio/events.h>
25 #include <linux/iio/buffer.h>
26 #include "iio_simple_dummy.h"
27 
28 /*
29  * A few elements needed to fake a bus for this driver
30  * Note instances parameter controls how many of these
31  * dummy devices are registered.
32  */
33 static unsigned instances = 1;
34 module_param(instances, int, 0);
35 
36 /* Pointer array used to fake bus elements */
37 static struct iio_dev **iio_dummy_devs;
38 
39 /* Fake a name for the part number, usually obtained from the id table */
40 static const char *iio_dummy_part_number = "iio_dummy_part_no";
41 
49  int val;
50  int val2;
51  int regval; /* what would be written to hardware */
52 };
53 
54 static const struct iio_dummy_accel_calibscale dummy_scales[] = {
55  { 0, 100, 0x8 }, /* 0.000100 */
56  { 0, 133, 0x7 }, /* 0.000133 */
57  { 733, 13, 0x9 }, /* 733.00013 */
58 };
59 
60 /*
61  * iio_dummy_channels - Description of available channels
62  *
63  * This array of structures tells the IIO core about what the device
64  * actually provides for a given channel.
65  */
66 static const struct iio_chan_spec iio_dummy_channels[] = {
67  /* indexed ADC channel in_voltage0_raw etc */
68  {
69  .type = IIO_VOLTAGE,
70  /* Channel has a numeric index of 0 */
71  .indexed = 1,
72  .channel = 0,
73  /* What other information is available? */
74  .info_mask =
75  /*
76  * in_voltage0_raw
77  * Raw (unscaled no bias removal etc) measurement
78  * from the device.
79  */
81  /*
82  * in_voltage0_offset
83  * Offset for userspace to apply prior to scale
84  * when converting to standard units (microvolts)
85  */
87  /*
88  * in_voltage0_scale
89  * Multipler for userspace to apply post offset
90  * when converting to standard units (microvolts)
91  */
93  /* The ordering of elements in the buffer via an enum */
94  .scan_index = voltage0,
95  .scan_type = { /* Description of storage in buffer */
96  .sign = 'u', /* unsigned */
97  .realbits = 13, /* 13 bits */
98  .storagebits = 16, /* 16 bits used for storage */
99  .shift = 0, /* zero shift */
100  },
101 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
102  /*
103  * simple event - triggered when value rises above
104  * a threshold
105  */
106  .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH,
108 #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
109  },
110  /* Differential ADC channel in_voltage1-voltage2_raw etc*/
111  {
112  .type = IIO_VOLTAGE,
113  .differential = 1,
114  /*
115  * Indexing for differential channels uses channel
116  * for the positive part, channel2 for the negative.
117  */
118  .indexed = 1,
119  .channel = 1,
120  .channel2 = 2,
121  .info_mask =
122  /*
123  * in_voltage1-voltage2_raw
124  * Raw (unscaled no bias removal etc) measurement
125  * from the device.
126  */
128  /*
129  * in_voltage-voltage_scale
130  * Shared version of scale - shared by differential
131  * input channels of type IIO_VOLTAGE.
132  */
134  .scan_index = diffvoltage1m2,
135  .scan_type = { /* Description of storage in buffer */
136  .sign = 's', /* signed */
137  .realbits = 12, /* 12 bits */
138  .storagebits = 16, /* 16 bits used for storage */
139  .shift = 0, /* zero shift */
140  },
141  },
142  /* Differential ADC channel in_voltage3-voltage4_raw etc*/
143  {
144  .type = IIO_VOLTAGE,
145  .differential = 1,
146  .indexed = 1,
147  .channel = 3,
148  .channel2 = 4,
149  .info_mask =
152  .scan_index = diffvoltage3m4,
153  .scan_type = {
154  .sign = 's',
155  .realbits = 11,
156  .storagebits = 16,
157  .shift = 0,
158  },
159  },
160  /*
161  * 'modified' (i.e. axis specified) acceleration channel
162  * in_accel_z_raw
163  */
164  {
165  .type = IIO_ACCEL,
166  .modified = 1,
167  /* Channel 2 is use for modifiers */
168  .channel2 = IIO_MOD_X,
169  .info_mask =
171  /*
172  * Internal bias correction value. Applied
173  * by the hardware or driver prior to userspace
174  * seeing the readings. Typically part of hardware
175  * calibration.
176  */
178  .scan_index = accelx,
179  .scan_type = { /* Description of storage in buffer */
180  .sign = 's', /* signed */
181  .realbits = 16, /* 16 bits */
182  .storagebits = 16, /* 16 bits used for storage */
183  .shift = 0, /* zero shift */
184  },
185  },
186  /*
187  * Convenience macro for timestamps. 4 is the index in
188  * the buffer.
189  */
191  /* DAC channel out_voltage0_raw */
192  {
193  .type = IIO_VOLTAGE,
194  .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
195  .output = 1,
196  .indexed = 1,
197  .channel = 0,
198  },
199 };
200 
210 static int iio_dummy_read_raw(struct iio_dev *indio_dev,
211  struct iio_chan_spec const *chan,
212  int *val,
213  int *val2,
214  long mask)
215 {
216  struct iio_dummy_state *st = iio_priv(indio_dev);
217  int ret = -EINVAL;
218 
219  mutex_lock(&st->lock);
220  switch (mask) {
221  case IIO_CHAN_INFO_RAW: /* magic value - channel value read */
222  switch (chan->type) {
223  case IIO_VOLTAGE:
224  if (chan->output) {
225  /* Set integer part to cached value */
226  *val = st->dac_val;
227  ret = IIO_VAL_INT;
228  } else if (chan->differential) {
229  if (chan->channel == 1)
230  *val = st->differential_adc_val[0];
231  else
232  *val = st->differential_adc_val[1];
233  ret = IIO_VAL_INT;
234  } else {
235  *val = st->single_ended_adc_val;
236  ret = IIO_VAL_INT;
237  }
238  break;
239  case IIO_ACCEL:
240  *val = st->accel_val;
241  ret = IIO_VAL_INT;
242  break;
243  default:
244  break;
245  }
246  break;
248  /* only single ended adc -> 7 */
249  *val = 7;
250  ret = IIO_VAL_INT;
251  break;
252  case IIO_CHAN_INFO_SCALE:
253  switch (chan->differential) {
254  case 0:
255  /* only single ended adc -> 0.001333 */
256  *val = 0;
257  *val2 = 1333;
259  break;
260  case 1:
261  /* all differential adc channels -> 0.000001344 */
262  *val = 0;
263  *val2 = 1344;
264  ret = IIO_VAL_INT_PLUS_NANO;
265  }
266  break;
268  /* only the acceleration axis - read from cache */
269  *val = st->accel_calibbias;
270  ret = IIO_VAL_INT;
271  break;
273  *val = st->accel_calibscale->val;
274  *val2 = st->accel_calibscale->val2;
276  break;
277  default:
278  break;
279  }
280  mutex_unlock(&st->lock);
281  return ret;
282 }
283 
297 static int iio_dummy_write_raw(struct iio_dev *indio_dev,
298  struct iio_chan_spec const *chan,
299  int val,
300  int val2,
301  long mask)
302 {
303  int i;
304  int ret = 0;
305  struct iio_dummy_state *st = iio_priv(indio_dev);
306 
307  switch (mask) {
308  case IIO_CHAN_INFO_RAW:
309  if (chan->output == 0)
310  return -EINVAL;
311 
312  /* Locking not required as writing single value */
313  mutex_lock(&st->lock);
314  st->dac_val = val;
315  mutex_unlock(&st->lock);
316  return 0;
318  mutex_lock(&st->lock);
319  /* Compare against table - hard matching here */
320  for (i = 0; i < ARRAY_SIZE(dummy_scales); i++)
321  if (val == dummy_scales[i].val &&
322  val2 == dummy_scales[i].val2)
323  break;
324  if (i == ARRAY_SIZE(dummy_scales))
325  ret = -EINVAL;
326  else
327  st->accel_calibscale = &dummy_scales[i];
328  mutex_unlock(&st->lock);
329  return ret;
330  default:
331  return -EINVAL;
332  }
333 }
334 
335 /*
336  * Device type specific information.
337  */
338 static const struct iio_info iio_dummy_info = {
339  .driver_module = THIS_MODULE,
340  .read_raw = &iio_dummy_read_raw,
341  .write_raw = &iio_dummy_write_raw,
342 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
343  .read_event_config = &iio_simple_dummy_read_event_config,
344  .write_event_config = &iio_simple_dummy_write_event_config,
345  .read_event_value = &iio_simple_dummy_read_event_value,
346  .write_event_value = &iio_simple_dummy_write_event_value,
347 #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
348 };
349 
357 static int iio_dummy_init_device(struct iio_dev *indio_dev)
358 {
359  struct iio_dummy_state *st = iio_priv(indio_dev);
360 
361  st->dac_val = 0;
362  st->single_ended_adc_val = 73;
363  st->differential_adc_val[0] = 33;
364  st->differential_adc_val[1] = -34;
365  st->accel_val = 34;
366  st->accel_calibbias = -7;
367  st->accel_calibscale = &dummy_scales[0];
368 
369  return 0;
370 }
371 
381 static int __devinit iio_dummy_probe(int index)
382 {
383  int ret;
384  struct iio_dev *indio_dev;
385  struct iio_dummy_state *st;
386 
387  /*
388  * Allocate an IIO device.
389  *
390  * This structure contains all generic state
391  * information about the device instance.
392  * It also has a region (accessed by iio_priv()
393  * for chip specific state information.
394  */
395  indio_dev = iio_device_alloc(sizeof(*st));
396  if (indio_dev == NULL) {
397  ret = -ENOMEM;
398  goto error_ret;
399  }
400 
401  st = iio_priv(indio_dev);
402  mutex_init(&st->lock);
403 
404  iio_dummy_init_device(indio_dev);
405  /*
406  * With hardware: Set the parent device.
407  * indio_dev->dev.parent = &spi->dev;
408  * indio_dev->dev.parent = &client->dev;
409  */
410 
411  /*
412  * Make the iio_dev struct available to remove function.
413  * Bus equivalents
414  * i2c_set_clientdata(client, indio_dev);
415  * spi_set_drvdata(spi, indio_dev);
416  */
417  iio_dummy_devs[index] = indio_dev;
418 
419 
420  /*
421  * Set the device name.
422  *
423  * This is typically a part number and obtained from the module
424  * id table.
425  * e.g. for i2c and spi:
426  * indio_dev->name = id->name;
427  * indio_dev->name = spi_get_device_id(spi)->name;
428  */
429  indio_dev->name = iio_dummy_part_number;
430 
431  /* Provide description of available channels */
432  indio_dev->channels = iio_dummy_channels;
433  indio_dev->num_channels = ARRAY_SIZE(iio_dummy_channels);
434 
435  /*
436  * Provide device type specific interface functions and
437  * constant data.
438  */
439  indio_dev->info = &iio_dummy_info;
440 
441  /* Specify that device provides sysfs type interfaces */
442  indio_dev->modes = INDIO_DIRECT_MODE;
443 
444  ret = iio_simple_dummy_events_register(indio_dev);
445  if (ret < 0)
446  goto error_free_device;
447 
448  /*
449  * Configure buffered capture support and register the channels with the
450  * buffer, but avoid the output channel being registered by reducing the
451  * number of channels by 1.
452  */
453  ret = iio_simple_dummy_configure_buffer(indio_dev, iio_dummy_channels, 5);
454  if (ret < 0)
455  goto error_unregister_events;
456 
457  ret = iio_device_register(indio_dev);
458  if (ret < 0)
459  goto error_unconfigure_buffer;
460 
461  return 0;
462 error_unconfigure_buffer:
464 error_unregister_events:
466 error_free_device:
467  iio_device_free(indio_dev);
468 error_ret:
469  return ret;
470 }
471 
478 static int iio_dummy_remove(int index)
479 {
480  int ret;
481  /*
482  * Get a pointer to the device instance iio_dev structure
483  * from the bus subsystem. E.g.
484  * struct iio_dev *indio_dev = i2c_get_clientdata(client);
485  * struct iio_dev *indio_dev = spi_get_drvdata(spi);
486  */
487  struct iio_dev *indio_dev = iio_dummy_devs[index];
488 
489 
490  /* Unregister the device */
491  iio_device_unregister(indio_dev);
492 
493  /* Device specific code to power down etc */
494 
495  /* Buffered capture related cleanup */
497 
498  ret = iio_simple_dummy_events_unregister(indio_dev);
499  if (ret)
500  goto error_ret;
501 
502  /* Free all structures */
503  iio_device_free(indio_dev);
504 
505 error_ret:
506  return ret;
507 }
508 
519 static __init int iio_dummy_init(void)
520 {
521  int i, ret;
522  if (instances > 10) {
523  instances = 1;
524  return -EINVAL;
525  }
526 
527  /* Fake a bus */
528  iio_dummy_devs = kcalloc(instances, sizeof(*iio_dummy_devs),
529  GFP_KERNEL);
530  /* Here we have no actual device so call probe */
531  for (i = 0; i < instances; i++) {
532  ret = iio_dummy_probe(i);
533  if (ret < 0)
534  return ret;
535  }
536  return 0;
537 }
538 module_init(iio_dummy_init);
539 
546 static __exit void iio_dummy_exit(void)
547 {
548  int i;
549  for (i = 0; i < instances; i++)
550  iio_dummy_remove(i);
551  kfree(iio_dummy_devs);
552 }
553 module_exit(iio_dummy_exit);
554 
555 MODULE_AUTHOR("Jonathan Cameron <[email protected]>");
556 MODULE_DESCRIPTION("IIO dummy driver");
557 MODULE_LICENSE("GPL v2");