Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | /**
* 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(indio_dev));
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);
}
|