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