staging:iio: Update iio_event_interface documentation
[deliverable/linux.git] / drivers / staging / iio / industrialio-core.c
CommitLineData
847ec80b
JC
1/* The industrial I/O core
2 *
3 * Copyright (c) 2008 Jonathan Cameron
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * Based on elements of hwmon and input subsystems.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/idr.h>
15#include <linux/kdev_t.h>
16#include <linux/err.h>
17#include <linux/device.h>
18#include <linux/fs.h>
847ec80b 19#include <linux/poll.h>
ffc18afa 20#include <linux/sched.h>
4439c935 21#include <linux/wait.h>
847ec80b 22#include <linux/cdev.h>
5a0e3ad6 23#include <linux/slab.h>
8e7d9672 24#include <linux/anon_inodes.h>
847ec80b 25#include "iio.h"
df9c1c42 26#include "iio_core.h"
6aea1c36 27#include "iio_core_trigger.h"
9dd1cb30 28#include "sysfs.h"
af5046af 29#include "events.h"
9dd1cb30 30
47c24fdd 31/* IDA to assign each registered device a unique id*/
b156cf70 32static DEFINE_IDA(iio_ida);
847ec80b 33
f625cb97 34static dev_t iio_devt;
847ec80b
JC
35
36#define IIO_DEV_MAX 256
5aaaeba8 37struct bus_type iio_bus_type = {
847ec80b 38 .name = "iio",
847ec80b 39};
5aaaeba8 40EXPORT_SYMBOL(iio_bus_type);
847ec80b 41
1e8dfcc6
JC
42static const char * const iio_data_type_name[] = {
43 [IIO_RAW] = "raw",
44 [IIO_PROCESSED] = "input",
45};
46
c6fc8062
JC
47static const char * const iio_direction[] = {
48 [0] = "in",
49 [1] = "out",
50};
51
ade7ef7b 52static const char * const iio_chan_type_name_spec[] = {
c6fc8062 53 [IIO_VOLTAGE] = "voltage",
faf290e8
MH
54 [IIO_CURRENT] = "current",
55 [IIO_POWER] = "power",
9bff02f8 56 [IIO_ACCEL] = "accel",
41ea040c 57 [IIO_ANGL_VEL] = "anglvel",
1d892719 58 [IIO_MAGN] = "magn",
9bff02f8
BF
59 [IIO_LIGHT] = "illuminance",
60 [IIO_INTENSITY] = "intensity",
f09f2c81 61 [IIO_PROXIMITY] = "proximity",
9bff02f8 62 [IIO_TEMP] = "temp",
1d892719
JC
63 [IIO_INCLI] = "incli",
64 [IIO_ROT] = "rot",
1d892719 65 [IIO_ANGL] = "angl",
9bff02f8 66 [IIO_TIMESTAMP] = "timestamp",
66dbe704 67 [IIO_CAPACITANCE] = "capacitance",
1d892719
JC
68};
69
330c6c57 70static const char * const iio_modifier_names[] = {
1d892719
JC
71 [IIO_MOD_X] = "x",
72 [IIO_MOD_Y] = "y",
73 [IIO_MOD_Z] = "z",
330c6c57
JC
74 [IIO_MOD_LIGHT_BOTH] = "both",
75 [IIO_MOD_LIGHT_IR] = "ir",
1d892719
JC
76};
77
78/* relies on pairs of these shared then separate */
79static const char * const iio_chan_info_postfix[] = {
c8a9f805
JC
80 [IIO_CHAN_INFO_SCALE] = "scale",
81 [IIO_CHAN_INFO_OFFSET] = "offset",
82 [IIO_CHAN_INFO_CALIBSCALE] = "calibscale",
83 [IIO_CHAN_INFO_CALIBBIAS] = "calibbias",
84 [IIO_CHAN_INFO_PEAK] = "peak_raw",
85 [IIO_CHAN_INFO_PEAK_SCALE] = "peak_scale",
86 [IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW] = "quadrature_correction_raw",
87 [IIO_CHAN_INFO_AVERAGE_RAW] = "mean_raw",
df94aba8
JC
88 [IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY]
89 = "filter_low_pass_3db_frequency",
1d892719
JC
90};
91
5fb21c82
JC
92const struct iio_chan_spec
93*iio_find_channel_from_si(struct iio_dev *indio_dev, int si)
94{
95 int i;
96
97 for (i = 0; i < indio_dev->num_channels; i++)
98 if (indio_dev->channels[i].scan_index == si)
99 return &indio_dev->channels[i];
100 return NULL;
101}
102
7ae8cf62
JC
103/**
104 * struct iio_detected_event_list - list element for events that have occurred
105 * @list: linked list header
106 * @ev: the event itself
107 */
108struct iio_detected_event_list {
109 struct list_head list;
110 struct iio_event_data ev;
111};
112
113/**
114 * struct iio_event_interface - chrdev interface for an event line
7ae8cf62
JC
115 * @wait: wait queue to allow blocking reads of events
116 * @event_list_lock: mutex to protect the list of detected events
117 * @det_events: list of detected events
118 * @max_events: maximum number of events before new ones are dropped
119 * @current_events: number of events in detected list
16a39b7a 120 * @dev_attr_list: list of event interface sysfs attribute
6356463c 121 * @flags: file operations related flags including busy flag.
16a39b7a 122 * @group: event interface sysfs attribute group
7ae8cf62
JC
123 */
124struct iio_event_interface {
7ae8cf62
JC
125 wait_queue_head_t wait;
126 struct mutex event_list_lock;
127 struct list_head det_events;
128 int max_events;
129 int current_events;
130 struct list_head dev_attr_list;
6356463c 131 unsigned long flags;
26d25ae3 132 struct attribute_group group;
7ae8cf62
JC
133};
134
f8c6f4e9 135int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
847ec80b 136{
f8c6f4e9 137 struct iio_event_interface *ev_int = indio_dev->event_interface;
847ec80b
JC
138 struct iio_detected_event_list *ev;
139 int ret = 0;
140
141 /* Does anyone care? */
142 mutex_lock(&ev_int->event_list_lock);
6356463c 143 if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
75c80753
JC
144 if (ev_int->current_events == ev_int->max_events) {
145 mutex_unlock(&ev_int->event_list_lock);
847ec80b 146 return 0;
75c80753 147 }
847ec80b
JC
148 ev = kmalloc(sizeof(*ev), GFP_KERNEL);
149 if (ev == NULL) {
150 ret = -ENOMEM;
75c80753 151 mutex_unlock(&ev_int->event_list_lock);
847ec80b
JC
152 goto error_ret;
153 }
154 ev->ev.id = ev_code;
155 ev->ev.timestamp = timestamp;
847ec80b 156
3b8ebfb4 157 list_add_tail(&ev->list, &ev_int->det_events);
847ec80b
JC
158 ev_int->current_events++;
159 mutex_unlock(&ev_int->event_list_lock);
160 wake_up_interruptible(&ev_int->wait);
161 } else
162 mutex_unlock(&ev_int->event_list_lock);
163
164error_ret:
165 return ret;
166}
847ec80b
JC
167EXPORT_SYMBOL(iio_push_event);
168
847ec80b
JC
169/* This turns up an awful lot */
170ssize_t iio_read_const_attr(struct device *dev,
171 struct device_attribute *attr,
172 char *buf)
173{
174 return sprintf(buf, "%s\n", to_iio_const_attr(attr)->string);
175}
176EXPORT_SYMBOL(iio_read_const_attr);
177
77712e5f
MB
178static ssize_t iio_event_chrdev_read(struct file *filep,
179 char __user *buf,
180 size_t count,
181 loff_t *f_ps)
847ec80b
JC
182{
183 struct iio_event_interface *ev_int = filep->private_data;
184 struct iio_detected_event_list *el;
dc8f5264 185 size_t len = sizeof(el->ev);
847ec80b 186 int ret;
dc8f5264
LPC
187
188 if (count < len)
189 return -EINVAL;
6356463c 190
847ec80b 191 mutex_lock(&ev_int->event_list_lock);
3b8ebfb4 192 if (list_empty(&ev_int->det_events)) {
847ec80b
JC
193 if (filep->f_flags & O_NONBLOCK) {
194 ret = -EAGAIN;
195 goto error_mutex_unlock;
196 }
197 mutex_unlock(&ev_int->event_list_lock);
198 /* Blocking on device; waiting for something to be there */
199 ret = wait_event_interruptible(ev_int->wait,
200 !list_empty(&ev_int
3b8ebfb4 201 ->det_events));
847ec80b
JC
202 if (ret)
203 goto error_ret;
25985edc 204 /* Single access device so no one else can get the data */
847ec80b
JC
205 mutex_lock(&ev_int->event_list_lock);
206 }
207
3b8ebfb4 208 el = list_first_entry(&ev_int->det_events,
847ec80b
JC
209 struct iio_detected_event_list,
210 list);
847ec80b
JC
211 if (copy_to_user(buf, &(el->ev), len)) {
212 ret = -EFAULT;
213 goto error_mutex_unlock;
214 }
215 list_del(&el->list);
216 ev_int->current_events--;
217 mutex_unlock(&ev_int->event_list_lock);
847ec80b
JC
218 kfree(el);
219
220 return len;
221
222error_mutex_unlock:
223 mutex_unlock(&ev_int->event_list_lock);
224error_ret:
225
226 return ret;
227}
228
77712e5f 229static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
847ec80b 230{
8e7d9672 231 struct iio_event_interface *ev_int = filep->private_data;
847ec80b 232 struct iio_detected_event_list *el, *t;
6356463c 233
847ec80b 234 mutex_lock(&ev_int->event_list_lock);
6356463c 235 clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
847ec80b
JC
236 /*
237 * In order to maintain a clean state for reopening,
238 * clear out any awaiting events. The mask will prevent
239 * any new __iio_push_event calls running.
240 */
3b8ebfb4 241 list_for_each_entry_safe(el, t, &ev_int->det_events, list) {
847ec80b
JC
242 list_del(&el->list);
243 kfree(el);
244 }
8e7d9672 245 ev_int->current_events = 0;
847ec80b
JC
246 mutex_unlock(&ev_int->event_list_lock);
247
248 return 0;
249}
250
251static const struct file_operations iio_event_chrdev_fileops = {
252 .read = iio_event_chrdev_read,
253 .release = iio_event_chrdev_release,
847ec80b 254 .owner = THIS_MODULE,
6038f373 255 .llseek = noop_llseek,
847ec80b
JC
256};
257
1aa04278 258static int iio_event_getfd(struct iio_dev *indio_dev)
8e7d9672 259{
aaa0b4f0 260 struct iio_event_interface *ev_int = indio_dev->event_interface;
b4641336
AV
261 int fd;
262
aaa0b4f0 263 if (ev_int == NULL)
8e7d9672
JC
264 return -ENODEV;
265
aaa0b4f0
AW
266 mutex_lock(&ev_int->event_list_lock);
267 if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
268 mutex_unlock(&ev_int->event_list_lock);
8e7d9672
JC
269 return -EBUSY;
270 }
aaa0b4f0 271 mutex_unlock(&ev_int->event_list_lock);
b4641336 272 fd = anon_inode_getfd("iio:event",
aaa0b4f0 273 &iio_event_chrdev_fileops, ev_int, O_RDONLY);
b4641336 274 if (fd < 0) {
aaa0b4f0 275 mutex_lock(&ev_int->event_list_lock);
b4641336 276 clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
aaa0b4f0 277 mutex_unlock(&ev_int->event_list_lock);
b4641336
AV
278 }
279 return fd;
8e7d9672
JC
280}
281
847ec80b
JC
282static int __init iio_init(void)
283{
284 int ret;
285
5aaaeba8
JC
286 /* Register sysfs bus */
287 ret = bus_register(&iio_bus_type);
847ec80b
JC
288 if (ret < 0) {
289 printk(KERN_ERR
5aaaeba8 290 "%s could not register bus type\n",
847ec80b
JC
291 __FILE__);
292 goto error_nothing;
293 }
294
9aa1a167
JC
295 ret = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio");
296 if (ret < 0) {
297 printk(KERN_ERR "%s: failed to allocate char dev region\n",
298 __FILE__);
5aaaeba8 299 goto error_unregister_bus_type;
9aa1a167 300 }
847ec80b
JC
301
302 return 0;
303
5aaaeba8
JC
304error_unregister_bus_type:
305 bus_unregister(&iio_bus_type);
847ec80b
JC
306error_nothing:
307 return ret;
308}
309
310static void __exit iio_exit(void)
311{
9aa1a167
JC
312 if (iio_devt)
313 unregister_chrdev_region(iio_devt, IIO_DEV_MAX);
5aaaeba8 314 bus_unregister(&iio_bus_type);
847ec80b
JC
315}
316
1d892719
JC
317static ssize_t iio_read_channel_info(struct device *dev,
318 struct device_attribute *attr,
319 char *buf)
847ec80b 320{
1d892719
JC
321 struct iio_dev *indio_dev = dev_get_drvdata(dev);
322 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
323 int val, val2;
6fe8135f
JC
324 int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
325 &val, &val2, this_attr->address);
1d892719
JC
326
327 if (ret < 0)
328 return ret;
847ec80b 329
1d892719
JC
330 if (ret == IIO_VAL_INT)
331 return sprintf(buf, "%d\n", val);
332 else if (ret == IIO_VAL_INT_PLUS_MICRO) {
333 if (val2 < 0)
334 return sprintf(buf, "-%d.%06u\n", val, -val2);
335 else
336 return sprintf(buf, "%d.%06u\n", val, val2);
71646e2c
MH
337 } else if (ret == IIO_VAL_INT_PLUS_NANO) {
338 if (val2 < 0)
339 return sprintf(buf, "-%d.%09u\n", val, -val2);
340 else
341 return sprintf(buf, "%d.%09u\n", val, val2);
1d892719
JC
342 } else
343 return 0;
344}
345
346static ssize_t iio_write_channel_info(struct device *dev,
347 struct device_attribute *attr,
348 const char *buf,
349 size_t len)
350{
351 struct iio_dev *indio_dev = dev_get_drvdata(dev);
352 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
5c04af04 353 int ret, integer = 0, fract = 0, fract_mult = 100000;
1d892719
JC
354 bool integer_part = true, negative = false;
355
356 /* Assumes decimal - precision based on number of digits */
6fe8135f 357 if (!indio_dev->info->write_raw)
1d892719 358 return -EINVAL;
5c04af04
MH
359
360 if (indio_dev->info->write_raw_get_fmt)
361 switch (indio_dev->info->write_raw_get_fmt(indio_dev,
362 this_attr->c, this_attr->address)) {
363 case IIO_VAL_INT_PLUS_MICRO:
364 fract_mult = 100000;
365 break;
366 case IIO_VAL_INT_PLUS_NANO:
367 fract_mult = 100000000;
368 break;
369 default:
370 return -EINVAL;
371 }
372
1d892719
JC
373 if (buf[0] == '-') {
374 negative = true;
375 buf++;
376 }
5c04af04 377
1d892719
JC
378 while (*buf) {
379 if ('0' <= *buf && *buf <= '9') {
380 if (integer_part)
381 integer = integer*10 + *buf - '0';
382 else {
5c04af04
MH
383 fract += fract_mult*(*buf - '0');
384 if (fract_mult == 1)
1d892719 385 break;
5c04af04 386 fract_mult /= 10;
1d892719
JC
387 }
388 } else if (*buf == '\n') {
389 if (*(buf + 1) == '\0')
390 break;
391 else
392 return -EINVAL;
393 } else if (*buf == '.') {
394 integer_part = false;
395 } else {
396 return -EINVAL;
397 }
398 buf++;
399 }
400 if (negative) {
401 if (integer)
402 integer = -integer;
403 else
5c04af04 404 fract = -fract;
1d892719
JC
405 }
406
6fe8135f 407 ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
5c04af04 408 integer, fract, this_attr->address);
1d892719
JC
409 if (ret)
410 return ret;
411
412 return len;
413}
414
df9c1c42 415static
1d892719
JC
416int __iio_device_attr_init(struct device_attribute *dev_attr,
417 const char *postfix,
418 struct iio_chan_spec const *chan,
419 ssize_t (*readfunc)(struct device *dev,
420 struct device_attribute *attr,
421 char *buf),
422 ssize_t (*writefunc)(struct device *dev,
423 struct device_attribute *attr,
424 const char *buf,
425 size_t len),
426 bool generic)
427{
428 int ret;
429 char *name_format, *full_postfix;
430 sysfs_attr_init(&dev_attr->attr);
1d892719 431
ade7ef7b 432 /* Build up postfix of <extend_name>_<modifier>_postfix */
0403e0d6 433 if (chan->modified && !generic) {
ade7ef7b
JC
434 if (chan->extend_name)
435 full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
436 iio_modifier_names[chan
437 ->channel2],
438 chan->extend_name,
439 postfix);
440 else
441 full_postfix = kasprintf(GFP_KERNEL, "%s_%s",
442 iio_modifier_names[chan
443 ->channel2],
444 postfix);
445 } else {
446 if (chan->extend_name == NULL)
447 full_postfix = kstrdup(postfix, GFP_KERNEL);
448 else
449 full_postfix = kasprintf(GFP_KERNEL,
450 "%s_%s",
451 chan->extend_name,
452 postfix);
453 }
454 if (full_postfix == NULL) {
455 ret = -ENOMEM;
456 goto error_ret;
457 }
1d892719 458
ade7ef7b
JC
459 if (chan->differential) { /* Differential can not have modifier */
460 if (generic)
461 name_format
462 = kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
463 iio_direction[chan->output],
464 iio_chan_type_name_spec[chan->type],
465 iio_chan_type_name_spec[chan->type],
466 full_postfix);
467 else if (chan->indexed)
468 name_format
469 = kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s",
470 iio_direction[chan->output],
471 iio_chan_type_name_spec[chan->type],
472 chan->channel,
473 iio_chan_type_name_spec[chan->type],
474 chan->channel2,
475 full_postfix);
476 else {
477 WARN_ON("Differential channels must be indexed\n");
478 ret = -EINVAL;
479 goto error_free_full_postfix;
480 }
481 } else { /* Single ended */
482 if (generic)
483 name_format
484 = kasprintf(GFP_KERNEL, "%s_%s_%s",
485 iio_direction[chan->output],
486 iio_chan_type_name_spec[chan->type],
487 full_postfix);
488 else if (chan->indexed)
489 name_format
490 = kasprintf(GFP_KERNEL, "%s_%s%d_%s",
491 iio_direction[chan->output],
492 iio_chan_type_name_spec[chan->type],
493 chan->channel,
494 full_postfix);
495 else
496 name_format
497 = kasprintf(GFP_KERNEL, "%s_%s_%s",
498 iio_direction[chan->output],
499 iio_chan_type_name_spec[chan->type],
500 full_postfix);
501 }
1d892719
JC
502 if (name_format == NULL) {
503 ret = -ENOMEM;
504 goto error_free_full_postfix;
505 }
506 dev_attr->attr.name = kasprintf(GFP_KERNEL,
507 name_format,
508 chan->channel,
509 chan->channel2);
510 if (dev_attr->attr.name == NULL) {
511 ret = -ENOMEM;
512 goto error_free_name_format;
513 }
514
515 if (readfunc) {
516 dev_attr->attr.mode |= S_IRUGO;
517 dev_attr->show = readfunc;
518 }
519
520 if (writefunc) {
521 dev_attr->attr.mode |= S_IWUSR;
522 dev_attr->store = writefunc;
523 }
524 kfree(name_format);
525 kfree(full_postfix);
526
527 return 0;
528
529error_free_name_format:
530 kfree(name_format);
531error_free_full_postfix:
532 kfree(full_postfix);
533error_ret:
534 return ret;
535}
536
df9c1c42 537static void __iio_device_attr_deinit(struct device_attribute *dev_attr)
1d892719
JC
538{
539 kfree(dev_attr->attr.name);
540}
541
542int __iio_add_chan_devattr(const char *postfix,
1d892719
JC
543 struct iio_chan_spec const *chan,
544 ssize_t (*readfunc)(struct device *dev,
545 struct device_attribute *attr,
546 char *buf),
547 ssize_t (*writefunc)(struct device *dev,
548 struct device_attribute *attr,
549 const char *buf,
550 size_t len),
e614a54b 551 u64 mask,
1d892719
JC
552 bool generic,
553 struct device *dev,
554 struct list_head *attr_list)
555{
556 int ret;
557 struct iio_dev_attr *iio_attr, *t;
558
559 iio_attr = kzalloc(sizeof *iio_attr, GFP_KERNEL);
560 if (iio_attr == NULL) {
561 ret = -ENOMEM;
562 goto error_ret;
563 }
564 ret = __iio_device_attr_init(&iio_attr->dev_attr,
565 postfix, chan,
566 readfunc, writefunc, generic);
567 if (ret)
568 goto error_iio_dev_attr_free;
569 iio_attr->c = chan;
570 iio_attr->address = mask;
571 list_for_each_entry(t, attr_list, l)
572 if (strcmp(t->dev_attr.attr.name,
573 iio_attr->dev_attr.attr.name) == 0) {
574 if (!generic)
575 dev_err(dev, "tried to double register : %s\n",
576 t->dev_attr.attr.name);
577 ret = -EBUSY;
578 goto error_device_attr_deinit;
579 }
1d892719
JC
580 list_add(&iio_attr->l, attr_list);
581
582 return 0;
583
584error_device_attr_deinit:
585 __iio_device_attr_deinit(&iio_attr->dev_attr);
586error_iio_dev_attr_free:
587 kfree(iio_attr);
588error_ret:
589 return ret;
590}
591
f8c6f4e9 592static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
1d892719
JC
593 struct iio_chan_spec const *chan)
594{
26d25ae3 595 int ret, i, attrcount = 0;
1d892719 596
1d892719
JC
597 if (chan->channel < 0)
598 return 0;
1e8dfcc6
JC
599
600 ret = __iio_add_chan_devattr(iio_data_type_name[chan->processed_val],
26d25ae3 601 chan,
1e8dfcc6 602 &iio_read_channel_info,
c6fc8062 603 (chan->output ?
1e8dfcc6
JC
604 &iio_write_channel_info : NULL),
605 0,
606 0,
f8c6f4e9
JC
607 &indio_dev->dev,
608 &indio_dev->channel_attr_list);
1d892719
JC
609 if (ret)
610 goto error_ret;
26d25ae3 611 attrcount++;
1d892719
JC
612
613 for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) {
614 ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2],
26d25ae3 615 chan,
1d892719
JC
616 &iio_read_channel_info,
617 &iio_write_channel_info,
c8a9f805 618 i/2,
1d892719 619 !(i%2),
f8c6f4e9
JC
620 &indio_dev->dev,
621 &indio_dev->channel_attr_list);
1d892719
JC
622 if (ret == -EBUSY && (i%2 == 0)) {
623 ret = 0;
624 continue;
625 }
626 if (ret < 0)
627 goto error_ret;
26d25ae3 628 attrcount++;
1d892719 629 }
26d25ae3 630 ret = attrcount;
1d892719
JC
631error_ret:
632 return ret;
633}
634
f8c6f4e9 635static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev,
1d892719
JC
636 struct iio_dev_attr *p)
637{
1d892719
JC
638 kfree(p->dev_attr.attr.name);
639 kfree(p);
640}
641
1b732888
JC
642static ssize_t iio_show_dev_name(struct device *dev,
643 struct device_attribute *attr,
644 char *buf)
645{
646 struct iio_dev *indio_dev = dev_get_drvdata(dev);
647 return sprintf(buf, "%s\n", indio_dev->name);
648}
649
650static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);
651
f8c6f4e9 652static int iio_device_register_sysfs(struct iio_dev *indio_dev)
1d892719 653{
26d25ae3 654 int i, ret = 0, attrcount, attrn, attrcount_orig = 0;
1d892719 655 struct iio_dev_attr *p, *n;
26d25ae3 656 struct attribute **attr;
1d892719 657
26d25ae3 658 /* First count elements in any existing group */
f8c6f4e9
JC
659 if (indio_dev->info->attrs) {
660 attr = indio_dev->info->attrs->attrs;
26d25ae3
JC
661 while (*attr++ != NULL)
662 attrcount_orig++;
847ec80b 663 }
26d25ae3 664 attrcount = attrcount_orig;
1d892719
JC
665 /*
666 * New channel registration method - relies on the fact a group does
667 * not need to be initialized if it is name is NULL.
668 */
f8c6f4e9
JC
669 INIT_LIST_HEAD(&indio_dev->channel_attr_list);
670 if (indio_dev->channels)
671 for (i = 0; i < indio_dev->num_channels; i++) {
672 ret = iio_device_add_channel_sysfs(indio_dev,
673 &indio_dev
1d892719
JC
674 ->channels[i]);
675 if (ret < 0)
676 goto error_clear_attrs;
26d25ae3 677 attrcount += ret;
1d892719 678 }
26d25ae3 679
f8c6f4e9 680 if (indio_dev->name)
26d25ae3
JC
681 attrcount++;
682
d83fb184
TM
683 indio_dev->chan_attr_group.attrs = kcalloc(attrcount + 1,
684 sizeof(indio_dev->chan_attr_group.attrs[0]),
685 GFP_KERNEL);
f8c6f4e9 686 if (indio_dev->chan_attr_group.attrs == NULL) {
26d25ae3
JC
687 ret = -ENOMEM;
688 goto error_clear_attrs;
1b732888 689 }
26d25ae3 690 /* Copy across original attributes */
f8c6f4e9
JC
691 if (indio_dev->info->attrs)
692 memcpy(indio_dev->chan_attr_group.attrs,
693 indio_dev->info->attrs->attrs,
694 sizeof(indio_dev->chan_attr_group.attrs[0])
26d25ae3
JC
695 *attrcount_orig);
696 attrn = attrcount_orig;
697 /* Add all elements from the list. */
f8c6f4e9
JC
698 list_for_each_entry(p, &indio_dev->channel_attr_list, l)
699 indio_dev->chan_attr_group.attrs[attrn++] = &p->dev_attr.attr;
700 if (indio_dev->name)
701 indio_dev->chan_attr_group.attrs[attrn++] = &dev_attr_name.attr;
26d25ae3 702
f8c6f4e9
JC
703 indio_dev->groups[indio_dev->groupcounter++] =
704 &indio_dev->chan_attr_group;
26d25ae3 705
1d892719 706 return 0;
1b732888 707
1d892719
JC
708error_clear_attrs:
709 list_for_each_entry_safe(p, n,
f8c6f4e9 710 &indio_dev->channel_attr_list, l) {
1d892719 711 list_del(&p->l);
f8c6f4e9 712 iio_device_remove_and_free_read_attr(indio_dev, p);
1d892719 713 }
1d892719 714
26d25ae3 715 return ret;
847ec80b
JC
716}
717
f8c6f4e9 718static void iio_device_unregister_sysfs(struct iio_dev *indio_dev)
847ec80b 719{
1d892719
JC
720
721 struct iio_dev_attr *p, *n;
26d25ae3 722
f8c6f4e9 723 list_for_each_entry_safe(p, n, &indio_dev->channel_attr_list, l) {
1d892719 724 list_del(&p->l);
f8c6f4e9 725 iio_device_remove_and_free_read_attr(indio_dev, p);
1d892719 726 }
f8c6f4e9 727 kfree(indio_dev->chan_attr_group.attrs);
847ec80b
JC
728}
729
1d892719
JC
730static const char * const iio_ev_type_text[] = {
731 [IIO_EV_TYPE_THRESH] = "thresh",
732 [IIO_EV_TYPE_MAG] = "mag",
8ce7375b
JC
733 [IIO_EV_TYPE_ROC] = "roc",
734 [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
735 [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
1d892719
JC
736};
737
738static const char * const iio_ev_dir_text[] = {
739 [IIO_EV_DIR_EITHER] = "either",
740 [IIO_EV_DIR_RISING] = "rising",
741 [IIO_EV_DIR_FALLING] = "falling"
742};
743
744static ssize_t iio_ev_state_store(struct device *dev,
745 struct device_attribute *attr,
746 const char *buf,
747 size_t len)
748{
749 struct iio_dev *indio_dev = dev_get_drvdata(dev);
aaf370db 750 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
1d892719 751 int ret;
c74b0de1
JC
752 bool val;
753
754 ret = strtobool(buf, &val);
755 if (ret < 0)
756 return ret;
1d892719 757
6fe8135f
JC
758 ret = indio_dev->info->write_event_config(indio_dev,
759 this_attr->address,
760 val);
1d892719
JC
761 return (ret < 0) ? ret : len;
762}
763
764static ssize_t iio_ev_state_show(struct device *dev,
765 struct device_attribute *attr,
766 char *buf)
767{
768 struct iio_dev *indio_dev = dev_get_drvdata(dev);
aaf370db 769 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
6fe8135f
JC
770 int val = indio_dev->info->read_event_config(indio_dev,
771 this_attr->address);
1d892719
JC
772
773 if (val < 0)
774 return val;
775 else
776 return sprintf(buf, "%d\n", val);
777}
778
779static ssize_t iio_ev_value_show(struct device *dev,
780 struct device_attribute *attr,
781 char *buf)
782{
783 struct iio_dev *indio_dev = dev_get_drvdata(dev);
784 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
785 int val, ret;
786
6fe8135f
JC
787 ret = indio_dev->info->read_event_value(indio_dev,
788 this_attr->address, &val);
1d892719
JC
789 if (ret < 0)
790 return ret;
791
792 return sprintf(buf, "%d\n", val);
793}
794
795static ssize_t iio_ev_value_store(struct device *dev,
796 struct device_attribute *attr,
797 const char *buf,
798 size_t len)
799{
800 struct iio_dev *indio_dev = dev_get_drvdata(dev);
801 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
802 unsigned long val;
803 int ret;
804
43c03645
LPC
805 if (!indio_dev->info->write_event_value)
806 return -EINVAL;
807
1d892719
JC
808 ret = strict_strtoul(buf, 10, &val);
809 if (ret)
810 return ret;
811
6fe8135f
JC
812 ret = indio_dev->info->write_event_value(indio_dev, this_attr->address,
813 val);
1d892719
JC
814 if (ret < 0)
815 return ret;
816
817 return len;
818}
819
f8c6f4e9 820static int iio_device_add_event_sysfs(struct iio_dev *indio_dev,
1d892719
JC
821 struct iio_chan_spec const *chan)
822{
e614a54b
JC
823 int ret = 0, i, attrcount = 0;
824 u64 mask = 0;
1d892719
JC
825 char *postfix;
826 if (!chan->event_mask)
827 return 0;
828
829 for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) {
830 postfix = kasprintf(GFP_KERNEL, "%s_%s_en",
c04ea8ae
JC
831 iio_ev_type_text[i/IIO_EV_DIR_MAX],
832 iio_ev_dir_text[i%IIO_EV_DIR_MAX]);
1d892719
JC
833 if (postfix == NULL) {
834 ret = -ENOMEM;
835 goto error_ret;
836 }
330c6c57 837 if (chan->modified)
1d892719 838 mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel,
c04ea8ae
JC
839 i/IIO_EV_DIR_MAX,
840 i%IIO_EV_DIR_MAX);
ade7ef7b
JC
841 else if (chan->differential)
842 mask = IIO_EVENT_CODE(chan->type,
843 0, 0,
844 i%IIO_EV_DIR_MAX,
845 i/IIO_EV_DIR_MAX,
846 0,
847 chan->channel,
848 chan->channel2);
330c6c57
JC
849 else
850 mask = IIO_UNMOD_EVENT_CODE(chan->type,
851 chan->channel,
c04ea8ae
JC
852 i/IIO_EV_DIR_MAX,
853 i%IIO_EV_DIR_MAX);
330c6c57 854
aaf370db 855 ret = __iio_add_chan_devattr(postfix,
aaf370db
JC
856 chan,
857 &iio_ev_state_show,
858 iio_ev_state_store,
859 mask,
aaf370db 860 0,
f8c6f4e9
JC
861 &indio_dev->dev,
862 &indio_dev->event_interface->
aaf370db 863 dev_attr_list);
1d892719
JC
864 kfree(postfix);
865 if (ret)
866 goto error_ret;
26d25ae3 867 attrcount++;
1d892719 868 postfix = kasprintf(GFP_KERNEL, "%s_%s_value",
c04ea8ae
JC
869 iio_ev_type_text[i/IIO_EV_DIR_MAX],
870 iio_ev_dir_text[i%IIO_EV_DIR_MAX]);
1d892719
JC
871 if (postfix == NULL) {
872 ret = -ENOMEM;
873 goto error_ret;
874 }
26d25ae3 875 ret = __iio_add_chan_devattr(postfix, chan,
1d892719
JC
876 iio_ev_value_show,
877 iio_ev_value_store,
878 mask,
879 0,
f8c6f4e9
JC
880 &indio_dev->dev,
881 &indio_dev->event_interface->
5aa96188 882 dev_attr_list);
1d892719
JC
883 kfree(postfix);
884 if (ret)
885 goto error_ret;
26d25ae3 886 attrcount++;
1d892719 887 }
26d25ae3 888 ret = attrcount;
1d892719
JC
889error_ret:
890 return ret;
891}
892
f8c6f4e9 893static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev)
1d892719
JC
894{
895 struct iio_dev_attr *p, *n;
1d892719 896 list_for_each_entry_safe(p, n,
f8c6f4e9 897 &indio_dev->event_interface->
1d892719 898 dev_attr_list, l) {
1d892719
JC
899 kfree(p->dev_attr.attr.name);
900 kfree(p);
901 }
1d892719
JC
902}
903
f8c6f4e9 904static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev)
847ec80b 905{
26d25ae3 906 int j, ret, attrcount = 0;
1e8dfcc6 907
f8c6f4e9 908 INIT_LIST_HEAD(&indio_dev->event_interface->dev_attr_list);
1d892719 909 /* Dynically created from the channels array */
f8c6f4e9
JC
910 for (j = 0; j < indio_dev->num_channels; j++) {
911 ret = iio_device_add_event_sysfs(indio_dev,
912 &indio_dev->channels[j]);
26d25ae3 913 if (ret < 0)
5aa96188 914 goto error_clear_attrs;
26d25ae3 915 attrcount += ret;
1d892719 916 }
26d25ae3 917 return attrcount;
847ec80b 918
1d892719 919error_clear_attrs:
f8c6f4e9 920 __iio_remove_event_config_attrs(indio_dev);
847ec80b
JC
921
922 return ret;
923}
924
f8c6f4e9 925static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev)
5aa96188
JC
926{
927 int j;
1e8dfcc6 928
f8c6f4e9
JC
929 for (j = 0; j < indio_dev->num_channels; j++)
930 if (indio_dev->channels[j].event_mask != 0)
5aa96188
JC
931 return true;
932 return false;
933}
934
1e8dfcc6
JC
935static void iio_setup_ev_int(struct iio_event_interface *ev_int)
936{
937 mutex_init(&ev_int->event_list_lock);
938 /* discussion point - make this variable? */
939 ev_int->max_events = 10;
940 ev_int->current_events = 0;
941 INIT_LIST_HEAD(&ev_int->det_events);
942 init_waitqueue_head(&ev_int->wait);
943}
944
26d25ae3 945static const char *iio_event_group_name = "events";
f8c6f4e9 946static int iio_device_register_eventset(struct iio_dev *indio_dev)
847ec80b 947{
26d25ae3
JC
948 struct iio_dev_attr *p;
949 int ret = 0, attrcount_orig = 0, attrcount, attrn;
950 struct attribute **attr;
847ec80b 951
f8c6f4e9
JC
952 if (!(indio_dev->info->event_attrs ||
953 iio_check_for_dynamic_events(indio_dev)))
847ec80b
JC
954 return 0;
955
f8c6f4e9 956 indio_dev->event_interface =
5aa96188 957 kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL);
f8c6f4e9 958 if (indio_dev->event_interface == NULL) {
847ec80b
JC
959 ret = -ENOMEM;
960 goto error_ret;
961 }
962
f8c6f4e9
JC
963 iio_setup_ev_int(indio_dev->event_interface);
964 if (indio_dev->info->event_attrs != NULL) {
965 attr = indio_dev->info->event_attrs->attrs;
26d25ae3
JC
966 while (*attr++ != NULL)
967 attrcount_orig++;
5aa96188 968 }
26d25ae3 969 attrcount = attrcount_orig;
f8c6f4e9
JC
970 if (indio_dev->channels) {
971 ret = __iio_add_event_config_attrs(indio_dev);
26d25ae3 972 if (ret < 0)
cc2439fd 973 goto error_free_setup_event_lines;
26d25ae3 974 attrcount += ret;
847ec80b
JC
975 }
976
f8c6f4e9 977 indio_dev->event_interface->group.name = iio_event_group_name;
d83fb184
TM
978 indio_dev->event_interface->group.attrs = kcalloc(attrcount + 1,
979 sizeof(indio_dev->event_interface->group.attrs[0]),
980 GFP_KERNEL);
f8c6f4e9 981 if (indio_dev->event_interface->group.attrs == NULL) {
26d25ae3
JC
982 ret = -ENOMEM;
983 goto error_free_setup_event_lines;
984 }
f8c6f4e9
JC
985 if (indio_dev->info->event_attrs)
986 memcpy(indio_dev->event_interface->group.attrs,
987 indio_dev->info->event_attrs->attrs,
988 sizeof(indio_dev->event_interface->group.attrs[0])
26d25ae3
JC
989 *attrcount_orig);
990 attrn = attrcount_orig;
991 /* Add all elements from the list. */
992 list_for_each_entry(p,
f8c6f4e9 993 &indio_dev->event_interface->dev_attr_list,
26d25ae3 994 l)
f8c6f4e9 995 indio_dev->event_interface->group.attrs[attrn++] =
26d25ae3 996 &p->dev_attr.attr;
f8c6f4e9
JC
997 indio_dev->groups[indio_dev->groupcounter++] =
998 &indio_dev->event_interface->group;
26d25ae3 999
847ec80b
JC
1000 return 0;
1001
cc2439fd 1002error_free_setup_event_lines:
f8c6f4e9
JC
1003 __iio_remove_event_config_attrs(indio_dev);
1004 kfree(indio_dev->event_interface);
847ec80b
JC
1005error_ret:
1006
1007 return ret;
1008}
1009
f8c6f4e9 1010static void iio_device_unregister_eventset(struct iio_dev *indio_dev)
847ec80b 1011{
f8c6f4e9 1012 if (indio_dev->event_interface == NULL)
847ec80b 1013 return;
f8c6f4e9
JC
1014 __iio_remove_event_config_attrs(indio_dev);
1015 kfree(indio_dev->event_interface->group.attrs);
1016 kfree(indio_dev->event_interface);
847ec80b
JC
1017}
1018
1019static void iio_dev_release(struct device *device)
1020{
f8c6f4e9
JC
1021 struct iio_dev *indio_dev = container_of(device, struct iio_dev, dev);
1022 cdev_del(&indio_dev->chrdev);
1023 if (indio_dev->modes & INDIO_BUFFER_TRIGGERED)
1024 iio_device_unregister_trigger_consumer(indio_dev);
1025 iio_device_unregister_eventset(indio_dev);
1026 iio_device_unregister_sysfs(indio_dev);
847ec80b
JC
1027}
1028
1029static struct device_type iio_dev_type = {
1030 .name = "iio_device",
1031 .release = iio_dev_release,
1032};
1033
6f7c8ee5 1034struct iio_dev *iio_allocate_device(int sizeof_priv)
847ec80b 1035{
6f7c8ee5
JC
1036 struct iio_dev *dev;
1037 size_t alloc_size;
1038
1039 alloc_size = sizeof(struct iio_dev);
1040 if (sizeof_priv) {
1041 alloc_size = ALIGN(alloc_size, IIO_ALIGN);
1042 alloc_size += sizeof_priv;
1043 }
1044 /* ensure 32-byte alignment of whole construct ? */
1045 alloc_size += IIO_ALIGN - 1;
1046
1047 dev = kzalloc(alloc_size, GFP_KERNEL);
847ec80b
JC
1048
1049 if (dev) {
26d25ae3 1050 dev->dev.groups = dev->groups;
847ec80b 1051 dev->dev.type = &iio_dev_type;
5aaaeba8 1052 dev->dev.bus = &iio_bus_type;
847ec80b
JC
1053 device_initialize(&dev->dev);
1054 dev_set_drvdata(&dev->dev, (void *)dev);
1055 mutex_init(&dev->mlock);
a9e39f9e
JC
1056
1057 dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL);
1058 if (dev->id < 0) {
1059 /* cannot use a dev_err as the name isn't available */
1060 printk(KERN_ERR "Failed to get id\n");
1061 kfree(dev);
1062 return NULL;
1063 }
1064 dev_set_name(&dev->dev, "iio:device%d", dev->id);
847ec80b
JC
1065 }
1066
1067 return dev;
1068}
1069EXPORT_SYMBOL(iio_allocate_device);
1070
1071void iio_free_device(struct iio_dev *dev)
1072{
a9e39f9e
JC
1073 if (dev) {
1074 ida_simple_remove(&iio_ida, dev->id);
1aa04278 1075 kfree(dev);
a9e39f9e 1076 }
847ec80b
JC
1077}
1078EXPORT_SYMBOL(iio_free_device);
1079
1aa04278 1080/**
14555b14 1081 * iio_chrdev_open() - chrdev file open for buffer access and ioctls
1aa04278
JC
1082 **/
1083static int iio_chrdev_open(struct inode *inode, struct file *filp)
1084{
f8c6f4e9 1085 struct iio_dev *indio_dev = container_of(inode->i_cdev,
1aa04278 1086 struct iio_dev, chrdev);
bb01443e
LPC
1087
1088 if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags))
1089 return -EBUSY;
1090
f8c6f4e9 1091 filp->private_data = indio_dev;
30eb82f0 1092
79335140 1093 return 0;
1aa04278
JC
1094}
1095
1096/**
14555b14 1097 * iio_chrdev_release() - chrdev file close buffer access and ioctls
1aa04278
JC
1098 **/
1099static int iio_chrdev_release(struct inode *inode, struct file *filp)
1100{
bb01443e
LPC
1101 struct iio_dev *indio_dev = container_of(inode->i_cdev,
1102 struct iio_dev, chrdev);
bb01443e 1103 clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags);
1aa04278
JC
1104 return 0;
1105}
1106
1107/* Somewhat of a cross file organization violation - ioctls here are actually
1108 * event related */
1109static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1110{
1111 struct iio_dev *indio_dev = filp->private_data;
1112 int __user *ip = (int __user *)arg;
1113 int fd;
1114
1115 if (cmd == IIO_GET_EVENT_FD_IOCTL) {
1116 fd = iio_event_getfd(indio_dev);
1117 if (copy_to_user(ip, &fd, sizeof(fd)))
1118 return -EFAULT;
1119 return 0;
1120 }
1121 return -EINVAL;
1122}
1123
14555b14
JC
1124static const struct file_operations iio_buffer_fileops = {
1125 .read = iio_buffer_read_first_n_outer_addr,
1aa04278
JC
1126 .release = iio_chrdev_release,
1127 .open = iio_chrdev_open,
14555b14 1128 .poll = iio_buffer_poll_addr,
1aa04278
JC
1129 .owner = THIS_MODULE,
1130 .llseek = noop_llseek,
1131 .unlocked_ioctl = iio_ioctl,
1132 .compat_ioctl = iio_ioctl,
1133};
1134
f8c6f4e9 1135int iio_device_register(struct iio_dev *indio_dev)
847ec80b
JC
1136{
1137 int ret;
1138
1aa04278 1139 /* configure elements for the chrdev */
f8c6f4e9 1140 indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id);
847ec80b 1141
f8c6f4e9 1142 ret = iio_device_register_sysfs(indio_dev);
847ec80b 1143 if (ret) {
f8c6f4e9 1144 dev_err(indio_dev->dev.parent,
847ec80b 1145 "Failed to register sysfs interfaces\n");
a9e39f9e 1146 goto error_ret;
847ec80b 1147 }
f8c6f4e9 1148 ret = iio_device_register_eventset(indio_dev);
847ec80b 1149 if (ret) {
f8c6f4e9 1150 dev_err(indio_dev->dev.parent,
c849d253 1151 "Failed to register event set\n");
847ec80b
JC
1152 goto error_free_sysfs;
1153 }
f8c6f4e9
JC
1154 if (indio_dev->modes & INDIO_BUFFER_TRIGGERED)
1155 iio_device_register_trigger_consumer(indio_dev);
847ec80b 1156
f8c6f4e9 1157 ret = device_add(&indio_dev->dev);
26d25ae3
JC
1158 if (ret < 0)
1159 goto error_unreg_eventset;
f8c6f4e9
JC
1160 cdev_init(&indio_dev->chrdev, &iio_buffer_fileops);
1161 indio_dev->chrdev.owner = indio_dev->info->driver_module;
1162 ret = cdev_add(&indio_dev->chrdev, indio_dev->dev.devt, 1);
26d25ae3
JC
1163 if (ret < 0)
1164 goto error_del_device;
847ec80b
JC
1165 return 0;
1166
847ec80b 1167error_del_device:
f8c6f4e9 1168 device_del(&indio_dev->dev);
26d25ae3 1169error_unreg_eventset:
f8c6f4e9 1170 iio_device_unregister_eventset(indio_dev);
26d25ae3 1171error_free_sysfs:
f8c6f4e9 1172 iio_device_unregister_sysfs(indio_dev);
847ec80b
JC
1173error_ret:
1174 return ret;
1175}
1176EXPORT_SYMBOL(iio_device_register);
1177
f8c6f4e9 1178void iio_device_unregister(struct iio_dev *indio_dev)
847ec80b 1179{
f8c6f4e9 1180 device_unregister(&indio_dev->dev);
847ec80b
JC
1181}
1182EXPORT_SYMBOL(iio_device_unregister);
847ec80b
JC
1183subsys_initcall(iio_init);
1184module_exit(iio_exit);
1185
1186MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
1187MODULE_DESCRIPTION("Industrial I/O core");
1188MODULE_LICENSE("GPL");
This page took 0.318278 seconds and 5 git commands to generate.