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