staging:iio:adc:ad7606: Use private data space from iio_allocate_device
[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>
19#include <linux/interrupt.h>
20#include <linux/poll.h>
ffc18afa 21#include <linux/sched.h>
4439c935 22#include <linux/wait.h>
847ec80b 23#include <linux/cdev.h>
5a0e3ad6 24#include <linux/slab.h>
847ec80b
JC
25#include "iio.h"
26#include "trigger_consumer.h"
27
28#define IIO_ID_PREFIX "device"
29#define IIO_ID_FORMAT IIO_ID_PREFIX "%d"
30
31/* IDR to assign each registered device a unique id*/
b156cf70 32static DEFINE_IDA(iio_ida);
847ec80b 33/* IDR to allocate character device minor numbers */
b156cf70 34static DEFINE_IDA(iio_chrdev_ida);
847ec80b 35/* Lock used to protect both of the above */
b156cf70 36static DEFINE_SPINLOCK(iio_ida_lock);
847ec80b
JC
37
38dev_t iio_devt;
39EXPORT_SYMBOL(iio_devt);
40
41#define IIO_DEV_MAX 256
5aaaeba8 42struct bus_type iio_bus_type = {
847ec80b 43 .name = "iio",
847ec80b 44};
5aaaeba8 45EXPORT_SYMBOL(iio_bus_type);
847ec80b 46
1d892719
JC
47static const char * const iio_chan_type_name_spec_shared[] = {
48 [IIO_TIMESTAMP] = "timestamp",
49 [IIO_ACCEL] = "accel",
50 [IIO_IN] = "in",
51 [IIO_IN_DIFF] = "in-in",
52 [IIO_GYRO] = "gyro",
53 [IIO_TEMP] = "temp",
54 [IIO_MAGN] = "magn",
55 [IIO_INCLI] = "incli",
56 [IIO_ROT] = "rot",
57 [IIO_INTENSITY] = "intensity",
58 [IIO_LIGHT] = "illuminance",
59 [IIO_ANGL] = "angl",
60};
61
62static const char * const iio_chan_type_name_spec_complex[] = {
63 [IIO_IN_DIFF] = "in%d-in%d",
64};
65
66static const char * const iio_modifier_names_light[] = {
67 [IIO_MOD_LIGHT_BOTH] = "both",
68 [IIO_MOD_LIGHT_IR] = "ir",
69};
70
71static const char * const iio_modifier_names_axial[] = {
72 [IIO_MOD_X] = "x",
73 [IIO_MOD_Y] = "y",
74 [IIO_MOD_Z] = "z",
75};
76
77/* relies on pairs of these shared then separate */
78static const char * const iio_chan_info_postfix[] = {
79 [IIO_CHAN_INFO_SCALE_SHARED/2] = "scale",
80 [IIO_CHAN_INFO_OFFSET_SHARED/2] = "offset",
81 [IIO_CHAN_INFO_CALIBSCALE_SHARED/2] = "calibscale",
82 [IIO_CHAN_INFO_CALIBBIAS_SHARED/2] = "calibbias",
eb7fea53
JC
83 [IIO_CHAN_INFO_PEAK_SHARED/2] = "peak_raw",
84 [IIO_CHAN_INFO_PEAK_SCALE_SHARED/2] = "peak_scale",
1d892719
JC
85};
86
aaf370db
JC
87int iio_push_event(struct iio_dev *dev_info,
88 int ev_line,
89 int ev_code,
90 s64 timestamp)
847ec80b 91{
aaf370db
JC
92 struct iio_event_interface *ev_int
93 = &dev_info->event_interfaces[ev_line];
847ec80b
JC
94 struct iio_detected_event_list *ev;
95 int ret = 0;
96
97 /* Does anyone care? */
98 mutex_lock(&ev_int->event_list_lock);
99 if (test_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags)) {
75c80753
JC
100 if (ev_int->current_events == ev_int->max_events) {
101 mutex_unlock(&ev_int->event_list_lock);
847ec80b 102 return 0;
75c80753 103 }
847ec80b
JC
104 ev = kmalloc(sizeof(*ev), GFP_KERNEL);
105 if (ev == NULL) {
106 ret = -ENOMEM;
75c80753 107 mutex_unlock(&ev_int->event_list_lock);
847ec80b
JC
108 goto error_ret;
109 }
110 ev->ev.id = ev_code;
111 ev->ev.timestamp = timestamp;
847ec80b
JC
112
113 list_add_tail(&ev->list, &ev_int->det_events.list);
114 ev_int->current_events++;
115 mutex_unlock(&ev_int->event_list_lock);
116 wake_up_interruptible(&ev_int->wait);
117 } else
118 mutex_unlock(&ev_int->event_list_lock);
119
120error_ret:
121 return ret;
122}
847ec80b
JC
123EXPORT_SYMBOL(iio_push_event);
124
847ec80b
JC
125
126/* This turns up an awful lot */
127ssize_t iio_read_const_attr(struct device *dev,
128 struct device_attribute *attr,
129 char *buf)
130{
131 return sprintf(buf, "%s\n", to_iio_const_attr(attr)->string);
132}
133EXPORT_SYMBOL(iio_read_const_attr);
134
847ec80b 135
77712e5f
MB
136static ssize_t iio_event_chrdev_read(struct file *filep,
137 char __user *buf,
138 size_t count,
139 loff_t *f_ps)
847ec80b
JC
140{
141 struct iio_event_interface *ev_int = filep->private_data;
142 struct iio_detected_event_list *el;
143 int ret;
144 size_t len;
145
146 mutex_lock(&ev_int->event_list_lock);
147 if (list_empty(&ev_int->det_events.list)) {
148 if (filep->f_flags & O_NONBLOCK) {
149 ret = -EAGAIN;
150 goto error_mutex_unlock;
151 }
152 mutex_unlock(&ev_int->event_list_lock);
153 /* Blocking on device; waiting for something to be there */
154 ret = wait_event_interruptible(ev_int->wait,
155 !list_empty(&ev_int
156 ->det_events.list));
157 if (ret)
158 goto error_ret;
25985edc 159 /* Single access device so no one else can get the data */
847ec80b
JC
160 mutex_lock(&ev_int->event_list_lock);
161 }
162
163 el = list_first_entry(&ev_int->det_events.list,
164 struct iio_detected_event_list,
165 list);
166 len = sizeof el->ev;
167 if (copy_to_user(buf, &(el->ev), len)) {
168 ret = -EFAULT;
169 goto error_mutex_unlock;
170 }
171 list_del(&el->list);
172 ev_int->current_events--;
173 mutex_unlock(&ev_int->event_list_lock);
847ec80b
JC
174 kfree(el);
175
176 return len;
177
178error_mutex_unlock:
179 mutex_unlock(&ev_int->event_list_lock);
180error_ret:
181
182 return ret;
183}
184
77712e5f 185static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
847ec80b
JC
186{
187 struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
188 struct iio_event_interface *ev_int = hand->private;
189 struct iio_detected_event_list *el, *t;
190
191 mutex_lock(&ev_int->event_list_lock);
192 clear_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags);
193 /*
194 * In order to maintain a clean state for reopening,
195 * clear out any awaiting events. The mask will prevent
196 * any new __iio_push_event calls running.
197 */
198 list_for_each_entry_safe(el, t, &ev_int->det_events.list, list) {
199 list_del(&el->list);
200 kfree(el);
201 }
202 mutex_unlock(&ev_int->event_list_lock);
203
204 return 0;
205}
206
77712e5f 207static int iio_event_chrdev_open(struct inode *inode, struct file *filep)
847ec80b
JC
208{
209 struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
210 struct iio_event_interface *ev_int = hand->private;
211
212 mutex_lock(&ev_int->event_list_lock);
213 if (test_and_set_bit(IIO_BUSY_BIT_POS, &hand->flags)) {
214 fops_put(filep->f_op);
215 mutex_unlock(&ev_int->event_list_lock);
216 return -EBUSY;
217 }
218 filep->private_data = hand->private;
219 mutex_unlock(&ev_int->event_list_lock);
220
221 return 0;
222}
223
224static const struct file_operations iio_event_chrdev_fileops = {
225 .read = iio_event_chrdev_read,
226 .release = iio_event_chrdev_release,
227 .open = iio_event_chrdev_open,
228 .owner = THIS_MODULE,
6038f373 229 .llseek = noop_llseek,
847ec80b
JC
230};
231
232static void iio_event_dev_release(struct device *dev)
233{
234 struct iio_event_interface *ev_int
235 = container_of(dev, struct iio_event_interface, dev);
236 cdev_del(&ev_int->handler.chrdev);
237 iio_device_free_chrdev_minor(MINOR(dev->devt));
238};
239
240static struct device_type iio_event_type = {
241 .release = iio_event_dev_release,
242};
243
244int iio_device_get_chrdev_minor(void)
245{
246 int ret, val;
247
b156cf70
JC
248ida_again:
249 if (unlikely(ida_pre_get(&iio_chrdev_ida, GFP_KERNEL) == 0))
847ec80b 250 return -ENOMEM;
b156cf70
JC
251 spin_lock(&iio_ida_lock);
252 ret = ida_get_new(&iio_chrdev_ida, &val);
253 spin_unlock(&iio_ida_lock);
847ec80b 254 if (unlikely(ret == -EAGAIN))
b156cf70 255 goto ida_again;
847ec80b
JC
256 else if (unlikely(ret))
257 return ret;
258 if (val > IIO_DEV_MAX)
259 return -ENOMEM;
260 return val;
261}
262
263void iio_device_free_chrdev_minor(int val)
264{
b156cf70
JC
265 spin_lock(&iio_ida_lock);
266 ida_remove(&iio_chrdev_ida, val);
267 spin_unlock(&iio_ida_lock);
847ec80b
JC
268}
269
b9d40a9d 270static int iio_setup_ev_int(struct iio_event_interface *ev_int,
847ec80b
JC
271 const char *name,
272 struct module *owner,
273 struct device *dev)
274{
275 int ret, minor;
276
5aaaeba8 277 ev_int->dev.bus = &iio_bus_type;
847ec80b
JC
278 ev_int->dev.parent = dev;
279 ev_int->dev.type = &iio_event_type;
280 device_initialize(&ev_int->dev);
281
282 minor = iio_device_get_chrdev_minor();
283 if (minor < 0) {
284 ret = minor;
285 goto error_device_put;
286 }
287 ev_int->dev.devt = MKDEV(MAJOR(iio_devt), minor);
288 dev_set_name(&ev_int->dev, "%s", name);
289
290 ret = device_add(&ev_int->dev);
291 if (ret)
292 goto error_free_minor;
293
294 cdev_init(&ev_int->handler.chrdev, &iio_event_chrdev_fileops);
295 ev_int->handler.chrdev.owner = owner;
296
297 mutex_init(&ev_int->event_list_lock);
298 /* discussion point - make this variable? */
299 ev_int->max_events = 10;
300 ev_int->current_events = 0;
301 INIT_LIST_HEAD(&ev_int->det_events.list);
302 init_waitqueue_head(&ev_int->wait);
303 ev_int->handler.private = ev_int;
304 ev_int->handler.flags = 0;
305
306 ret = cdev_add(&ev_int->handler.chrdev, ev_int->dev.devt, 1);
307 if (ret)
308 goto error_unreg_device;
309
310 return 0;
311
312error_unreg_device:
313 device_unregister(&ev_int->dev);
314error_free_minor:
315 iio_device_free_chrdev_minor(minor);
316error_device_put:
317 put_device(&ev_int->dev);
318
319 return ret;
320}
321
b9d40a9d 322static void iio_free_ev_int(struct iio_event_interface *ev_int)
847ec80b
JC
323{
324 device_unregister(&ev_int->dev);
325 put_device(&ev_int->dev);
326}
327
328static int __init iio_dev_init(void)
329{
330 int err;
331
332 err = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio");
333 if (err < 0)
334 printk(KERN_ERR "%s: failed to allocate char dev region\n",
335 __FILE__);
336
337 return err;
338}
339
340static void __exit iio_dev_exit(void)
341{
342 if (iio_devt)
343 unregister_chrdev_region(iio_devt, IIO_DEV_MAX);
344}
345
346static int __init iio_init(void)
347{
348 int ret;
349
5aaaeba8
JC
350 /* Register sysfs bus */
351 ret = bus_register(&iio_bus_type);
847ec80b
JC
352 if (ret < 0) {
353 printk(KERN_ERR
5aaaeba8 354 "%s could not register bus type\n",
847ec80b
JC
355 __FILE__);
356 goto error_nothing;
357 }
358
359 ret = iio_dev_init();
360 if (ret < 0)
5aaaeba8 361 goto error_unregister_bus_type;
847ec80b
JC
362
363 return 0;
364
5aaaeba8
JC
365error_unregister_bus_type:
366 bus_unregister(&iio_bus_type);
847ec80b
JC
367error_nothing:
368 return ret;
369}
370
371static void __exit iio_exit(void)
372{
373 iio_dev_exit();
5aaaeba8 374 bus_unregister(&iio_bus_type);
847ec80b
JC
375}
376
1d892719
JC
377static ssize_t iio_read_channel_info(struct device *dev,
378 struct device_attribute *attr,
379 char *buf)
847ec80b 380{
1d892719
JC
381 struct iio_dev *indio_dev = dev_get_drvdata(dev);
382 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
383 int val, val2;
384 int ret = indio_dev->read_raw(indio_dev, this_attr->c,
385 &val, &val2, this_attr->address);
386
387 if (ret < 0)
388 return ret;
847ec80b 389
1d892719
JC
390 if (ret == IIO_VAL_INT)
391 return sprintf(buf, "%d\n", val);
392 else if (ret == IIO_VAL_INT_PLUS_MICRO) {
393 if (val2 < 0)
394 return sprintf(buf, "-%d.%06u\n", val, -val2);
395 else
396 return sprintf(buf, "%d.%06u\n", val, val2);
397 } else
398 return 0;
399}
400
401static ssize_t iio_write_channel_info(struct device *dev,
402 struct device_attribute *attr,
403 const char *buf,
404 size_t len)
405{
406 struct iio_dev *indio_dev = dev_get_drvdata(dev);
407 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
408 int ret, integer = 0, micro = 0, micro_mult = 100000;
409 bool integer_part = true, negative = false;
410
411 /* Assumes decimal - precision based on number of digits */
412 if (!indio_dev->write_raw)
413 return -EINVAL;
414 if (buf[0] == '-') {
415 negative = true;
416 buf++;
417 }
418 while (*buf) {
419 if ('0' <= *buf && *buf <= '9') {
420 if (integer_part)
421 integer = integer*10 + *buf - '0';
422 else {
423 micro += micro_mult*(*buf - '0');
424 if (micro_mult == 1)
425 break;
426 micro_mult /= 10;
427 }
428 } else if (*buf == '\n') {
429 if (*(buf + 1) == '\0')
430 break;
431 else
432 return -EINVAL;
433 } else if (*buf == '.') {
434 integer_part = false;
435 } else {
436 return -EINVAL;
437 }
438 buf++;
439 }
440 if (negative) {
441 if (integer)
442 integer = -integer;
443 else
444 micro = -micro;
445 }
446
447 ret = indio_dev->write_raw(indio_dev, this_attr->c,
448 integer, micro, this_attr->address);
449 if (ret)
450 return ret;
451
452 return len;
453}
454
455static int __iio_build_postfix(struct iio_chan_spec const *chan,
456 bool generic,
457 const char *postfix,
458 char **result)
459{
460 char *all_post;
461 /* 3 options - generic, extend_name, modified - if generic, extend_name
462 * and modified cannot apply.*/
463
464 if (generic || (!chan->modified && !chan->extend_name)) {
465 all_post = kasprintf(GFP_KERNEL, "%s", postfix);
466 } else if (chan->modified) {
467 const char *intermediate;
468 switch (chan->type) {
469 case IIO_INTENSITY:
470 intermediate
471 = iio_modifier_names_light[chan->channel2];
472 break;
473 case IIO_ACCEL:
474 case IIO_GYRO:
475 case IIO_MAGN:
476 case IIO_INCLI:
477 case IIO_ROT:
478 case IIO_ANGL:
479 intermediate
480 = iio_modifier_names_axial[chan->channel2];
481 break;
482 default:
483 return -EINVAL;
484 }
485 if (chan->extend_name)
486 all_post = kasprintf(GFP_KERNEL, "%s_%s_%s",
487 intermediate,
488 chan->extend_name,
489 postfix);
490 else
491 all_post = kasprintf(GFP_KERNEL, "%s_%s",
492 intermediate,
493 postfix);
494 } else
495 all_post = kasprintf(GFP_KERNEL, "%s_%s", chan->extend_name,
496 postfix);
497 if (all_post == NULL)
498 return -ENOMEM;
499 *result = all_post;
500 return 0;
501}
502
503int __iio_device_attr_init(struct device_attribute *dev_attr,
504 const char *postfix,
505 struct iio_chan_spec const *chan,
506 ssize_t (*readfunc)(struct device *dev,
507 struct device_attribute *attr,
508 char *buf),
509 ssize_t (*writefunc)(struct device *dev,
510 struct device_attribute *attr,
511 const char *buf,
512 size_t len),
513 bool generic)
514{
515 int ret;
516 char *name_format, *full_postfix;
517 sysfs_attr_init(&dev_attr->attr);
518 ret = __iio_build_postfix(chan, generic, postfix, &full_postfix);
519 if (ret)
847ec80b 520 goto error_ret;
1d892719
JC
521
522 /* Special case for types that uses both channel numbers in naming */
523 if (chan->type == IIO_IN_DIFF && !generic)
524 name_format
525 = kasprintf(GFP_KERNEL, "%s_%s",
526 iio_chan_type_name_spec_complex[chan->type],
527 full_postfix);
528 else if (generic || !chan->indexed)
529 name_format
530 = kasprintf(GFP_KERNEL, "%s_%s",
531 iio_chan_type_name_spec_shared[chan->type],
532 full_postfix);
533 else
534 name_format
535 = kasprintf(GFP_KERNEL, "%s%d_%s",
536 iio_chan_type_name_spec_shared[chan->type],
537 chan->channel,
538 full_postfix);
539
540 if (name_format == NULL) {
541 ret = -ENOMEM;
542 goto error_free_full_postfix;
543 }
544 dev_attr->attr.name = kasprintf(GFP_KERNEL,
545 name_format,
546 chan->channel,
547 chan->channel2);
548 if (dev_attr->attr.name == NULL) {
549 ret = -ENOMEM;
550 goto error_free_name_format;
551 }
552
553 if (readfunc) {
554 dev_attr->attr.mode |= S_IRUGO;
555 dev_attr->show = readfunc;
556 }
557
558 if (writefunc) {
559 dev_attr->attr.mode |= S_IWUSR;
560 dev_attr->store = writefunc;
561 }
562 kfree(name_format);
563 kfree(full_postfix);
564
565 return 0;
566
567error_free_name_format:
568 kfree(name_format);
569error_free_full_postfix:
570 kfree(full_postfix);
571error_ret:
572 return ret;
573}
574
575void __iio_device_attr_deinit(struct device_attribute *dev_attr)
576{
577 kfree(dev_attr->attr.name);
578}
579
580int __iio_add_chan_devattr(const char *postfix,
581 const char *group,
582 struct iio_chan_spec const *chan,
583 ssize_t (*readfunc)(struct device *dev,
584 struct device_attribute *attr,
585 char *buf),
586 ssize_t (*writefunc)(struct device *dev,
587 struct device_attribute *attr,
588 const char *buf,
589 size_t len),
590 int mask,
591 bool generic,
592 struct device *dev,
593 struct list_head *attr_list)
594{
595 int ret;
596 struct iio_dev_attr *iio_attr, *t;
597
598 iio_attr = kzalloc(sizeof *iio_attr, GFP_KERNEL);
599 if (iio_attr == NULL) {
600 ret = -ENOMEM;
601 goto error_ret;
602 }
603 ret = __iio_device_attr_init(&iio_attr->dev_attr,
604 postfix, chan,
605 readfunc, writefunc, generic);
606 if (ret)
607 goto error_iio_dev_attr_free;
608 iio_attr->c = chan;
609 iio_attr->address = mask;
610 list_for_each_entry(t, attr_list, l)
611 if (strcmp(t->dev_attr.attr.name,
612 iio_attr->dev_attr.attr.name) == 0) {
613 if (!generic)
614 dev_err(dev, "tried to double register : %s\n",
615 t->dev_attr.attr.name);
616 ret = -EBUSY;
617 goto error_device_attr_deinit;
618 }
619
620 ret = sysfs_add_file_to_group(&dev->kobj,
621 &iio_attr->dev_attr.attr, group);
622 if (ret < 0)
623 goto error_device_attr_deinit;
624
625 list_add(&iio_attr->l, attr_list);
626
627 return 0;
628
629error_device_attr_deinit:
630 __iio_device_attr_deinit(&iio_attr->dev_attr);
631error_iio_dev_attr_free:
632 kfree(iio_attr);
633error_ret:
634 return ret;
635}
636
637static int iio_device_add_channel_sysfs(struct iio_dev *dev_info,
638 struct iio_chan_spec const *chan)
639{
640 int ret, i;
641
642
643 if (chan->channel < 0)
644 return 0;
645 if (chan->processed_val)
646 ret = __iio_add_chan_devattr("input", NULL, chan,
647 &iio_read_channel_info,
648 NULL,
649 0,
650 0,
651 &dev_info->dev,
652 &dev_info->channel_attr_list);
653 else
654 ret = __iio_add_chan_devattr("raw", NULL, chan,
655 &iio_read_channel_info,
656 NULL,
657 0,
658 0,
659 &dev_info->dev,
660 &dev_info->channel_attr_list);
661 if (ret)
662 goto error_ret;
663
664 for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) {
665 ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2],
666 NULL, chan,
667 &iio_read_channel_info,
668 &iio_write_channel_info,
669 (1 << i),
670 !(i%2),
671 &dev_info->dev,
672 &dev_info->channel_attr_list);
673 if (ret == -EBUSY && (i%2 == 0)) {
674 ret = 0;
675 continue;
676 }
677 if (ret < 0)
678 goto error_ret;
679 }
680error_ret:
681 return ret;
682}
683
684static void iio_device_remove_and_free_read_attr(struct iio_dev *dev_info,
685 struct iio_dev_attr *p)
686{
687 sysfs_remove_file_from_group(&dev_info->dev.kobj,
688 &p->dev_attr.attr, NULL);
689 kfree(p->dev_attr.attr.name);
690 kfree(p);
691}
692
1b732888
JC
693static ssize_t iio_show_dev_name(struct device *dev,
694 struct device_attribute *attr,
695 char *buf)
696{
697 struct iio_dev *indio_dev = dev_get_drvdata(dev);
698 return sprintf(buf, "%s\n", indio_dev->name);
699}
700
701static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);
702
1d892719
JC
703static int iio_device_register_sysfs(struct iio_dev *dev_info)
704{
705 int i, ret = 0;
706 struct iio_dev_attr *p, *n;
707
708 if (dev_info->attrs) {
709 ret = sysfs_create_group(&dev_info->dev.kobj, dev_info->attrs);
710 if (ret) {
711 dev_err(dev_info->dev.parent,
712 "Failed to register sysfs hooks\n");
713 goto error_ret;
714 }
847ec80b
JC
715 }
716
1d892719
JC
717 /*
718 * New channel registration method - relies on the fact a group does
719 * not need to be initialized if it is name is NULL.
720 */
721 INIT_LIST_HEAD(&dev_info->channel_attr_list);
722 if (dev_info->channels)
723 for (i = 0; i < dev_info->num_channels; i++) {
724 ret = iio_device_add_channel_sysfs(dev_info,
725 &dev_info
726 ->channels[i]);
727 if (ret < 0)
728 goto error_clear_attrs;
729 }
1b732888
JC
730 if (dev_info->name) {
731 ret = sysfs_add_file_to_group(&dev_info->dev.kobj,
732 &dev_attr_name.attr,
733 NULL);
734 if (ret)
735 goto error_clear_attrs;
736 }
1d892719 737 return 0;
1b732888 738
1d892719
JC
739error_clear_attrs:
740 list_for_each_entry_safe(p, n,
741 &dev_info->channel_attr_list, l) {
742 list_del(&p->l);
743 iio_device_remove_and_free_read_attr(dev_info, p);
744 }
745 if (dev_info->attrs)
746 sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
847ec80b
JC
747error_ret:
748 return ret;
1d892719 749
847ec80b
JC
750}
751
752static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
753{
1d892719
JC
754
755 struct iio_dev_attr *p, *n;
1b732888
JC
756 if (dev_info->name)
757 sysfs_remove_file_from_group(&dev_info->dev.kobj,
758 &dev_attr_name.attr,
759 NULL);
1d892719
JC
760 list_for_each_entry_safe(p, n, &dev_info->channel_attr_list, l) {
761 list_del(&p->l);
762 iio_device_remove_and_free_read_attr(dev_info, p);
763 }
764
765 if (dev_info->attrs)
766 sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
847ec80b
JC
767}
768
f3cdc285 769/* Return a negative errno on failure */
b156cf70 770int iio_get_new_ida_val(struct ida *this_ida)
847ec80b
JC
771{
772 int ret;
773 int val;
774
b156cf70
JC
775ida_again:
776 if (unlikely(ida_pre_get(this_ida, GFP_KERNEL) == 0))
847ec80b
JC
777 return -ENOMEM;
778
b156cf70
JC
779 spin_lock(&iio_ida_lock);
780 ret = ida_get_new(this_ida, &val);
781 spin_unlock(&iio_ida_lock);
847ec80b 782 if (unlikely(ret == -EAGAIN))
b156cf70 783 goto ida_again;
847ec80b
JC
784 else if (unlikely(ret))
785 return ret;
786
787 return val;
788}
b156cf70 789EXPORT_SYMBOL(iio_get_new_ida_val);
847ec80b 790
b156cf70 791void iio_free_ida_val(struct ida *this_ida, int id)
847ec80b 792{
b156cf70
JC
793 spin_lock(&iio_ida_lock);
794 ida_remove(this_ida, id);
795 spin_unlock(&iio_ida_lock);
847ec80b 796}
b156cf70 797EXPORT_SYMBOL(iio_free_ida_val);
847ec80b
JC
798
799static int iio_device_register_id(struct iio_dev *dev_info,
b156cf70 800 struct ida *this_ida)
847ec80b 801{
b156cf70 802 dev_info->id = iio_get_new_ida_val(&iio_ida);
847ec80b
JC
803 if (dev_info->id < 0)
804 return dev_info->id;
805 return 0;
806}
807
808static void iio_device_unregister_id(struct iio_dev *dev_info)
809{
b156cf70 810 iio_free_ida_val(&iio_ida, dev_info->id);
847ec80b
JC
811}
812
1d892719
JC
813static const char * const iio_ev_type_text[] = {
814 [IIO_EV_TYPE_THRESH] = "thresh",
815 [IIO_EV_TYPE_MAG] = "mag",
816 [IIO_EV_TYPE_ROC] = "roc"
817};
818
819static const char * const iio_ev_dir_text[] = {
820 [IIO_EV_DIR_EITHER] = "either",
821 [IIO_EV_DIR_RISING] = "rising",
822 [IIO_EV_DIR_FALLING] = "falling"
823};
824
825static ssize_t iio_ev_state_store(struct device *dev,
826 struct device_attribute *attr,
827 const char *buf,
828 size_t len)
829{
830 struct iio_dev *indio_dev = dev_get_drvdata(dev);
aaf370db 831 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
1d892719
JC
832 int ret;
833 unsigned long val;
834 ret = strict_strtoul(buf, 10, &val);
835 if (ret || val < 0 || val > 1)
836 return -EINVAL;
837
aaf370db 838 ret = indio_dev->write_event_config(indio_dev, this_attr->address,
1d892719
JC
839 val);
840 return (ret < 0) ? ret : len;
841}
842
843static ssize_t iio_ev_state_show(struct device *dev,
844 struct device_attribute *attr,
845 char *buf)
846{
847 struct iio_dev *indio_dev = dev_get_drvdata(dev);
aaf370db
JC
848 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
849 int val = indio_dev->read_event_config(indio_dev, this_attr->address);
1d892719
JC
850
851 if (val < 0)
852 return val;
853 else
854 return sprintf(buf, "%d\n", val);
855}
856
857static ssize_t iio_ev_value_show(struct device *dev,
858 struct device_attribute *attr,
859 char *buf)
860{
861 struct iio_dev *indio_dev = dev_get_drvdata(dev);
862 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
863 int val, ret;
864
865 ret = indio_dev->read_event_value(indio_dev,
866 this_attr->address, &val);
867 if (ret < 0)
868 return ret;
869
870 return sprintf(buf, "%d\n", val);
871}
872
873static ssize_t iio_ev_value_store(struct device *dev,
874 struct device_attribute *attr,
875 const char *buf,
876 size_t len)
877{
878 struct iio_dev *indio_dev = dev_get_drvdata(dev);
879 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
880 unsigned long val;
881 int ret;
882
883 ret = strict_strtoul(buf, 10, &val);
884 if (ret)
885 return ret;
886
887 ret = indio_dev->write_event_value(indio_dev, this_attr->address,
888 val);
889 if (ret < 0)
890 return ret;
891
892 return len;
893}
894
1d892719
JC
895static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
896 struct iio_chan_spec const *chan)
897{
898
899 int ret = 0, i, mask;
900 char *postfix;
901 if (!chan->event_mask)
902 return 0;
903
904 for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) {
905 postfix = kasprintf(GFP_KERNEL, "%s_%s_en",
906 iio_ev_type_text[i/IIO_EV_TYPE_MAX],
907 iio_ev_dir_text[i%IIO_EV_TYPE_MAX]);
908 if (postfix == NULL) {
909 ret = -ENOMEM;
910 goto error_ret;
911 }
912 switch (chan->type) {
913 /* Switch this to a table at some point */
914 case IIO_IN:
915 mask = IIO_UNMOD_EVENT_CODE(chan->type, chan->channel,
916 i/IIO_EV_TYPE_MAX,
917 i%IIO_EV_TYPE_MAX);
918 break;
919 case IIO_ACCEL:
920 mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel,
921 i/IIO_EV_TYPE_MAX,
922 i%IIO_EV_TYPE_MAX);
923 break;
924 case IIO_IN_DIFF:
925 mask = IIO_MOD_EVENT_CODE(chan->type, chan->channel,
926 chan->channel2,
927 i/IIO_EV_TYPE_MAX,
928 i%IIO_EV_TYPE_MAX);
929 break;
930 default:
931 printk(KERN_INFO "currently unhandled type of event\n");
932 }
aaf370db
JC
933 ret = __iio_add_chan_devattr(postfix,
934 NULL,
935 chan,
936 &iio_ev_state_show,
937 iio_ev_state_store,
938 mask,
939 /*HACK. - limits us to one
940 event interface - fix by
941 extending the bitmask - but
942 how far*/
943 0,
944 &dev_info->event_interfaces[0]
945 .dev,
946 &dev_info->event_interfaces[0].
947 dev_attr_list);
1d892719
JC
948 kfree(postfix);
949 if (ret)
950 goto error_ret;
951
952 postfix = kasprintf(GFP_KERNEL, "%s_%s_value",
953 iio_ev_type_text[i/IIO_EV_TYPE_MAX],
954 iio_ev_dir_text[i%IIO_EV_TYPE_MAX]);
955 if (postfix == NULL) {
956 ret = -ENOMEM;
957 goto error_ret;
958 }
959 ret = __iio_add_chan_devattr(postfix, NULL, chan,
960 iio_ev_value_show,
961 iio_ev_value_store,
962 mask,
963 0,
964 &dev_info->event_interfaces[0]
965 .dev,
966 &dev_info->event_interfaces[0]
967 .dev_attr_list);
968 kfree(postfix);
969 if (ret)
970 goto error_ret;
971
972 }
973
974error_ret:
975 return ret;
976}
977
978static inline void __iio_remove_all_event_sysfs(struct iio_dev *dev_info,
979 const char *groupname,
980 int num)
981{
982 struct iio_dev_attr *p, *n;
1d892719
JC
983 list_for_each_entry_safe(p, n,
984 &dev_info->event_interfaces[num].
985 dev_attr_list, l) {
986 sysfs_remove_file_from_group(&dev_info
987 ->event_interfaces[num].dev.kobj,
988 &p->dev_attr.attr,
989 groupname);
990 kfree(p->dev_attr.attr.name);
991 kfree(p);
992 }
1d892719
JC
993}
994
847ec80b
JC
995static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
996{
1d892719 997 int j;
847ec80b 998 int ret;
847ec80b
JC
999 struct attribute **attrp, **attrq;
1000
1001 if (dev_info->event_conf_attrs && dev_info->event_conf_attrs[i].attrs) {
1002 attrp = dev_info->event_conf_attrs[i].attrs;
1003 while (*attrp) {
1d892719
JC
1004 ret = sysfs_add_file_to_group(&dev_info
1005 ->event_interfaces[0]
1006 .dev.kobj,
847ec80b 1007 *attrp,
1d892719 1008 NULL);
847ec80b
JC
1009 if (ret)
1010 goto error_ret;
1011 attrp++;
1012 }
1013 }
1d892719
JC
1014 INIT_LIST_HEAD(&dev_info->event_interfaces[0].dev_attr_list);
1015 /* Dynically created from the channels array */
1016 if (dev_info->channels) {
1017 for (j = 0; j < dev_info->num_channels; j++) {
1018 ret = iio_device_add_event_sysfs(dev_info,
1019 &dev_info
1020 ->channels[j]);
1021 if (ret)
1022 goto error_clear_attrs;
1023 }
1024 }
847ec80b
JC
1025 return 0;
1026
1d892719
JC
1027error_clear_attrs:
1028 __iio_remove_all_event_sysfs(dev_info,
1029 NULL,
1030 i);
847ec80b
JC
1031error_ret:
1032 attrq = dev_info->event_conf_attrs[i].attrs;
1033 while (attrq != attrp) {
1d892719
JC
1034 sysfs_remove_file_from_group(&dev_info
1035 ->event_interfaces[0]
1036 .dev.kobj,
1037 *attrq,
1038 NULL);
847ec80b
JC
1039 attrq++;
1040 }
1041
1042 return ret;
1043}
1044
1045static inline int __iio_remove_event_config_attrs(struct iio_dev *dev_info,
1046 int i)
1047{
1048 struct attribute **attrq;
1d892719
JC
1049 __iio_remove_all_event_sysfs(dev_info,
1050 NULL,
1051 i);
847ec80b
JC
1052 if (dev_info->event_conf_attrs
1053 && dev_info->event_conf_attrs[i].attrs) {
1054 attrq = dev_info->event_conf_attrs[i].attrs;
1055 while (*attrq) {
1d892719
JC
1056 sysfs_remove_file_from_group(&dev_info
1057 ->event_interfaces[0]
1058 .dev.kobj,
847ec80b 1059 *attrq,
1d892719 1060 NULL);
847ec80b
JC
1061 attrq++;
1062 }
1063 }
1064
1065 return 0;
1066}
1067
1068static int iio_device_register_eventset(struct iio_dev *dev_info)
1069{
1070 int ret = 0, i, j;
1071
1072 if (dev_info->num_interrupt_lines == 0)
1073 return 0;
1074
1075 dev_info->event_interfaces =
1076 kzalloc(sizeof(struct iio_event_interface)
1077 *dev_info->num_interrupt_lines,
1078 GFP_KERNEL);
1079 if (dev_info->event_interfaces == NULL) {
1080 ret = -ENOMEM;
1081 goto error_ret;
1082 }
1083
847ec80b
JC
1084 for (i = 0; i < dev_info->num_interrupt_lines; i++) {
1085 dev_info->event_interfaces[i].owner = dev_info->driver_module;
847ec80b
JC
1086
1087 snprintf(dev_info->event_interfaces[i]._name, 20,
ba5c6fba
JC
1088 "%s:event%d",
1089 dev_name(&dev_info->dev),
3d550fba 1090 i);
847ec80b
JC
1091
1092 ret = iio_setup_ev_int(&dev_info->event_interfaces[i],
1093 (const char *)(dev_info
1094 ->event_interfaces[i]
1095 ._name),
1096 dev_info->driver_module,
1097 &dev_info->dev);
1098 if (ret) {
1099 dev_err(&dev_info->dev,
1100 "Could not get chrdev interface\n");
847ec80b
JC
1101 goto error_free_setup_ev_ints;
1102 }
847ec80b 1103
5cba220b
JC
1104 dev_set_drvdata(&dev_info->event_interfaces[i].dev,
1105 (void *)dev_info);
1d892719
JC
1106
1107 if (dev_info->event_attrs != NULL)
1108 ret = sysfs_create_group(&dev_info
1109 ->event_interfaces[i]
1110 .dev.kobj,
1111 &dev_info->event_attrs[i]);
5cba220b 1112
847ec80b
JC
1113 if (ret) {
1114 dev_err(&dev_info->dev,
1115 "Failed to register sysfs for event attrs");
1116 goto error_remove_sysfs_interfaces;
1117 }
1118 }
1119
1120 for (i = 0; i < dev_info->num_interrupt_lines; i++) {
1121 ret = __iio_add_event_config_attrs(dev_info, i);
1122 if (ret)
1123 goto error_unregister_config_attrs;
1124 }
1125
1126 return 0;
1127
1128error_unregister_config_attrs:
1129 for (j = 0; j < i; j++)
1130 __iio_remove_event_config_attrs(dev_info, i);
1131 i = dev_info->num_interrupt_lines - 1;
1132error_remove_sysfs_interfaces:
1133 for (j = 0; j < i; j++)
1d892719
JC
1134 if (dev_info->event_attrs != NULL)
1135 sysfs_remove_group(&dev_info
5cba220b 1136 ->event_interfaces[j].dev.kobj,
847ec80b 1137 &dev_info->event_attrs[j]);
847ec80b 1138error_free_setup_ev_ints:
3d550fba 1139 for (j = 0; j < i; j++)
847ec80b 1140 iio_free_ev_int(&dev_info->event_interfaces[j]);
847ec80b
JC
1141 kfree(dev_info->event_interfaces);
1142error_ret:
1143
1144 return ret;
1145}
1146
1147static void iio_device_unregister_eventset(struct iio_dev *dev_info)
1148{
1149 int i;
1150
1151 if (dev_info->num_interrupt_lines == 0)
1152 return;
1d892719
JC
1153 for (i = 0; i < dev_info->num_interrupt_lines; i++) {
1154 __iio_remove_event_config_attrs(dev_info, i);
1155 if (dev_info->event_attrs != NULL)
1156 sysfs_remove_group(&dev_info
1157 ->event_interfaces[i].dev.kobj,
1158 &dev_info->event_attrs[i]);
1159 }
847ec80b 1160
3d550fba 1161 for (i = 0; i < dev_info->num_interrupt_lines; i++)
847ec80b 1162 iio_free_ev_int(&dev_info->event_interfaces[i]);
847ec80b
JC
1163 kfree(dev_info->event_interfaces);
1164}
1165
1166static void iio_dev_release(struct device *device)
1167{
1168 struct iio_dev *dev = to_iio_dev(device);
1169
1170 iio_put();
1171 kfree(dev);
1172}
1173
1174static struct device_type iio_dev_type = {
1175 .name = "iio_device",
1176 .release = iio_dev_release,
1177};
1178
6f7c8ee5 1179struct iio_dev *iio_allocate_device(int sizeof_priv)
847ec80b 1180{
6f7c8ee5
JC
1181 struct iio_dev *dev;
1182 size_t alloc_size;
1183
1184 alloc_size = sizeof(struct iio_dev);
1185 if (sizeof_priv) {
1186 alloc_size = ALIGN(alloc_size, IIO_ALIGN);
1187 alloc_size += sizeof_priv;
1188 }
1189 /* ensure 32-byte alignment of whole construct ? */
1190 alloc_size += IIO_ALIGN - 1;
1191
1192 dev = kzalloc(alloc_size, GFP_KERNEL);
847ec80b
JC
1193
1194 if (dev) {
1195 dev->dev.type = &iio_dev_type;
5aaaeba8 1196 dev->dev.bus = &iio_bus_type;
847ec80b
JC
1197 device_initialize(&dev->dev);
1198 dev_set_drvdata(&dev->dev, (void *)dev);
1199 mutex_init(&dev->mlock);
1200 iio_get();
1201 }
1202
1203 return dev;
1204}
1205EXPORT_SYMBOL(iio_allocate_device);
1206
1207void iio_free_device(struct iio_dev *dev)
1208{
1209 if (dev)
1210 iio_put_device(dev);
1211}
1212EXPORT_SYMBOL(iio_free_device);
1213
1214int iio_device_register(struct iio_dev *dev_info)
1215{
1216 int ret;
1217
b156cf70 1218 ret = iio_device_register_id(dev_info, &iio_ida);
847ec80b
JC
1219 if (ret) {
1220 dev_err(&dev_info->dev, "Failed to get id\n");
1221 goto error_ret;
1222 }
1223 dev_set_name(&dev_info->dev, "device%d", dev_info->id);
1224
1225 ret = device_add(&dev_info->dev);
1226 if (ret)
b156cf70 1227 goto error_free_ida;
847ec80b
JC
1228 ret = iio_device_register_sysfs(dev_info);
1229 if (ret) {
1230 dev_err(dev_info->dev.parent,
1231 "Failed to register sysfs interfaces\n");
1232 goto error_del_device;
1233 }
1234 ret = iio_device_register_eventset(dev_info);
1235 if (ret) {
1236 dev_err(dev_info->dev.parent,
c849d253 1237 "Failed to register event set\n");
847ec80b
JC
1238 goto error_free_sysfs;
1239 }
1240 if (dev_info->modes & INDIO_RING_TRIGGERED)
1241 iio_device_register_trigger_consumer(dev_info);
1242
1243 return 0;
1244
1245error_free_sysfs:
1246 iio_device_unregister_sysfs(dev_info);
1247error_del_device:
1248 device_del(&dev_info->dev);
b156cf70 1249error_free_ida:
847ec80b
JC
1250 iio_device_unregister_id(dev_info);
1251error_ret:
1252 return ret;
1253}
1254EXPORT_SYMBOL(iio_device_register);
1255
1256void iio_device_unregister(struct iio_dev *dev_info)
1257{
1258 if (dev_info->modes & INDIO_RING_TRIGGERED)
1259 iio_device_unregister_trigger_consumer(dev_info);
1260 iio_device_unregister_eventset(dev_info);
1261 iio_device_unregister_sysfs(dev_info);
1262 iio_device_unregister_id(dev_info);
1263 device_unregister(&dev_info->dev);
1264}
1265EXPORT_SYMBOL(iio_device_unregister);
1266
1267void iio_put(void)
1268{
1269 module_put(THIS_MODULE);
1270}
1271
1272void iio_get(void)
1273{
1274 __module_get(THIS_MODULE);
1275}
1276
1277subsys_initcall(iio_init);
1278module_exit(iio_exit);
1279
1280MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
1281MODULE_DESCRIPTION("Industrial I/O core");
1282MODULE_LICENSE("GPL");
This page took 0.276777 seconds and 5 git commands to generate.