Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002  /*
0003  * Copyright (c) 2012 Analog Devices, Inc.
0004  *  Author: Lars-Peter Clausen <lars@metafoo.de>
0005  */
0006 
0007 #include <linux/kernel.h>
0008 #include <linux/export.h>
0009 #include <linux/module.h>
0010 #include <linux/iio/iio.h>
0011 #include <linux/iio/buffer.h>
0012 #include <linux/iio/buffer_impl.h>
0013 #include <linux/iio/kfifo_buf.h>
0014 #include <linux/iio/triggered_buffer.h>
0015 #include <linux/iio/trigger_consumer.h>
0016 
0017 /**
0018  * iio_triggered_buffer_setup_ext() - Setup triggered buffer and pollfunc
0019  * @indio_dev:      IIO device structure
0020  * @h:          Function which will be used as pollfunc top half
0021  * @thread:     Function which will be used as pollfunc bottom half
0022  * @direction:      Direction of the data stream (in/out).
0023  * @setup_ops:      Buffer setup functions to use for this device.
0024  *          If NULL the default setup functions for triggered
0025  *          buffers will be used.
0026  * @buffer_attrs:   Extra sysfs buffer attributes for this IIO buffer
0027  *
0028  * This function combines some common tasks which will normally be performed
0029  * when setting up a triggered buffer. It will allocate the buffer and the
0030  * pollfunc.
0031  *
0032  * Before calling this function the indio_dev structure should already be
0033  * completely initialized, but not yet registered. In practice this means that
0034  * this function should be called right before iio_device_register().
0035  *
0036  * To free the resources allocated by this function call
0037  * iio_triggered_buffer_cleanup().
0038  */
0039 int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev,
0040     irqreturn_t (*h)(int irq, void *p),
0041     irqreturn_t (*thread)(int irq, void *p),
0042     enum iio_buffer_direction direction,
0043     const struct iio_buffer_setup_ops *setup_ops,
0044     const struct attribute **buffer_attrs)
0045 {
0046     struct iio_buffer *buffer;
0047     int ret;
0048 
0049     buffer = iio_kfifo_allocate();
0050     if (!buffer) {
0051         ret = -ENOMEM;
0052         goto error_ret;
0053     }
0054 
0055     indio_dev->pollfunc = iio_alloc_pollfunc(h,
0056                          thread,
0057                          IRQF_ONESHOT,
0058                          indio_dev,
0059                          "%s_consumer%d",
0060                          indio_dev->name,
0061                          iio_device_id(indio_dev));
0062     if (indio_dev->pollfunc == NULL) {
0063         ret = -ENOMEM;
0064         goto error_kfifo_free;
0065     }
0066 
0067     /* Ring buffer functions - here trigger setup related */
0068     indio_dev->setup_ops = setup_ops;
0069 
0070     /* Flag that polled ring buffering is possible */
0071     indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
0072 
0073     buffer->direction = direction;
0074     buffer->attrs = buffer_attrs;
0075 
0076     ret = iio_device_attach_buffer(indio_dev, buffer);
0077     if (ret < 0)
0078         goto error_dealloc_pollfunc;
0079 
0080     return 0;
0081 
0082 error_dealloc_pollfunc:
0083     iio_dealloc_pollfunc(indio_dev->pollfunc);
0084 error_kfifo_free:
0085     iio_kfifo_free(buffer);
0086 error_ret:
0087     return ret;
0088 }
0089 EXPORT_SYMBOL(iio_triggered_buffer_setup_ext);
0090 
0091 /**
0092  * iio_triggered_buffer_cleanup() - Free resources allocated by iio_triggered_buffer_setup_ext()
0093  * @indio_dev: IIO device structure
0094  */
0095 void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev)
0096 {
0097     iio_dealloc_pollfunc(indio_dev->pollfunc);
0098     iio_kfifo_free(indio_dev->buffer);
0099 }
0100 EXPORT_SYMBOL(iio_triggered_buffer_cleanup);
0101 
0102 static void devm_iio_triggered_buffer_clean(void *indio_dev)
0103 {
0104     iio_triggered_buffer_cleanup(indio_dev);
0105 }
0106 
0107 int devm_iio_triggered_buffer_setup_ext(struct device *dev,
0108                     struct iio_dev *indio_dev,
0109                     irqreturn_t (*h)(int irq, void *p),
0110                     irqreturn_t (*thread)(int irq, void *p),
0111                     enum iio_buffer_direction direction,
0112                     const struct iio_buffer_setup_ops *ops,
0113                     const struct attribute **buffer_attrs)
0114 {
0115     int ret;
0116 
0117     ret = iio_triggered_buffer_setup_ext(indio_dev, h, thread, direction,
0118                          ops, buffer_attrs);
0119     if (ret)
0120         return ret;
0121 
0122     return devm_add_action_or_reset(dev, devm_iio_triggered_buffer_clean,
0123                     indio_dev);
0124 }
0125 EXPORT_SYMBOL_GPL(devm_iio_triggered_buffer_setup_ext);
0126 
0127 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
0128 MODULE_DESCRIPTION("IIO helper functions for setting up triggered buffers");
0129 MODULE_LICENSE("GPL");