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[] = { |
Alison Schofield | f8087ab | 2015-10-26 13:48:23 -0700 | [diff] [blame] | 30 | [DUMMY_INDEX_VOLTAGE_0] = 7, |
| 31 | [DUMMY_INDEX_DIFFVOLTAGE_1M2] = -33, |
| 32 | [DUMMY_INDEX_DIFFVOLTAGE_3M4] = -2, |
| 33 | [DUMMY_INDEX_ACCELX] = 344, |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 34 | }; |
Cristina Opriceana | 862cb6c | 2015-07-10 17:10:21 +0300 | [diff] [blame] | 35 | |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 36 | /** |
| 37 | * iio_simple_dummy_trigger_h() - the trigger handler function |
| 38 | * @irq: the interrupt number |
| 39 | * @p: private data - always a pointer to the poll func. |
| 40 | * |
Masanari Iida | 99de0c2 | 2012-05-09 03:18:17 +0900 | [diff] [blame] | 41 | * This is the guts of buffered capture. On a trigger event occurring, |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 42 | * if the pollfunc is attached then this handler is called as a threaded |
| 43 | * interrupt (and hence may sleep). It is responsible for grabbing data |
| 44 | * from the device and pushing it into the associated buffer. |
| 45 | */ |
| 46 | static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) |
| 47 | { |
| 48 | struct iio_poll_func *pf = p; |
| 49 | struct iio_dev *indio_dev = pf->indio_dev; |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 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); |
Cristina Opriceana | 8f94c31 | 2015-03-31 12:51:38 +0300 | [diff] [blame] | 54 | if (!data) |
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; |
Catalina Mocanu | 4b4c727 | 2014-09-18 14:55:06 -0700 | [diff] [blame] | 75 | |
Jonathan Cameron | 550268ca | 2011-12-05 22:18:15 +0000 | [diff] [blame] | 76 | for (i = 0, j = 0; |
| 77 | i < bitmap_weight(indio_dev->active_scan_mask, |
| 78 | indio_dev->masklength); |
Peter Meerwald | 708706f | 2012-06-22 09:47:41 +0200 | [diff] [blame] | 79 | i++, j++) { |
Jonathan Cameron | 84b36ce | 2012-06-30 20:06:00 +0100 | [diff] [blame] | 80 | j = find_next_bit(indio_dev->active_scan_mask, |
Peter Meerwald | 708706f | 2012-06-22 09:47:41 +0200 | [diff] [blame] | 81 | indio_dev->masklength, j); |
Peter Meerwald | d163a19 | 2012-06-18 20:33:04 +0200 | [diff] [blame] | 82 | /* random access read from the 'device' */ |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 83 | data[i] = fakedata[j]; |
| 84 | len += 2; |
| 85 | } |
| 86 | } |
Lars-Peter Clausen | 09a799d | 2013-09-19 14:00:00 +0100 | [diff] [blame] | 87 | |
| 88 | iio_push_to_buffers_with_timestamp(indio_dev, data, iio_get_time_ns()); |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 89 | |
| 90 | kfree(data); |
| 91 | |
Lars-Peter Clausen | a1bdeef | 2012-07-04 17:09:00 +0100 | [diff] [blame] | 92 | done: |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 93 | /* |
| 94 | * Tell the core we are done with this trigger and ready for the |
| 95 | * next one. |
| 96 | */ |
| 97 | iio_trigger_notify_done(indio_dev->trig); |
| 98 | |
| 99 | return IRQ_HANDLED; |
| 100 | } |
| 101 | |
| 102 | static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = { |
| 103 | /* |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 104 | * iio_triggered_buffer_postenable: |
| 105 | * Generic function that simply attaches the pollfunc to the trigger. |
| 106 | * Replace this to mess with hardware state before we attach the |
| 107 | * trigger. |
| 108 | */ |
| 109 | .postenable = &iio_triggered_buffer_postenable, |
| 110 | /* |
| 111 | * iio_triggered_buffer_predisable: |
| 112 | * Generic function that simple detaches the pollfunc from the trigger. |
| 113 | * Replace this to put hardware state back again after the trigger is |
| 114 | * detached but before userspace knows we have disabled the ring. |
| 115 | */ |
| 116 | .predisable = &iio_triggered_buffer_predisable, |
| 117 | }; |
| 118 | |
Lars-Peter Clausen | 4ae0301 | 2014-11-26 18:55:11 +0100 | [diff] [blame] | 119 | int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 120 | { |
| 121 | int ret; |
| 122 | struct iio_buffer *buffer; |
| 123 | |
| 124 | /* Allocate a buffer to use - here a kfifo */ |
Karol Wrona | 7ab374a | 2014-12-19 18:39:24 +0100 | [diff] [blame] | 125 | buffer = iio_kfifo_allocate(); |
Cristina Opriceana | 8f94c31 | 2015-03-31 12:51:38 +0300 | [diff] [blame] | 126 | if (!buffer) { |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 127 | ret = -ENOMEM; |
| 128 | goto error_ret; |
| 129 | } |
| 130 | |
Lars-Peter Clausen | 9e69c93 | 2013-10-04 12:06:00 +0100 | [diff] [blame] | 131 | iio_device_attach_buffer(indio_dev, buffer); |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 132 | |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 133 | /* Enable timestamps by default */ |
| 134 | buffer->scan_timestamp = true; |
| 135 | |
| 136 | /* |
| 137 | * Tell the core what device type specific functions should |
| 138 | * be run on either side of buffer capture enable / disable. |
| 139 | */ |
Jonathan Cameron | 1612244 | 2011-12-05 22:18:14 +0000 | [diff] [blame] | 140 | indio_dev->setup_ops = &iio_simple_dummy_buffer_setup_ops; |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 141 | |
| 142 | /* |
| 143 | * Configure a polling function. |
| 144 | * When a trigger event with this polling function connected |
| 145 | * occurs, this function is run. Typically this grabs data |
| 146 | * from the device. |
| 147 | * |
Alexander Stein | 569c4ac | 2012-12-19 17:56:00 +0000 | [diff] [blame] | 148 | * NULL for the bottom half. This is normally implemented only if we |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 149 | * either want to ping a capture now pin (no sleeping) or grab |
| 150 | * a timestamp as close as possible to a data ready trigger firing. |
| 151 | * |
| 152 | * IRQF_ONESHOT ensures irqs are masked such that only one instance |
| 153 | * of the handler can run at a time. |
| 154 | * |
| 155 | * "iio_simple_dummy_consumer%d" formatting string for the irq 'name' |
| 156 | * as seen under /proc/interrupts. Remaining parameters as per printk. |
| 157 | */ |
| 158 | indio_dev->pollfunc = iio_alloc_pollfunc(NULL, |
| 159 | &iio_simple_dummy_trigger_h, |
| 160 | IRQF_ONESHOT, |
| 161 | indio_dev, |
| 162 | "iio_simple_dummy_consumer%d", |
| 163 | indio_dev->id); |
| 164 | |
Cristina Opriceana | 8f94c31 | 2015-03-31 12:51:38 +0300 | [diff] [blame] | 165 | if (!indio_dev->pollfunc) { |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 166 | ret = -ENOMEM; |
| 167 | goto error_free_buffer; |
| 168 | } |
| 169 | |
| 170 | /* |
| 171 | * Notify the core that this device is capable of buffered capture |
| 172 | * driven by a trigger. |
| 173 | */ |
| 174 | indio_dev->modes |= INDIO_BUFFER_TRIGGERED; |
Lars-Peter Clausen | 3fff227 | 2012-09-12 12:06:00 +0100 | [diff] [blame] | 175 | |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 176 | return 0; |
| 177 | |
| 178 | error_free_buffer: |
| 179 | iio_kfifo_free(indio_dev->buffer); |
| 180 | error_ret: |
| 181 | return ret; |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 182 | } |
| 183 | |
| 184 | /** |
| 185 | * iio_simple_dummy_unconfigure_buffer() - release buffer resources |
| 186 | * @indo_dev: device instance state |
| 187 | */ |
| 188 | void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev) |
| 189 | { |
Jonathan Cameron | 9ad2e2e | 2011-10-14 16:34:15 +0100 | [diff] [blame] | 190 | iio_dealloc_pollfunc(indio_dev->pollfunc); |
| 191 | iio_kfifo_free(indio_dev->buffer); |
| 192 | } |