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