]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds1xx2/api.c
drivers: return SR_ERR_NA on unsupported config key
[libsigrok.git] / hardware / rigol-ds1xx2 / api.c
CommitLineData
f4816ac6
ML
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
88e429c9 5 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
f4816ac6
ML
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
e0b7d23c
ML
21#include <fcntl.h>
22#include <unistd.h>
23#include <stdlib.h>
24#include <string.h>
f4816ac6
ML
25#include <glib.h>
26#include "libsigrok.h"
27#include "libsigrok-internal.h"
28#include "protocol.h"
29
d62d7ad1
BV
30#define NUM_TIMEBASE 12
31#define NUM_VDIV 8
32
f6a0ac9f 33static const int32_t hwcaps[] = {
1953564a 34 SR_CONF_OSCILLOSCOPE,
1953564a
BV
35 SR_CONF_TIMEBASE,
36 SR_CONF_TRIGGER_SOURCE,
37 SR_CONF_TRIGGER_SLOPE,
38 SR_CONF_HORIZ_TRIGGERPOS,
39 SR_CONF_VDIV,
40 SR_CONF_COUPLING,
d62d7ad1
BV
41 SR_CONF_NUM_TIMEBASE,
42 SR_CONF_NUM_VDIV,
e0b7d23c
ML
43};
44
f6a0ac9f 45static const uint64_t timebases[][2] = {
e0b7d23c
ML
46 /* nanoseconds */
47 { 2, 1000000000 },
48 { 5, 1000000000 },
49 { 10, 1000000000 },
50 { 20, 1000000000 },
51 { 50, 1000000000 },
52 { 100, 1000000000 },
53 { 500, 1000000000 },
54 /* microseconds */
55 { 1, 1000000 },
56 { 2, 1000000 },
57 { 5, 1000000 },
58 { 10, 1000000 },
59 { 20, 1000000 },
60 { 50, 1000000 },
61 { 100, 1000000 },
62 { 200, 1000000 },
63 { 500, 1000000 },
64 /* milliseconds */
65 { 1, 1000 },
66 { 2, 1000 },
67 { 5, 1000 },
68 { 10, 1000 },
69 { 20, 1000 },
70 { 50, 1000 },
71 { 100, 1000 },
72 { 200, 1000 },
73 { 500, 1000 },
74 /* seconds */
75 { 1, 1 },
76 { 2, 1 },
77 { 5, 1 },
78 { 10, 1 },
79 { 20, 1 },
80 { 50, 1 },
e0b7d23c
ML
81};
82
f6a0ac9f 83static const uint64_t vdivs[][2] = {
e0b7d23c
ML
84 /* millivolts */
85 { 2, 1000 },
86 { 5, 1000 },
87 { 10, 1000 },
88 { 20, 1000 },
89 { 50, 1000 },
90 { 100, 1000 },
91 { 200, 1000 },
92 { 500, 1000 },
93 /* volts */
94 { 1, 1 },
95 { 2, 1 },
96 { 5, 1 },
97 { 10, 1 },
e0b7d23c
ML
98};
99
100static const char *trigger_sources[] = {
101 "CH1",
102 "CH2",
103 "EXT",
104 "AC Line",
6bb192bc
ML
105 "D0",
106 "D1",
107 "D2",
108 "D3",
109 "D4",
110 "D5",
111 "D6",
112 "D7",
113 "D8",
114 "D9",
115 "D10",
116 "D11",
117 "D12",
118 "D13",
119 "D14",
120 "D15",
e0b7d23c
ML
121};
122
123static const char *coupling[] = {
124 "AC",
125 "DC",
126 "GND",
e0b7d23c
ML
127};
128
512bb890
BV
129static const char *supported_models[] = {
130 "DS1052E",
131 "DS1102E",
132 "DS1052D",
333bf022 133 "DS1102D",
512bb890
BV
134};
135
f4816ac6
ML
136SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info;
137static struct sr_dev_driver *di = &rigol_ds1xx2_driver_info;
138
139/* Properly close and free all devices. */
140static int clear_instances(void)
141{
142 struct sr_dev_inst *sdi;
143 struct drv_context *drvc;
144 struct dev_context *devc;
145 GSList *l;
146
147 if (!(drvc = di->priv))
148 return SR_OK;
149
150 for (l = drvc->instances; l; l = l->next) {
151 if (!(sdi = l->data))
152 continue;
153 if (!(devc = sdi->priv))
154 continue;
155
fb6e5ba8 156 g_free(devc->device);
254dd102
BV
157 g_free(devc->coupling[0]);
158 g_free(devc->coupling[1]);
159 g_free(devc->trigger_source);
160 g_free(devc->trigger_slope);
e0b7d23c 161 close(devc->fd);
f4816ac6
ML
162
163 sr_dev_inst_free(sdi);
164 }
165
166 g_slist_free(drvc->instances);
167 drvc->instances = NULL;
168
169 return SR_OK;
170}
171
254dd102
BV
172static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
173{
174 struct dev_context *devc;
254dd102
BV
175 va_list args;
176 char buf[256];
177
178 devc = sdi->priv;
179
180 va_start(args, format);
181 vsnprintf(buf, 255, format, args);
182 va_end(args);
183 if (rigol_ds1xx2_send(devc, buf) != SR_OK)
184 return SR_ERR;
185
186 /* When setting a bunch of parameters in a row, the DS1052E scrambles
187 * some of them unless there is at least 100ms delay in between. */
8f35be72
BV
188 sr_spew("delay %dms", 100);
189 g_usleep(100);
254dd102
BV
190
191 return SR_OK;
192}
193
e0b7d23c 194static int hw_init(struct sr_context *sr_ctx)
f4816ac6 195{
063e7aef 196 return std_hw_init(sr_ctx, di, DRIVER_LOG_DOMAIN);
f4816ac6
ML
197}
198
199static GSList *hw_scan(GSList *options)
200{
201 struct drv_context *drvc;
e0b7d23c
ML
202 struct sr_dev_inst *sdi;
203 struct dev_context *devc;
204 struct sr_probe *probe;
f4816ac6 205 GSList *devices;
fb6e5ba8
ML
206 GDir *dir;
207 const gchar *dev_name;
208 const gchar *dev_dir = "/dev/";
209 const gchar *prefix = "usbtmc";
210 gchar *device;
211 const gchar *idn_query = "*IDN?";
f6a0ac9f
BV
212 unsigned int i;
213 int len, num_tokens, fd;
fb6e5ba8
ML
214 const gchar *delimiter = ",";
215 gchar **tokens;
512bb890 216 const char *manufacturer, *model, *version;
512bb890 217 gboolean matched = FALSE;
6bb192bc 218 gboolean has_digital = FALSE;
fb6e5ba8 219 char buf[256];
6bb192bc 220 gchar *channel_name;
fb6e5ba8 221
f4816ac6
ML
222 (void)options;
223
f4816ac6
ML
224 drvc = di->priv;
225 drvc->instances = NULL;
226
4b97c74e
UH
227 devices = NULL;
228
fb6e5ba8 229 dir = g_dir_open("/sys/class/usb/", 0, NULL);
e0b7d23c 230
fb6e5ba8
ML
231 if (dir == NULL)
232 return NULL;
e0b7d23c 233
29d957ce 234 while ((dev_name = g_dir_read_name(dir)) != NULL) {
fb6e5ba8
ML
235 if (strncmp(dev_name, prefix, strlen(prefix)))
236 continue;
237
238 device = g_strconcat(dev_dir, dev_name, NULL);
239
240 fd = open(device, O_RDWR);
241 len = write(fd, idn_query, strlen(idn_query));
242 len = read(fd, buf, sizeof(buf));
243 close(fd);
29d957ce 244 if (len == 0) {
fb6e5ba8
ML
245 g_free(device);
246 return NULL;
247 }
248
249 buf[len] = 0;
250 tokens = g_strsplit(buf, delimiter, 0);
251 close(fd);
512bb890 252 sr_dbg("response: %s %d [%s]", device, len, buf);
fb6e5ba8
ML
253
254 for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
255
512bb890 256 if (num_tokens < 4) {
fb6e5ba8
ML
257 g_strfreev(tokens);
258 g_free(device);
e0b7d23c 259 return NULL;
fb6e5ba8 260 }
512bb890
BV
261
262 manufacturer = tokens[0];
263 model = tokens[1];
264 version = tokens[3];
265
266 if (strcmp(manufacturer, "Rigol Technologies")) {
267 g_strfreev(tokens);
268 g_free(device);
269 return NULL;
270 }
271
333bf022 272 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
512bb890
BV
273 if (!strcmp(model, supported_models[i])) {
274 matched = 1;
6bb192bc 275 has_digital = g_str_has_suffix(model, "D");
512bb890
BV
276 break;
277 }
278 }
279
280 if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
281 manufacturer, model, version))) {
282 g_strfreev(tokens);
283 g_free(device);
284 return NULL;
285 }
286
fb6e5ba8
ML
287 g_strfreev(tokens);
288
29d957ce
UH
289 if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
290 sr_err("Device context malloc failed.");
fb6e5ba8
ML
291 g_free(device);
292 return NULL;
293 }
254dd102 294 devc->limit_frames = 0;
fb6e5ba8 295 devc->device = device;
6bb192bc 296 devc->has_digital = has_digital;
fb6e5ba8
ML
297 sdi->priv = devc;
298 sdi->driver = di;
299
29d957ce 300 for (i = 0; i < 2; i++) {
6bb192bc 301 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
29d957ce 302 i == 0 ? "CH1" : "CH2")))
fb6e5ba8
ML
303 return NULL;
304 sdi->probes = g_slist_append(sdi->probes, probe);
305 }
306
6bb192bc
ML
307 if (devc->has_digital) {
308 for (i = 0; i < 16; i++) {
309 if (!(channel_name = g_strdup_printf("D%d", i)))
310 return NULL;
311 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
312 g_free(channel_name);
313 if (!probe)
314 return NULL;
315 sdi->probes = g_slist_append(sdi->probes, probe);
316 }
317 }
318
fb6e5ba8
ML
319 drvc->instances = g_slist_append(drvc->instances, sdi);
320 devices = g_slist_append(devices, sdi);
e0b7d23c 321 }
fb6e5ba8
ML
322
323 g_dir_close(dir);
f4816ac6
ML
324
325 return devices;
326}
327
328static GSList *hw_dev_list(void)
329{
0e94d524 330 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
331}
332
333static int hw_dev_open(struct sr_dev_inst *sdi)
334{
29d957ce
UH
335 struct dev_context *devc;
336 int fd;
fb6e5ba8 337
29d957ce 338 devc = sdi->priv;
e0b7d23c 339
29d957ce 340 if ((fd = open(devc->device, O_RDWR)) == -1)
e0b7d23c 341 return SR_ERR;
e0b7d23c
ML
342 devc->fd = fd;
343
254dd102
BV
344 if (rigol_ds1xx2_get_dev_cfg(sdi) != SR_OK)
345 /* TODO: force configuration? */
346 return SR_ERR;
f4816ac6
ML
347
348 return SR_OK;
349}
350
351static int hw_dev_close(struct sr_dev_inst *sdi)
352{
29d957ce
UH
353 struct dev_context *devc;
354
355 devc = sdi->priv;
e0b7d23c
ML
356
357 close(devc->fd);
f4816ac6
ML
358
359 return SR_OK;
360}
361
362static int hw_cleanup(void)
363{
364 clear_instances();
365
f4816ac6
ML
366 return SR_OK;
367}
368
d62d7ad1
BV
369static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
370{
371
372 (void)sdi;
373
374 switch (id) {
375 case SR_CONF_NUM_TIMEBASE:
376 *data = g_variant_new_int32(NUM_TIMEBASE);
377 break;
378 case SR_CONF_NUM_VDIV:
379 *data = g_variant_new_int32(NUM_VDIV);
380 break;
381 default:
bd6fbf62 382 return SR_ERR_NA;
d62d7ad1
BV
383 }
384
385 return SR_OK;
386}
387
f6a0ac9f 388static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
f4816ac6 389{
29d957ce 390 struct dev_context *devc;
f6a0ac9f 391 uint64_t tmp_u64, p, q;
254dd102 392 double t_dbl;
f6a0ac9f 393 unsigned int i;
254dd102
BV
394 int ret;
395 const char *tmp_str;
f4816ac6 396
29d957ce
UH
397 devc = sdi->priv;
398
f4816ac6
ML
399 if (sdi->status != SR_ST_ACTIVE) {
400 sr_err("Device inactive, can't set config options.");
401 return SR_ERR;
402 }
403
404 ret = SR_OK;
035a1078 405 switch (id) {
1953564a 406 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 407 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 408 break;
1953564a 409 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 410 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
411 if (tmp_u64 != 0 && tmp_u64 != 1)
412 return SR_ERR;
413 g_free(devc->trigger_slope);
414 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
415 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 416 break;
1953564a 417 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
418 t_dbl = g_variant_get_double(data);
419 if (t_dbl < 0.0 || t_dbl > 1.0)
420 return SR_ERR;
421 devc->horiz_triggerpos = t_dbl;
422 /* We have the trigger offset as a percentage of the frame, but
423 * need to express this in seconds. */
424 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
425 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
e0b7d23c 426 break;
1953564a 427 case SR_CONF_TIMEBASE:
f6a0ac9f 428 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
429 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
430 if (timebases[i][0] == p && timebases[i][1] == q) {
254dd102
BV
431 devc->timebase = (float)p / q;
432 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
f6a0ac9f
BV
433 break;
434 }
435 }
254dd102
BV
436 if (i == ARRAY_SIZE(timebases))
437 ret = SR_ERR_ARG;
e0b7d23c 438 break;
1953564a 439 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 440 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
441 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
442 if (!strcmp(trigger_sources[i], tmp_str)) {
443 g_free(devc->trigger_source);
444 devc->trigger_source = g_strdup(trigger_sources[i]);
445 if (!strcmp(devc->trigger_source, "AC Line"))
446 tmp_str = "ACL";
447 else if (!strcmp(devc->trigger_source, "CH1"))
448 tmp_str = "CHAN1";
449 else if (!strcmp(devc->trigger_source, "CH2"))
450 tmp_str = "CHAN2";
451 else
452 tmp_str = (char *)devc->trigger_source;
453 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
454 break;
455 }
4e108ace 456 }
254dd102
BV
457 if (i == ARRAY_SIZE(trigger_sources))
458 ret = SR_ERR_ARG;
e0b7d23c 459 break;
1953564a 460 case SR_CONF_VDIV:
f6a0ac9f 461 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
462 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
463 if (vdivs[i][0] != p || vdivs[i][1] != q)
464 continue;
254dd102
BV
465 devc->vdiv[0] = devc->vdiv[1] = (float)p / q;
466 set_cfg(sdi, ":CHAN1:SCAL %.3f", devc->vdiv[0]);
467 ret = set_cfg(sdi, ":CHAN2:SCAL %.3f", devc->vdiv[1]);
f6a0ac9f 468 break;
e0b7d23c 469 }
f6a0ac9f 470 if (i == ARRAY_SIZE(vdivs))
e0b7d23c
ML
471 ret = SR_ERR_ARG;
472 break;
1953564a 473 case SR_CONF_COUPLING:
e0b7d23c 474 /* TODO: Not supporting coupling per channel yet. */
f6a0ac9f
BV
475 tmp_str = g_variant_get_string(data, NULL);
476 for (i = 0; i < ARRAY_SIZE(coupling); i++) {
477 if (!strcmp(tmp_str, coupling[i])) {
254dd102
BV
478 g_free(devc->coupling[0]);
479 g_free(devc->coupling[1]);
480 devc->coupling[0] = g_strdup(coupling[i]);
481 devc->coupling[1] = g_strdup(coupling[i]);
482 set_cfg(sdi, ":CHAN1:COUP %s", devc->coupling[0]);
483 ret = set_cfg(sdi, ":CHAN2:COUP %s", devc->coupling[1]);
e0b7d23c
ML
484 break;
485 }
486 }
f6a0ac9f 487 if (i == ARRAY_SIZE(coupling))
e0b7d23c
ML
488 ret = SR_ERR_ARG;
489 break;
f4816ac6 490 default:
bd6fbf62 491 ret = SR_ERR_NA;
29d957ce 492 break;
f4816ac6
ML
493 }
494
495 return ret;
496}
497
f6a0ac9f 498static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
a1c743fc 499{
861c447b
BV
500 GVariant *tuple, *rational[2];
501 GVariantBuilder gvb;
502 unsigned int i;
a7be14ad 503 struct dev_context *devc;
a1c743fc
BV
504
505 switch (key) {
9a6517d1 506 case SR_CONF_DEVICE_OPTIONS:
f6a0ac9f
BV
507 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
508 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
9a6517d1 509 break;
2a7b113d 510 case SR_CONF_COUPLING:
169dbe85
UH
511 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
512 break;
e4f2b2ad 513 case SR_CONF_VDIV:
861c447b
BV
514 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
515 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
516 rational[0] = g_variant_new_uint64(vdivs[i][0]);
517 rational[1] = g_variant_new_uint64(vdivs[i][1]);
518 tuple = g_variant_new_tuple(rational, 2);
519 g_variant_builder_add_value(&gvb, tuple);
520 }
521 *data = g_variant_builder_end(&gvb);
e4f2b2ad 522 break;
41f5bd09 523 case SR_CONF_TIMEBASE:
861c447b
BV
524 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
525 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
526 rational[0] = g_variant_new_uint64(timebases[i][0]);
527 rational[1] = g_variant_new_uint64(timebases[i][1]);
528 tuple = g_variant_new_tuple(rational, 2);
529 g_variant_builder_add_value(&gvb, tuple);
530 }
531 *data = g_variant_builder_end(&gvb);
41f5bd09 532 break;
328bafab 533 case SR_CONF_TRIGGER_SOURCE:
a7be14ad
BV
534 if (!sdi || !sdi->priv)
535 /* Can't know this until we have the exact model. */
536 return SR_ERR_ARG;
537 devc = sdi->priv;
f6a0ac9f 538 *data = g_variant_new_strv(trigger_sources,
6bb192bc 539 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 540 break;
a1c743fc 541 default:
bd6fbf62 542 return SR_ERR_NA;
a1c743fc
BV
543 }
544
545 return SR_OK;
546}
547
254dd102 548static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 549{
29d957ce 550 struct dev_context *devc;
254dd102
BV
551 struct sr_probe *probe;
552 GSList *l;
254dd102 553 char cmd[256];
29d957ce 554
e0b7d23c
ML
555 (void)cb_data;
556
29d957ce
UH
557 devc = sdi->priv;
558
254dd102
BV
559 for (l = sdi->probes; l; l = l->next) {
560 probe = l->data;
6bb192bc
ML
561 sr_dbg("handling probe %s", probe->name);
562 if (probe->type == SR_PROBE_ANALOG) {
563 if (probe->enabled)
564 devc->enabled_analog_probes = g_slist_append(
565 devc->enabled_analog_probes, probe);
566 if (probe->enabled != devc->analog_channels[probe->index]) {
567 /* Enabled channel is currently disabled, or vice versa. */
568 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
569 probe->enabled ? "ON" : "OFF");
570 if (rigol_ds1xx2_send(devc, cmd) != SR_OK)
571 return SR_ERR;
572 }
573 } else if (probe->type == SR_PROBE_LOGIC) {
574 if (probe->enabled)
575 devc->enabled_digital_probes = g_slist_append(
576 devc->enabled_digital_probes, probe);
577 if (probe->enabled != devc->digital_channels[probe->index]) {
578 /* Enabled channel is currently disabled, or vice versa. */
579 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
580 probe->enabled ? "ON" : "OFF");
581 if (rigol_ds1xx2_send(devc, cmd) != SR_OK)
582 return SR_ERR;
583 }
254dd102
BV
584 }
585 }
6bb192bc 586 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 587 return SR_ERR;
e0b7d23c 588
254dd102 589 sr_source_add(devc->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
e0b7d23c
ML
590
591 /* Send header packet to the session bus. */
4afdfd46 592 std_session_send_df_header(cb_data, DRIVER_LOG_DOMAIN);
e0b7d23c 593
254dd102 594 /* Fetch the first frame. */
6bb192bc
ML
595 if (devc->enabled_analog_probes) {
596 devc->channel_frame = devc->enabled_analog_probes->data;
597 if (rigol_ds1xx2_send(devc, ":WAV:DATA? CHAN%d",
598 devc->channel_frame->index + 1) != SR_OK)
599 return SR_ERR;
600 } else {
601 devc->channel_frame = devc->enabled_digital_probes->data;
602 if (rigol_ds1xx2_send(devc, ":WAV:DATA? DIG") != SR_OK)
603 return SR_ERR;
604 }
f4816ac6 605
ee7e9bee
ML
606 devc->num_frame_bytes = 0;
607
f4816ac6
ML
608 return SR_OK;
609}
610
254dd102 611static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 612{
29d957ce
UH
613 struct dev_context *devc;
614
f4816ac6
ML
615 (void)cb_data;
616
29d957ce
UH
617 devc = sdi->priv;
618
f4816ac6
ML
619 if (sdi->status != SR_ST_ACTIVE) {
620 sr_err("Device inactive, can't stop acquisition.");
621 return SR_ERR;
622 }
623
6bb192bc
ML
624 g_slist_free(devc->enabled_analog_probes);
625 g_slist_free(devc->enabled_digital_probes);
626 devc->enabled_analog_probes = NULL;
627 devc->enabled_digital_probes = NULL;
e0b7d23c 628 sr_source_remove(devc->fd);
f4816ac6
ML
629
630 return SR_OK;
631}
632
633SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
634 .name = "rigol-ds1xx2",
635 .longname = "Rigol DS1xx2",
636 .api_version = 1,
637 .init = hw_init,
638 .cleanup = hw_cleanup,
639 .scan = hw_scan,
640 .dev_list = hw_dev_list,
641 .dev_clear = clear_instances,
d62d7ad1 642 .config_get = config_get,
035a1078 643 .config_set = config_set,
a1c743fc 644 .config_list = config_list,
f4816ac6
ML
645 .dev_open = hw_dev_open,
646 .dev_close = hw_dev_close,
254dd102
BV
647 .dev_acquisition_start = dev_acquisition_start,
648 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
649 .priv = NULL,
650};