summaryrefslogtreecommitdiff
path: root/drivers/staging/iio/ring_sw.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/iio/ring_sw.h')
-rw-r--r--drivers/staging/iio/ring_sw.h189
1 files changed, 189 insertions, 0 deletions
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
new file mode 100644
index 000000000000..ae70ee0538fb
--- /dev/null
+++ b/drivers/staging/iio/ring_sw.h
@@ -0,0 +1,189 @@
+/* The industrial I/O simple minimally locked ring buffer.
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This code is deliberately kept separate from the main industrialio I/O core
+ * as it is intended that in the future a number of different software ring
+ * buffer implementations will exist with different characteristics to suit
+ * different applications.
+ *
+ * This particular one was designed for a data capture application where it was
+ * particularly important that no userspace reads would interrupt the capture
+ * process. To this end the ring is not locked during a read.
+ *
+ * Comments on this buffer design welcomed. It's far from efficient and some of
+ * my understanding of the effects of scheduling on this are somewhat limited.
+ * Frankly, to my mind, this is the current weak point in the industrial I/O
+ * patch set.
+ */
+
+#ifndef _IIO_RING_SW_H_
+#define _IIO_RING_SW_H_
+/* NEEDS COMMENTS */
+/* The intention is that this should be a separate module from the iio core.
+ * This is a bit like supporting algorithms dependent on what the device
+ * driver requests - some may support multiple options */
+
+
+#include <linux/autoconf.h>
+#include "iio.h"
+#include "ring_generic.h"
+
+#if defined CONFIG_IIO_SW_RING || defined CONFIG_IIO_SW_RING_MODULE
+
+/**
+ * iio_create_sw_rb() software ring buffer allocation
+ * @r: pointer to ring buffer pointer
+ **/
+int iio_create_sw_rb(struct iio_ring_buffer **r);
+
+/**
+ * iio_init_sw_rb() initialize the software ring buffer
+ * @r: pointer to a software ring buffer created by an
+ * iio_create_sw_rb call.
+ **/
+int iio_init_sw_rb(struct iio_ring_buffer *r, struct iio_dev *indio_dev);
+/**
+ * iio_exit_sw_rb() reverse what was done in iio_init_sw_rb
+ **/
+void iio_exit_sw_rb(struct iio_ring_buffer *r);
+
+/**
+ * iio_free_sw_rb() free memory occupied by the core ring buffer struct
+ **/
+void iio_free_sw_rb(struct iio_ring_buffer *r);
+
+/**
+ * iio_mark_sw_rb_in_use() reference counting to prevent incorrect chances
+ **/
+void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r);
+
+/**
+ * iio_unmark_sw_rb_in_use() notify the ring buffer that we don't care anymore
+ **/
+void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r);
+
+/**
+ * iio_read_last_from_sw_rb() attempt to read the last stored datum from the rb
+ **/
+int iio_read_last_from_sw_rb(struct iio_ring_buffer *r, u8 *data);
+
+/**
+ * iio_store_to_sw_rb() store a new datum to the ring buffer
+ * @rb: pointer to ring buffer instance
+ * @data: the datum to be stored including timestamp if relevant.
+ * @timestamp: timestamp which will be attached to buffer events if relevant.
+ **/
+int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp);
+
+/**
+ * iio_rip_sw_rb() attempt to read data from the ring buffer
+ * @r: ring buffer instance
+ * @count: number of datum's to try and read
+ * @data: where the data will be stored.
+ * @dead_offset: how much of the stored data was possibly invalidated by
+ * the end of the copy.
+ **/
+int iio_rip_sw_rb(struct iio_ring_buffer *r,
+ size_t count,
+ u8 **data,
+ int *dead_offset);
+
+/**
+ * iio_request_update_sw_rb() update params if update needed
+ **/
+int iio_request_update_sw_rb(struct iio_ring_buffer *r);
+
+/**
+ * iio_mark_update_needed_sw_rb() tell the ring buffer it needs a param update
+ **/
+int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r);
+
+
+/**
+ * iio_get_bpd_sw_rb() get the datum size in bytes
+ **/
+int iio_get_bpd_sw_rb(struct iio_ring_buffer *r);
+
+/**
+ * iio_set_bpd_sw_rb() set the datum size in bytes
+ **/
+int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd);
+
+/**
+ * iio_get_length_sw_rb() get how many datums the rb may contain
+ **/
+int iio_get_length_sw_rb(struct iio_ring_buffer *r);
+
+/**
+ * iio_set_length_sw_rb() set how many datums the rb may contain
+ **/
+int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length);
+
+/**
+ * iio_ring_sw_register_funcs() helper function to set up rb access
+ **/
+static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
+{
+ ra->mark_in_use = &iio_mark_sw_rb_in_use;
+ ra->unmark_in_use = &iio_unmark_sw_rb_in_use;
+
+ ra->store_to = &iio_store_to_sw_rb;
+ ra->read_last = &iio_read_last_from_sw_rb;
+ ra->rip_lots = &iio_rip_sw_rb;
+
+ ra->mark_param_change = &iio_mark_update_needed_sw_rb;
+ ra->request_update = &iio_request_update_sw_rb;
+
+ ra->get_bpd = &iio_get_bpd_sw_rb;
+ ra->set_bpd = &iio_set_bpd_sw_rb;
+
+ ra->get_length = &iio_get_length_sw_rb;
+ ra->set_length = &iio_set_length_sw_rb;
+};
+
+/**
+ * struct iio_sw_ring_buffer - software ring buffer
+ * @buf: generic ring buffer elements
+ * @data: the ring buffer memory
+ * @read_p: read pointer (oldest available)
+ * @write_p: write pointer
+ * @last_written_p: read pointer (newest available)
+ * @half_p: half buffer length behind write_p (event generation)
+ * @use_count: reference count to prevent resizing when in use
+ * @update_needed: flag to indicated change in size requested
+ * @use_lock: lock to prevent change in size when in use
+ *
+ * Note that the first element of all ring buffers must be a
+ * struct iio_ring_buffer.
+**/
+
+struct iio_sw_ring_buffer {
+ struct iio_ring_buffer buf;
+ unsigned char *data;
+ unsigned char *read_p;
+ unsigned char *write_p;
+ unsigned char *last_written_p;
+ /* used to act as a point at which to signal an event */
+ unsigned char *half_p;
+ int use_count;
+ int update_needed;
+ spinlock_t use_lock;
+};
+
+#define iio_to_sw_ring(r) container_of(r, struct iio_sw_ring_buffer, buf)
+
+struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
+void iio_sw_rb_free(struct iio_ring_buffer *ring);
+
+
+
+#else /* CONFIG_IIO_RING_BUFFER*/
+static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
+{};
+#endif /* !CONFIG_IIO_RING_BUFFER */
+#endif /* _IIO_RING_SW_H_ */