Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 1 | /** |
| 2 | * Copyright (c) 2011 Jonathan Cameron |
| 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify it |
| 5 | * under the terms of the GNU General Public License version 2 as published by |
| 6 | * the Free Software Foundation. |
| 7 | * |
| 8 | * Buffer handling elements of industrial I/O reference driver. |
| 9 | * Uses the kfifo buffer. |
| 10 | * |
| 11 | * To test without hardware use the sysfs trigger. |
| 12 | */ |
| 13 | |
| 14 | #include <linux/kernel.h> |
Paul Gortmaker | 8e336a7 | 2011-07-10 13:09:12 -0400 | [diff] [blame] | 15 | #include <linux/export.h> |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 16 | #include <linux/slab.h> |
| 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/irq.h> |
| 19 | #include <linux/bitmap.h> |
| 20 | |
Jonathan Cameron | 06458e2 | 2012-04-25 15:54:58 +0100 | [diff] [blame] | 21 | #include <linux/iio/iio.h> |
| 22 | #include <linux/iio/trigger_consumer.h> |
| 23 | #include <linux/iio/kfifo_buf.h> |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 24 | |
| 25 | #include "iio_simple_dummy.h" |
| 26 | |
| 27 | /* Some fake data */ |
| 28 | |
| 29 | static const s16 fakedata[] = { |
| 30 | [voltage0] = 7, |
| 31 | [diffvoltage1m2] = -33, |
| 32 | [diffvoltage3m4] = -2, |
| 33 | [accelx] = 344, |
| 34 | }; |
| 35 | /** |
| 36 | * iio_simple_dummy_trigger_h() - the trigger handler function |
| 37 | * @irq: the interrupt number |
| 38 | * @p: private data - always a pointer to the poll func. |
| 39 | * |
Masanari Iida | 99de0c2 | 2012-05-09 03:18:17 +0900 | [diff] [blame] | 40 | * This is the guts of buffered capture. On a trigger event occurring, |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 41 | * if the pollfunc is attached then this handler is called as a threaded |
| 42 | * interrupt (and hence may sleep). It is responsible for grabbing data |
| 43 | * from the device and pushing it into the associated buffer. |
| 44 | */ |
| 45 | static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) |
| 46 | { |
| 47 | struct iio_poll_func *pf = p; |
| 48 | struct iio_dev *indio_dev = pf->indio_dev; |
| 49 | struct iio_buffer *buffer = indio_dev->buffer; |
| 50 | int len = 0; |
Jonathan Cameron | 420fe2e | 2012-04-21 10:09:35 +0100 | [diff] [blame] | 51 | u16 *data; |
| 52 | |
| 53 | data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 54 | if (data == NULL) |
Lars-Peter Clausen | a1bdeef | 2012-07-04 17:09:00 +0100 | [diff] [blame] | 55 | goto done; |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 56 | |
Jonathan Cameron | 550268ca | 2011-12-05 22:18:15 +0000 | [diff] [blame] | 57 | if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) { |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 58 | /* |
| 59 | * Three common options here: |
| 60 | * hardware scans: certain combinations of channels make |
| 61 | * up a fast read. The capture will consist of all of them. |
| 62 | * Hence we just call the grab data function and fill the |
| 63 | * buffer without processing. |
Masanari Iida | 99de0c2 | 2012-05-09 03:18:17 +0900 | [diff] [blame] | 64 | * software scans: can be considered to be random access |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 65 | * so efficient reading is just a case of minimal bus |
| 66 | * transactions. |
| 67 | * software culled hardware scans: |
| 68 | * occasionally a driver may process the nearest hardware |
| 69 | * scan to avoid storing elements that are not desired. This |
Peter Meerwald | 25c38aa | 2012-06-15 19:27:10 +0200 | [diff] [blame] | 70 | * is the fiddliest option by far. |
| 71 | * Here let's pretend we have random access. And the values are |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 72 | * in the constant table fakedata. |
| 73 | */ |
| 74 | int i, j; |
Jonathan Cameron | 550268ca | 2011-12-05 22:18:15 +0000 | [diff] [blame] | 75 | for (i = 0, j = 0; |
| 76 | i < bitmap_weight(indio_dev->active_scan_mask, |
| 77 | indio_dev->masklength); |
Peter Meerwald | 708706f | 2012-06-22 09:47:41 +0200 | [diff] [blame] | 78 | i++, j++) { |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 79 | j = find_next_bit(buffer->scan_mask, |
Peter Meerwald | 708706f | 2012-06-22 09:47:41 +0200 | [diff] [blame] | 80 | indio_dev->masklength, j); |
Peter Meerwald | d163a19 | 2012-06-18 20:33:04 +0200 | [diff] [blame] | 81 | /* random access read from the 'device' */ |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 82 | data[i] = fakedata[j]; |
| 83 | len += 2; |
| 84 | } |
| 85 | } |
Peter Meerwald | 8b32b11 | 2012-06-22 09:47:43 +0200 | [diff] [blame] | 86 | /* Store the timestamp at an 8 byte aligned offset */ |
Jonathan Cameron | fd6487f | 2012-04-21 10:09:44 +0100 | [diff] [blame] | 87 | if (indio_dev->scan_timestamp) |
Peter Meerwald | be344c8 | 2012-07-14 17:23:00 +0100 | [diff] [blame] | 88 | *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64))) |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 89 | = iio_get_time_ns(); |
Lars-Peter Clausen | ce56ade | 2012-09-04 13:38:00 +0100 | [diff] [blame] | 90 | iio_push_to_buffer(buffer, (u8 *)data); |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 91 | |
| 92 | kfree(data); |
| 93 | |
Lars-Peter Clausen | a1bdeef | 2012-07-04 17:09:00 +0100 | [diff] [blame] | 94 | done: |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 95 | /* |
| 96 | * Tell the core we are done with this trigger and ready for the |
| 97 | * next one. |
| 98 | */ |
| 99 | iio_trigger_notify_done(indio_dev->trig); |
| 100 | |
| 101 | return IRQ_HANDLED; |
| 102 | } |
| 103 | |
| 104 | static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = { |
| 105 | /* |
| 106 | * iio_sw_buffer_preenable: |
| 107 | * Generic function for equal sized ring elements + 64 bit timestamp |
| 108 | * Assumes that any combination of channels can be enabled. |
| 109 | * Typically replaced to implement restrictions on what combinations |
| 110 | * can be captured (hardware scan modes). |
| 111 | */ |
| 112 | .preenable = &iio_sw_buffer_preenable, |
| 113 | /* |
| 114 | * iio_triggered_buffer_postenable: |
| 115 | * Generic function that simply attaches the pollfunc to the trigger. |
| 116 | * Replace this to mess with hardware state before we attach the |
| 117 | * trigger. |
| 118 | */ |
| 119 | .postenable = &iio_triggered_buffer_postenable, |
| 120 | /* |
| 121 | * iio_triggered_buffer_predisable: |
| 122 | * Generic function that simple detaches the pollfunc from the trigger. |
| 123 | * Replace this to put hardware state back again after the trigger is |
| 124 | * detached but before userspace knows we have disabled the ring. |
| 125 | */ |
| 126 | .predisable = &iio_triggered_buffer_predisable, |
| 127 | }; |
| 128 | |
Lars-Peter Clausen | 3fff227 | 2012-09-12 12:06:00 +0100 | [diff] [blame] | 129 | int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev, |
| 130 | const struct iio_chan_spec *channels, unsigned int num_channels) |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 131 | { |
| 132 | int ret; |
| 133 | struct iio_buffer *buffer; |
| 134 | |
| 135 | /* Allocate a buffer to use - here a kfifo */ |
| 136 | buffer = iio_kfifo_allocate(indio_dev); |
| 137 | if (buffer == NULL) { |
| 138 | ret = -ENOMEM; |
| 139 | goto error_ret; |
| 140 | } |
| 141 | |
| 142 | indio_dev->buffer = buffer; |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 143 | |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 144 | /* Enable timestamps by default */ |
| 145 | buffer->scan_timestamp = true; |
| 146 | |
| 147 | /* |
| 148 | * Tell the core what device type specific functions should |
| 149 | * be run on either side of buffer capture enable / disable. |
| 150 | */ |
Jonathan Cameron | 1612244 | 2011-12-05 22:18:14 +0000 | [diff] [blame] | 151 | indio_dev->setup_ops = &iio_simple_dummy_buffer_setup_ops; |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 152 | |
| 153 | /* |
| 154 | * Configure a polling function. |
| 155 | * When a trigger event with this polling function connected |
| 156 | * occurs, this function is run. Typically this grabs data |
| 157 | * from the device. |
| 158 | * |
| 159 | * NULL for the top half. This is normally implemented only if we |
| 160 | * either want to ping a capture now pin (no sleeping) or grab |
| 161 | * a timestamp as close as possible to a data ready trigger firing. |
| 162 | * |
| 163 | * IRQF_ONESHOT ensures irqs are masked such that only one instance |
| 164 | * of the handler can run at a time. |
| 165 | * |
| 166 | * "iio_simple_dummy_consumer%d" formatting string for the irq 'name' |
| 167 | * as seen under /proc/interrupts. Remaining parameters as per printk. |
| 168 | */ |
| 169 | indio_dev->pollfunc = iio_alloc_pollfunc(NULL, |
| 170 | &iio_simple_dummy_trigger_h, |
| 171 | IRQF_ONESHOT, |
| 172 | indio_dev, |
| 173 | "iio_simple_dummy_consumer%d", |
| 174 | indio_dev->id); |
| 175 | |
| 176 | if (indio_dev->pollfunc == NULL) { |
| 177 | ret = -ENOMEM; |
| 178 | goto error_free_buffer; |
| 179 | } |
| 180 | |
| 181 | /* |
| 182 | * Notify the core that this device is capable of buffered capture |
| 183 | * driven by a trigger. |
| 184 | */ |
| 185 | indio_dev->modes |= INDIO_BUFFER_TRIGGERED; |
Lars-Peter Clausen | 3fff227 | 2012-09-12 12:06:00 +0100 | [diff] [blame] | 186 | |
| 187 | ret = iio_buffer_register(indio_dev, channels, num_channels); |
| 188 | if (ret) |
| 189 | goto error_dealloc_pollfunc; |
| 190 | |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 191 | return 0; |
| 192 | |
Lars-Peter Clausen | 3fff227 | 2012-09-12 12:06:00 +0100 | [diff] [blame] | 193 | error_dealloc_pollfunc: |
| 194 | iio_dealloc_pollfunc(indio_dev->pollfunc); |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 195 | error_free_buffer: |
| 196 | iio_kfifo_free(indio_dev->buffer); |
| 197 | error_ret: |
| 198 | return ret; |
| 199 | |
| 200 | } |
| 201 | |
| 202 | /** |
| 203 | * iio_simple_dummy_unconfigure_buffer() - release buffer resources |
| 204 | * @indo_dev: device instance state |
| 205 | */ |
| 206 | void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev) |
| 207 | { |
Lars-Peter Clausen | 3fff227 | 2012-09-12 12:06:00 +0100 | [diff] [blame] | 208 | iio_buffer_unregister(indio_dev); |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 209 | iio_dealloc_pollfunc(indio_dev->pollfunc); |
| 210 | iio_kfifo_free(indio_dev->buffer); |
| 211 | } |