]> sigrok.org Git - libsigrok.git/blame_incremental - hardware/rigol-ds1xx2/api.c
Add SR_ERR_PROBE_GROUP, denoting a probe group requirement
[libsigrok.git] / hardware / rigol-ds1xx2 / api.c
... / ...
CommitLineData
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
5 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <fcntl.h>
22#include <unistd.h>
23#include <stdlib.h>
24#include <string.h>
25#include <glib.h>
26#include "libsigrok.h"
27#include "libsigrok-internal.h"
28#include "protocol.h"
29
30#define NUM_TIMEBASE 12
31#define NUM_VDIV 8
32
33static const int32_t hwopts[] = {
34 SR_CONF_CONN,
35};
36
37static const int32_t hwcaps[] = {
38 SR_CONF_OSCILLOSCOPE,
39 SR_CONF_TIMEBASE,
40 SR_CONF_TRIGGER_SOURCE,
41 SR_CONF_TRIGGER_SLOPE,
42 SR_CONF_HORIZ_TRIGGERPOS,
43 SR_CONF_NUM_TIMEBASE,
44};
45
46static const int32_t analog_hwcaps[] = {
47 SR_CONF_NUM_VDIV,
48 SR_CONF_VDIV,
49 SR_CONF_COUPLING
50};
51
52static const uint64_t timebases[][2] = {
53 /* nanoseconds */
54 { 2, 1000000000 },
55 { 5, 1000000000 },
56 { 10, 1000000000 },
57 { 20, 1000000000 },
58 { 50, 1000000000 },
59 { 100, 1000000000 },
60 { 500, 1000000000 },
61 /* microseconds */
62 { 1, 1000000 },
63 { 2, 1000000 },
64 { 5, 1000000 },
65 { 10, 1000000 },
66 { 20, 1000000 },
67 { 50, 1000000 },
68 { 100, 1000000 },
69 { 200, 1000000 },
70 { 500, 1000000 },
71 /* milliseconds */
72 { 1, 1000 },
73 { 2, 1000 },
74 { 5, 1000 },
75 { 10, 1000 },
76 { 20, 1000 },
77 { 50, 1000 },
78 { 100, 1000 },
79 { 200, 1000 },
80 { 500, 1000 },
81 /* seconds */
82 { 1, 1 },
83 { 2, 1 },
84 { 5, 1 },
85 { 10, 1 },
86 { 20, 1 },
87 { 50, 1 },
88};
89
90static const uint64_t vdivs[][2] = {
91 /* millivolts */
92 { 2, 1000 },
93 { 5, 1000 },
94 { 10, 1000 },
95 { 20, 1000 },
96 { 50, 1000 },
97 { 100, 1000 },
98 { 200, 1000 },
99 { 500, 1000 },
100 /* volts */
101 { 1, 1 },
102 { 2, 1 },
103 { 5, 1 },
104 { 10, 1 },
105};
106
107static const char *trigger_sources[] = {
108 "CH1",
109 "CH2",
110 "EXT",
111 "AC Line",
112 "D0",
113 "D1",
114 "D2",
115 "D3",
116 "D4",
117 "D5",
118 "D6",
119 "D7",
120 "D8",
121 "D9",
122 "D10",
123 "D11",
124 "D12",
125 "D13",
126 "D14",
127 "D15",
128};
129
130static const char *coupling[] = {
131 "AC",
132 "DC",
133 "GND",
134};
135
136static const char *supported_models[] = {
137 "DS1052E",
138 "DS1102E",
139 "DS1152E",
140 "DS1052D",
141 "DS1102D",
142 "DS1152D",
143};
144
145SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info;
146static struct sr_dev_driver *di = &rigol_ds1xx2_driver_info;
147
148static void clear_helper(void *priv)
149{
150 struct dev_context *devc;
151
152 devc = priv;
153 g_free(devc->coupling[0]);
154 g_free(devc->coupling[1]);
155 g_free(devc->trigger_source);
156 g_free(devc->trigger_slope);
157 g_slist_free(devc->analog_groups[0].probes);
158 g_slist_free(devc->analog_groups[1].probes);
159 g_slist_free(devc->digital_group.probes);
160}
161
162static int dev_clear(void)
163{
164 return std_dev_clear(di, clear_helper);
165}
166
167static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
168{
169 va_list args;
170 char buf[256];
171
172 va_start(args, format);
173 vsnprintf(buf, 255, format, args);
174 va_end(args);
175 if (rigol_ds1xx2_send(sdi, buf) != SR_OK)
176 return SR_ERR;
177
178 /* When setting a bunch of parameters in a row, the DS1052E scrambles
179 * some of them unless there is at least 100ms delay in between. */
180 sr_spew("delay %dms", 100);
181 g_usleep(100000);
182
183 return SR_OK;
184}
185
186static int init(struct sr_context *sr_ctx)
187{
188 return std_init(sr_ctx, di, LOG_PREFIX);
189}
190
191static int probe_port(const char *port, GSList **devices)
192{
193 struct dev_context *devc;
194 struct sr_dev_inst *sdi;
195 struct sr_serial_dev_inst *serial;
196 struct sr_probe *probe;
197 unsigned int i;
198 int len, num_tokens;
199 gboolean matched, has_digital;
200 const char *manufacturer, *model, *version;
201 char buf[256];
202 gchar **tokens, *channel_name;
203
204 *devices = NULL;
205 if (!(serial = sr_serial_dev_inst_new(port, NULL)))
206 return SR_ERR_MALLOC;
207
208 if (serial_open(serial, SERIAL_RDWR) != SR_OK)
209 return SR_ERR;
210 len = serial_write(serial, "*IDN?", 5);
211 len = serial_read(serial, buf, sizeof(buf));
212 if (serial_close(serial) != SR_OK)
213 return SR_ERR;
214
215 sr_serial_dev_inst_free(serial);
216
217 if (len == 0)
218 return SR_ERR_NA;
219
220 buf[len] = 0;
221 tokens = g_strsplit(buf, ",", 0);
222 sr_dbg("response: %s [%s]", port, buf);
223
224 for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
225
226 if (num_tokens < 4) {
227 g_strfreev(tokens);
228 return SR_ERR_NA;
229 }
230
231 manufacturer = tokens[0];
232 model = tokens[1];
233 version = tokens[3];
234
235 if (strcmp(manufacturer, "Rigol Technologies")) {
236 g_strfreev(tokens);
237 return SR_ERR_NA;
238 }
239
240 matched = has_digital = FALSE;
241 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
242 if (!strcmp(model, supported_models[i])) {
243 matched = TRUE;
244 has_digital = g_str_has_suffix(model, "D");
245 break;
246 }
247 }
248
249 if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
250 manufacturer, model, version))) {
251 g_strfreev(tokens);
252 return SR_ERR_NA;
253 }
254
255 g_strfreev(tokens);
256
257 if (!(sdi->conn = sr_serial_dev_inst_new(port, NULL)))
258 return SR_ERR_MALLOC;
259 sdi->driver = di;
260 sdi->inst_type = SR_INST_SERIAL;
261
262 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
263 return SR_ERR_MALLOC;
264 devc->limit_frames = 0;
265 devc->has_digital = has_digital;
266
267 for (i = 0; i < 2; i++) {
268 channel_name = (i == 0 ? "CH1" : "CH2");
269 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name)))
270 return SR_ERR_MALLOC;
271 sdi->probes = g_slist_append(sdi->probes, probe);
272 devc->analog_groups[i].name = channel_name;
273 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
274 sdi->probe_groups = g_slist_append(sdi->probe_groups,
275 &devc->analog_groups[i]);
276 }
277
278 if (devc->has_digital) {
279 for (i = 0; i < 16; i++) {
280 if (!(channel_name = g_strdup_printf("D%d", i)))
281 return SR_ERR_MALLOC;
282 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
283 g_free(channel_name);
284 if (!probe)
285 return SR_ERR_MALLOC;
286 sdi->probes = g_slist_append(sdi->probes, probe);
287 devc->digital_group.probes = g_slist_append(
288 devc->digital_group.probes, probe);
289 devc->digital_group.name = "LA";
290 sdi->probe_groups = g_slist_append(sdi->probe_groups,
291 &devc->digital_group);
292 }
293 }
294 sdi->priv = devc;
295
296 *devices = g_slist_append(NULL, sdi);
297
298 return SR_OK;
299}
300
301static GSList *scan(GSList *options)
302{
303 struct drv_context *drvc;
304 struct sr_config *src;
305 GSList *l, *devices;
306 GDir *dir;
307 int ret;
308 const gchar *dev_name;
309 gchar *port = NULL;
310
311 drvc = di->priv;
312
313 for (l = options; l; l = l->next) {
314 src = l->data;
315 if (src->key == SR_CONF_CONN) {
316 port = (char *)g_variant_get_string(src->data, NULL);
317 break;
318 }
319 }
320
321 devices = NULL;
322 if (port) {
323 if (probe_port(port, &devices) == SR_ERR_MALLOC)
324 return NULL;
325 } else {
326 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
327 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
328 return NULL;
329 while ((dev_name = g_dir_read_name(dir))) {
330 if (strncmp(dev_name, "usbtmc", 6))
331 continue;
332 port = g_strconcat("/dev/", dev_name, NULL);
333 ret = probe_port(port, &devices);
334 g_free(port);
335 if (ret == SR_ERR_MALLOC) {
336 g_dir_close(dir);
337 return NULL;
338 }
339 }
340 g_dir_close(dir);
341 }
342
343 /* Tack a copy of the newly found devices onto the driver list. */
344 l = g_slist_copy(devices);
345 drvc->instances = g_slist_concat(drvc->instances, l);
346
347 return devices;
348}
349
350static GSList *dev_list(void)
351{
352 return ((struct drv_context *)(di->priv))->instances;
353}
354
355static int dev_open(struct sr_dev_inst *sdi)
356{
357
358 if (serial_open(sdi->conn, SERIAL_RDWR) != SR_OK)
359 return SR_ERR;
360
361 if (rigol_ds1xx2_get_dev_cfg(sdi) != SR_OK)
362 return SR_ERR;
363
364 sdi->status = SR_ST_ACTIVE;
365
366 return SR_OK;
367}
368
369static int dev_close(struct sr_dev_inst *sdi)
370{
371 struct sr_serial_dev_inst *serial;
372
373 serial = sdi->conn;
374 if (serial && serial->fd != -1) {
375 serial_close(serial);
376 sdi->status = SR_ST_INACTIVE;
377 }
378
379 return SR_OK;
380}
381
382static int cleanup(void)
383{
384 return dev_clear();
385}
386
387static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
388 const struct sr_probe_group *probe_group)
389{
390 struct dev_context *devc;
391 unsigned int i;
392
393 if (!sdi || !(devc = sdi->priv))
394 return SR_ERR_ARG;
395
396 switch (id) {
397 case SR_CONF_NUM_TIMEBASE:
398 *data = g_variant_new_int32(NUM_TIMEBASE);
399 break;
400 case SR_CONF_NUM_VDIV:
401 for (i = 0; i < 2; i++) {
402 if (probe_group == &devc->analog_groups[i]) {
403 *data = g_variant_new_int32(NUM_VDIV);
404 return SR_OK;
405 }
406 }
407 return SR_ERR_NA;
408 default:
409 return SR_ERR_NA;
410 }
411
412 return SR_OK;
413}
414
415static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
416 const struct sr_probe_group *probe_group)
417{
418 struct dev_context *devc;
419 uint64_t tmp_u64, p, q;
420 double t_dbl;
421 unsigned int i, j;
422 int ret;
423 const char *tmp_str;
424
425 if (!(devc = sdi->priv))
426 return SR_ERR_ARG;
427
428 if (sdi->status != SR_ST_ACTIVE)
429 return SR_ERR_DEV_CLOSED;
430
431 ret = SR_OK;
432 switch (id) {
433 case SR_CONF_LIMIT_FRAMES:
434 devc->limit_frames = g_variant_get_uint64(data);
435 break;
436 case SR_CONF_TRIGGER_SLOPE:
437 tmp_u64 = g_variant_get_uint64(data);
438 if (tmp_u64 != 0 && tmp_u64 != 1)
439 return SR_ERR;
440 g_free(devc->trigger_slope);
441 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
442 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
443 break;
444 case SR_CONF_HORIZ_TRIGGERPOS:
445 t_dbl = g_variant_get_double(data);
446 if (t_dbl < 0.0 || t_dbl > 1.0)
447 return SR_ERR;
448 devc->horiz_triggerpos = t_dbl;
449 /* We have the trigger offset as a percentage of the frame, but
450 * need to express this in seconds. */
451 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
452 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
453 break;
454 case SR_CONF_TIMEBASE:
455 g_variant_get(data, "(tt)", &p, &q);
456 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
457 if (timebases[i][0] == p && timebases[i][1] == q) {
458 devc->timebase = (float)p / q;
459 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
460 break;
461 }
462 }
463 if (i == ARRAY_SIZE(timebases))
464 ret = SR_ERR_ARG;
465 break;
466 case SR_CONF_TRIGGER_SOURCE:
467 tmp_str = g_variant_get_string(data, NULL);
468 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
469 if (!strcmp(trigger_sources[i], tmp_str)) {
470 g_free(devc->trigger_source);
471 devc->trigger_source = g_strdup(trigger_sources[i]);
472 if (!strcmp(devc->trigger_source, "AC Line"))
473 tmp_str = "ACL";
474 else if (!strcmp(devc->trigger_source, "CH1"))
475 tmp_str = "CHAN1";
476 else if (!strcmp(devc->trigger_source, "CH2"))
477 tmp_str = "CHAN2";
478 else
479 tmp_str = (char *)devc->trigger_source;
480 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
481 break;
482 }
483 }
484 if (i == ARRAY_SIZE(trigger_sources))
485 ret = SR_ERR_ARG;
486 break;
487 case SR_CONF_VDIV:
488 g_variant_get(data, "(tt)", &p, &q);
489 for (i = 0; i < 2; i++) {
490 if (probe_group == &devc->analog_groups[i])
491 {
492 for (j = 0; j < ARRAY_SIZE(vdivs); j++)
493 {
494 if (vdivs[j][0] != p || vdivs[j][1] != q)
495 continue;
496 devc->vdiv[i] = (float)p / q;
497 return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
498 devc->vdiv[i]);
499 }
500 return SR_ERR_ARG;
501 }
502 }
503 return SR_ERR_NA;
504 case SR_CONF_COUPLING:
505 tmp_str = g_variant_get_string(data, NULL);
506 for (i = 0; i < 2; i++) {
507 if (probe_group == &devc->analog_groups[i])
508 {
509 for (j = 0; j < ARRAY_SIZE(coupling); j++)
510 {
511 if (!strcmp(tmp_str, coupling[j]))
512 {
513 g_free(devc->coupling[i]);
514 devc->coupling[i] = g_strdup(coupling[j]);
515 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
516 devc->coupling[i]);
517 }
518 }
519 return SR_ERR_ARG;
520 }
521 }
522 return SR_ERR_NA;
523 default:
524 ret = SR_ERR_NA;
525 break;
526 }
527
528 return ret;
529}
530
531static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
532 const struct sr_probe_group *probe_group)
533{
534 GVariant *tuple, *rational[2];
535 GVariantBuilder gvb;
536 unsigned int i;
537 struct dev_context *devc;
538
539 if (key == SR_CONF_SCAN_OPTIONS) {
540 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
541 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
542 return SR_OK;
543 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
544 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
545 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
546 return SR_OK;
547 }
548
549 /* Every other option requires a valid device instance. */
550 if (!sdi || !(devc = sdi->priv))
551 return SR_ERR_ARG;
552
553 switch (key) {
554 break;
555 case SR_CONF_DEVICE_OPTIONS:
556 if (probe_group == &devc->digital_group) {
557 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
558 NULL, 0, sizeof(int32_t));
559 return SR_OK;
560 } else {
561 for (i = 0; i < 2; i++) {
562 if (probe_group == &devc->analog_groups[i]) {
563 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
564 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
565 return SR_OK;
566 }
567 }
568 return SR_ERR_NA;
569 }
570 case SR_CONF_COUPLING:
571 for (i = 0; i < 2; i++) {
572 if (probe_group == &devc->analog_groups[i]) {
573 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
574 return SR_OK;
575 }
576 }
577 return SR_ERR_NA;
578 case SR_CONF_VDIV:
579 for (i = 0; i < 2; i++) {
580 if (probe_group == &devc->analog_groups[i]) {
581 rational[0] = g_variant_new_uint64(vdivs[i][0]);
582 rational[1] = g_variant_new_uint64(vdivs[i][1]);
583 *data = g_variant_new_tuple(rational, 2);
584 return SR_OK;
585 }
586 }
587 return SR_ERR_NA;
588 case SR_CONF_TIMEBASE:
589 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
590 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
591 rational[0] = g_variant_new_uint64(timebases[i][0]);
592 rational[1] = g_variant_new_uint64(timebases[i][1]);
593 tuple = g_variant_new_tuple(rational, 2);
594 g_variant_builder_add_value(&gvb, tuple);
595 }
596 *data = g_variant_builder_end(&gvb);
597 break;
598 case SR_CONF_TRIGGER_SOURCE:
599 *data = g_variant_new_strv(trigger_sources,
600 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
601 break;
602 default:
603 return SR_ERR_NA;
604 }
605
606 return SR_OK;
607}
608
609static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
610{
611 struct sr_serial_dev_inst *serial;
612 struct dev_context *devc;
613 struct sr_probe *probe;
614 GSList *l;
615 char cmd[256];
616
617 if (sdi->status != SR_ST_ACTIVE)
618 return SR_ERR_DEV_CLOSED;
619
620 serial = sdi->conn;
621 devc = sdi->priv;
622
623 for (l = sdi->probes; l; l = l->next) {
624 probe = l->data;
625 sr_dbg("handling probe %s", probe->name);
626 if (probe->type == SR_PROBE_ANALOG) {
627 if (probe->enabled)
628 devc->enabled_analog_probes = g_slist_append(
629 devc->enabled_analog_probes, probe);
630 if (probe->enabled != devc->analog_channels[probe->index]) {
631 /* Enabled channel is currently disabled, or vice versa. */
632 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
633 probe->enabled ? "ON" : "OFF");
634 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
635 return SR_ERR;
636 }
637 } else if (probe->type == SR_PROBE_LOGIC) {
638 if (probe->enabled)
639 devc->enabled_digital_probes = g_slist_append(
640 devc->enabled_digital_probes, probe);
641 if (probe->enabled != devc->digital_channels[probe->index]) {
642 /* Enabled channel is currently disabled, or vice versa. */
643 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
644 probe->enabled ? "ON" : "OFF");
645 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
646 return SR_ERR;
647 }
648 }
649 }
650 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
651 return SR_ERR;
652
653 sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
654
655 /* Send header packet to the session bus. */
656 std_session_send_df_header(cb_data, LOG_PREFIX);
657
658 /* Fetch the first frame. */
659 if (devc->enabled_analog_probes) {
660 devc->channel_frame = devc->enabled_analog_probes->data;
661 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%d",
662 devc->channel_frame->index + 1) != SR_OK)
663 return SR_ERR;
664 } else {
665 devc->channel_frame = devc->enabled_digital_probes->data;
666 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG") != SR_OK)
667 return SR_ERR;
668 }
669
670 devc->num_frame_bytes = 0;
671
672 return SR_OK;
673}
674
675static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
676{
677 struct dev_context *devc;
678 struct sr_serial_dev_inst *serial;
679
680 (void)cb_data;
681
682 devc = sdi->priv;
683
684 if (sdi->status != SR_ST_ACTIVE) {
685 sr_err("Device inactive, can't stop acquisition.");
686 return SR_ERR;
687 }
688
689 g_slist_free(devc->enabled_analog_probes);
690 g_slist_free(devc->enabled_digital_probes);
691 devc->enabled_analog_probes = NULL;
692 devc->enabled_digital_probes = NULL;
693 serial = sdi->conn;
694 sr_source_remove(serial->fd);
695
696 return SR_OK;
697}
698
699SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
700 .name = "rigol-ds1xx2",
701 .longname = "Rigol DS1xx2",
702 .api_version = 1,
703 .init = init,
704 .cleanup = cleanup,
705 .scan = scan,
706 .dev_list = dev_list,
707 .dev_clear = dev_clear,
708 .config_get = config_get,
709 .config_set = config_set,
710 .config_list = config_list,
711 .dev_open = dev_open,
712 .dev_close = dev_close,
713 .dev_acquisition_start = dev_acquisition_start,
714 .dev_acquisition_stop = dev_acquisition_stop,
715 .priv = NULL,
716};