summaryrefslogtreecommitdiffstats
path: root/drivers/iio/dummy/iio_simple_dummy_buffer.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman2015-12-01 18:13:29 +0100
committerGreg Kroah-Hartman2015-12-01 18:13:29 +0100
commitf3cf3fb7ec854c2b2429e5bb23186746e6511dae (patch)
treeb4e71d2a6422ca33a95f9a1e0458ab90c3b89846 /drivers/iio/dummy/iio_simple_dummy_buffer.c
parentstaging: unisys: better config switch comments (diff)
parentiio: pulsedlight-lidar-lite: add runtime PM (diff)
downloadkernel-qcow2-linux-f3cf3fb7ec854c2b2429e5bb23186746e6511dae.tar.gz
kernel-qcow2-linux-f3cf3fb7ec854c2b2429e5bb23186746e6511dae.tar.xz
kernel-qcow2-linux-f3cf3fb7ec854c2b2429e5bb23186746e6511dae.zip
Merge tag 'iio-for-4.5a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes: First set of new device support, features and cleanups for IIO in the 4.5 cycle Usual mixed bag, but the big item perhaps in this series is the DMA buffer support added by Lars-Peter Clausen. It's been in the works for a long time and it will be interesting to see what hardware support shows up now that this is available. New core features + associate cleanup. * Add generic DMA buffer infrastructure * Add a DMAengine framework based buffer Also associated minor changes. - Set the device buffer watermark based on the minimum watermark for all attached buffers rather than just the 'primary' one. - iio_buffer_init - only set the watermark default if one hasn't already been provided. This allows simple support for devices with a fixed watermark. - read only attribute for watermark on fixed watermark devices. - add explicit buffer enable/disable callbacks to allow the buffer to do more than trivial actions when it is being turned on and off. * IIO_VAL_INT support in write_raw_get_fmt function. New device support * Freescale MMA7455/7456L accelerometers * Memsic MXC6255XC accelerometer * ST lis2dh12 accelerometer * TI ADS8688 ADC * TI Palamas (twl6035/7) gpadc New driver features * mma8452 - support either of the available interrupt pins to cope with the case where board layout has lead to a particular one being connected. Staging graduation * Dummy driver - this driver acts as both an example and a test device for those with out hardware to develop userspace code against. Cleanups and minor bits and bobs. * treewide - Sort out the ordering of iio_device_register/unregister vs runtime pm function calls so that it's all nice and consistent and not race prone. - Check sscanf return values. None of the cases will actually happen as the strings are supplied internally, but best to be consistent on this. * ad7780 - switch over to the gpio descriptor interface and remove the now unused platform data which gets rid of a header entirely. * ad7793 - drop a pointless else statement. * at91_adc - Swap kmalloc_array in for a kmalloc doing the same job. * dummy - get rid of some commented out lines that snuck in during the move of the driver. * lm3533-als - Print an error message on provision of an invalid resistance. * mcp320x - Add compatible strings with vendor prefix and deprecate those with no vendor prefix. * mxs-lradc - Use BIT macro in various places rather than shifted ones. * pa12203001 - Power off the chip if the registration fails. * pulsedlight-lidar-lite - add runtime PM support. * xilinx XADC - constify an iio_buffer_setup_ops structure.
Diffstat (limited to 'drivers/iio/dummy/iio_simple_dummy_buffer.c')
-rw-r--r--drivers/iio/dummy/iio_simple_dummy_buffer.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/drivers/iio/dummy/iio_simple_dummy_buffer.c b/drivers/iio/dummy/iio_simple_dummy_buffer.c
new file mode 100644
index 000000000000..cf44a6f79431
--- /dev/null
+++ b/drivers/iio/dummy/iio_simple_dummy_buffer.c
@@ -0,0 +1,192 @@
+/**
+ * Copyright (c) 2011 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.
+ *
+ * Buffer handling elements of industrial I/O reference driver.
+ * Uses the kfifo buffer.
+ *
+ * To test without hardware use the sysfs trigger.
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/bitmap.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/kfifo_buf.h>
+
+#include "iio_simple_dummy.h"
+
+/* Some fake data */
+
+static const s16 fakedata[] = {
+ [DUMMY_INDEX_VOLTAGE_0] = 7,
+ [DUMMY_INDEX_DIFFVOLTAGE_1M2] = -33,
+ [DUMMY_INDEX_DIFFVOLTAGE_3M4] = -2,
+ [DUMMY_INDEX_ACCELX] = 344,
+};
+
+/**
+ * iio_simple_dummy_trigger_h() - the trigger handler function
+ * @irq: the interrupt number
+ * @p: private data - always a pointer to the poll func.
+ *
+ * This is the guts of buffered capture. On a trigger event occurring,
+ * if the pollfunc is attached then this handler is called as a threaded
+ * interrupt (and hence may sleep). It is responsible for grabbing data
+ * from the device and pushing it into the associated buffer.
+ */
+static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ int len = 0;
+ u16 *data;
+
+ data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+ if (!data)
+ goto done;
+
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) {
+ /*
+ * Three common options here:
+ * hardware scans: certain combinations of channels make
+ * up a fast read. The capture will consist of all of them.
+ * Hence we just call the grab data function and fill the
+ * buffer without processing.
+ * software scans: can be considered to be random access
+ * so efficient reading is just a case of minimal bus
+ * transactions.
+ * software culled hardware scans:
+ * occasionally a driver may process the nearest hardware
+ * scan to avoid storing elements that are not desired. This
+ * is the fiddliest option by far.
+ * Here let's pretend we have random access. And the values are
+ * in the constant table fakedata.
+ */
+ int i, j;
+
+ for (i = 0, j = 0;
+ i < bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength);
+ i++, j++) {
+ j = find_next_bit(indio_dev->active_scan_mask,
+ indio_dev->masklength, j);
+ /* random access read from the 'device' */
+ data[i] = fakedata[j];
+ len += 2;
+ }
+ }
+
+ iio_push_to_buffers_with_timestamp(indio_dev, data, iio_get_time_ns());
+
+ kfree(data);
+
+done:
+ /*
+ * Tell the core we are done with this trigger and ready for the
+ * next one.
+ */
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
+ /*
+ * iio_triggered_buffer_postenable:
+ * Generic function that simply attaches the pollfunc to the trigger.
+ * Replace this to mess with hardware state before we attach the
+ * trigger.
+ */
+ .postenable = &iio_triggered_buffer_postenable,
+ /*
+ * iio_triggered_buffer_predisable:
+ * Generic function that simple detaches the pollfunc from the trigger.
+ * Replace this to put hardware state back again after the trigger is
+ * detached but before userspace knows we have disabled the ring.
+ */
+ .predisable = &iio_triggered_buffer_predisable,
+};
+
+int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
+{
+ int ret;
+ struct iio_buffer *buffer;
+
+ /* Allocate a buffer to use - here a kfifo */
+ buffer = iio_kfifo_allocate();
+ if (!buffer) {
+ ret = -ENOMEM;
+ goto error_ret;
+ }
+
+ iio_device_attach_buffer(indio_dev, buffer);
+
+ /* Enable timestamps by default */
+ buffer->scan_timestamp = true;
+
+ /*
+ * Tell the core what device type specific functions should
+ * be run on either side of buffer capture enable / disable.
+ */
+ indio_dev->setup_ops = &iio_simple_dummy_buffer_setup_ops;
+
+ /*
+ * Configure a polling function.
+ * When a trigger event with this polling function connected
+ * occurs, this function is run. Typically this grabs data
+ * from the device.
+ *
+ * NULL for the bottom half. This is normally implemented only if we
+ * either want to ping a capture now pin (no sleeping) or grab
+ * a timestamp as close as possible to a data ready trigger firing.
+ *
+ * IRQF_ONESHOT ensures irqs are masked such that only one instance
+ * of the handler can run at a time.
+ *
+ * "iio_simple_dummy_consumer%d" formatting string for the irq 'name'
+ * as seen under /proc/interrupts. Remaining parameters as per printk.
+ */
+ indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
+ &iio_simple_dummy_trigger_h,
+ IRQF_ONESHOT,
+ indio_dev,
+ "iio_simple_dummy_consumer%d",
+ indio_dev->id);
+
+ if (!indio_dev->pollfunc) {
+ ret = -ENOMEM;
+ goto error_free_buffer;
+ }
+
+ /*
+ * Notify the core that this device is capable of buffered capture
+ * driven by a trigger.
+ */
+ indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
+
+ return 0;
+
+error_free_buffer:
+ iio_kfifo_free(indio_dev->buffer);
+error_ret:
+ return ret;
+}
+
+/**
+ * iio_simple_dummy_unconfigure_buffer() - release buffer resources
+ * @indo_dev: device instance state
+ */
+void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
+{
+ iio_dealloc_pollfunc(indio_dev->pollfunc);
+ iio_kfifo_free(indio_dev->buffer);
+}