Commit | Line | Data |
---|---|---|
7026ea4b JC |
1 | /* The industrial I/O core |
2 | * | |
3 | * Copyright (c) 2008 Jonathan Cameron | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms of the GNU General Public License version 2 as published by | |
7 | * the Free Software Foundation. | |
8 | * | |
9 | * Handling of ring allocation / resizing. | |
10 | * | |
11 | * | |
12 | * Things to look at here. | |
13 | * - Better memory allocation techniques? | |
14 | * - Alternative access techniques? | |
15 | */ | |
16 | #include <linux/kernel.h> | |
17 | #include <linux/device.h> | |
7026ea4b | 18 | #include <linux/fs.h> |
7026ea4b | 19 | #include <linux/cdev.h> |
5a0e3ad6 | 20 | #include <linux/slab.h> |
a7348347 | 21 | #include <linux/poll.h> |
7026ea4b JC |
22 | |
23 | #include "iio.h" | |
df9c1c42 | 24 | #include "iio_core.h" |
9dd1cb30 | 25 | #include "sysfs.h" |
7026ea4b JC |
26 | #include "ring_generic.h" |
27 | ||
7026ea4b JC |
28 | |
29 | /** | |
b4281733 | 30 | * iio_ring_read_first_n_outer() - chrdev read for ring buffer access |
7026ea4b JC |
31 | * |
32 | * This function relies on all ring buffer implementations having an | |
33 | * iio_ring _bufer as their first element. | |
34 | **/ | |
1aa04278 JC |
35 | ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf, |
36 | size_t n, loff_t *f_ps) | |
7026ea4b | 37 | { |
1aa04278 JC |
38 | struct iio_dev *indio_dev = filp->private_data; |
39 | struct iio_ring_buffer *rb = indio_dev->ring; | |
d5857d65 | 40 | |
5565a450 | 41 | if (!rb->access->read_first_n) |
7026ea4b | 42 | return -EINVAL; |
8d213f24 | 43 | return rb->access->read_first_n(rb, n, buf); |
7026ea4b JC |
44 | } |
45 | ||
a7348347 JC |
46 | /** |
47 | * iio_ring_poll() - poll the ring to find out if it has data | |
48 | */ | |
1aa04278 JC |
49 | unsigned int iio_ring_poll(struct file *filp, |
50 | struct poll_table_struct *wait) | |
a7348347 | 51 | { |
1aa04278 JC |
52 | struct iio_dev *indio_dev = filp->private_data; |
53 | struct iio_ring_buffer *rb = indio_dev->ring; | |
a7348347 JC |
54 | |
55 | poll_wait(filp, &rb->pollq, wait); | |
56 | if (rb->stufftoread) | |
57 | return POLLIN | POLLRDNORM; | |
58 | /* need a way of knowing if there may be enough data... */ | |
8d213f24 | 59 | return 0; |
a7348347 JC |
60 | } |
61 | ||
1aa04278 | 62 | void iio_chrdev_ring_open(struct iio_dev *indio_dev) |
7026ea4b | 63 | { |
1aa04278 JC |
64 | struct iio_ring_buffer *rb = indio_dev->ring; |
65 | if (rb && rb->access->mark_in_use) | |
66 | rb->access->mark_in_use(rb); | |
7026ea4b | 67 | } |
7026ea4b | 68 | |
1aa04278 | 69 | void iio_chrdev_ring_release(struct iio_dev *indio_dev) |
7026ea4b | 70 | { |
1aa04278 | 71 | struct iio_ring_buffer *rb = indio_dev->ring; |
758d988c | 72 | |
1aa04278 JC |
73 | clear_bit(IIO_BUSY_BIT_POS, &rb->flags); |
74 | if (rb->access->unmark_in_use) | |
75 | rb->access->unmark_in_use(rb); | |
7026ea4b | 76 | |
7026ea4b JC |
77 | } |
78 | ||
79 | void iio_ring_buffer_init(struct iio_ring_buffer *ring, | |
80 | struct iio_dev *dev_info) | |
81 | { | |
7026ea4b | 82 | ring->indio_dev = dev_info; |
a7348347 | 83 | init_waitqueue_head(&ring->pollq); |
7026ea4b JC |
84 | } |
85 | EXPORT_SYMBOL(iio_ring_buffer_init); | |
86 | ||
1d892719 | 87 | static ssize_t iio_show_scan_index(struct device *dev, |
8d213f24 JC |
88 | struct device_attribute *attr, |
89 | char *buf) | |
1d892719 | 90 | { |
8d213f24 | 91 | return sprintf(buf, "%u\n", to_iio_dev_attr(attr)->c->scan_index); |
1d892719 JC |
92 | } |
93 | ||
94 | static ssize_t iio_show_fixed_type(struct device *dev, | |
95 | struct device_attribute *attr, | |
96 | char *buf) | |
97 | { | |
98 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | |
99 | return sprintf(buf, "%c%d/%d>>%u\n", | |
100 | this_attr->c->scan_type.sign, | |
101 | this_attr->c->scan_type.realbits, | |
102 | this_attr->c->scan_type.storagebits, | |
103 | this_attr->c->scan_type.shift); | |
104 | } | |
105 | ||
8d213f24 JC |
106 | static ssize_t iio_scan_el_show(struct device *dev, |
107 | struct device_attribute *attr, | |
108 | char *buf) | |
109 | { | |
110 | int ret; | |
1aa04278 | 111 | struct iio_dev *dev_info = dev_get_drvdata(dev); |
8d213f24 | 112 | |
1aa04278 JC |
113 | ret = iio_scan_mask_query(dev_info->ring, |
114 | to_iio_dev_attr(attr)->address); | |
8d213f24 JC |
115 | if (ret < 0) |
116 | return ret; | |
117 | return sprintf(buf, "%d\n", ret); | |
118 | } | |
119 | ||
120 | static int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit) | |
121 | { | |
122 | if (bit > IIO_MAX_SCAN_LENGTH) | |
123 | return -EINVAL; | |
124 | ring->scan_mask &= ~(1 << bit); | |
125 | ring->scan_count--; | |
126 | return 0; | |
127 | } | |
128 | ||
129 | static ssize_t iio_scan_el_store(struct device *dev, | |
130 | struct device_attribute *attr, | |
131 | const char *buf, | |
132 | size_t len) | |
133 | { | |
134 | int ret = 0; | |
135 | bool state; | |
1aa04278 JC |
136 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
137 | struct iio_ring_buffer *ring = indio_dev->ring; | |
8d213f24 JC |
138 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
139 | ||
140 | state = !(buf[0] == '0'); | |
141 | mutex_lock(&indio_dev->mlock); | |
142 | if (indio_dev->currentmode == INDIO_RING_TRIGGERED) { | |
143 | ret = -EBUSY; | |
144 | goto error_ret; | |
145 | } | |
146 | ret = iio_scan_mask_query(ring, this_attr->address); | |
147 | if (ret < 0) | |
148 | goto error_ret; | |
149 | if (!state && ret) { | |
150 | ret = iio_scan_mask_clear(ring, this_attr->address); | |
151 | if (ret) | |
152 | goto error_ret; | |
153 | } else if (state && !ret) { | |
154 | ret = iio_scan_mask_set(ring, this_attr->address); | |
155 | if (ret) | |
156 | goto error_ret; | |
157 | } | |
158 | ||
159 | error_ret: | |
160 | mutex_unlock(&indio_dev->mlock); | |
161 | ||
162 | return ret ? ret : len; | |
163 | ||
164 | } | |
165 | ||
166 | static ssize_t iio_scan_el_ts_show(struct device *dev, | |
167 | struct device_attribute *attr, | |
168 | char *buf) | |
169 | { | |
1aa04278 JC |
170 | struct iio_dev *dev_info = dev_get_drvdata(dev); |
171 | return sprintf(buf, "%d\n", dev_info->ring->scan_timestamp); | |
8d213f24 JC |
172 | } |
173 | ||
174 | static ssize_t iio_scan_el_ts_store(struct device *dev, | |
175 | struct device_attribute *attr, | |
176 | const char *buf, | |
177 | size_t len) | |
178 | { | |
179 | int ret = 0; | |
1aa04278 | 180 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
8d213f24 | 181 | bool state; |
1aa04278 | 182 | |
8d213f24 JC |
183 | state = !(buf[0] == '0'); |
184 | mutex_lock(&indio_dev->mlock); | |
185 | if (indio_dev->currentmode == INDIO_RING_TRIGGERED) { | |
186 | ret = -EBUSY; | |
187 | goto error_ret; | |
188 | } | |
1aa04278 | 189 | indio_dev->ring->scan_timestamp = state; |
8d213f24 JC |
190 | error_ret: |
191 | mutex_unlock(&indio_dev->mlock); | |
192 | ||
193 | return ret ? ret : len; | |
194 | } | |
195 | ||
1aa04278 | 196 | static int iio_ring_add_channel_sysfs(struct iio_dev *indio_dev, |
1d892719 JC |
197 | const struct iio_chan_spec *chan) |
198 | { | |
199 | int ret; | |
1aa04278 | 200 | struct iio_ring_buffer *ring = indio_dev->ring; |
1d892719 JC |
201 | |
202 | ret = __iio_add_chan_devattr("index", "scan_elements", | |
203 | chan, | |
204 | &iio_show_scan_index, | |
205 | NULL, | |
206 | 0, | |
207 | 0, | |
1aa04278 | 208 | &indio_dev->dev, |
1d892719 JC |
209 | &ring->scan_el_dev_attr_list); |
210 | if (ret) | |
211 | goto error_ret; | |
212 | ||
213 | ret = __iio_add_chan_devattr("type", "scan_elements", | |
214 | chan, | |
215 | &iio_show_fixed_type, | |
216 | NULL, | |
217 | 0, | |
218 | 0, | |
1aa04278 | 219 | &indio_dev->dev, |
1d892719 | 220 | &ring->scan_el_dev_attr_list); |
1d892719 JC |
221 | if (ret) |
222 | goto error_ret; | |
223 | ||
a88b3ebc JC |
224 | if (chan->type != IIO_TIMESTAMP) |
225 | ret = __iio_add_chan_devattr("en", "scan_elements", | |
226 | chan, | |
227 | &iio_scan_el_show, | |
228 | &iio_scan_el_store, | |
229 | chan->scan_index, | |
230 | 0, | |
1aa04278 | 231 | &indio_dev->dev, |
a88b3ebc JC |
232 | &ring->scan_el_dev_attr_list); |
233 | else | |
234 | ret = __iio_add_chan_devattr("en", "scan_elements", | |
235 | chan, | |
236 | &iio_scan_el_ts_show, | |
237 | &iio_scan_el_ts_store, | |
238 | chan->scan_index, | |
239 | 0, | |
1aa04278 | 240 | &indio_dev->dev, |
a88b3ebc | 241 | &ring->scan_el_dev_attr_list); |
1d892719 JC |
242 | error_ret: |
243 | return ret; | |
244 | } | |
245 | ||
1aa04278 | 246 | static void iio_ring_remove_and_free_scan_dev_attr(struct iio_dev *indio_dev, |
1d892719 JC |
247 | struct iio_dev_attr *p) |
248 | { | |
1aa04278 | 249 | sysfs_remove_file_from_group(&indio_dev->dev.kobj, |
1d892719 JC |
250 | &p->dev_attr.attr, "scan_elements"); |
251 | kfree(p->dev_attr.attr.name); | |
252 | kfree(p); | |
253 | } | |
254 | ||
255 | static struct attribute *iio_scan_el_dummy_attrs[] = { | |
256 | NULL | |
257 | }; | |
258 | ||
259 | static struct attribute_group iio_scan_el_dummy_group = { | |
260 | .name = "scan_elements", | |
261 | .attrs = iio_scan_el_dummy_attrs | |
262 | }; | |
263 | ||
1aa04278 | 264 | static void __iio_ring_attr_cleanup(struct iio_dev *indio_dev) |
1d892719 JC |
265 | { |
266 | struct iio_dev_attr *p, *n; | |
1aa04278 | 267 | struct iio_ring_buffer *ring = indio_dev->ring; |
a88b3ebc | 268 | int anydynamic = !list_empty(&ring->scan_el_dev_attr_list); |
1d892719 JC |
269 | list_for_each_entry_safe(p, n, |
270 | &ring->scan_el_dev_attr_list, l) | |
1aa04278 | 271 | iio_ring_remove_and_free_scan_dev_attr(indio_dev, p); |
1d892719 JC |
272 | |
273 | if (ring->scan_el_attrs) | |
1aa04278 | 274 | sysfs_remove_group(&indio_dev->dev.kobj, |
1d892719 JC |
275 | ring->scan_el_attrs); |
276 | else if (anydynamic) | |
1aa04278 | 277 | sysfs_remove_group(&indio_dev->dev.kobj, |
1d892719 JC |
278 | &iio_scan_el_dummy_group); |
279 | } | |
280 | ||
c009f7e4 JC |
281 | int iio_ring_buffer_register(struct iio_dev *indio_dev, |
282 | const struct iio_chan_spec *channels, | |
283 | int num_channels) | |
1d892719 | 284 | { |
1aa04278 | 285 | struct iio_ring_buffer *ring = indio_dev->ring; |
1d892719 | 286 | int ret, i; |
758d988c | 287 | |
bf32963c | 288 | if (ring->scan_el_attrs) { |
1aa04278 | 289 | ret = sysfs_create_group(&indio_dev->dev.kobj, |
bf32963c MS |
290 | ring->scan_el_attrs); |
291 | if (ret) { | |
1aa04278 | 292 | dev_err(&indio_dev->dev, |
bf32963c | 293 | "Failed to add sysfs scan elements\n"); |
1aa04278 | 294 | goto error_ret; |
bf32963c | 295 | } |
1d892719 | 296 | } else if (channels) { |
1aa04278 | 297 | ret = sysfs_create_group(&indio_dev->dev.kobj, |
1d892719 JC |
298 | &iio_scan_el_dummy_group); |
299 | if (ret) | |
1aa04278 JC |
300 | goto error_ret; |
301 | } | |
302 | if (ring->attrs) { | |
303 | ret = sysfs_create_group(&indio_dev->dev.kobj, | |
304 | ring->attrs); | |
305 | if (ret) | |
306 | goto error_cleanup_dynamic; | |
bf32963c MS |
307 | } |
308 | ||
1d892719 | 309 | INIT_LIST_HEAD(&ring->scan_el_dev_attr_list); |
1d892719 JC |
310 | if (channels) { |
311 | /* new magic */ | |
312 | for (i = 0; i < num_channels; i++) { | |
1aa04278 JC |
313 | ret = iio_ring_add_channel_sysfs(indio_dev, |
314 | &channels[i]); | |
1d892719 | 315 | if (ret < 0) |
1aa04278 | 316 | goto error_cleanup_group; |
1d892719 JC |
317 | } |
318 | } | |
319 | ||
320 | return 0; | |
1aa04278 JC |
321 | error_cleanup_group: |
322 | if (ring->attrs) | |
323 | sysfs_remove_group(&indio_dev->dev.kobj, ring->attrs); | |
1d892719 | 324 | error_cleanup_dynamic: |
1aa04278 | 325 | __iio_ring_attr_cleanup(indio_dev); |
7026ea4b JC |
326 | error_ret: |
327 | return ret; | |
328 | } | |
c009f7e4 | 329 | EXPORT_SYMBOL(iio_ring_buffer_register); |
1d892719 | 330 | |
1aa04278 | 331 | void iio_ring_buffer_unregister(struct iio_dev *indio_dev) |
7026ea4b | 332 | { |
1aa04278 JC |
333 | if (indio_dev->ring->attrs) |
334 | sysfs_remove_group(&indio_dev->dev.kobj, | |
335 | indio_dev->ring->attrs); | |
336 | __iio_ring_attr_cleanup(indio_dev); | |
7026ea4b JC |
337 | } |
338 | EXPORT_SYMBOL(iio_ring_buffer_unregister); | |
339 | ||
340 | ssize_t iio_read_ring_length(struct device *dev, | |
341 | struct device_attribute *attr, | |
342 | char *buf) | |
343 | { | |
1aa04278 JC |
344 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
345 | struct iio_ring_buffer *ring = indio_dev->ring; | |
7026ea4b | 346 | |
5565a450 | 347 | if (ring->access->get_length) |
8d213f24 JC |
348 | return sprintf(buf, "%d\n", |
349 | ring->access->get_length(ring)); | |
7026ea4b | 350 | |
8d213f24 | 351 | return 0; |
7026ea4b JC |
352 | } |
353 | EXPORT_SYMBOL(iio_read_ring_length); | |
354 | ||
0abd2428 | 355 | ssize_t iio_write_ring_length(struct device *dev, |
7026ea4b JC |
356 | struct device_attribute *attr, |
357 | const char *buf, | |
358 | size_t len) | |
359 | { | |
360 | int ret; | |
361 | ulong val; | |
1aa04278 JC |
362 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
363 | struct iio_ring_buffer *ring = indio_dev->ring; | |
8d213f24 | 364 | |
7026ea4b JC |
365 | ret = strict_strtoul(buf, 10, &val); |
366 | if (ret) | |
367 | return ret; | |
368 | ||
5565a450 JC |
369 | if (ring->access->get_length) |
370 | if (val == ring->access->get_length(ring)) | |
7026ea4b JC |
371 | return len; |
372 | ||
5565a450 JC |
373 | if (ring->access->set_length) { |
374 | ring->access->set_length(ring, val); | |
375 | if (ring->access->mark_param_change) | |
376 | ring->access->mark_param_change(ring); | |
7026ea4b JC |
377 | } |
378 | ||
379 | return len; | |
380 | } | |
381 | EXPORT_SYMBOL(iio_write_ring_length); | |
382 | ||
ffcab07a | 383 | ssize_t iio_read_ring_bytes_per_datum(struct device *dev, |
7026ea4b JC |
384 | struct device_attribute *attr, |
385 | char *buf) | |
386 | { | |
1aa04278 JC |
387 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
388 | struct iio_ring_buffer *ring = indio_dev->ring; | |
7026ea4b | 389 | |
5565a450 | 390 | if (ring->access->get_bytes_per_datum) |
8d213f24 JC |
391 | return sprintf(buf, "%d\n", |
392 | ring->access->get_bytes_per_datum(ring)); | |
7026ea4b | 393 | |
8d213f24 | 394 | return 0; |
7026ea4b | 395 | } |
ffcab07a | 396 | EXPORT_SYMBOL(iio_read_ring_bytes_per_datum); |
7026ea4b JC |
397 | |
398 | ssize_t iio_store_ring_enable(struct device *dev, | |
399 | struct device_attribute *attr, | |
400 | const char *buf, | |
401 | size_t len) | |
402 | { | |
403 | int ret; | |
404 | bool requested_state, current_state; | |
405 | int previous_mode; | |
1aa04278 JC |
406 | struct iio_dev *dev_info = dev_get_drvdata(dev); |
407 | struct iio_ring_buffer *ring = dev_info->ring; | |
7026ea4b JC |
408 | |
409 | mutex_lock(&dev_info->mlock); | |
410 | previous_mode = dev_info->currentmode; | |
411 | requested_state = !(buf[0] == '0'); | |
412 | current_state = !!(previous_mode & INDIO_ALL_RING_MODES); | |
413 | if (current_state == requested_state) { | |
414 | printk(KERN_INFO "iio-ring, current state requested again\n"); | |
415 | goto done; | |
416 | } | |
417 | if (requested_state) { | |
5565a450 JC |
418 | if (ring->setup_ops->preenable) { |
419 | ret = ring->setup_ops->preenable(dev_info); | |
7026ea4b JC |
420 | if (ret) { |
421 | printk(KERN_ERR | |
422 | "Buffer not started:" | |
423 | "ring preenable failed\n"); | |
424 | goto error_ret; | |
425 | } | |
426 | } | |
5565a450 JC |
427 | if (ring->access->request_update) { |
428 | ret = ring->access->request_update(ring); | |
7026ea4b JC |
429 | if (ret) { |
430 | printk(KERN_INFO | |
431 | "Buffer not started:" | |
432 | "ring parameter update failed\n"); | |
433 | goto error_ret; | |
434 | } | |
435 | } | |
5565a450 JC |
436 | if (ring->access->mark_in_use) |
437 | ring->access->mark_in_use(ring); | |
7026ea4b JC |
438 | /* Definitely possible for devices to support both of these.*/ |
439 | if (dev_info->modes & INDIO_RING_TRIGGERED) { | |
440 | if (!dev_info->trig) { | |
441 | printk(KERN_INFO | |
442 | "Buffer not started: no trigger\n"); | |
443 | ret = -EINVAL; | |
5565a450 JC |
444 | if (ring->access->unmark_in_use) |
445 | ring->access->unmark_in_use(ring); | |
7026ea4b JC |
446 | goto error_ret; |
447 | } | |
448 | dev_info->currentmode = INDIO_RING_TRIGGERED; | |
449 | } else if (dev_info->modes & INDIO_RING_HARDWARE_BUFFER) | |
450 | dev_info->currentmode = INDIO_RING_HARDWARE_BUFFER; | |
451 | else { /* should never be reached */ | |
452 | ret = -EINVAL; | |
453 | goto error_ret; | |
454 | } | |
455 | ||
5565a450 | 456 | if (ring->setup_ops->postenable) { |
5565a450 | 457 | ret = ring->setup_ops->postenable(dev_info); |
7026ea4b JC |
458 | if (ret) { |
459 | printk(KERN_INFO | |
460 | "Buffer not started:" | |
461 | "postenable failed\n"); | |
5565a450 JC |
462 | if (ring->access->unmark_in_use) |
463 | ring->access->unmark_in_use(ring); | |
7026ea4b | 464 | dev_info->currentmode = previous_mode; |
5565a450 JC |
465 | if (ring->setup_ops->postdisable) |
466 | ring->setup_ops->postdisable(dev_info); | |
7026ea4b JC |
467 | goto error_ret; |
468 | } | |
469 | } | |
470 | } else { | |
5565a450 JC |
471 | if (ring->setup_ops->predisable) { |
472 | ret = ring->setup_ops->predisable(dev_info); | |
7026ea4b JC |
473 | if (ret) |
474 | goto error_ret; | |
475 | } | |
5565a450 JC |
476 | if (ring->access->unmark_in_use) |
477 | ring->access->unmark_in_use(ring); | |
7026ea4b | 478 | dev_info->currentmode = INDIO_DIRECT_MODE; |
5565a450 JC |
479 | if (ring->setup_ops->postdisable) { |
480 | ret = ring->setup_ops->postdisable(dev_info); | |
7026ea4b JC |
481 | if (ret) |
482 | goto error_ret; | |
483 | } | |
484 | } | |
485 | done: | |
486 | mutex_unlock(&dev_info->mlock); | |
487 | return len; | |
488 | ||
489 | error_ret: | |
490 | mutex_unlock(&dev_info->mlock); | |
491 | return ret; | |
492 | } | |
493 | EXPORT_SYMBOL(iio_store_ring_enable); | |
8d213f24 | 494 | |
7026ea4b JC |
495 | ssize_t iio_show_ring_enable(struct device *dev, |
496 | struct device_attribute *attr, | |
497 | char *buf) | |
498 | { | |
1aa04278 JC |
499 | struct iio_dev *dev_info = dev_get_drvdata(dev); |
500 | return sprintf(buf, "%d\n", !!(dev_info->currentmode | |
7026ea4b JC |
501 | & INDIO_ALL_RING_MODES)); |
502 | } | |
503 | EXPORT_SYMBOL(iio_show_ring_enable); | |
504 | ||
5565a450 JC |
505 | int iio_sw_ring_preenable(struct iio_dev *indio_dev) |
506 | { | |
507 | struct iio_ring_buffer *ring = indio_dev->ring; | |
508 | size_t size; | |
509 | dev_dbg(&indio_dev->dev, "%s\n", __func__); | |
510 | /* Check if there are any scan elements enabled, if not fail*/ | |
511 | if (!(ring->scan_count || ring->scan_timestamp)) | |
512 | return -EINVAL; | |
513 | if (ring->scan_timestamp) | |
514 | if (ring->scan_count) | |
515 | /* Timestamp (aligned to s64) and data */ | |
516 | size = (((ring->scan_count * ring->bpe) | |
517 | + sizeof(s64) - 1) | |
518 | & ~(sizeof(s64) - 1)) | |
519 | + sizeof(s64); | |
520 | else /* Timestamp only */ | |
521 | size = sizeof(s64); | |
522 | else /* Data only */ | |
523 | size = ring->scan_count * ring->bpe; | |
524 | ring->access->set_bytes_per_datum(ring, size); | |
525 | ||
526 | return 0; | |
527 | } | |
528 | EXPORT_SYMBOL(iio_sw_ring_preenable); |