]> sigrok.org Git - libsigrok.git/blame - hardware/demo/demo.c
Enforce open device before config_set()/dev_acquisition_start()
[libsigrok.git] / hardware / demo / demo.c
CommitLineData
6239c175 1/*
50985c20 2 * This file is part of the libsigrok project.
6239c175
UH
3 *
4 * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
fc96e6f8 5 * Copyright (C) 2011 Olivier Fauchon <olivier@aixmarseille.com>
c216d623 6 * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
6239c175
UH
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <stdlib.h>
85b5af06 24#include <unistd.h>
6239c175 25#include <string.h>
d35aaf02
UH
26#ifdef _WIN32
27#include <io.h>
28#include <fcntl.h>
29#define pipe(fds) _pipe(fds, 4096, _O_BINARY)
30#endif
45c59c8b
BV
31#include "libsigrok.h"
32#include "libsigrok-internal.h"
6239c175 33
92bcedf6
UH
34/* Message logging helpers with driver-specific prefix string. */
35#define DRIVER_LOG_DOMAIN "demo: "
36#define sr_log(l, s, args...) sr_log(l, DRIVER_LOG_DOMAIN s, ## args)
37#define sr_spew(s, args...) sr_spew(DRIVER_LOG_DOMAIN s, ## args)
38#define sr_dbg(s, args...) sr_dbg(DRIVER_LOG_DOMAIN s, ## args)
39#define sr_info(s, args...) sr_info(DRIVER_LOG_DOMAIN s, ## args)
40#define sr_warn(s, args...) sr_warn(DRIVER_LOG_DOMAIN s, ## args)
41#define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args)
42
c03ed397 43/* TODO: Number of probes should be configurable. */
e15f48c2 44#define NUM_PROBES 8
c03ed397 45
e15f48c2 46#define DEMONAME "Demo device"
c03ed397
UH
47
48/* The size of chunks to send through the session bus. */
49/* TODO: Should be configurable. */
e15f48c2 50#define BUFSIZE 4096
85b5af06 51
2474d87e
BV
52#define STR_PATTERN_SIGROK "sigrok"
53#define STR_PATTERN_RANDOM "random"
54#define STR_PATTERN_INC "incremental"
55#define STR_PATTERN_ALL_LOW "all-low"
56#define STR_PATTERN_ALL_HIGH "all-high"
57
0d31276b 58/* Supported patterns which we can generate */
e15f48c2 59enum {
0d31276b
UH
60 /**
61 * Pattern which spells "sigrok" using '0's (with '1's as "background")
62 * when displayed using the 'bits' output format.
63 */
c8f4624d 64 PATTERN_SIGROK,
0d31276b 65
c03ed397 66 /** Pattern which consists of (pseudo-)random values on all probes. */
c8f4624d 67 PATTERN_RANDOM,
0d31276b
UH
68
69 /**
70 * Pattern which consists of incrementing numbers.
71 * TODO: Better description.
72 */
c8f4624d 73 PATTERN_INC,
c03ed397
UH
74
75 /** Pattern where all probes have a low logic state. */
76 PATTERN_ALL_LOW,
77
78 /** Pattern where all probes have a high logic state. */
79 PATTERN_ALL_HIGH,
e15f48c2 80};
85b5af06 81
b4750a3a
BV
82/* Private, per-device-instance driver context. */
83struct dev_context {
33ef7573 84 struct sr_dev_inst *sdi;
e15f48c2 85 int pipe_fds[2];
e0532047 86 GIOChannel *channel;
a7684294
JH
87 uint64_t cur_samplerate;
88 uint64_t limit_samples;
89 uint64_t limit_msec;
e15f48c2 90 uint8_t sample_generator;
e15f48c2 91 uint64_t samples_counter;
3e9b7f9c 92 void *cb_data;
3b203673 93 int64_t starttime;
e15f48c2 94};
85b5af06 95
915f7cc8 96static const int hwcaps[] = {
1953564a
BV
97 SR_CONF_LOGIC_ANALYZER,
98 SR_CONF_DEMO_DEV,
99 SR_CONF_SAMPLERATE,
100 SR_CONF_PATTERN_MODE,
101 SR_CONF_LIMIT_SAMPLES,
102 SR_CONF_LIMIT_MSEC,
103 SR_CONF_CONTINUOUS,
6239c175
UH
104};
105
d00088ca
BV
106static const uint64_t samplerates[] = {
107 SR_HZ(1),
108 SR_GHZ(1),
109 SR_HZ(1),
4bfbf9fc
BV
110};
111
c8f4624d 112static const char *pattern_strings[] = {
c03ed397 113 "sigrok",
e15f48c2
BV
114 "random",
115 "incremental",
c03ed397
UH
116 "all-low",
117 "all-high",
85b5af06
UH
118};
119
d261dbbf 120/* We name the probes 0-7 on our demo driver. */
464d12c7 121static const char *probe_names[NUM_PROBES + 1] = {
78693401 122 "0", "1", "2", "3", "4", "5", "6", "7",
464d12c7
KS
123 NULL,
124};
125
c8f4624d 126static uint8_t pattern_sigrok[] = {
917e0e71
BV
127 0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
128 0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
129 0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
130 0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
131 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
132 0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135};
136
ea9cfed7
UH
137/* Private, per-device-instance driver context. */
138/* TODO: struct context as with the other drivers. */
139
e7eb703f 140/* List of struct sr_dev_inst, maintained by dev_open()/dev_close(). */
dcf03d6d 141SR_PRIV struct sr_dev_driver demo_driver_info;
a873c594 142static struct sr_dev_driver *di = &demo_driver_info;
6239c175 143
69b07d14 144static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
6239c175 145
eebb6067
UH
146static int clear_instances(void)
147{
148 /* Nothing needed so far. */
149
150 return SR_OK;
151}
152
34f06b90 153static int hw_init(struct sr_context *sr_ctx)
61136ea6 154{
063e7aef 155 return std_hw_init(sr_ctx, di, DRIVER_LOG_DOMAIN);
61136ea6
BV
156}
157
067d0716 158static GSList *hw_scan(GSList *options)
6239c175 159{
d68e2d1a 160 struct sr_dev_inst *sdi;
87ca93c5 161 struct sr_probe *probe;
b4750a3a 162 struct drv_context *drvc;
33ef7573 163 struct dev_context *devc;
067d0716 164 GSList *devices;
87ca93c5 165 int i;
067d0716
BV
166
167 (void)options;
64d33dc2 168
a873c594 169 drvc = di->priv;
4b97c74e 170
067d0716 171 devices = NULL;
85b5af06 172
d3683c42 173 sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, DEMONAME, NULL, NULL);
c03ed397 174 if (!sdi) {
e45ad6e2
UH
175 sr_err("Device instance creation failed.");
176 return NULL;
c03ed397 177 }
a873c594 178 sdi->driver = di;
e15f48c2 179
87ca93c5 180 for (i = 0; probe_names[i]; i++) {
de6e0eca 181 if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
87ca93c5
BV
182 probe_names[i])))
183 return NULL;
184 sdi->probes = g_slist_append(sdi->probes, probe);
185 }
186
067d0716 187 devices = g_slist_append(devices, sdi);
b4750a3a 188 drvc->instances = g_slist_append(drvc->instances, sdi);
85b5af06 189
33ef7573 190 if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
e45ad6e2
UH
191 sr_err("Device context malloc failed.");
192 return NULL;
33ef7573
JH
193 }
194
195 devc->sdi = sdi;
a7684294
JH
196 devc->cur_samplerate = SR_KHZ(200);
197 devc->limit_samples = 0;
198 devc->limit_msec = 0;
199 devc->sample_generator = PATTERN_SIGROK;
33ef7573
JH
200
201 sdi->priv = devc;
202
067d0716 203 return devices;
6239c175
UH
204}
205
811deee4
BV
206static GSList *hw_dev_list(void)
207{
0e94d524 208 return ((struct drv_context *)(di->priv))->instances;
811deee4
BV
209}
210
25a0f108 211static int hw_dev_open(struct sr_dev_inst *sdi)
6239c175 212{
25a0f108 213 (void)sdi;
6239c175 214
e73ffd42 215 sdi->status = SR_ST_ACTIVE;
697785d1 216
e46b8fb1 217 return SR_OK;
6239c175
UH
218}
219
25a0f108 220static int hw_dev_close(struct sr_dev_inst *sdi)
6239c175 221{
25a0f108 222 (void)sdi;
6239c175 223
e73ffd42 224 sdi->status = SR_ST_INACTIVE;
697785d1
UH
225
226 return SR_OK;
6239c175
UH
227}
228
57ab7d9f 229static int hw_cleanup(void)
6239c175 230{
ed20a428
JH
231 GSList *l;
232 struct sr_dev_inst *sdi;
233 struct drv_context *drvc;
234 int ret = SR_OK;
235
236 if (!(drvc = di->priv))
237 return SR_OK;
238
239 /* Properly close and free all devices. */
240 for (l = drvc->instances; l; l = l->next) {
241 if (!(sdi = l->data)) {
242 /* Log error, but continue cleaning up the rest. */
243 sr_err("%s: sdi was NULL, continuing", __func__);
244 ret = SR_ERR_BUG;
245 continue;
246 }
247 sr_dev_inst_free(sdi);
248 }
249 g_slist_free(drvc->instances);
250 drvc->instances = NULL;
251
252 return ret;
6239c175
UH
253}
254
d00088ca 255static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
6239c175 256{
a7684294 257 struct dev_context *const devc = sdi->priv;
6f57fd96 258
035a1078 259 switch (id) {
123e1313 260 case SR_CONF_SAMPLERATE:
a7684294 261 *data = g_variant_new_uint64(devc->cur_samplerate);
6239c175 262 break;
2474d87e 263 case SR_CONF_LIMIT_SAMPLES:
a7684294 264 *data = g_variant_new_uint64(devc->limit_samples);
2474d87e
BV
265 break;
266 case SR_CONF_LIMIT_MSEC:
a7684294 267 *data = g_variant_new_uint64(devc->limit_msec);
2474d87e
BV
268 break;
269 case SR_CONF_PATTERN_MODE:
a7684294 270 switch (devc->sample_generator) {
2474d87e 271 case PATTERN_SIGROK:
d00088ca 272 *data = g_variant_new_string(STR_PATTERN_SIGROK);
2474d87e
BV
273 break;
274 case PATTERN_RANDOM:
d00088ca 275 *data = g_variant_new_string(STR_PATTERN_RANDOM);
2474d87e
BV
276 break;
277 case PATTERN_INC:
d00088ca 278 *data = g_variant_new_string(STR_PATTERN_INC);
2474d87e
BV
279 break;
280 case PATTERN_ALL_LOW:
d00088ca 281 *data = g_variant_new_string(STR_PATTERN_ALL_LOW);
2474d87e
BV
282 break;
283 case PATTERN_ALL_HIGH:
d00088ca 284 *data = g_variant_new_string(STR_PATTERN_ALL_HIGH);
2474d87e
BV
285 break;
286 }
287 break;
7dfcf010 288 default:
bd6fbf62 289 return SR_ERR_NA;
6239c175
UH
290 }
291
dfb0fa1a 292 return SR_OK;
6239c175
UH
293}
294
d00088ca 295static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
6239c175
UH
296{
297 int ret;
1b79df2f 298 const char *stropt;
6239c175 299
a7684294 300 struct dev_context *const devc = sdi->priv;
6239c175 301
e73ffd42
BV
302 if (sdi->status != SR_ST_ACTIVE)
303 return SR_ERR_DEV_CLOSED;
304
035a1078 305 if (id == SR_CONF_SAMPLERATE) {
a7684294 306 devc->cur_samplerate = g_variant_get_uint64(data);
92bcedf6 307 sr_dbg("%s: setting samplerate to %" PRIu64, __func__,
a7684294 308 devc->cur_samplerate);
e46b8fb1 309 ret = SR_OK;
035a1078 310 } else if (id == SR_CONF_LIMIT_SAMPLES) {
a7684294
JH
311 devc->limit_msec = 0;
312 devc->limit_samples = g_variant_get_uint64(data);
92bcedf6 313 sr_dbg("%s: setting limit_samples to %" PRIu64, __func__,
a7684294 314 devc->limit_samples);
e46b8fb1 315 ret = SR_OK;
035a1078 316 } else if (id == SR_CONF_LIMIT_MSEC) {
a7684294
JH
317 devc->limit_msec = g_variant_get_uint64(data);
318 devc->limit_samples = 0;
92bcedf6 319 sr_dbg("%s: setting limit_msec to %" PRIu64, __func__,
a7684294 320 devc->limit_msec);
e46b8fb1 321 ret = SR_OK;
035a1078 322 } else if (id == SR_CONF_PATTERN_MODE) {
d00088ca 323 stropt = g_variant_get_string(data, NULL);
c03ed397 324 ret = SR_OK;
2474d87e 325 if (!strcmp(stropt, STR_PATTERN_SIGROK)) {
a7684294 326 devc->sample_generator = PATTERN_SIGROK;
2474d87e 327 } else if (!strcmp(stropt, STR_PATTERN_RANDOM)) {
a7684294 328 devc->sample_generator = PATTERN_RANDOM;
2474d87e 329 } else if (!strcmp(stropt, STR_PATTERN_INC)) {
a7684294 330 devc->sample_generator = PATTERN_INC;
2474d87e 331 } else if (!strcmp(stropt, STR_PATTERN_ALL_LOW)) {
a7684294 332 devc->sample_generator = PATTERN_ALL_LOW;
2474d87e 333 } else if (!strcmp(stropt, STR_PATTERN_ALL_HIGH)) {
a7684294 334 devc->sample_generator = PATTERN_ALL_HIGH;
e15f48c2 335 } else {
e46b8fb1 336 ret = SR_ERR;
e15f48c2 337 }
a7684294
JH
338 sr_dbg("%s: setting pattern to %d",
339 __func__, devc->sample_generator);
6239c175 340 } else {
bd6fbf62 341 ret = SR_ERR_NA;
6239c175
UH
342 }
343
344 return ret;
345}
346
d00088ca 347static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
a1c743fc 348{
d00088ca
BV
349 GVariant *gvar;
350 GVariantBuilder gvb;
a1c743fc
BV
351
352 (void)sdi;
353
354 switch (key) {
9a6517d1 355 case SR_CONF_DEVICE_OPTIONS:
d00088ca
BV
356 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
357 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
9a6517d1 358 break;
a1c743fc 359 case SR_CONF_SAMPLERATE:
d00088ca
BV
360 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
361 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
362 ARRAY_SIZE(samplerates), sizeof(uint64_t));
363 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
364 *data = g_variant_builder_end(&gvb);
a1c743fc 365 break;
dd96ea98 366 case SR_CONF_PATTERN_MODE:
d00088ca 367 *data = g_variant_new_strv(pattern_strings, ARRAY_SIZE(pattern_strings));
dd96ea98 368 break;
a1c743fc 369 default:
bd6fbf62 370 return SR_ERR_NA;
a1c743fc
BV
371 }
372
373 return SR_OK;
374}
375
3b203673
AG
376static void samples_generator(uint8_t *buf, uint64_t size,
377 struct dev_context *devc)
85b5af06 378{
cddd1c5f 379 static uint64_t p = 0;
cddd1c5f 380 uint64_t i;
85b5af06 381
c03ed397 382 /* TODO: Needed? */
5096c6a6 383 memset(buf, 0, size);
85b5af06 384
b4750a3a 385 switch (devc->sample_generator) {
c03ed397 386 case PATTERN_SIGROK: /* sigrok pattern */
917e0e71 387 for (i = 0; i < size; i++) {
bbd7ef0f
JH
388 *(buf + i) = ~(pattern_sigrok[
389 p++ % sizeof(pattern_sigrok)] >> 1);
917e0e71
BV
390 }
391 break;
c8f4624d 392 case PATTERN_RANDOM: /* Random */
5096c6a6
UH
393 for (i = 0; i < size; i++)
394 *(buf + i) = (uint8_t)(rand() & 0xff);
85b5af06 395 break;
c8f4624d 396 case PATTERN_INC: /* Simple increment */
5096c6a6 397 for (i = 0; i < size; i++)
bbd7ef0f 398 *(buf + i) = p++;
85b5af06 399 break;
c03ed397 400 case PATTERN_ALL_LOW: /* All probes are low */
5a9660dd 401 memset(buf, 0x00, size);
c03ed397
UH
402 break;
403 case PATTERN_ALL_HIGH: /* All probes are high */
5a9660dd 404 memset(buf, 0xff, size);
c03ed397
UH
405 break;
406 default:
92bcedf6 407 sr_err("Unknown pattern: %d.", devc->sample_generator);
c03ed397 408 break;
85b5af06
UH
409 }
410}
411
85b5af06 412/* Callback handling data */
1f9813eb 413static int receive_data(int fd, int revents, void *cb_data)
85b5af06 414{
b4750a3a 415 struct dev_context *devc = cb_data;
b9c735a2 416 struct sr_datafeed_packet packet;
9c939c51 417 struct sr_datafeed_logic logic;
3b203673
AG
418 uint8_t buf[BUFSIZE];
419 static uint64_t samples_to_send, expected_samplenum, sending_now;
420 int64_t time, elapsed;
1924f59f 421
cb93f8a9
UH
422 (void)fd;
423 (void)revents;
1924f59f 424
3b203673
AG
425 /* How many "virtual" samples should we have collected by now? */
426 time = g_get_monotonic_time();
427 elapsed = time - devc->starttime;
a7684294 428 expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
3b203673
AG
429 /* Of those, how many do we still have to send? */
430 samples_to_send = expected_samplenum - devc->samples_counter;
431
a7684294 432 if (devc->limit_samples) {
3b203673 433 samples_to_send = MIN(samples_to_send,
a7684294 434 devc->limit_samples - devc->samples_counter);
3b203673 435 }
85b5af06 436
3b203673
AG
437 while (samples_to_send > 0) {
438 sending_now = MIN(samples_to_send, sizeof(buf));
439 samples_to_send -= sending_now;
440 samples_generator(buf, sending_now, devc);
441
442 packet.type = SR_DF_LOGIC;
443 packet.payload = &logic;
444 logic.length = sending_now;
445 logic.unitsize = 1;
446 logic.data = buf;
3e9b7f9c 447 sr_session_send(devc->cb_data, &packet);
3b203673
AG
448 devc->samples_counter += sending_now;
449 }
450
a7684294
JH
451 if (devc->limit_samples &&
452 devc->samples_counter >= devc->limit_samples) {
35e199da 453 sr_info("Requested number of samples reached.");
33ef7573 454 hw_dev_acquisition_stop(devc->sdi, cb_data);
c216d623 455 return TRUE;
85b5af06 456 }
1924f59f 457
85b5af06
UH
458 return TRUE;
459}
460
3ffb6964
BV
461static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
462 void *cb_data)
6239c175 463{
33ef7573 464 struct dev_context *const devc = sdi->priv;
85b5af06 465
e73ffd42
BV
466 if (sdi->status != SR_ST_ACTIVE)
467 return SR_ERR_DEV_CLOSED;
468
3e9b7f9c 469 devc->cb_data = cb_data;
b4750a3a 470 devc->samples_counter = 0;
85b5af06 471
3b203673
AG
472 /*
473 * Setting two channels connected by a pipe is a remnant from when the
474 * demo driver generated data in a thread, and collected and sent the
475 * data in the main program loop.
476 * They are kept here because it provides a convenient way of setting
477 * up a timeout-based polling mechanism.
478 */
b4750a3a 479 if (pipe(devc->pipe_fds)) {
c03ed397 480 /* TODO: Better error message. */
92bcedf6 481 sr_err("%s: pipe() failed", __func__);
e46b8fb1 482 return SR_ERR;
c03ed397 483 }
85b5af06 484
e0532047 485 devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
d35aaf02 486
e0532047 487 g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
e6e8f8e0 488
d35aaf02 489 /* Set channel encoding to binary (default is UTF-8). */
e0532047 490 g_io_channel_set_encoding(devc->channel, NULL, NULL);
d35aaf02
UH
491
492 /* Make channels to unbuffered. */
e0532047 493 g_io_channel_set_buffered(devc->channel, FALSE);
d35aaf02 494
e0532047 495 sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
b4750a3a 496 40, receive_data, devc);
85b5af06 497
4afdfd46
UH
498 /* Send header packet to the session bus. */
499 std_session_send_df_header(cb_data, DRIVER_LOG_DOMAIN);
f366e86c 500
3b203673
AG
501 /* We use this timestamp to decide how many more samples to send. */
502 devc->starttime = g_get_monotonic_time();
503
e46b8fb1 504 return SR_OK;
6239c175
UH
505}
506
69b07d14 507static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
6239c175 508{
33ef7573 509 struct dev_context *const devc = sdi->priv;
c216d623 510 struct sr_datafeed_packet packet;
7fd3e859 511
33ef7573 512 (void)cb_data;
7fd3e859 513
49145a63
AG
514 sr_dbg("Stopping aquisition.");
515
e0532047
JH
516 sr_session_source_remove_channel(devc->channel);
517 g_io_channel_shutdown(devc->channel, FALSE, NULL);
2150a69b
JH
518 g_io_channel_unref(devc->channel);
519 devc->channel = NULL;
c216d623
AG
520
521 /* Send last packet. */
522 packet.type = SR_DF_END;
3e9b7f9c 523 sr_session_send(devc->cb_data, &packet);
7fd3e859 524
3010f21c 525 return SR_OK;
6239c175
UH
526}
527
c09f0b57 528SR_PRIV struct sr_dev_driver demo_driver_info = {
e519ba86
UH
529 .name = "demo",
530 .longname = "Demo driver and pattern generator",
531 .api_version = 1,
532 .init = hw_init,
533 .cleanup = hw_cleanup,
61136ea6 534 .scan = hw_scan,
811deee4 535 .dev_list = hw_dev_list,
eebb6067 536 .dev_clear = clear_instances,
035a1078
BV
537 .config_get = config_get,
538 .config_set = config_set,
a1c743fc 539 .config_list = config_list,
e7eb703f
UH
540 .dev_open = hw_dev_open,
541 .dev_close = hw_dev_close,
69040b7c
UH
542 .dev_acquisition_start = hw_dev_acquisition_start,
543 .dev_acquisition_stop = hw_dev_acquisition_stop,
b4750a3a 544 .priv = NULL,
6239c175 545};