]> sigrok.org Git - libsigrok.git/blame - hardware/openbench-logic-sniffer/api.c
Add std_serial_dev_close() function.
[libsigrok.git] / hardware / openbench-logic-sniffer / api.c
CommitLineData
0aba65da 1/*
50985c20 2 * This file is part of the libsigrok project.
0aba65da 3 *
13d8e03c 4 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
0aba65da
UH
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "protocol.h"
21
22#define SERIALCOMM "115200/8n1"
23
e46aa4f6 24static const int32_t hwopts[] = {
1953564a
BV
25 SR_CONF_CONN,
26 SR_CONF_SERIALCOMM,
aeabd308
UH
27};
28
e46aa4f6 29static const int32_t hwcaps[] = {
1953564a
BV
30 SR_CONF_LOGIC_ANALYZER,
31 SR_CONF_SAMPLERATE,
0c05591a 32 SR_CONF_TRIGGER_TYPE,
1953564a
BV
33 SR_CONF_CAPTURE_RATIO,
34 SR_CONF_LIMIT_SAMPLES,
eb1b610b 35 SR_CONF_EXTERNAL_CLOCK,
967760a8 36 SR_CONF_PATTERN_MODE,
7b0a57fd 37 SR_CONF_SWAP,
1953564a 38 SR_CONF_RLE,
0aba65da
UH
39};
40
967760a8
MR
41#define STR_PATTERN_EXTERNAL "external"
42#define STR_PATTERN_INTERNAL "internal"
43
44/* Supported methods of test pattern outputs */
45enum {
46 /**
47 * Capture pins 31:16 (unbuffered wing) output a test pattern
48 * that can captured on pins 0:15.
49 */
50 PATTERN_EXTERNAL,
51
52 /** Route test pattern internally to capture buffer. */
53 PATTERN_INTERNAL,
54};
55
7c07a178
UH
56static const char *patterns[] = {
57 STR_PATTERN_EXTERNAL,
58 STR_PATTERN_INTERNAL,
59};
60
0aba65da
UH
61/* Probes are numbered 0-31 (on the PCB silkscreen). */
62SR_PRIV const char *ols_probe_names[NUM_PROBES + 1] = {
78693401
UH
63 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
64 "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
65 "24", "25", "26", "27", "28", "29", "30", "31",
0aba65da
UH
66 NULL,
67};
68
d3b38ad3 69/* Default supported samplerates, can be overridden by device metadata. */
e46aa4f6
BV
70static const uint64_t samplerates[] = {
71 SR_HZ(10),
72 SR_MHZ(200),
73 SR_HZ(1),
0aba65da
UH
74};
75
76SR_PRIV struct sr_dev_driver ols_driver_info;
77static struct sr_dev_driver *di = &ols_driver_info;
78
eea49cf1
UH
79static int dev_clear(void)
80{
81 return std_dev_clear(di, NULL);
82}
83
03f4de8c 84static int init(struct sr_context *sr_ctx)
0aba65da 85{
f6beaac5 86 return std_init(sr_ctx, di, LOG_PREFIX);
0aba65da
UH
87}
88
03f4de8c 89static GSList *scan(GSList *options)
0aba65da 90{
1987b8d6 91 struct sr_config *src;
0aba65da
UH
92 struct sr_dev_inst *sdi;
93 struct drv_context *drvc;
94 struct dev_context *devc;
95 struct sr_probe *probe;
96 struct sr_serial_dev_inst *serial;
97 GPollFD probefd;
98 GSList *l, *devices;
99 int ret, i;
100 const char *conn, *serialcomm;
101 char buf[8];
102
0aba65da 103 drvc = di->priv;
4b97c74e 104
0aba65da
UH
105 devices = NULL;
106
107 conn = serialcomm = NULL;
108 for (l = options; l; l = l->next) {
1987b8d6
BV
109 src = l->data;
110 switch (src->key) {
1953564a 111 case SR_CONF_CONN:
e46aa4f6 112 conn = g_variant_get_string(src->data, NULL);
0aba65da 113 break;
1953564a 114 case SR_CONF_SERIALCOMM:
e46aa4f6 115 serialcomm = g_variant_get_string(src->data, NULL);
0aba65da
UH
116 break;
117 }
118 }
119 if (!conn)
120 return NULL;
121
122 if (serialcomm == NULL)
123 serialcomm = SERIALCOMM;
124
125 if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
126 return NULL;
127
128 /* The discovery procedure is like this: first send the Reset
129 * command (0x00) 5 times, since the device could be anywhere
130 * in a 5-byte command. Then send the ID command (0x02).
131 * If the device responds with 4 bytes ("OLS1" or "SLA1"), we
132 * have a match.
133 */
134 sr_info("Probing %s.", conn);
135 if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
136 return NULL;
137
138 ret = SR_OK;
139 for (i = 0; i < 5; i++) {
140 if ((ret = send_shortcommand(serial, CMD_RESET)) != SR_OK) {
141 sr_err("Port %s is not writable.", conn);
142 break;
143 }
144 }
145 if (ret != SR_OK) {
146 serial_close(serial);
147 sr_err("Could not use port %s. Quitting.", conn);
148 return NULL;
149 }
150 send_shortcommand(serial, CMD_ID);
151
152 /* Wait 10ms for a response. */
153 g_usleep(10000);
154
155 probefd.fd = serial->fd;
156 probefd.events = G_IO_IN;
157 g_poll(&probefd, 1, 1);
158
159 if (probefd.revents != G_IO_IN)
160 return NULL;
161 if (serial_read(serial, buf, 4) != 4)
162 return NULL;
163 if (strncmp(buf, "1SLO", 4) && strncmp(buf, "1ALS", 4))
164 return NULL;
165
166 /* Definitely using the OLS protocol, check if it supports
167 * the metadata command.
168 */
169 send_shortcommand(serial, CMD_METADATA);
170 if (g_poll(&probefd, 1, 10) > 0) {
171 /* Got metadata. */
172 sdi = get_metadata(serial);
173 sdi->index = 0;
174 devc = sdi->priv;
175 } else {
176 /* Not an OLS -- some other board that uses the sump protocol. */
72cd99b8 177 sr_info("Device does not support metadata.");
0aba65da
UH
178 sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
179 "Sump", "Logic Analyzer", "v1.0");
180 sdi->driver = di;
0aba65da
UH
181 for (i = 0; i < 32; i++) {
182 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
183 ols_probe_names[i])))
184 return 0;
185 sdi->probes = g_slist_append(sdi->probes, probe);
186 }
bf256783 187 devc = ols_dev_new();
0aba65da
UH
188 sdi->priv = devc;
189 }
bf256783
BV
190 /* Configure samplerate and divider. */
191 if (ols_set_samplerate(sdi, DEFAULT_SAMPLERATE) != SR_OK)
192 sr_dbg("Failed to set default samplerate (%"PRIu64").",
193 DEFAULT_SAMPLERATE);
194 /* Clear trigger masks, values and stages. */
195 ols_configure_probes(sdi);
459a0f26
BV
196 sdi->inst_type = SR_INST_SERIAL;
197 sdi->conn = serial;
bf256783 198
0aba65da
UH
199 drvc->instances = g_slist_append(drvc->instances, sdi);
200 devices = g_slist_append(devices, sdi);
201
202 serial_close(serial);
203
204 return devices;
205}
206
03f4de8c 207static GSList *dev_list(void)
0aba65da 208{
0e94d524 209 return ((struct drv_context *)(di->priv))->instances;
0aba65da
UH
210}
211
03f4de8c 212static int dev_open(struct sr_dev_inst *sdi)
0aba65da 213{
459a0f26 214 struct sr_serial_dev_inst *serial;
0aba65da 215
459a0f26 216 serial = sdi->conn;
4403c39f 217 if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
0aba65da
UH
218 return SR_ERR;
219
220 sdi->status = SR_ST_ACTIVE;
221
222 return SR_OK;
223}
224
03f4de8c 225static int dev_close(struct sr_dev_inst *sdi)
0aba65da 226{
459a0f26 227 struct sr_serial_dev_inst *serial;
0aba65da 228
459a0f26
BV
229 serial = sdi->conn;
230 if (serial && serial->fd != -1) {
231 serial_close(serial);
0aba65da
UH
232 sdi->status = SR_ST_INACTIVE;
233 }
234
235 return SR_OK;
236}
237
eea49cf1 238static int cleanup(void)
0aba65da 239{
eea49cf1 240 return dev_clear();
0aba65da
UH
241}
242
8f996b89
ML
243static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
244 const struct sr_probe_group *probe_group)
0aba65da
UH
245{
246 struct dev_context *devc;
247
8f996b89
ML
248 (void)probe_group;
249
0c05591a
BV
250 if (!sdi)
251 return SR_ERR_ARG;
252
253 devc = sdi->priv;
035a1078 254 switch (id) {
123e1313 255 case SR_CONF_SAMPLERATE:
0c05591a
BV
256 *data = g_variant_new_uint64(devc->cur_samplerate);
257 break;
258 case SR_CONF_CAPTURE_RATIO:
259 *data = g_variant_new_uint64(devc->capture_ratio);
260 break;
261 case SR_CONF_LIMIT_SAMPLES:
262 *data = g_variant_new_uint64(devc->limit_samples);
263 break;
967760a8
MR
264 case SR_CONF_PATTERN_MODE:
265 if (devc->flag_reg & FLAG_EXTERNAL_TEST_MODE)
266 *data = g_variant_new_string(STR_PATTERN_EXTERNAL);
267 else if (devc->flag_reg & FLAG_INTERNAL_TEST_MODE)
268 *data = g_variant_new_string(STR_PATTERN_INTERNAL);
269 break;
0c05591a
BV
270 case SR_CONF_RLE:
271 *data = g_variant_new_boolean(devc->flag_reg & FLAG_RLE ? TRUE : FALSE);
0aba65da
UH
272 break;
273 default:
bd6fbf62 274 return SR_ERR_NA;
0aba65da
UH
275 }
276
277 return SR_OK;
278}
279
8f996b89
ML
280static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
281 const struct sr_probe_group *probe_group)
0aba65da
UH
282{
283 struct dev_context *devc;
284 int ret;
e46aa4f6 285 uint64_t tmp_u64;
967760a8 286 const char *stropt;
0aba65da 287
8f996b89
ML
288 (void)probe_group;
289
e73ffd42
BV
290 if (sdi->status != SR_ST_ACTIVE)
291 return SR_ERR_DEV_CLOSED;
292
0aba65da
UH
293 devc = sdi->priv;
294
035a1078 295 switch (id) {
1953564a 296 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
297 tmp_u64 = g_variant_get_uint64(data);
298 if (tmp_u64 < samplerates[0] || tmp_u64 > samplerates[1])
299 return SR_ERR_SAMPLERATE;
300 ret = ols_set_samplerate(sdi, g_variant_get_uint64(data));
0aba65da 301 break;
1953564a 302 case SR_CONF_LIMIT_SAMPLES:
e46aa4f6
BV
303 tmp_u64 = g_variant_get_uint64(data);
304 if (tmp_u64 < MIN_NUM_SAMPLES)
0aba65da 305 return SR_ERR;
e46aa4f6 306 devc->limit_samples = tmp_u64;
0aba65da
UH
307 ret = SR_OK;
308 break;
1953564a 309 case SR_CONF_CAPTURE_RATIO:
e46aa4f6 310 devc->capture_ratio = g_variant_get_uint64(data);
0aba65da
UH
311 if (devc->capture_ratio < 0 || devc->capture_ratio > 100) {
312 devc->capture_ratio = 0;
313 ret = SR_ERR;
314 } else
315 ret = SR_OK;
316 break;
eb1b610b
MR
317 case SR_CONF_EXTERNAL_CLOCK:
318 if (g_variant_get_boolean(data)) {
319 sr_info("Enabling external clock.");
320 devc->flag_reg |= FLAG_CLOCK_EXTERNAL;
321 } else {
322 sr_info("Disabled external clock.");
323 devc->flag_reg &= ~FLAG_CLOCK_EXTERNAL;
324 }
325 ret = SR_OK;
326 break;
967760a8
MR
327 case SR_CONF_PATTERN_MODE:
328 stropt = g_variant_get_string(data, NULL);
329 ret = SR_OK;
330 if (!strcmp(stropt, STR_PATTERN_INTERNAL)) {
331 sr_info("Enabling internal test mode.");
332 devc->flag_reg |= FLAG_INTERNAL_TEST_MODE;
333 } else if (!strcmp(stropt, STR_PATTERN_EXTERNAL)) {
334 sr_info("Enabling external test mode.");
335 devc->flag_reg |= FLAG_EXTERNAL_TEST_MODE;
336 } else {
337 ret = SR_ERR;
338 }
339 break;
7b0a57fd
MR
340 case SR_CONF_SWAP:
341 if (g_variant_get_boolean(data)) {
342 sr_info("Enabling channel swapping.");
343 devc->flag_reg |= FLAG_SWAP_PROBES;
344 } else {
345 sr_info("Disabling channel swapping.");
346 devc->flag_reg &= ~FLAG_SWAP_PROBES;
347 }
348 ret = SR_OK;
349 break;
350
1953564a 351 case SR_CONF_RLE:
e46aa4f6 352 if (g_variant_get_boolean(data)) {
0aba65da
UH
353 sr_info("Enabling RLE.");
354 devc->flag_reg |= FLAG_RLE;
aeea0572
BV
355 } else {
356 sr_info("Disabling RLE.");
357 devc->flag_reg &= ~FLAG_RLE;
0aba65da
UH
358 }
359 ret = SR_OK;
360 break;
361 default:
bd6fbf62 362 ret = SR_ERR_NA;
0aba65da
UH
363 }
364
365 return ret;
366}
367
8f996b89
ML
368static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
369 const struct sr_probe_group *probe_group)
a1c743fc 370{
e46aa4f6
BV
371 GVariant *gvar;
372 GVariantBuilder gvb;
a1c743fc
BV
373
374 (void)sdi;
8f996b89 375 (void)probe_group;
a1c743fc
BV
376
377 switch (key) {
0d485e30 378 case SR_CONF_SCAN_OPTIONS:
e46aa4f6
BV
379 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
380 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
0d485e30 381 break;
9a6517d1 382 case SR_CONF_DEVICE_OPTIONS:
e46aa4f6
BV
383 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
384 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
9a6517d1 385 break;
a1c743fc 386 case SR_CONF_SAMPLERATE:
e46aa4f6
BV
387 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
388 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
389 ARRAY_SIZE(samplerates), sizeof(uint64_t));
390 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
391 *data = g_variant_builder_end(&gvb);
a1c743fc 392 break;
c50277a6 393 case SR_CONF_TRIGGER_TYPE:
e46aa4f6 394 *data = g_variant_new_string(TRIGGER_TYPE);
c50277a6 395 break;
7c07a178
UH
396 case SR_CONF_PATTERN_MODE:
397 *data = g_variant_new_strv(patterns, ARRAY_SIZE(patterns));
398 break;
a1c743fc 399 default:
bd6fbf62 400 return SR_ERR_NA;
a1c743fc
BV
401 }
402
403 return SR_OK;
404}
405
03f4de8c 406static int dev_acquisition_start(const struct sr_dev_inst *sdi,
0aba65da
UH
407 void *cb_data)
408{
0aba65da 409 struct dev_context *devc;
459a0f26 410 struct sr_serial_dev_inst *serial;
0aba65da
UH
411 uint32_t trigger_config[4];
412 uint32_t data;
413 uint16_t readcount, delaycount;
414 uint8_t changrp_mask;
415 int num_channels;
416 int i;
417
e73ffd42
BV
418 if (sdi->status != SR_ST_ACTIVE)
419 return SR_ERR_DEV_CLOSED;
420
0aba65da 421 devc = sdi->priv;
459a0f26 422 serial = sdi->conn;
0aba65da 423
0aba65da
UH
424 if (ols_configure_probes(sdi) != SR_OK) {
425 sr_err("Failed to configure probes.");
426 return SR_ERR;
427 }
428
429 /*
430 * Enable/disable channel groups in the flag register according to the
431 * probe mask. Calculate this here, because num_channels is needed
432 * to limit readcount.
433 */
434 changrp_mask = 0;
435 num_channels = 0;
436 for (i = 0; i < 4; i++) {
437 if (devc->probe_mask & (0xff << (i * 8))) {
438 changrp_mask |= (1 << i);
439 num_channels++;
440 }
441 }
442
443 /*
444 * Limit readcount to prevent reading past the end of the hardware
445 * buffer.
446 */
447 readcount = MIN(devc->max_samples / num_channels, devc->limit_samples) / 4;
448
449 memset(trigger_config, 0, 16);
2e5b73c0 450 trigger_config[devc->num_stages] |= 0x08;
0aba65da
UH
451 if (devc->trigger_mask[0]) {
452 delaycount = readcount * (1 - devc->capture_ratio / 100.0);
453 devc->trigger_at = (readcount - delaycount) * 4 - devc->num_stages;
454
459a0f26 455 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_0,
0aba65da
UH
456 reverse32(devc->trigger_mask[0])) != SR_OK)
457 return SR_ERR;
459a0f26 458 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_0,
0aba65da
UH
459 reverse32(devc->trigger_value[0])) != SR_OK)
460 return SR_ERR;
459a0f26 461 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_0,
0aba65da
UH
462 trigger_config[0]) != SR_OK)
463 return SR_ERR;
464
459a0f26 465 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_1,
0aba65da
UH
466 reverse32(devc->trigger_mask[1])) != SR_OK)
467 return SR_ERR;
459a0f26 468 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_1,
0aba65da
UH
469 reverse32(devc->trigger_value[1])) != SR_OK)
470 return SR_ERR;
459a0f26 471 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_1,
0aba65da
UH
472 trigger_config[1]) != SR_OK)
473 return SR_ERR;
474
459a0f26 475 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_2,
0aba65da
UH
476 reverse32(devc->trigger_mask[2])) != SR_OK)
477 return SR_ERR;
459a0f26 478 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_2,
0aba65da
UH
479 reverse32(devc->trigger_value[2])) != SR_OK)
480 return SR_ERR;
459a0f26 481 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_2,
0aba65da
UH
482 trigger_config[2]) != SR_OK)
483 return SR_ERR;
484
459a0f26 485 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_3,
0aba65da
UH
486 reverse32(devc->trigger_mask[3])) != SR_OK)
487 return SR_ERR;
459a0f26 488 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_3,
0aba65da
UH
489 reverse32(devc->trigger_value[3])) != SR_OK)
490 return SR_ERR;
459a0f26 491 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_3,
0aba65da
UH
492 trigger_config[3]) != SR_OK)
493 return SR_ERR;
494 } else {
459a0f26 495 if (send_longcommand(serial, CMD_SET_TRIGGER_MASK_0,
0aba65da
UH
496 devc->trigger_mask[0]) != SR_OK)
497 return SR_ERR;
459a0f26 498 if (send_longcommand(serial, CMD_SET_TRIGGER_VALUE_0,
0aba65da
UH
499 devc->trigger_value[0]) != SR_OK)
500 return SR_ERR;
459a0f26 501 if (send_longcommand(serial, CMD_SET_TRIGGER_CONFIG_0,
0aba65da
UH
502 0x00000008) != SR_OK)
503 return SR_ERR;
504 delaycount = readcount;
505 }
506
507 sr_info("Setting samplerate to %" PRIu64 "Hz (divider %u, "
de524099
MR
508 "demux %s, noise_filter %s)", devc->cur_samplerate,
509 devc->cur_samplerate_divider,
510 devc->flag_reg & FLAG_DEMUX ? "on" : "off",
511 devc->flag_reg & FLAG_FILTER ? "on": "off");
459a0f26 512 if (send_longcommand(serial, CMD_SET_DIVIDER,
0aba65da
UH
513 reverse32(devc->cur_samplerate_divider)) != SR_OK)
514 return SR_ERR;
515
516 /* Send sample limit and pre/post-trigger capture ratio. */
517 data = ((readcount - 1) & 0xffff) << 16;
518 data |= (delaycount - 1) & 0xffff;
459a0f26 519 if (send_longcommand(serial, CMD_CAPTURE_SIZE, reverse16(data)) != SR_OK)
0aba65da
UH
520 return SR_ERR;
521
522 /* The flag register wants them here, and 1 means "disable channel". */
523 devc->flag_reg |= ~(changrp_mask << 2) & 0x3c;
0aba65da
UH
524 devc->rle_count = 0;
525 data = (devc->flag_reg << 24) | ((devc->flag_reg << 8) & 0xff0000);
459a0f26 526 if (send_longcommand(serial, CMD_SET_FLAGS, data) != SR_OK)
0aba65da
UH
527 return SR_ERR;
528
529 /* Start acquisition on the device. */
459a0f26 530 if (send_shortcommand(serial, CMD_RUN) != SR_OK)
0aba65da
UH
531 return SR_ERR;
532
bf256783
BV
533 /* Reset all operational states. */
534 devc->num_transfers = devc->num_samples = devc->num_bytes = 0;
abb39e6b 535 memset(devc->sample, 0, 4);
bf256783 536
4afdfd46 537 /* Send header packet to the session bus. */
29a27196 538 std_session_send_df_header(cb_data, LOG_PREFIX);
4afdfd46 539
abc4b335 540 serial_source_add(serial, G_IO_IN, -1, ols_receive_data, cb_data);
0aba65da 541
0aba65da
UH
542 return SR_OK;
543}
544
03f4de8c 545static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
0aba65da 546{
0aba65da
UH
547 (void)cb_data;
548
549 abort_acquisition(sdi);
550
551 return SR_OK;
552}
553
554SR_PRIV struct sr_dev_driver ols_driver_info = {
555 .name = "ols",
556 .longname = "Openbench Logic Sniffer",
557 .api_version = 1,
03f4de8c 558 .init = init,
eea49cf1 559 .cleanup = cleanup,
03f4de8c
BV
560 .scan = scan,
561 .dev_list = dev_list,
562 .dev_clear = dev_clear,
035a1078
BV
563 .config_get = config_get,
564 .config_set = config_set,
a1c743fc 565 .config_list = config_list,
03f4de8c
BV
566 .dev_open = dev_open,
567 .dev_close = dev_close,
568 .dev_acquisition_start = dev_acquisition_start,
569 .dev_acquisition_stop = dev_acquisition_stop,
0aba65da
UH
570 .priv = NULL,
571};