^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2012 Analog Devices, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Lars-Peter Clausen <lars@metafoo.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/iio/kfifo_buf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * iio_triggered_buffer_setup() - Setup triggered buffer and pollfunc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @indio_dev: IIO device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * @h: Function which will be used as pollfunc top half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * @thread: Function which will be used as pollfunc bottom half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * @setup_ops: Buffer setup functions to use for this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * If NULL the default setup functions for triggered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * buffers will be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * This function combines some common tasks which will normally be performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * when setting up a triggered buffer. It will allocate the buffer and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * pollfunc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Before calling this function the indio_dev structure should already be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * completely initialized, but not yet registered. In practice this means that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * this function should be called right before iio_device_register().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * To free the resources allocated by this function call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * iio_triggered_buffer_cleanup().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) irqreturn_t (*h)(int irq, void *p),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) irqreturn_t (*thread)(int irq, void *p),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) const struct iio_buffer_setup_ops *setup_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct iio_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) buffer = iio_kfifo_allocate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (!buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) iio_device_attach_buffer(indio_dev, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) indio_dev->pollfunc = iio_alloc_pollfunc(h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) "%s_consumer%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) indio_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) indio_dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (indio_dev->pollfunc == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) goto error_kfifo_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Ring buffer functions - here trigger setup related */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) indio_dev->setup_ops = setup_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Flag that polled ring buffering is possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) error_kfifo_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) iio_kfifo_free(indio_dev->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) error_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) EXPORT_SYMBOL(iio_triggered_buffer_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * iio_triggered_buffer_cleanup() - Free resources allocated by iio_triggered_buffer_setup()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @indio_dev: IIO device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) iio_dealloc_pollfunc(indio_dev->pollfunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) iio_kfifo_free(indio_dev->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) EXPORT_SYMBOL(iio_triggered_buffer_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static void devm_iio_triggered_buffer_clean(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) iio_triggered_buffer_cleanup(*(struct iio_dev **)res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int devm_iio_triggered_buffer_setup(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) irqreturn_t (*h)(int irq, void *p),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) irqreturn_t (*thread)(int irq, void *p),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) const struct iio_buffer_setup_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct iio_dev **ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ptr = devres_alloc(devm_iio_triggered_buffer_clean, sizeof(*ptr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (!ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *ptr = indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ret = iio_triggered_buffer_setup(indio_dev, h, thread, ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) devres_add(dev, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) devres_free(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) EXPORT_SYMBOL_GPL(devm_iio_triggered_buffer_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) MODULE_DESCRIPTION("IIO helper functions for setting up triggered buffers");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) MODULE_LICENSE("GPL");