]> sigrok.org Git - libsigrok.git/blob - hardware/rigol-ds1xx2/api.c
rigol-ds1xx2: fix bitrot in device cleanup code
[libsigrok.git] / hardware / rigol-ds1xx2 / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
5  * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <glib.h>
26 #include "libsigrok.h"
27 #include "libsigrok-internal.h"
28 #include "protocol.h"
29
30 #define NUM_TIMEBASE  12
31 #define NUM_VDIV      8
32
33 static const int32_t hwopts[] = {
34         SR_CONF_CONN,
35 };
36
37 static const int32_t hwcaps[] = {
38         SR_CONF_OSCILLOSCOPE,
39         SR_CONF_TIMEBASE,
40         SR_CONF_TRIGGER_SOURCE,
41         SR_CONF_TRIGGER_SLOPE,
42         SR_CONF_HORIZ_TRIGGERPOS,
43         SR_CONF_NUM_TIMEBASE,
44 };
45
46 static const int32_t analog_hwcaps[] = {
47         SR_CONF_NUM_VDIV,
48         SR_CONF_VDIV,
49         SR_CONF_COUPLING
50 };
51
52 static const uint64_t timebases[][2] = {
53         /* nanoseconds */
54         { 2, 1000000000 },
55         { 5, 1000000000 },
56         { 10, 1000000000 },
57         { 20, 1000000000 },
58         { 50, 1000000000 },
59         { 100, 1000000000 },
60         { 500, 1000000000 },
61         /* microseconds */
62         { 1, 1000000 },
63         { 2, 1000000 },
64         { 5, 1000000 },
65         { 10, 1000000 },
66         { 20, 1000000 },
67         { 50, 1000000 },
68         { 100, 1000000 },
69         { 200, 1000000 },
70         { 500, 1000000 },
71         /* milliseconds */
72         { 1, 1000 },
73         { 2, 1000 },
74         { 5, 1000 },
75         { 10, 1000 },
76         { 20, 1000 },
77         { 50, 1000 },
78         { 100, 1000 },
79         { 200, 1000 },
80         { 500, 1000 },
81         /* seconds */
82         { 1, 1 },
83         { 2, 1 },
84         { 5, 1 },
85         { 10, 1 },
86         { 20, 1 },
87         { 50, 1 },
88 };
89
90 static const uint64_t vdivs[][2] = {
91         /* millivolts */
92         { 2, 1000 },
93         { 5, 1000 },
94         { 10, 1000 },
95         { 20, 1000 },
96         { 50, 1000 },
97         { 100, 1000 },
98         { 200, 1000 },
99         { 500, 1000 },
100         /* volts */
101         { 1, 1 },
102         { 2, 1 },
103         { 5, 1 },
104         { 10, 1 },
105 };
106
107 static const char *trigger_sources[] = {
108         "CH1",
109         "CH2",
110         "EXT",
111         "AC Line",
112         "D0",
113         "D1",
114         "D2",
115         "D3",
116         "D4",
117         "D5",
118         "D6",
119         "D7",
120         "D8",
121         "D9",
122         "D10",
123         "D11",
124         "D12",
125         "D13",
126         "D14",
127         "D15",
128 };
129
130 static const char *coupling[] = {
131         "AC",
132         "DC",
133         "GND",
134 };
135
136 static const char *supported_models[] = {
137         "DS1052E",
138         "DS1102E",
139         "DS1152E",
140         "DS1052D",
141         "DS1102D",
142         "DS1152D",
143 };
144
145 SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info;
146 static struct sr_dev_driver *di = &rigol_ds1xx2_driver_info;
147
148 static void clear_helper(void *priv)
149 {
150         struct dev_context *devc;
151
152         devc = priv;
153         g_free(devc->coupling[0]);
154         g_free(devc->coupling[1]);
155         g_free(devc->trigger_source);
156         g_free(devc->trigger_slope);
157         g_slist_free(devc->analog_groups[0].probes);
158         g_slist_free(devc->analog_groups[1].probes);
159         g_slist_free(devc->digital_group.probes);
160 }
161
162 static int dev_clear(void)
163 {
164         return std_dev_clear(di, clear_helper);
165 }
166
167 static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
168 {
169         va_list args;
170         char buf[256];
171
172         va_start(args, format);
173         vsnprintf(buf, 255, format, args);
174         va_end(args);
175         if (rigol_ds1xx2_send(sdi, buf) != SR_OK)
176                 return SR_ERR;
177
178         /* When setting a bunch of parameters in a row, the DS1052E scrambles
179          * some of them unless there is at least 100ms delay in between. */
180         sr_spew("delay %dms", 100);
181         g_usleep(100000);
182
183         return SR_OK;
184 }
185
186 static int init(struct sr_context *sr_ctx)
187 {
188         return std_init(sr_ctx, di, LOG_PREFIX);
189 }
190
191 static int probe_port(const char *port, GSList **devices)
192 {
193         struct dev_context *devc;
194         struct sr_dev_inst *sdi;
195         struct sr_serial_dev_inst *serial;
196         struct sr_probe *probe;
197         unsigned int i;
198         int len, num_tokens;
199         gboolean matched, has_digital;
200         const char *manufacturer, *model, *version;
201         char buf[256];
202         gchar **tokens, *channel_name;
203
204         *devices = NULL;
205         if (!(serial = sr_serial_dev_inst_new(port, NULL)))
206                 return SR_ERR_MALLOC;
207
208         if (serial_open(serial, SERIAL_RDWR) != SR_OK)
209                 return SR_ERR;
210         len = serial_write(serial, "*IDN?", 5);
211         len = serial_read(serial, buf, sizeof(buf));
212         if (serial_close(serial) != SR_OK)
213                 return SR_ERR;
214
215         sr_serial_dev_inst_free(serial);
216
217         if (len == 0)
218                 return SR_ERR_NA;
219
220         buf[len] = 0;
221         tokens = g_strsplit(buf, ",", 0);
222         sr_dbg("response: %s [%s]", port, buf);
223
224         for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
225
226         if (num_tokens < 4) {
227                 g_strfreev(tokens);
228                 return SR_ERR_NA;
229         }
230
231         manufacturer = tokens[0];
232         model = tokens[1];
233         version = tokens[3];
234
235         if (strcmp(manufacturer, "Rigol Technologies")) {
236                 g_strfreev(tokens);
237                 return SR_ERR_NA;
238         }
239
240         matched = has_digital = FALSE;
241         for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
242                 if (!strcmp(model, supported_models[i])) {
243                         matched = TRUE;
244                         has_digital = g_str_has_suffix(model, "D");
245                         break;
246                 }
247         }
248
249         if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
250                 manufacturer, model, version))) {
251                 g_strfreev(tokens);
252                 return SR_ERR_NA;
253         }
254
255         g_strfreev(tokens);
256
257         if (!(sdi->conn = sr_serial_dev_inst_new(port, NULL)))
258                 return SR_ERR_MALLOC;
259         sdi->driver = di;
260         sdi->inst_type = SR_INST_SERIAL;
261
262         if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
263                 return SR_ERR_MALLOC;
264         devc->limit_frames = 0;
265         devc->has_digital = has_digital;
266
267         for (i = 0; i < 2; i++) {
268                 channel_name = (i == 0 ? "CH1" : "CH2");
269                 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name)))
270                         return SR_ERR_MALLOC;
271                 sdi->probes = g_slist_append(sdi->probes, probe);
272                 devc->analog_groups[i].name = channel_name;
273                 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
274                 sdi->probe_groups = g_slist_append(sdi->probe_groups,
275                                 &devc->analog_groups[i]);
276         }
277
278         if (devc->has_digital) {
279                 for (i = 0; i < 16; i++) {
280                         if (!(channel_name = g_strdup_printf("D%d", i)))
281                                 return SR_ERR_MALLOC;
282                         probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
283                         g_free(channel_name);
284                         if (!probe)
285                                 return SR_ERR_MALLOC;
286                         sdi->probes = g_slist_append(sdi->probes, probe);
287                         devc->digital_group.probes = g_slist_append(
288                                         devc->digital_group.probes, probe);
289                         devc->digital_group.name = "LA";
290                         sdi->probe_groups = g_slist_append(sdi->probe_groups,
291                                         &devc->digital_group);
292                 }
293         }
294         sdi->priv = devc;
295
296         *devices = g_slist_append(NULL, sdi);
297
298         return SR_OK;
299 }
300
301 static GSList *scan(GSList *options)
302 {
303         struct drv_context *drvc;
304         struct sr_config *src;
305         GSList *l, *devices;
306         GDir *dir;
307         int ret;
308         const gchar *dev_name;
309         gchar *port = NULL;
310
311         drvc = di->priv;
312
313         for (l = options; l; l = l->next) {
314                 src = l->data;
315                 if (src->key == SR_CONF_CONN) {
316                         port = (char *)g_variant_get_string(src->data, NULL);
317                         break;
318                 }
319         }
320
321         devices = NULL;
322         if (port) {
323                 if (probe_port(port, &devices) == SR_ERR_MALLOC)
324                         return NULL;
325         } else {
326                 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
327                         if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
328                                 return NULL;
329                 while ((dev_name = g_dir_read_name(dir))) {
330                         if (strncmp(dev_name, "usbtmc", 6))
331                                 continue;
332                         port = g_strconcat("/dev/", dev_name, NULL);
333                         ret = probe_port(port, &devices);
334                         g_free(port);
335                         if (ret == SR_ERR_MALLOC) {
336                                 g_dir_close(dir);
337                                 return NULL;
338                         }
339                 }
340                 g_dir_close(dir);
341         }
342
343         /* Tack a copy of the newly found devices onto the driver list. */
344         l = g_slist_copy(devices);
345         drvc->instances = g_slist_concat(drvc->instances, l);
346
347         return devices;
348 }
349
350 static GSList *dev_list(void)
351 {
352         return ((struct drv_context *)(di->priv))->instances;
353 }
354
355 static int dev_open(struct sr_dev_inst *sdi)
356 {
357
358         if (serial_open(sdi->conn, SERIAL_RDWR) != SR_OK)
359                 return SR_ERR;
360
361         if (rigol_ds1xx2_get_dev_cfg(sdi) != SR_OK)
362                 return SR_ERR;
363
364         sdi->status = SR_ST_ACTIVE;
365
366         return SR_OK;
367 }
368
369 static int dev_close(struct sr_dev_inst *sdi)
370 {
371         struct sr_serial_dev_inst *serial;
372
373         serial = sdi->conn;
374         if (serial && serial->fd != -1) {
375                 serial_close(serial);
376                 sdi->status = SR_ST_INACTIVE;
377         }
378
379         return SR_OK;
380 }
381
382 static int cleanup(void)
383 {
384         return dev_clear();
385 }
386
387 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
388                 const struct sr_probe_group *probe_group)
389 {
390         struct dev_context *devc;
391         unsigned int i;
392
393         if (!sdi || !(devc = sdi->priv))
394                 return SR_ERR_ARG;
395
396         switch (id) {
397         case SR_CONF_NUM_TIMEBASE:
398                 *data = g_variant_new_int32(NUM_TIMEBASE);
399                 break;
400         case SR_CONF_NUM_VDIV:
401                 for (i = 0; i < 2; i++) {
402                         if (probe_group == &devc->analog_groups[i]) {
403                                 *data = g_variant_new_int32(NUM_VDIV);
404                                 return SR_OK;
405                         }
406                 }
407                 return SR_ERR_NA;
408         default:
409                 return SR_ERR_NA;
410         }
411
412         return SR_OK;
413 }
414
415 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
416                 const struct sr_probe_group *probe_group)
417 {
418         struct dev_context *devc;
419         uint64_t tmp_u64, p, q;
420         double t_dbl;
421         unsigned int i, j;
422         int ret;
423         const char *tmp_str;
424
425         if (!(devc = sdi->priv))
426                 return SR_ERR_ARG;
427
428         if (sdi->status != SR_ST_ACTIVE)
429                 return SR_ERR_DEV_CLOSED;
430
431         ret = SR_OK;
432         switch (id) {
433         case SR_CONF_LIMIT_FRAMES:
434                 devc->limit_frames = g_variant_get_uint64(data);
435                 break;
436         case SR_CONF_TRIGGER_SLOPE:
437                 tmp_u64 = g_variant_get_uint64(data);
438                 if (tmp_u64 != 0 && tmp_u64 != 1)
439                         return SR_ERR;
440                 g_free(devc->trigger_slope);
441                 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
442                 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
443                 break;
444         case SR_CONF_HORIZ_TRIGGERPOS:
445                 t_dbl = g_variant_get_double(data);
446                 if (t_dbl < 0.0 || t_dbl > 1.0)
447                         return SR_ERR;
448                 devc->horiz_triggerpos = t_dbl;
449                 /* We have the trigger offset as a percentage of the frame, but
450                  * need to express this in seconds. */
451                 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
452                 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
453                 break;
454         case SR_CONF_TIMEBASE:
455                 g_variant_get(data, "(tt)", &p, &q);
456                 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
457                         if (timebases[i][0] == p && timebases[i][1] == q) {
458                                 devc->timebase = (float)p / q;
459                                 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
460                                 break;
461                         }
462                 }
463                 if (i == ARRAY_SIZE(timebases))
464                         ret = SR_ERR_ARG;
465                 break;
466         case SR_CONF_TRIGGER_SOURCE:
467                 tmp_str = g_variant_get_string(data, NULL);
468                 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
469                         if (!strcmp(trigger_sources[i], tmp_str)) {
470                                 g_free(devc->trigger_source);
471                                 devc->trigger_source = g_strdup(trigger_sources[i]);
472                                 if (!strcmp(devc->trigger_source, "AC Line"))
473                                         tmp_str = "ACL";
474                                 else if (!strcmp(devc->trigger_source, "CH1"))
475                                         tmp_str = "CHAN1";
476                                 else if (!strcmp(devc->trigger_source, "CH2"))
477                                         tmp_str = "CHAN2";
478                                 else
479                                         tmp_str = (char *)devc->trigger_source;
480                                 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
481                                 break;
482                         }
483                 }
484                 if (i == ARRAY_SIZE(trigger_sources))
485                         ret = SR_ERR_ARG;
486                 break;
487         case SR_CONF_VDIV:
488                 g_variant_get(data, "(tt)", &p, &q);
489                 for (i = 0; i < 2; i++) {
490                         if (probe_group == &devc->analog_groups[i])
491                         {
492                                 for (j = 0; j < ARRAY_SIZE(vdivs); j++)
493                                 {
494                                         if (vdivs[j][0] != p || vdivs[j][1] != q)
495                                                 continue;
496                                         devc->vdiv[i] = (float)p / q;
497                                         return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
498                                                         devc->vdiv[i]);
499                                 }
500                                 return SR_ERR_ARG;
501                         }
502                 }
503                 return SR_ERR_NA;
504         case SR_CONF_COUPLING:
505                 tmp_str = g_variant_get_string(data, NULL);
506                 for (i = 0; i < 2; i++) {
507                         if (probe_group == &devc->analog_groups[i])
508                         {
509                                 for (j = 0; j < ARRAY_SIZE(coupling); j++)
510                                 {
511                                         if (!strcmp(tmp_str, coupling[j]))
512                                         {
513                                                 g_free(devc->coupling[i]);
514                                                 devc->coupling[i] = g_strdup(coupling[j]);
515                                                 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
516                                                                 devc->coupling[i]);
517                                         }
518                                 }
519                                 return SR_ERR_ARG;
520                         }
521                 }
522                 return SR_ERR_NA;
523         default:
524                 ret = SR_ERR_NA;
525                 break;
526         }
527
528         return ret;
529 }
530
531 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
532                 const struct sr_probe_group *probe_group)
533 {
534         GVariant *tuple, *rational[2];
535         GVariantBuilder gvb;
536         unsigned int i;
537         struct dev_context *devc;
538
539         if (key == SR_CONF_SCAN_OPTIONS) {
540                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
541                                 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
542                 return SR_OK;
543         } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
544                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
545                         hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
546                 return SR_OK;
547         }
548
549         /* Every other option requires a valid device instance. */
550         if (!sdi || !(devc = sdi->priv))
551                 return SR_ERR_ARG;
552
553         switch (key) {
554                 break;
555         case SR_CONF_DEVICE_OPTIONS:
556                 if (probe_group == &devc->digital_group) {
557                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
558                                 NULL, 0, sizeof(int32_t));
559                         return SR_OK;
560                 } else {
561                         for (i = 0; i < 2; i++) {
562                                 if (probe_group == &devc->analog_groups[i]) {
563                                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
564                                                 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
565                                         return SR_OK;
566                                 }
567                         }
568                         return SR_ERR_NA;
569                 }
570         case SR_CONF_COUPLING:
571                 for (i = 0; i < 2; i++) {
572                         if (probe_group == &devc->analog_groups[i]) {
573                                 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
574                                 return SR_OK;
575                         }
576                 }
577                 return SR_ERR_NA;
578         case SR_CONF_VDIV:
579                 for (i = 0; i < 2; i++) {
580                         if (probe_group == &devc->analog_groups[i]) {
581                                 rational[0] = g_variant_new_uint64(vdivs[i][0]);
582                                 rational[1] = g_variant_new_uint64(vdivs[i][1]);
583                                 *data = g_variant_new_tuple(rational, 2);
584                                 return SR_OK;
585                         }
586                 }
587                 return SR_ERR_NA;
588         case SR_CONF_TIMEBASE:
589                 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
590                 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
591                         rational[0] = g_variant_new_uint64(timebases[i][0]);
592                         rational[1] = g_variant_new_uint64(timebases[i][1]);
593                         tuple = g_variant_new_tuple(rational, 2);
594                         g_variant_builder_add_value(&gvb, tuple);
595                 }
596                 *data = g_variant_builder_end(&gvb);
597                 break;
598         case SR_CONF_TRIGGER_SOURCE:
599                 *data = g_variant_new_strv(trigger_sources,
600                                 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
601                 break;
602         default:
603                 return SR_ERR_NA;
604         }
605
606         return SR_OK;
607 }
608
609 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
610 {
611         struct sr_serial_dev_inst *serial;
612         struct dev_context *devc;
613         struct sr_probe *probe;
614         GSList *l;
615         char cmd[256];
616
617         if (sdi->status != SR_ST_ACTIVE)
618                 return SR_ERR_DEV_CLOSED;
619
620         serial = sdi->conn;
621         devc = sdi->priv;
622
623         for (l = sdi->probes; l; l = l->next) {
624                 probe = l->data;
625                 sr_dbg("handling probe %s", probe->name);
626                 if (probe->type == SR_PROBE_ANALOG) {
627                         if (probe->enabled)
628                                 devc->enabled_analog_probes = g_slist_append(
629                                                 devc->enabled_analog_probes, probe);
630                         if (probe->enabled != devc->analog_channels[probe->index]) {
631                                 /* Enabled channel is currently disabled, or vice versa. */
632                                 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
633                                                 probe->enabled ? "ON" : "OFF");
634                                 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
635                                         return SR_ERR;
636                         }
637                 } else if (probe->type == SR_PROBE_LOGIC) {
638                         if (probe->enabled)
639                                 devc->enabled_digital_probes = g_slist_append(
640                                                 devc->enabled_digital_probes, probe);
641                         if (probe->enabled != devc->digital_channels[probe->index]) {
642                                 /* Enabled channel is currently disabled, or vice versa. */
643                                 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
644                                                 probe->enabled ? "ON" : "OFF");
645                                 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
646                                         return SR_ERR;
647                         }
648                 }
649         }
650         if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
651                 return SR_ERR;
652
653         sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
654
655         /* Send header packet to the session bus. */
656         std_session_send_df_header(cb_data, LOG_PREFIX);
657
658         /* Fetch the first frame. */
659         if (devc->enabled_analog_probes) {
660                 devc->channel_frame = devc->enabled_analog_probes->data;
661                 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%d",
662                                 devc->channel_frame->index + 1) != SR_OK)
663                         return SR_ERR;
664         } else {
665                 devc->channel_frame = devc->enabled_digital_probes->data;
666                 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG") != SR_OK)
667                         return SR_ERR;
668         }
669
670         devc->num_frame_bytes = 0;
671
672         return SR_OK;
673 }
674
675 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
676 {
677         struct dev_context *devc;
678         struct sr_serial_dev_inst *serial;
679
680         (void)cb_data;
681
682         devc = sdi->priv;
683
684         if (sdi->status != SR_ST_ACTIVE) {
685                 sr_err("Device inactive, can't stop acquisition.");
686                 return SR_ERR;
687         }
688
689         g_slist_free(devc->enabled_analog_probes);
690         g_slist_free(devc->enabled_digital_probes);
691         devc->enabled_analog_probes = NULL;
692         devc->enabled_digital_probes = NULL;
693         serial = sdi->conn;
694         sr_source_remove(serial->fd);
695
696         return SR_OK;
697 }
698
699 SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
700         .name = "rigol-ds1xx2",
701         .longname = "Rigol DS1xx2",
702         .api_version = 1,
703         .init = init,
704         .cleanup = cleanup,
705         .scan = scan,
706         .dev_list = dev_list,
707         .dev_clear = dev_clear,
708         .config_get = config_get,
709         .config_set = config_set,
710         .config_list = config_list,
711         .dev_open = dev_open,
712         .dev_close = dev_close,
713         .dev_acquisition_start = dev_acquisition_start,
714         .dev_acquisition_stop = dev_acquisition_stop,
715         .priv = NULL,
716 };