2 * This file is part of the libsigrok project.
4 * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
5 * Copyright (C) 2011 Olivier Fauchon <olivier@aixmarseille.com>
6 * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
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.
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.
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
30 #define pipe(fds) _pipe(fds, 4096, _O_BINARY)
32 #include "libsigrok.h"
33 #include "libsigrok-internal.h"
35 #define LOG_PREFIX "demo"
37 #define DEFAULT_NUM_LOGIC_CHANNELS 8
38 #define DEFAULT_NUM_ANALOG_CHANNELS 4
40 /* The size in bytes of chunks to send through the session bus. */
41 #define LOGIC_BUFSIZE 4096
42 /* Size of the analog pattern space per channel. */
43 #define ANALOG_BUFSIZE 4096
45 #define DEFAULT_ANALOG_AMPLITUDE 25
46 #define ANALOG_SAMPLES_PER_PERIOD 20
48 /* Logic patterns we can generate. */
51 * Spells "sigrok" across 8 channels using '0's (with '1's as
52 * "background") when displayed using the 'bits' output format.
53 * The pattern is repeated every 8 channels, shifted to the right
58 /** Pseudo-random values on all channels. */
62 * Incrementing number across 8 channels. The pattern is repeated
63 * every 8 channels, shifted to the right in time by one bit.
67 /** All channels have a low logic state. */
70 /** All channels have a high logic state. */
74 /* Analog patterns we can generate. */
85 static const char *logic_pattern_str[] = {
93 static const char *analog_pattern_str[] = {
103 float pattern_data[ANALOG_BUFSIZE];
104 unsigned int num_samples;
105 struct sr_datafeed_analog packet;
108 /* Private, per-device-instance driver context. */
112 uint64_t cur_samplerate;
114 uint64_t limit_samples;
116 uint64_t logic_counter;
117 uint64_t analog_counter;
121 int32_t num_logic_channels;
122 unsigned int logic_unitsize;
123 /* There is only ever one logic channel group, so its pattern goes here. */
124 uint8_t logic_pattern;
125 unsigned char logic_data[LOGIC_BUFSIZE];
127 int32_t num_analog_channels;
131 static const uint32_t scanopts[] = {
132 SR_CONF_NUM_LOGIC_CHANNELS,
133 SR_CONF_NUM_ANALOG_CHANNELS,
136 static const uint32_t devopts[] = {
138 SR_CONF_LOGIC_ANALYZER,
139 SR_CONF_OSCILLOSCOPE,
141 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,
142 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
145 static const uint32_t devopts_global[] = {
146 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
149 static const uint32_t devopts_cg_logic[] = {
150 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
153 static const uint32_t devopts_cg_analog[] = {
154 SR_CONF_PATTERN_MODE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
155 SR_CONF_AMPLITUDE | SR_CONF_GET | SR_CONF_SET,
158 static const uint64_t samplerates[] = {
164 static uint8_t pattern_sigrok[] = {
165 0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
166 0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
167 0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
168 0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
169 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
170 0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 SR_PRIV struct sr_dev_driver demo_driver_info;
176 static struct sr_dev_driver *di = &demo_driver_info;
178 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
181 static int init(struct sr_context *sr_ctx)
183 return std_init(sr_ctx, di, LOG_PREFIX);
186 static void generate_analog_pattern(struct analog_gen *ag, uint64_t sample_rate)
190 unsigned int num_samples, i;
193 sr_dbg("Generating %s pattern.", analog_pattern_str[ag->pattern]);
195 num_samples = ANALOG_BUFSIZE / sizeof(float);
197 switch (ag->pattern) {
199 value = ag->amplitude;
201 for (i = 0; i < num_samples; i++) {
206 ag->pattern_data[i] = value;
208 ag->num_samples = last_end;
212 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
214 /* Make sure the number of samples we put out is an integer
215 * multiple of our period size */
216 /* FIXME we actually need only one period. A ringbuffer would be
218 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
221 for (i = 0; i < num_samples; i++) {
222 t = (double) i / (double) sample_rate;
223 ag->pattern_data[i] = ag->amplitude *
224 sin(2 * M_PI * frequency * t);
227 ag->num_samples = num_samples;
230 case PATTERN_TRIANGLE:
231 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
233 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
236 for (i = 0; i < num_samples; i++) {
237 t = (double) i / (double) sample_rate;
238 ag->pattern_data[i] = (2 * ag->amplitude / M_PI) *
239 asin(sin(2 * M_PI * frequency * t));
242 ag->num_samples = num_samples;
245 case PATTERN_SAWTOOTH:
246 frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
248 while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
251 for (i = 0; i < num_samples; i++) {
252 t = (double) i / (double) sample_rate;
253 ag->pattern_data[i] = 2 * ag->amplitude *
254 ((t * frequency) - floor(0.5f + t * frequency));
257 ag->num_samples = num_samples;
262 static GSList *scan(GSList *options)
264 struct drv_context *drvc;
265 struct dev_context *devc;
266 struct sr_dev_inst *sdi;
267 struct sr_channel *ch;
268 struct sr_channel_group *cg, *acg;
269 struct sr_config *src;
270 struct analog_gen *ag;
272 int num_logic_channels, num_analog_channels, pattern, i;
273 char channel_name[16];
277 num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS;
278 num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS;
279 for (l = options; l; l = l->next) {
282 case SR_CONF_NUM_LOGIC_CHANNELS:
283 num_logic_channels = g_variant_get_int32(src->data);
285 case SR_CONF_NUM_ANALOG_CHANNELS:
286 num_analog_channels = g_variant_get_int32(src->data);
292 sdi = sr_dev_inst_new(SR_ST_ACTIVE, "Demo device", NULL, NULL);
294 sr_err("Device instance creation failed.");
299 devc = g_malloc(sizeof(struct dev_context));
300 devc->cur_samplerate = SR_KHZ(200);
301 devc->limit_samples = 0;
302 devc->limit_msec = 0;
304 devc->continuous = FALSE;
305 devc->num_logic_channels = num_logic_channels;
306 devc->logic_unitsize = (devc->num_logic_channels + 7) / 8;
307 devc->logic_pattern = PATTERN_SIGROK;
308 devc->num_analog_channels = num_analog_channels;
310 /* Logic channels, all in one channel group. */
311 cg = g_malloc0(sizeof(struct sr_channel_group));
312 cg->name = g_strdup("Logic");
313 for (i = 0; i < num_logic_channels; i++) {
314 sprintf(channel_name, "D%d", i);
315 if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, channel_name)))
317 sdi->channels = g_slist_append(sdi->channels, ch);
318 cg->channels = g_slist_append(cg->channels, ch);
320 sdi->channel_groups = g_slist_append(NULL, cg);
322 /* Analog channels, channel groups and pattern generators. */
324 /* An "Analog" channel group with all analog channels in it. */
325 acg = g_malloc0(sizeof(struct sr_channel_group));
326 acg->name = g_strdup("Analog");
327 sdi->channel_groups = g_slist_append(sdi->channel_groups, acg);
329 devc->ch_ag = g_hash_table_new(g_direct_hash, g_direct_equal);
330 for (i = 0; i < num_analog_channels; i++) {
331 snprintf(channel_name, 16, "A%d", i);
332 ch = sr_channel_new(i + num_logic_channels, SR_CHANNEL_ANALOG,
334 sdi->channels = g_slist_append(sdi->channels, ch);
335 acg->channels = g_slist_append(acg->channels, ch);
337 /* Every analog channel gets its own channel group as well. */
338 cg = g_malloc0(sizeof(struct sr_channel_group));
339 cg->name = g_strdup(channel_name);
340 cg->channels = g_slist_append(NULL, ch);
341 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
343 /* Every channel gets a generator struct. */
344 ag = g_malloc(sizeof(struct analog_gen));
345 ag->amplitude = DEFAULT_ANALOG_AMPLITUDE;
346 ag->packet.channels = cg->channels;
348 ag->packet.mqflags = 0;
349 ag->packet.unit = SR_UNIT_VOLT;
350 ag->packet.data = ag->pattern_data;
351 ag->pattern = pattern;
352 g_hash_table_insert(devc->ch_ag, ch, ag);
354 if (++pattern == ARRAY_SIZE(analog_pattern_str))
359 devices = g_slist_append(devices, sdi);
360 drvc->instances = g_slist_append(drvc->instances, sdi);
365 static GSList *dev_list(void)
367 return ((struct drv_context *)(di->priv))->instances;
370 static int dev_open(struct sr_dev_inst *sdi)
372 sdi->status = SR_ST_ACTIVE;
377 static int dev_close(struct sr_dev_inst *sdi)
379 sdi->status = SR_ST_INACTIVE;
384 static void clear_helper(void *priv)
386 struct dev_context *devc;
392 /* Analog generators. */
393 g_hash_table_iter_init(&iter, devc->ch_ag);
394 while (g_hash_table_iter_next(&iter, NULL, &value))
396 g_hash_table_unref(devc->ch_ag);
400 static int cleanup(void)
402 return std_dev_clear(di, clear_helper);
405 static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
406 const struct sr_channel_group *cg)
408 struct dev_context *devc;
409 struct sr_channel *ch;
410 struct analog_gen *ag;
418 case SR_CONF_SAMPLERATE:
419 *data = g_variant_new_uint64(devc->cur_samplerate);
421 case SR_CONF_LIMIT_SAMPLES:
422 *data = g_variant_new_uint64(devc->limit_samples);
424 case SR_CONF_LIMIT_MSEC:
425 *data = g_variant_new_uint64(devc->limit_msec);
427 case SR_CONF_PATTERN_MODE:
429 return SR_ERR_CHANNEL_GROUP;
430 /* Any channel in the group will do. */
431 ch = cg->channels->data;
432 if (ch->type == SR_CHANNEL_LOGIC) {
433 pattern = devc->logic_pattern;
434 *data = g_variant_new_string(logic_pattern_str[pattern]);
435 } else if (ch->type == SR_CHANNEL_ANALOG) {
436 ag = g_hash_table_lookup(devc->ch_ag, ch);
437 pattern = ag->pattern;
438 *data = g_variant_new_string(analog_pattern_str[pattern]);
442 case SR_CONF_AMPLITUDE:
444 return SR_ERR_CHANNEL_GROUP;
445 /* Any channel in the group will do. */
446 ch = cg->channels->data;
447 if (ch->type != SR_CHANNEL_ANALOG)
449 ag = g_hash_table_lookup(devc->ch_ag, ch);
450 *data = g_variant_new_double(ag->amplitude);
459 static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
460 const struct sr_channel_group *cg)
462 struct dev_context *devc;
463 struct analog_gen *ag;
464 struct sr_channel *ch;
466 int logic_pattern, analog_pattern, ret;
472 if (sdi->status != SR_ST_ACTIVE)
473 return SR_ERR_DEV_CLOSED;
477 case SR_CONF_SAMPLERATE:
478 devc->cur_samplerate = g_variant_get_uint64(data);
479 sr_dbg("Setting samplerate to %" PRIu64, devc->cur_samplerate);
481 case SR_CONF_LIMIT_SAMPLES:
482 devc->limit_msec = 0;
483 devc->limit_samples = g_variant_get_uint64(data);
484 sr_dbg("Setting sample limit to %" PRIu64, devc->limit_samples);
486 case SR_CONF_LIMIT_MSEC:
487 devc->limit_msec = g_variant_get_uint64(data);
488 devc->limit_samples = 0;
489 sr_dbg("Setting time limit to %" PRIu64"ms", devc->limit_msec);
491 case SR_CONF_PATTERN_MODE:
493 return SR_ERR_CHANNEL_GROUP;
494 stropt = g_variant_get_string(data, NULL);
495 logic_pattern = analog_pattern = -1;
496 for (i = 0; i < ARRAY_SIZE(logic_pattern_str); i++) {
497 if (!strcmp(stropt, logic_pattern_str[i])) {
502 for (i = 0; i < ARRAY_SIZE(analog_pattern_str); i++) {
503 if (!strcmp(stropt, analog_pattern_str[i])) {
508 if (logic_pattern == -1 && analog_pattern == -1)
510 for (l = cg->channels; l; l = l->next) {
512 if (ch->type == SR_CHANNEL_LOGIC) {
513 if (logic_pattern == -1)
515 sr_dbg("Setting logic pattern to %s",
516 logic_pattern_str[logic_pattern]);
517 devc->logic_pattern = logic_pattern;
518 /* Might as well do this now, these are static. */
519 if (logic_pattern == PATTERN_ALL_LOW)
520 memset(devc->logic_data, 0x00, LOGIC_BUFSIZE);
521 else if (logic_pattern == PATTERN_ALL_HIGH)
522 memset(devc->logic_data, 0xff, LOGIC_BUFSIZE);
523 } else if (ch->type == SR_CHANNEL_ANALOG) {
524 if (analog_pattern == -1)
526 sr_dbg("Setting analog pattern for channel %s to %s",
527 ch->name, analog_pattern_str[analog_pattern]);
528 ag = g_hash_table_lookup(devc->ch_ag, ch);
529 ag->pattern = analog_pattern;
534 case SR_CONF_AMPLITUDE:
536 return SR_ERR_CHANNEL_GROUP;
537 for (l = cg->channels; l; l = l->next) {
539 if (ch->type != SR_CHANNEL_ANALOG)
541 ag = g_hash_table_lookup(devc->ch_ag, ch);
542 ag->amplitude = g_variant_get_double(data);
552 static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
553 const struct sr_channel_group *cg)
555 struct sr_channel *ch;
561 if (key == SR_CONF_SCAN_OPTIONS) {
562 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
563 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
567 if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
568 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
569 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
578 case SR_CONF_DEVICE_OPTIONS:
579 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
580 devopts_global, ARRAY_SIZE(devopts_global), sizeof(uint32_t));
582 case SR_CONF_SAMPLERATE:
583 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
584 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
585 ARRAY_SIZE(samplerates), sizeof(uint64_t));
586 g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
587 *data = g_variant_builder_end(&gvb);
593 /* Any channel in the group will do. */
594 ch = cg->channels->data;
596 case SR_CONF_DEVICE_OPTIONS:
597 if (ch->type == SR_CHANNEL_LOGIC)
598 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
599 devopts_cg_logic, ARRAY_SIZE(devopts_cg_logic),
601 else if (ch->type == SR_CHANNEL_ANALOG)
602 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
603 devopts_cg_analog, ARRAY_SIZE(devopts_cg_analog),
608 case SR_CONF_PATTERN_MODE:
609 if (ch->type == SR_CHANNEL_LOGIC)
610 *data = g_variant_new_strv(logic_pattern_str,
611 ARRAY_SIZE(logic_pattern_str));
612 else if (ch->type == SR_CHANNEL_ANALOG)
613 *data = g_variant_new_strv(analog_pattern_str,
614 ARRAY_SIZE(analog_pattern_str));
626 static void logic_generator(struct sr_dev_inst *sdi, uint64_t size)
628 struct dev_context *devc;
634 switch (devc->logic_pattern) {
636 memset(devc->logic_data, 0x00, size);
637 for (i = 0; i < size; i += devc->logic_unitsize) {
638 for (j = 0; j < devc->logic_unitsize; j++) {
639 pat = pattern_sigrok[(devc->step + j) % sizeof(pattern_sigrok)] >> 1;
640 devc->logic_data[i + j] = ~pat;
646 for (i = 0; i < size; i++)
647 devc->logic_data[i] = (uint8_t)(rand() & 0xff);
650 for (i = 0; i < size; i++) {
651 for (j = 0; j < devc->logic_unitsize; j++) {
652 devc->logic_data[i + j] = devc->step;
657 case PATTERN_ALL_LOW:
658 case PATTERN_ALL_HIGH:
659 /* These were set when the pattern mode was selected. */
662 sr_err("Unknown pattern: %d.", devc->logic_pattern);
667 /* Callback handling data */
668 static int prepare_data(int fd, int revents, void *cb_data)
670 struct sr_dev_inst *sdi;
671 struct dev_context *devc;
672 struct sr_datafeed_packet packet;
673 struct sr_datafeed_logic logic;
674 struct analog_gen *ag;
677 uint64_t logic_todo, analog_todo, expected_samplenum, analog_sent, sending_now;
678 int64_t time, elapsed;
685 logic_todo = analog_todo = 0;
687 /* How many samples should we have sent by now? */
688 time = g_get_monotonic_time();
689 elapsed = time - devc->starttime;
690 expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
692 /* But never more than the limit, if there is one. */
693 if (!devc->continuous)
694 expected_samplenum = MIN(expected_samplenum, devc->limit_samples);
696 /* Of those, how many do we still have to send? */
697 if (devc->num_logic_channels)
698 logic_todo = expected_samplenum - devc->logic_counter;
699 if (devc->num_analog_channels)
700 analog_todo = expected_samplenum - devc->analog_counter;
702 while (logic_todo || analog_todo) {
704 if (logic_todo > 0) {
705 sending_now = MIN(logic_todo, LOGIC_BUFSIZE / devc->logic_unitsize);
706 logic_generator(sdi, sending_now * devc->logic_unitsize);
707 packet.type = SR_DF_LOGIC;
708 packet.payload = &logic;
709 logic.length = sending_now * devc->logic_unitsize;
710 logic.unitsize = devc->logic_unitsize;
711 logic.data = devc->logic_data;
712 sr_session_send(sdi, &packet);
713 logic_todo -= sending_now;
714 devc->logic_counter += sending_now;
717 /* Analog, one channel at a time */
718 if (analog_todo > 0) {
721 g_hash_table_iter_init(&iter, devc->ch_ag);
722 while (g_hash_table_iter_next(&iter, NULL, &value)) {
724 packet.type = SR_DF_ANALOG;
725 packet.payload = &ag->packet;
727 /* FIXME we should make sure we output a whole
728 * period of data before we send out again the
729 * beginning of our buffer. A ring buffer would
730 * help here as well */
732 sending_now = MIN(analog_todo, ag->num_samples);
733 ag->packet.num_samples = sending_now;
734 sr_session_send(sdi, &packet);
736 /* Whichever channel group gets there first. */
737 analog_sent = MAX(analog_sent, sending_now);
739 analog_todo -= analog_sent;
740 devc->analog_counter += analog_sent;
744 if (!devc->continuous
745 && (!devc->num_logic_channels || devc->logic_counter >= devc->limit_samples)
746 && (!devc->num_analog_channels || devc->analog_counter >= devc->limit_samples)) {
747 sr_dbg("Requested number of samples reached.");
748 dev_acquisition_stop(sdi, cb_data);
755 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
757 struct dev_context *devc;
763 if (sdi->status != SR_ST_ACTIVE)
764 return SR_ERR_DEV_CLOSED;
767 devc->continuous = !devc->limit_samples;
768 devc->logic_counter = devc->analog_counter = 0;
771 * Setting two channels connected by a pipe is a remnant from when the
772 * demo driver generated data in a thread, and collected and sent the
773 * data in the main program loop.
774 * They are kept here because it provides a convenient way of setting
775 * up a timeout-based polling mechanism.
777 if (pipe(devc->pipe_fds)) {
778 sr_err("%s: pipe() failed", __func__);
782 g_hash_table_iter_init(&iter, devc->ch_ag);
783 while (g_hash_table_iter_next(&iter, NULL, &value))
784 generate_analog_pattern(value, devc->cur_samplerate);
786 devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]);
787 g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL);
789 /* Set channel encoding to binary (default is UTF-8). */
790 g_io_channel_set_encoding(devc->channel, NULL, NULL);
792 /* Make channels unbuffered. */
793 g_io_channel_set_buffered(devc->channel, FALSE);
795 sr_session_source_add_channel(sdi->session, devc->channel,
796 G_IO_IN | G_IO_ERR, 40, prepare_data, (void *)sdi);
798 /* Send header packet to the session bus. */
799 std_session_send_df_header(sdi, LOG_PREFIX);
801 /* We use this timestamp to decide how many more samples to send. */
802 devc->starttime = g_get_monotonic_time();
807 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
809 struct dev_context *devc;
810 struct sr_datafeed_packet packet;
815 sr_dbg("Stopping acquisition.");
817 sr_session_source_remove_channel(sdi->session, devc->channel);
818 g_io_channel_shutdown(devc->channel, FALSE, NULL);
819 g_io_channel_unref(devc->channel);
820 devc->channel = NULL;
822 /* Send last packet. */
823 packet.type = SR_DF_END;
824 sr_session_send(sdi, &packet);
829 SR_PRIV struct sr_dev_driver demo_driver_info = {
831 .longname = "Demo driver and pattern generator",
836 .dev_list = dev_list,
838 .config_get = config_get,
839 .config_set = config_set,
840 .config_list = config_list,
841 .dev_open = dev_open,
842 .dev_close = dev_close,
843 .dev_acquisition_start = dev_acquisition_start,
844 .dev_acquisition_stop = dev_acquisition_stop,