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