]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds/api.c
hwdriver: Change TRIGGER_SLOPE setting to string type.
[libsigrok.git] / hardware / rigol-ds / 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>
bafd4890 6 * Copyright (C) 2013 Mathias Grimmberger <mgri@zaphod.sax.de>
f4816ac6
ML
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 3 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, see <http://www.gnu.org/licenses/>.
20 */
21
e0b7d23c
ML
22#include <fcntl.h>
23#include <unistd.h>
24#include <stdlib.h>
25#include <string.h>
2b0e4a46 26#include <math.h>
f4816ac6
ML
27#include <glib.h>
28#include "libsigrok.h"
29#include "libsigrok-internal.h"
30#include "protocol.h"
31
ca55277c
ML
32static const int32_t hwopts[] = {
33 SR_CONF_CONN,
0dc7b43e 34 SR_CONF_SERIALCOMM
ca55277c
ML
35};
36
f6a0ac9f 37static const int32_t hwcaps[] = {
1953564a 38 SR_CONF_OSCILLOSCOPE,
1953564a
BV
39 SR_CONF_TIMEBASE,
40 SR_CONF_TRIGGER_SOURCE,
41 SR_CONF_TRIGGER_SLOPE,
42 SR_CONF_HORIZ_TRIGGERPOS,
d62d7ad1 43 SR_CONF_NUM_TIMEBASE,
c1bcb8cc 44 SR_CONF_LIMIT_FRAMES,
4914dd4b 45 SR_CONF_SAMPLERATE,
f48e0249
ML
46};
47
48static const int32_t analog_hwcaps[] = {
d62d7ad1 49 SR_CONF_NUM_VDIV,
f48e0249 50 SR_CONF_VDIV,
78bcc55a 51 SR_CONF_COUPLING,
babab622 52 SR_CONF_DATA_SOURCE,
e0b7d23c
ML
53};
54
f6a0ac9f 55static const uint64_t timebases[][2] = {
e0b7d23c 56 /* nanoseconds */
8e06edf5 57 { 1, 1000000000 },
e0b7d23c
ML
58 { 2, 1000000000 },
59 { 5, 1000000000 },
60 { 10, 1000000000 },
61 { 20, 1000000000 },
62 { 50, 1000000000 },
63 { 100, 1000000000 },
64 { 500, 1000000000 },
65 /* microseconds */
66 { 1, 1000000 },
67 { 2, 1000000 },
68 { 5, 1000000 },
69 { 10, 1000000 },
70 { 20, 1000000 },
71 { 50, 1000000 },
72 { 100, 1000000 },
73 { 200, 1000000 },
74 { 500, 1000000 },
75 /* milliseconds */
76 { 1, 1000 },
77 { 2, 1000 },
78 { 5, 1000 },
79 { 10, 1000 },
80 { 20, 1000 },
81 { 50, 1000 },
82 { 100, 1000 },
83 { 200, 1000 },
84 { 500, 1000 },
85 /* seconds */
86 { 1, 1 },
87 { 2, 1 },
88 { 5, 1 },
89 { 10, 1 },
90 { 20, 1 },
91 { 50, 1 },
bafd4890
ML
92 { 100, 1 },
93 { 200, 1 },
94 { 500, 1 },
8e06edf5 95 { 1000, 1 },
e0b7d23c
ML
96};
97
f6a0ac9f 98static const uint64_t vdivs[][2] = {
bafd4890
ML
99 /* microvolts */
100 { 500, 1000000 },
e0b7d23c 101 /* millivolts */
bafd4890 102 { 1, 1000 },
e0b7d23c
ML
103 { 2, 1000 },
104 { 5, 1000 },
105 { 10, 1000 },
106 { 20, 1000 },
107 { 50, 1000 },
108 { 100, 1000 },
109 { 200, 1000 },
110 { 500, 1000 },
111 /* volts */
112 { 1, 1 },
113 { 2, 1 },
114 { 5, 1 },
115 { 10, 1 },
e0b7d23c
ML
116};
117
bafd4890
ML
118#define NUM_TIMEBASE ARRAY_SIZE(timebases)
119#define NUM_VDIV ARRAY_SIZE(vdivs)
120
e0b7d23c
ML
121static const char *trigger_sources[] = {
122 "CH1",
123 "CH2",
821fbcad
ML
124 "CH3",
125 "CH4",
e0b7d23c
ML
126 "EXT",
127 "AC Line",
6bb192bc
ML
128 "D0",
129 "D1",
130 "D2",
131 "D3",
132 "D4",
133 "D5",
134 "D6",
135 "D7",
136 "D8",
137 "D9",
138 "D10",
139 "D11",
140 "D12",
141 "D13",
142 "D14",
143 "D15",
e0b7d23c
ML
144};
145
146static const char *coupling[] = {
147 "AC",
148 "DC",
149 "GND",
e0b7d23c
ML
150};
151
babab622
ML
152/* Do not change the order of entries */
153static const char *data_sources[] = {
154 "Live",
155 "Memory",
156 "Segmented",
157};
158
569d4dbd
ML
159enum vendor {
160 RIGOL,
161 AGILENT,
162};
163
164enum series {
165 VS5000,
166 DS1000,
167 DS2000,
168 DS2000A,
169 DSO1000,
170};
10afee13 171
569d4dbd
ML
172/* short name, full name */
173static const struct rigol_ds_vendor supported_vendors[] = {
174 [RIGOL] = {"Rigol", "Rigol Technologies"},
175 [AGILENT] = {"Agilent", "Rigol Technologies"},
176};
177
178#define VENDOR(x) &supported_vendors[x]
179/* vendor, series, protocol, max timebase, min vdiv, number of horizontal divs,
180 * live waveform samples, memory buffer samples */
181static const struct rigol_ds_series supported_series[] = {
182 [VS5000] = {VENDOR(RIGOL), "VS5000", PROTOCOL_V1, FORMAT_RAW,
183 {50, 1}, {2, 1000}, 14, 2048, 0},
184 [DS1000] = {VENDOR(RIGOL), "DS1000", PROTOCOL_V2, FORMAT_IEEE488_2,
185 {50, 1}, {2, 1000}, 12, 600, 1048576},
186 [DS2000] = {VENDOR(RIGOL), "DS2000", PROTOCOL_V3, FORMAT_IEEE488_2,
187 {500, 1}, {2, 1000}, 14, 1400, 14000},
188 [DS2000A] = {VENDOR(RIGOL), "DS2000A", PROTOCOL_V3, FORMAT_IEEE488_2,
189 {1000, 1}, {500, 1000000}, 14, 1400, 14000},
190 [DSO1000] = {VENDOR(AGILENT), "DSO1000", PROTOCOL_V3, FORMAT_IEEE488_2,
191 {50, 1}, {2, 1000}, 12, 600, 20480},
192};
10afee13 193
569d4dbd
ML
194#define SERIES(x) &supported_series[x]
195/* series, model, min timebase, analog channels, digital */
bafd4890 196static const struct rigol_ds_model supported_models[] = {
569d4dbd
ML
197 {SERIES(VS5000), "VS5022", {20, 1000000000}, 2, false},
198 {SERIES(VS5000), "VS5042", {10, 1000000000}, 2, false},
199 {SERIES(VS5000), "VS5062", {5, 1000000000}, 2, false},
200 {SERIES(VS5000), "VS5102", {2, 1000000000}, 2, false},
201 {SERIES(VS5000), "VS5202", {2, 1000000000}, 2, false},
202 {SERIES(VS5000), "VS5022D", {20, 1000000000}, 2, true},
203 {SERIES(VS5000), "VS5042D", {10, 1000000000}, 2, true},
204 {SERIES(VS5000), "VS5062D", {5, 1000000000}, 2, true},
205 {SERIES(VS5000), "VS5102D", {2, 1000000000}, 2, true},
206 {SERIES(VS5000), "VS5202D", {2, 1000000000}, 2, true},
207 {SERIES(DS1000), "DS1052E", {5, 1000000000}, 2, false},
208 {SERIES(DS1000), "DS1102E", {2, 1000000000}, 2, false},
209 {SERIES(DS1000), "DS1152E", {2, 1000000000}, 2, false},
210 {SERIES(DS1000), "DS1052D", {5, 1000000000}, 2, true},
211 {SERIES(DS1000), "DS1102D", {2, 1000000000}, 2, true},
212 {SERIES(DS1000), "DS1152D", {2, 1000000000}, 2, true},
213 {SERIES(DS2000), "DS2072", {5, 1000000000}, 2, false},
214 {SERIES(DS2000), "DS2102", {5, 1000000000}, 2, false},
215 {SERIES(DS2000), "DS2202", {2, 1000000000}, 2, false},
216 {SERIES(DS2000), "DS2302", {1, 1000000000}, 2, false},
217 {SERIES(DS2000A), "DS2072A", {5, 1000000000}, 2, false},
218 {SERIES(DS2000A), "DS2102A", {5, 1000000000}, 2, false},
219 {SERIES(DS2000A), "DS2202A", {2, 1000000000}, 2, false},
220 {SERIES(DS2000A), "DS2302A", {1, 1000000000}, 2, false},
221 {SERIES(DSO1000), "DSO1002A", {5, 1000000000}, 2, false},
222 {SERIES(DSO1000), "DSO1004A", {5, 1000000000}, 4, false},
223 {SERIES(DSO1000), "DSO1012A", {2, 1000000000}, 2, false},
224 {SERIES(DSO1000), "DSO1014A", {2, 1000000000}, 4, false},
225 {SERIES(DSO1000), "DSO1022A", {2, 1000000000}, 2, false},
226 {SERIES(DSO1000), "DSO1024A", {2, 1000000000}, 4, false},
512bb890
BV
227};
228
3086efdd
ML
229SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
230static struct sr_dev_driver *di = &rigol_ds_driver_info;
f4816ac6 231
fa85f376 232static void clear_helper(void *priv)
f4816ac6 233{
f4816ac6 234 struct dev_context *devc;
f4816ac6 235
ba358ffd 236 devc = priv;
babab622
ML
237 g_free(devc->data);
238 g_free(devc->buffer);
fa85f376
UH
239 g_free(devc->coupling[0]);
240 g_free(devc->coupling[1]);
241 g_free(devc->trigger_source);
242 g_free(devc->trigger_slope);
ba358ffd
BV
243 g_slist_free(devc->analog_groups[0].probes);
244 g_slist_free(devc->analog_groups[1].probes);
245 g_slist_free(devc->digital_group.probes);
fa85f376 246}
f4816ac6 247
3b412e3a 248static int dev_clear(void)
fa85f376
UH
249{
250 return std_dev_clear(di, clear_helper);
f4816ac6
ML
251}
252
6078d2c9 253static int init(struct sr_context *sr_ctx)
f4816ac6 254{
f6beaac5 255 return std_init(sr_ctx, di, LOG_PREFIX);
f4816ac6
ML
256}
257
3520422f 258static int probe_port(const char *resource, const char *serialcomm, GSList **devices)
f4816ac6 259{
cc9fd2d2
BV
260 struct dev_context *devc;
261 struct sr_dev_inst *sdi;
ae1bc1cc
ML
262 struct sr_scpi_dev_inst *scpi;
263 struct sr_scpi_hw_info *hw_info;
cc9fd2d2 264 struct sr_probe *probe;
8dd0b290 265 long n[3];
f6a0ac9f 266 unsigned int i;
bafd4890 267 const struct rigol_ds_model *model = NULL;
569d4dbd 268 gchar *channel_name, **version;
fb6e5ba8 269
46a743c1 270 *devices = NULL;
0dc7b43e 271
c3515cea
AJ
272 if (!(scpi = scpi_dev_inst_new(resource, serialcomm)))
273 return SR_ERR;
9bd4c956 274
ae1bc1cc 275 if (sr_scpi_open(scpi) != SR_OK) {
10afee13 276 sr_info("Couldn't open SCPI device.");
ae1bc1cc 277 sr_scpi_free(scpi);
9bd4c956 278 return SR_ERR;
ae1bc1cc 279 };
9bd4c956 280
ae1bc1cc
ML
281 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
282 sr_info("Couldn't get IDN response.");
283 sr_scpi_close(scpi);
284 sr_scpi_free(scpi);
285 return SR_ERR;
ca55277c 286 }
e0b7d23c 287
ca55277c 288 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
569d4dbd
ML
289 if (!strcasecmp(hw_info->manufacturer,
290 supported_models[i].series->vendor->full_name) &&
10afee13 291 !strcmp(hw_info->model, supported_models[i].name)) {
bafd4890 292 model = &supported_models[i];
ca55277c 293 break;
fb6e5ba8 294 }
ca55277c 295 }
fb6e5ba8 296
bafd4890 297 if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
569d4dbd
ML
298 model->series->vendor->name,
299 model->name,
ae1bc1cc
ML
300 hw_info->firmware_version))) {
301 sr_scpi_hw_info_free(hw_info);
b4936bae 302 sr_scpi_close(scpi);
ae1bc1cc 303 sr_scpi_free(scpi);
ca55277c
ML
304 return SR_ERR_NA;
305 }
fb6e5ba8 306
b4936bae 307 sr_scpi_close(scpi);
ae1bc1cc
ML
308
309 sdi->conn = scpi;
fb6e5ba8 310
cc9fd2d2 311 sdi->driver = di;
ae1bc1cc 312 sdi->inst_type = SR_INST_SCPI;
512bb890 313
cc9fd2d2 314 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
ca55277c 315 return SR_ERR_MALLOC;
ae1bc1cc 316
cc9fd2d2 317 devc->limit_frames = 0;
bafd4890 318 devc->model = model;
569d4dbd 319 devc->format = model->series->format;
8dd0b290 320
569d4dbd
ML
321 /* DS1000 models with firmware before 0.2.4 used the old data format. */
322 if (model->series == SERIES(DS1000)) {
8dd0b290
BV
323 version = g_strsplit(hw_info->firmware_version, ".", 0);
324 do {
325 if (!version[0] || !version[1] || !version[2])
326 break;
327 if (version[0][0] == 0 || version[1][0] == 0 || version[2][0] == 0)
328 break;
329 for (i = 0; i < 3; i++) {
330 if (sr_atol(version[i], &n[i]) != SR_OK)
331 break;
332 }
333 if (i != 3)
334 break;
335 if (n[0] != 0 || n[1] > 2)
336 break;
337 if (n[1] == 2 && n[2] > 3)
338 break;
569d4dbd
ML
339 sr_dbg("Found DS1000 firmware < 0.2.4, using raw data format.");
340 devc->format = FORMAT_RAW;
8dd0b290
BV
341 } while(0);
342 g_strfreev(version);
343 }
344
345 sr_scpi_hw_info_free(hw_info);
512bb890 346
821fbcad
ML
347 for (i = 0; i < model->analog_channels; i++) {
348 if (!(channel_name = g_strdup_printf("CH%d", i + 1)))
ca55277c 349 return SR_ERR_MALLOC;
821fbcad 350 probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name);
ca55277c 351 sdi->probes = g_slist_append(sdi->probes, probe);
3d3a601e
ML
352 devc->analog_groups[i].name = channel_name;
353 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
354 sdi->probe_groups = g_slist_append(sdi->probe_groups,
355 &devc->analog_groups[i]);
ca55277c 356 }
512bb890 357
bafd4890 358 if (devc->model->has_digital) {
ca55277c
ML
359 for (i = 0; i < 16; i++) {
360 if (!(channel_name = g_strdup_printf("D%d", i)))
361 return SR_ERR_MALLOC;
362 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
363 g_free(channel_name);
364 if (!probe)
365 return SR_ERR_MALLOC;
366 sdi->probes = g_slist_append(sdi->probes, probe);
3d3a601e
ML
367 devc->digital_group.probes = g_slist_append(
368 devc->digital_group.probes, probe);
512bb890 369 }
b3916147
ML
370 devc->digital_group.name = "LA";
371 sdi->probe_groups = g_slist_append(sdi->probe_groups,
372 &devc->digital_group);
ca55277c 373 }
bafd4890
ML
374
375 for (i = 0; i < NUM_TIMEBASE; i++) {
376 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
377 devc->timebases = &timebases[i];
569d4dbd 378 if (!memcmp(&devc->model->series->max_timebase, &timebases[i], sizeof(uint64_t[2])))
bafd4890
ML
379 devc->num_timebases = &timebases[i] - devc->timebases + 1;
380 }
381
0709197d 382 for (i = 0; i < NUM_VDIV; i++)
569d4dbd 383 if (!memcmp(&devc->model->series->min_vdiv, &vdivs[i], sizeof(uint64_t[2])))
6ff1394e 384 devc->vdivs = &vdivs[i];
bafd4890 385
babab622
ML
386 if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
387 return SR_ERR_MALLOC;
388 if (!(devc->data = g_try_malloc(ACQ_BUFFER_SIZE * sizeof(float))))
389 return SR_ERR_MALLOC;
390
391 devc->data_source = DATA_SOURCE_LIVE;
392
cc9fd2d2
BV
393 sdi->priv = devc;
394
395 *devices = g_slist_append(NULL, sdi);
512bb890 396
ca55277c
ML
397 return SR_OK;
398}
512bb890 399
6078d2c9 400static GSList *scan(GSList *options)
ca55277c
ML
401{
402 struct drv_context *drvc;
ca55277c 403 struct sr_config *src;
cc9fd2d2 404 GSList *l, *devices;
ca55277c 405 GDir *dir;
ca55277c 406 int ret;
cc9fd2d2
BV
407 const gchar *dev_name;
408 gchar *port = NULL;
0dc7b43e 409 gchar *serialcomm = NULL;
fb6e5ba8 410
ca55277c 411 drvc = di->priv;
d2e0b1fa 412
ca55277c
ML
413 for (l = options; l; l = l->next) {
414 src = l->data;
0dc7b43e
ML
415 switch (src->key) {
416 case SR_CONF_CONN:
cc9fd2d2 417 port = (char *)g_variant_get_string(src->data, NULL);
ca55277c 418 break;
0dc7b43e
ML
419 case SR_CONF_SERIALCOMM:
420 serialcomm = (char *)g_variant_get_string(src->data, NULL);
421 break;
fb6e5ba8 422 }
ca55277c 423 }
fb6e5ba8 424
46a743c1 425 devices = NULL;
cc9fd2d2 426 if (port) {
0dc7b43e
ML
427 if (probe_port(port, serialcomm, &devices) == SR_ERR_MALLOC) {
428 g_free(port);
429 if (serialcomm)
430 g_free(serialcomm);
ca55277c 431 return NULL;
0dc7b43e 432 }
ca55277c 433 } else {
da970d24
BV
434 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
435 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
436 return NULL;
ca55277c 437 while ((dev_name = g_dir_read_name(dir))) {
cc9fd2d2 438 if (strncmp(dev_name, "usbtmc", 6))
ca55277c 439 continue;
cc9fd2d2 440 port = g_strconcat("/dev/", dev_name, NULL);
0dc7b43e 441 ret = probe_port(port, serialcomm, &devices);
cc9fd2d2 442 g_free(port);
0dc7b43e
ML
443 if (serialcomm)
444 g_free(serialcomm);
ca55277c
ML
445 if (ret == SR_ERR_MALLOC) {
446 g_dir_close(dir);
ca55277c 447 return NULL;
6bb192bc
ML
448 }
449 }
ca55277c
ML
450 g_dir_close(dir);
451 }
f4816ac6 452
46a743c1
BV
453 /* Tack a copy of the newly found devices onto the driver list. */
454 l = g_slist_copy(devices);
455 drvc->instances = g_slist_concat(drvc->instances, l);
cc9fd2d2 456
f4816ac6
ML
457 return devices;
458}
459
6078d2c9 460static GSList *dev_list(void)
f4816ac6 461{
0e94d524 462 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
463}
464
6078d2c9 465static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 466{
ae1bc1cc 467 struct sr_scpi_dev_inst *scpi = sdi->conn;
9bd4c956 468
ae1bc1cc 469 if (sr_scpi_open(scpi) < 0)
e0b7d23c 470 return SR_ERR;
e0b7d23c 471
3086efdd 472 if (rigol_ds_get_dev_cfg(sdi) != SR_OK)
254dd102 473 return SR_ERR;
f4816ac6 474
46a743c1 475 sdi->status = SR_ST_ACTIVE;
cc9fd2d2 476
f4816ac6
ML
477 return SR_OK;
478}
479
6078d2c9 480static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 481{
ae1bc1cc 482 struct sr_scpi_dev_inst *scpi;
22c19688 483 struct dev_context *devc;
ae1bc1cc
ML
484
485 scpi = sdi->conn;
22c19688
ML
486 devc = sdi->priv;
487
569d4dbd 488 if (devc->model->series->protocol >= PROTOCOL_V2)
38354d9d 489 rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
e0b7d23c 490
ae1bc1cc
ML
491 if (scpi) {
492 if (sr_scpi_close(scpi) < 0)
493 return SR_ERR;
cc9fd2d2
BV
494 sdi->status = SR_ST_INACTIVE;
495 }
f4816ac6
ML
496
497 return SR_OK;
498}
499
6078d2c9 500static int cleanup(void)
f4816ac6 501{
3b412e3a 502 return dev_clear();
f4816ac6
ML
503}
504
5415e602
ML
505static int analog_frame_size(const struct sr_dev_inst *sdi)
506{
507 struct dev_context *devc = sdi->priv;
508 struct sr_probe *probe;
509 int analog_probes = 0;
510 GSList *l;
511
569d4dbd
ML
512 for (l = sdi->probes; l; l = l->next) {
513 probe = l->data;
514 if (probe->type == SR_PROBE_ANALOG && probe->enabled)
515 analog_probes++;
516 }
517
824eb2ac
ML
518 if (analog_probes == 0)
519 return 0;
520
569d4dbd
ML
521 switch (devc->data_source) {
522 case DATA_SOURCE_LIVE:
523 return devc->model->series->live_samples;
524 case DATA_SOURCE_MEMORY:
525 return devc->model->series->buffer_samples / analog_probes;
470140fc 526 default:
569d4dbd 527 return 0;
5415e602
ML
528 }
529}
530
d22250a9
ML
531static int digital_frame_size(const struct sr_dev_inst *sdi)
532{
533 struct dev_context *devc = sdi->priv;
534
569d4dbd
ML
535 switch (devc->data_source) {
536 case DATA_SOURCE_LIVE:
537 return devc->model->series->live_samples * 2;
538 case DATA_SOURCE_MEMORY:
539 return devc->model->series->buffer_samples * 2;
d22250a9
ML
540 default:
541 return 0;
542 }
543}
544
8f996b89
ML
545static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
546 const struct sr_probe_group *probe_group)
d62d7ad1 547{
e43fdd8d 548 struct dev_context *devc;
2b0e4a46
AJ
549 struct sr_probe *probe;
550 const char *tmp_str;
c2b394d5 551 uint64_t samplerate;
2b0e4a46
AJ
552 int analog_channel = -1;
553 float smallest_diff = 0.0000000001;
554 int idx = -1;
555 unsigned i;
d62d7ad1 556
e43fdd8d
BV
557 if (!sdi || !(devc = sdi->priv))
558 return SR_ERR_ARG;
559
be60a9e4 560 /* If a probe group is specified, it must be a valid one. */
c2b394d5 561 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
562 sr_err("Invalid probe group specified.");
563 return SR_ERR;
be60a9e4
BV
564 }
565
2b0e4a46
AJ
566 if (probe_group) {
567 probe = g_slist_nth_data(probe_group->probes, 0);
568 if (!probe)
569 return SR_ERR;
570 if (probe->type == SR_PROBE_ANALOG) {
571 if (probe->name[2] < '1' || probe->name[2] > '4')
572 return SR_ERR;
573 analog_channel = probe->name[2] - '1';
574 }
575 }
576
d62d7ad1
BV
577 switch (id) {
578 case SR_CONF_NUM_TIMEBASE:
569d4dbd 579 *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
d62d7ad1
BV
580 break;
581 case SR_CONF_NUM_VDIV:
72ecba02 582 *data = g_variant_new_int32(NUM_VDIV);
babab622
ML
583 case SR_CONF_DATA_SOURCE:
584 if (devc->data_source == DATA_SOURCE_LIVE)
585 *data = g_variant_new_string("Live");
586 else if (devc->data_source == DATA_SOURCE_MEMORY)
587 *data = g_variant_new_string("Memory");
588 else
589 *data = g_variant_new_string("Segmented");
590 break;
4914dd4b
ML
591 case SR_CONF_SAMPLERATE:
592 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 593 samplerate = analog_frame_size(sdi) /
569d4dbd 594 (devc->timebase * devc->model->series->num_horizontal_divs);
4914dd4b 595 *data = g_variant_new_uint64(samplerate);
c2b394d5 596 } else {
4914dd4b 597 return SR_ERR_NA;
c2b394d5 598 }
4914dd4b 599 break;
2b0e4a46
AJ
600 case SR_CONF_TRIGGER_SOURCE:
601 if (!strcmp(devc->trigger_source, "ACL"))
602 tmp_str = "AC Line";
603 else if (!strcmp(devc->trigger_source, "CHAN1"))
604 tmp_str = "CH1";
605 else if (!strcmp(devc->trigger_source, "CHAN2"))
606 tmp_str = "CH2";
607 else if (!strcmp(devc->trigger_source, "CHAN3"))
608 tmp_str = "CH3";
609 else if (!strcmp(devc->trigger_source, "CHAN4"))
610 tmp_str = "CH4";
611 else
612 tmp_str = devc->trigger_source;
613 *data = g_variant_new_string(tmp_str);
614 break;
615 case SR_CONF_TIMEBASE:
616 for (i = 0; i < devc->num_timebases; i++) {
617 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
618 float diff = fabs(devc->timebase - tb);
619 if (diff < smallest_diff) {
620 smallest_diff = diff;
621 idx = i;
622 }
623 }
624 if (idx < 0)
625 return SR_ERR_NA;
626 *data = g_variant_new("(tt)", devc->timebases[idx][0],
627 devc->timebases[idx][1]);
628 break;
629 case SR_CONF_VDIV:
630 if (analog_channel < 0)
631 return SR_ERR_NA;
632 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
633 float vdiv = (float)vdivs[i][0] / vdivs[i][1];
634 float diff = fabs(devc->vdiv[analog_channel] - vdiv);
635 if (diff < smallest_diff) {
636 smallest_diff = diff;
637 idx = i;
638 }
639 }
640 if (idx < 0)
641 return SR_ERR_NA;
642 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
643 break;
644 case SR_CONF_COUPLING:
645 if (analog_channel < 0)
646 return SR_ERR_NA;
647 *data = g_variant_new_string(devc->coupling[analog_channel]);
648 break;
d62d7ad1 649 default:
bd6fbf62 650 return SR_ERR_NA;
d62d7ad1
BV
651 }
652
653 return SR_OK;
654}
655
8f996b89
ML
656static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
657 const struct sr_probe_group *probe_group)
f4816ac6 658{
29d957ce 659 struct dev_context *devc;
ca9b9f48 660 uint64_t p, q;
254dd102 661 double t_dbl;
f48e0249 662 unsigned int i, j;
254dd102
BV
663 int ret;
664 const char *tmp_str;
889ef4a0 665 char buffer[16];
f4816ac6 666
e43fdd8d
BV
667 if (!(devc = sdi->priv))
668 return SR_ERR_ARG;
29d957ce 669
e73ffd42
BV
670 if (sdi->status != SR_ST_ACTIVE)
671 return SR_ERR_DEV_CLOSED;
f4816ac6 672
be60a9e4 673 /* If a probe group is specified, it must be a valid one. */
c2b394d5 674 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
675 sr_err("Invalid probe group specified.");
676 return SR_ERR;
be60a9e4
BV
677 }
678
f4816ac6 679 ret = SR_OK;
035a1078 680 switch (id) {
1953564a 681 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 682 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 683 break;
1953564a 684 case SR_CONF_TRIGGER_SLOPE:
ca9b9f48
DE
685 tmp_str = g_variant_get_string(data, NULL);
686
687 if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r'))
688 return SR_ERR_ARG;
689
254dd102 690 g_free(devc->trigger_slope);
ca9b9f48 691 devc->trigger_slope = g_strdup((tmp_str[0] == 'r') ? "POS" : "NEG");
38354d9d 692 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 693 break;
1953564a 694 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
695 t_dbl = g_variant_get_double(data);
696 if (t_dbl < 0.0 || t_dbl > 1.0)
697 return SR_ERR;
698 devc->horiz_triggerpos = t_dbl;
699 /* We have the trigger offset as a percentage of the frame, but
700 * need to express this in seconds. */
bafd4890 701 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
889ef4a0 702 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
38354d9d 703 ret = rigol_ds_config_set(sdi, ":TIM:OFFS %s", buffer);
e0b7d23c 704 break;
1953564a 705 case SR_CONF_TIMEBASE:
f6a0ac9f 706 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
707 for (i = 0; i < devc->num_timebases; i++) {
708 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102 709 devc->timebase = (float)p / q;
889ef4a0
AJ
710 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
711 devc->timebase);
38354d9d 712 ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
f6a0ac9f
BV
713 break;
714 }
715 }
bafd4890 716 if (i == devc->num_timebases)
254dd102 717 ret = SR_ERR_ARG;
e0b7d23c 718 break;
1953564a 719 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 720 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
721 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
722 if (!strcmp(trigger_sources[i], tmp_str)) {
723 g_free(devc->trigger_source);
724 devc->trigger_source = g_strdup(trigger_sources[i]);
725 if (!strcmp(devc->trigger_source, "AC Line"))
726 tmp_str = "ACL";
727 else if (!strcmp(devc->trigger_source, "CH1"))
728 tmp_str = "CHAN1";
729 else if (!strcmp(devc->trigger_source, "CH2"))
730 tmp_str = "CHAN2";
821fbcad
ML
731 else if (!strcmp(devc->trigger_source, "CH3"))
732 tmp_str = "CHAN3";
733 else if (!strcmp(devc->trigger_source, "CH4"))
734 tmp_str = "CHAN4";
254dd102
BV
735 else
736 tmp_str = (char *)devc->trigger_source;
38354d9d 737 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
254dd102
BV
738 break;
739 }
4e108ace 740 }
254dd102
BV
741 if (i == ARRAY_SIZE(trigger_sources))
742 ret = SR_ERR_ARG;
e0b7d23c 743 break;
1953564a 744 case SR_CONF_VDIV:
be60a9e4
BV
745 if (!probe_group) {
746 sr_err("No probe group specified.");
747 return SR_ERR_PROBE_GROUP;
748 }
f6a0ac9f 749 g_variant_get(data, "(tt)", &p, &q);
f48e0249 750 for (i = 0; i < 2; i++) {
78bcc55a
BV
751 if (probe_group == &devc->analog_groups[i]) {
752 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
753 if (vdivs[j][0] != p || vdivs[j][1] != q)
754 continue;
755 devc->vdiv[i] = (float)p / q;
889ef4a0
AJ
756 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
757 devc->vdiv[i]);
38354d9d 758 return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
889ef4a0 759 buffer);
f48e0249
ML
760 }
761 return SR_ERR_ARG;
762 }
e0b7d23c 763 }
f48e0249 764 return SR_ERR_NA;
1953564a 765 case SR_CONF_COUPLING:
78bcc55a
BV
766 if (!probe_group) {
767 sr_err("No probe group specified.");
768 return SR_ERR_PROBE_GROUP;
769 }
f6a0ac9f 770 tmp_str = g_variant_get_string(data, NULL);
f48e0249 771 for (i = 0; i < 2; i++) {
78bcc55a
BV
772 if (probe_group == &devc->analog_groups[i]) {
773 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
774 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
775 g_free(devc->coupling[i]);
776 devc->coupling[i] = g_strdup(coupling[j]);
38354d9d 777 return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
f48e0249
ML
778 devc->coupling[i]);
779 }
780 }
781 return SR_ERR_ARG;
e0b7d23c
ML
782 }
783 }
f48e0249 784 return SR_ERR_NA;
babab622
ML
785 case SR_CONF_DATA_SOURCE:
786 tmp_str = g_variant_get_string(data, NULL);
787 if (!strcmp(tmp_str, "Live"))
788 devc->data_source = DATA_SOURCE_LIVE;
569d4dbd
ML
789 else if (devc->model->series->protocol >= PROTOCOL_V2
790 && !strcmp(tmp_str, "Memory"))
babab622 791 devc->data_source = DATA_SOURCE_MEMORY;
569d4dbd 792 else if (devc->model->series->protocol >= PROTOCOL_V3
babab622
ML
793 && !strcmp(tmp_str, "Segmented"))
794 devc->data_source = DATA_SOURCE_SEGMENTED;
795 else
796 return SR_ERR;
797 break;
f4816ac6 798 default:
bd6fbf62 799 ret = SR_ERR_NA;
29d957ce 800 break;
f4816ac6
ML
801 }
802
803 return ret;
804}
805
8f996b89
ML
806static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
807 const struct sr_probe_group *probe_group)
a1c743fc 808{
861c447b
BV
809 GVariant *tuple, *rational[2];
810 GVariantBuilder gvb;
811 unsigned int i;
7cc1a550
ML
812 struct dev_context *devc = NULL;
813
814 if (sdi)
815 devc = sdi->priv;
8f996b89 816
e43fdd8d 817 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
818 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
819 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d
BV
820 return SR_OK;
821 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
822 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
823 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
824 return SR_OK;
825 }
826
827 /* Every other option requires a valid device instance. */
828 if (!sdi || !(devc = sdi->priv))
829 return SR_ERR_ARG;
830
be60a9e4
BV
831 /* If a probe group is specified, it must be a valid one. */
832 if (probe_group) {
833 if (probe_group != &devc->analog_groups[0]
834 && probe_group != &devc->analog_groups[1]) {
835 sr_err("Invalid probe group specified.");
836 return SR_ERR;
837 }
838 }
839
e43fdd8d 840 switch (key) {
9a6517d1 841 case SR_CONF_DEVICE_OPTIONS:
be60a9e4
BV
842 if (!probe_group) {
843 sr_err("No probe group specified.");
844 return SR_ERR_PROBE_GROUP;
845 }
e43fdd8d 846 if (probe_group == &devc->digital_group) {
f48e0249
ML
847 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
848 NULL, 0, sizeof(int32_t));
849 return SR_OK;
850 } else {
851 for (i = 0; i < 2; i++) {
852 if (probe_group == &devc->analog_groups[i]) {
853 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
854 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
855 return SR_OK;
856 }
857 }
858 return SR_ERR_NA;
859 }
5f77dffc 860 break;
2a7b113d 861 case SR_CONF_COUPLING:
be60a9e4
BV
862 if (!probe_group) {
863 sr_err("No probe group specified.");
864 return SR_ERR_PROBE_GROUP;
f48e0249 865 }
58f43369
BV
866 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
867 break;
e4f2b2ad 868 case SR_CONF_VDIV:
7cc1a550
ML
869 if (!devc)
870 /* Can't know this until we have the exact model. */
871 return SR_ERR_ARG;
be60a9e4
BV
872 if (!probe_group) {
873 sr_err("No probe group specified.");
874 return SR_ERR_PROBE_GROUP;
861c447b 875 }
58f43369 876 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
0709197d 877 for (i = 0; i < NUM_VDIV; i++) {
bafd4890
ML
878 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
879 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
880 tuple = g_variant_new_tuple(rational, 2);
881 g_variant_builder_add_value(&gvb, tuple);
882 }
883 *data = g_variant_builder_end(&gvb);
884 break;
41f5bd09 885 case SR_CONF_TIMEBASE:
7cc1a550
ML
886 if (!devc)
887 /* Can't know this until we have the exact model. */
888 return SR_ERR_ARG;
a31b2ccb
AJ
889 if (devc->num_timebases <= 0)
890 return SR_ERR_NA;
861c447b 891 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
892 for (i = 0; i < devc->num_timebases; i++) {
893 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
894 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
895 tuple = g_variant_new_tuple(rational, 2);
896 g_variant_builder_add_value(&gvb, tuple);
897 }
898 *data = g_variant_builder_end(&gvb);
41f5bd09 899 break;
328bafab 900 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
901 if (!devc)
902 /* Can't know this until we have the exact model. */
903 return SR_ERR_ARG;
f6a0ac9f 904 *data = g_variant_new_strv(trigger_sources,
bafd4890 905 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 906 break;
babab622
ML
907 case SR_CONF_DATA_SOURCE:
908 if (!devc)
909 /* Can't know this until we have the exact model. */
910 return SR_ERR_ARG;
569d4dbd
ML
911 switch (devc->model->series->protocol) {
912 case PROTOCOL_V1:
913 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
914 break;
915 case PROTOCOL_V2:
babab622 916 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
569d4dbd
ML
917 break;
918 default:
919 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
920 break;
921 }
babab622 922 break;
a1c743fc 923 default:
bd6fbf62 924 return SR_ERR_NA;
a1c743fc
BV
925 }
926
927 return SR_OK;
928}
929
254dd102 930static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 931{
ae1bc1cc 932 struct sr_scpi_dev_inst *scpi;
29d957ce 933 struct dev_context *devc;
254dd102 934 struct sr_probe *probe;
f76c24f6 935 struct sr_datafeed_packet packet;
254dd102 936 GSList *l;
29d957ce 937
e73ffd42
BV
938 if (sdi->status != SR_ST_ACTIVE)
939 return SR_ERR_DEV_CLOSED;
e0b7d23c 940
ae1bc1cc 941 scpi = sdi->conn;
29d957ce
UH
942 devc = sdi->priv;
943
51b294cd
ML
944 devc->num_frames = 0;
945
254dd102
BV
946 for (l = sdi->probes; l; l = l->next) {
947 probe = l->data;
6bb192bc
ML
948 sr_dbg("handling probe %s", probe->name);
949 if (probe->type == SR_PROBE_ANALOG) {
950 if (probe->enabled)
951 devc->enabled_analog_probes = g_slist_append(
952 devc->enabled_analog_probes, probe);
953 if (probe->enabled != devc->analog_channels[probe->index]) {
954 /* Enabled channel is currently disabled, or vice versa. */
38354d9d 955 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", probe->index + 1,
6396b0a7 956 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 957 return SR_ERR;
904fd29b 958 devc->analog_channels[probe->index] = probe->enabled;
6bb192bc
ML
959 }
960 } else if (probe->type == SR_PROBE_LOGIC) {
04e8e01e 961 if (probe->enabled) {
6bb192bc
ML
962 devc->enabled_digital_probes = g_slist_append(
963 devc->enabled_digital_probes, probe);
04e8e01e
ML
964 /* Turn on LA module if currently off. */
965 if (!devc->la_enabled) {
38354d9d 966 if (rigol_ds_config_set(sdi, ":LA:DISP ON") != SR_OK)
04e8e01e
ML
967 return SR_ERR;
968 devc->la_enabled = TRUE;
969 }
970 }
6bb192bc
ML
971 if (probe->enabled != devc->digital_channels[probe->index]) {
972 /* Enabled channel is currently disabled, or vice versa. */
38354d9d 973 if (rigol_ds_config_set(sdi, ":DIG%d:TURN %s", probe->index,
6396b0a7 974 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 975 return SR_ERR;
904fd29b 976 devc->digital_channels[probe->index] = probe->enabled;
6bb192bc 977 }
254dd102
BV
978 }
979 }
1fed20cb 980
6bb192bc 981 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 982 return SR_ERR;
e0b7d23c 983
04e8e01e
ML
984 /* Turn off LA module if on and no digital probes selected. */
985 if (devc->la_enabled && !devc->enabled_digital_probes)
38354d9d 986 if (rigol_ds_config_set(sdi, ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
987 return SR_ERR;
988
e086b750
ML
989 /* Set memory mode. */
990 if (devc->data_source == DATA_SOURCE_SEGMENTED) {
991 sr_err("Data source 'Segmented' not yet supported");
992 return SR_ERR;
993 }
994
995 devc->analog_frame_size = analog_frame_size(sdi);
996 devc->digital_frame_size = digital_frame_size(sdi);
997
569d4dbd
ML
998 switch (devc->model->series->protocol) {
999 case PROTOCOL_V2:
e086b750
ML
1000 if (rigol_ds_config_set(sdi, ":ACQ:MDEP LONG") != SR_OK)
1001 return SR_ERR;
569d4dbd
ML
1002 break;
1003 case PROTOCOL_V3:
e086b750
ML
1004 /* Apparently for the DS2000 the memory
1005 * depth can only be set in Running state -
1006 * this matches the behaviour of the UI. */
38354d9d 1007 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb 1008 return SR_ERR;
e086b750
ML
1009 if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
1010 devc->analog_frame_size) != SR_OK)
1011 return SR_ERR;
1012 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
1fed20cb 1013 return SR_ERR;
569d4dbd
ML
1014 break;
1015 default:
1016 break;
1fed20cb
ML
1017 }
1018
e086b750
ML
1019 if (devc->data_source == DATA_SOURCE_LIVE)
1020 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1021 return SR_ERR;
1022
ae1bc1cc 1023 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
1024
1025 /* Send header packet to the session bus. */
29a27196 1026 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 1027
821fbcad
ML
1028 if (devc->enabled_analog_probes)
1029 devc->channel_entry = devc->enabled_analog_probes;
1030 else
1031 devc->channel_entry = devc->enabled_digital_probes;
1032
e086b750
ML
1033 if (rigol_ds_capture_start(sdi) != SR_OK)
1034 return SR_ERR;
f4816ac6 1035
f76c24f6
ML
1036 /* Start of first frame. */
1037 packet.type = SR_DF_FRAME_BEGIN;
1038 sr_session_send(cb_data, &packet);
1039
f4816ac6
ML
1040 return SR_OK;
1041}
1042
254dd102 1043static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 1044{
29d957ce 1045 struct dev_context *devc;
ae1bc1cc 1046 struct sr_scpi_dev_inst *scpi;
b751cf7a 1047 struct sr_datafeed_packet packet;
29d957ce 1048
f4816ac6
ML
1049 (void)cb_data;
1050
29d957ce
UH
1051 devc = sdi->priv;
1052
f4816ac6
ML
1053 if (sdi->status != SR_ST_ACTIVE) {
1054 sr_err("Device inactive, can't stop acquisition.");
1055 return SR_ERR;
1056 }
1057
b751cf7a
ML
1058 /* End of last frame. */
1059 packet.type = SR_DF_END;
1060 sr_session_send(sdi, &packet);
1061
6bb192bc
ML
1062 g_slist_free(devc->enabled_analog_probes);
1063 g_slist_free(devc->enabled_digital_probes);
1064 devc->enabled_analog_probes = NULL;
1065 devc->enabled_digital_probes = NULL;
ae1bc1cc
ML
1066 scpi = sdi->conn;
1067 sr_scpi_source_remove(scpi);
f4816ac6
ML
1068
1069 return SR_OK;
1070}
1071
3086efdd
ML
1072SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
1073 .name = "rigol-ds",
1074 .longname = "Rigol DS",
f4816ac6 1075 .api_version = 1,
6078d2c9
UH
1076 .init = init,
1077 .cleanup = cleanup,
1078 .scan = scan,
1079 .dev_list = dev_list,
3b412e3a 1080 .dev_clear = dev_clear,
d62d7ad1 1081 .config_get = config_get,
035a1078 1082 .config_set = config_set,
a1c743fc 1083 .config_list = config_list,
6078d2c9
UH
1084 .dev_open = dev_open,
1085 .dev_close = dev_close,
254dd102
BV
1086 .dev_acquisition_start = dev_acquisition_start,
1087 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
1088 .priv = NULL,
1089};