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