]> sigrok.org Git - libsigrok.git/blame - src/hardware/hung-chang-dso-2100/api.c
Introduce standard implementation of the dev_list() callback
[libsigrok.git] / src / hardware / hung-chang-dso-2100 / api.c
CommitLineData
05ac4a98
DG
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2015 Daniel Glöckner <daniel-gl@gmx.net>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
6ec6c43b 20#include <config.h>
c9404469
DG
21#include <ieee1284.h>
22#include <string.h>
05ac4a98
DG
23#include "protocol.h"
24
25SR_PRIV struct sr_dev_driver hung_chang_dso_2100_driver_info;
26
c9404469
DG
27static const uint32_t scanopts[] = {
28 SR_CONF_CONN,
29};
30
31static const uint32_t drvopts[] = {
32 SR_CONF_OSCILLOSCOPE,
33};
34
35static const uint32_t devopts[] = {
36 SR_CONF_CONN | SR_CONF_GET,
37 SR_CONF_LIMIT_FRAMES | SR_CONF_GET | SR_CONF_SET,
38 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
39 SR_CONF_TRIGGER_SOURCE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
40 SR_CONF_TRIGGER_SLOPE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
41 SR_CONF_BUFFERSIZE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
42};
43
44static const uint32_t cgopts[] = {
45 SR_CONF_VDIV | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
46 SR_CONF_COUPLING | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
47 SR_CONF_PROBE_FACTOR | SR_CONF_GET | SR_CONF_SET,
48};
49
50static const uint64_t samplerates[] = {
51 SR_MHZ(100), SR_MHZ(50), SR_MHZ(25), SR_MHZ(20),
52 SR_MHZ(10), SR_MHZ(5), SR_KHZ(2500), SR_MHZ(2),
53 SR_MHZ(1), SR_KHZ(500), SR_KHZ(250), SR_KHZ(200),
54 SR_KHZ(100), SR_KHZ(50), SR_KHZ(25), SR_KHZ(20),
55 SR_KHZ(10), SR_KHZ(5), SR_HZ(2500), SR_KHZ(2),
56 SR_KHZ(1), SR_HZ(500), SR_HZ(250), SR_HZ(200),
57 SR_HZ(100), SR_HZ(50), SR_HZ(25), SR_HZ(20)
58};
59
60/* must be in sync with readout_steps[] in protocol.c */
61static const uint64_t buffersizes[] = {
62 2 * 500, 3 * 500, 4 * 500, 5 * 500,
63 6 * 500, 7 * 500, 8 * 500, 9 * 500, 10 * 500,
64 12 * 500 - 2, 14 * 500 - 2, 16 * 500 - 2,
65 18 * 500 - 2, 20 * 500 - 2, 10240 - 2
66};
67
68static const uint64_t vdivs[][2] = {
69 { 10, 1000 },
70 { 20, 1000 },
71 { 50, 1000 },
72 { 100, 1000 },
73 { 200, 1000 },
74 { 500, 1000 },
75 { 1, 1 },
76 { 2, 1 },
77 { 5, 1 },
78};
79
80/* Bits 4 and 5 enable relays that add /10 filters to the chain
81 * Bits 0 and 1 select an output from a resistor array */
82static const uint8_t vdivs_map[] = {
83 0x01, 0x02, 0x03, 0x21, 0x22, 0x23, 0x31, 0x32, 0x33
84};
85
86
87static const char *trigger_sources[] = {
88 "A", "B", "EXT"
89};
90
91static const uint8_t trigger_sources_map[] = {
92 0x00, 0x80, 0x40
93};
94
95static const char *trigger_slopes[] = {
96 "f", "r"
97};
98
99static const char *coupling[] = {
100 "DC", "AC", "GND"
101};
102
103static const uint8_t coupling_map[] = {
104 0x00, 0x08, 0x04
105};
106
05ac4a98
DG
107static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
108{
109 return std_init(sr_ctx, di, LOG_PREFIX);
110}
111
c9404469
DG
112static GSList *scan_port(GSList *devices, struct sr_dev_driver *di,
113 struct parport *port)
05ac4a98 114{
c9404469
DG
115 struct sr_dev_inst *sdi;
116 struct sr_channel *ch;
117 struct sr_channel_group *cg;
118 struct dev_context *devc;
05ac4a98 119 struct drv_context *drvc;
c9404469 120 int i;
05ac4a98 121
c9404469
DG
122 if (ieee1284_open(port, 0, &i) != E1284_OK) {
123 sr_err("Can't open parallel port %s", port->name);
124 goto fail1;
125 }
05ac4a98 126
c9404469
DG
127 if ((i & (CAP1284_RAW | CAP1284_BYTE)) != (CAP1284_RAW | CAP1284_BYTE)) {
128 sr_err("Parallel port %s does not provide low-level bidirection access",
129 port->name);
130 goto fail2;
131 }
132
133 if (ieee1284_claim(port) != E1284_OK) {
134 sr_err("Parallel port %s already in use", port->name);
135 goto fail2;
136 }
137
138 if (!hung_chang_dso_2100_check_id(port))
139 goto fail3;
140
141 sdi = g_malloc0(sizeof(struct sr_dev_inst));
142 sdi->status = SR_ST_INACTIVE;
143 sdi->vendor = g_strdup("Hung-Chang");
144 sdi->model = g_strdup("DSO-2100");
145 sdi->driver = di;
05ac4a98 146 drvc = di->context;
c9404469
DG
147 sdi->inst_type = 0; /* FIXME */
148 sdi->conn = port;
149 ieee1284_ref(port);
150
151 for (i = 0; i < NUM_CHANNELS; i++) {
152 cg = g_malloc0(sizeof(struct sr_channel_group));
153 cg->name = g_strdup(trigger_sources[i]);
154 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, FALSE, trigger_sources[i]);
155 cg->channels = g_slist_append(cg->channels, ch);
156 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
157 }
158
159 devc = g_malloc0(sizeof(struct dev_context));
160 devc->enabled_channel = g_slist_append(NULL, NULL);
161 devc->channel = 0;
162 devc->rate = 0;
163 devc->probe[0] = 10;
164 devc->probe[1] = 10;
165 devc->cctl[0] = 0x31; /* 1V/div, DC coupling, trigger on channel A*/
166 devc->cctl[1] = 0x31; /* 1V/div, DC coupling, no tv sync trigger */
167 devc->edge = 0;
168 devc->tlevel = 0x80;
169 devc->pos[0] = 0x80;
170 devc->pos[1] = 0x80;
171 devc->offset[0] = 0x80;
172 devc->offset[1] = 0x80;
173 devc->gain[0] = 0x80;
174 devc->gain[1] = 0x80;
175 devc->frame_limit = 0;
176 devc->last_step = 0; /* buffersize = 1000 */
177 sdi->priv = devc;
178
179 drvc->instances = g_slist_append(drvc->instances, sdi);
180 devices = g_slist_append(devices, sdi);
181
182fail3:
183 ieee1284_release(port);
184fail2:
185 ieee1284_close(port);
186fail1:
187 return devices;
188}
189
190static GSList *scan(struct sr_dev_driver *di, GSList *options)
191{
192 struct parport_list ports;
193 struct sr_config *src;
194 const char *conn = NULL;
195 GSList *devices, *option;
196 gboolean port_found;
197 int i;
198
199
200 for (option = options; option; option = option->next) {
201 src = option->data;
202 if (src->key == SR_CONF_CONN) {
203 conn = g_variant_get_string(src->data, NULL);
204 break;
205 }
206 }
207
208 if (!conn)
209 return NULL;
05ac4a98 210
c9404469
DG
211 if (ieee1284_find_ports(&ports, 0) != E1284_OK)
212 return NULL;
213
214 devices = NULL;
215 port_found = FALSE;
216 for (i = 0; i < ports.portc; i++)
217 if (!strcmp(ports.portv[i]->name, conn)) {
218 port_found = TRUE;
219 devices = scan_port(devices, di, ports.portv[i]);
220 }
221
222 if (!port_found) {
223 sr_err("Parallel port %s not found. Valid names are:", conn);
224 for (i = 0; i < ports.portc; i++)
225 sr_err("\t%s", ports.portv[i]->name);
226 }
227
228 ieee1284_free_ports(&ports);
05ac4a98
DG
229
230 return devices;
231}
232
c9404469
DG
233static void clear_private(void *priv)
234{
235 struct dev_context *devc = priv;
236
237 g_slist_free(devc->enabled_channel);
238}
239
05ac4a98
DG
240static int dev_clear(const struct sr_dev_driver *di)
241{
c9404469
DG
242 struct drv_context *drvc = di->context;
243 struct sr_dev_inst *sdi;
244 GSList *l;
245
246 if (drvc) {
247 for (l = drvc->instances; l; l = l->next) {
248 sdi = l->data;
249 ieee1284_unref(sdi->conn);
250 }
251 }
252
253 return std_dev_clear(di, clear_private);
05ac4a98
DG
254}
255
256static int dev_open(struct sr_dev_inst *sdi)
257{
c9404469
DG
258 struct dev_context *devc = sdi->priv;
259 int i;
260
261 if (sdi->status != SR_ST_INACTIVE)
262 goto fail1;
263
264 if (ieee1284_open(sdi->conn, 0, &i) != E1284_OK)
265 goto fail1;
05ac4a98 266
c9404469
DG
267 if (ieee1284_claim(sdi->conn) != E1284_OK)
268 goto fail2;
269
270 if (ieee1284_data_dir(sdi->conn, 1) != E1284_OK)
271 goto fail3;
272
273 if (hung_chang_dso_2100_move_to(sdi, 1))
274 goto fail3;
275
276 devc->samples = g_try_malloc(1000 * sizeof(*devc->samples));
277 if (!devc->samples)
278 goto fail3;
05ac4a98
DG
279
280 sdi->status = SR_ST_ACTIVE;
281
282 return SR_OK;
c9404469
DG
283
284fail3:
285 hung_chang_dso_2100_reset_port(sdi->conn);
286 ieee1284_release(sdi->conn);
287fail2:
288 ieee1284_close(sdi->conn);
289fail1:
290 return SR_ERR;
05ac4a98
DG
291}
292
293static int dev_close(struct sr_dev_inst *sdi)
294{
c9404469 295 struct dev_context *devc = sdi->priv;
05ac4a98 296
c9404469
DG
297 if (sdi->status != SR_ST_ACTIVE)
298 return SR_OK;
05ac4a98 299
c9404469
DG
300 g_free(devc->samples);
301 hung_chang_dso_2100_reset_port(sdi->conn);
302 ieee1284_release(sdi->conn);
303 ieee1284_close(sdi->conn);
05ac4a98
DG
304 sdi->status = SR_ST_INACTIVE;
305
306 return SR_OK;
307}
308
c9404469
DG
309static int find_in_array(GVariant *data, const GVariantType *type,
310 const void *arr, int n)
311{
312 const char * const *sarr;
313 const char *s;
314 const uint64_t *u64arr;
315 const uint8_t *u8arr;
316 uint64_t u64;
317 uint8_t u8;
318 int i;
319
320 if (!g_variant_is_of_type(data, type))
321 return -1;
322
323 switch (g_variant_classify(data)) {
324 case G_VARIANT_CLASS_STRING:
325 s = g_variant_get_string(data, NULL);
326 sarr = arr;
327
328 for (i = 0; i < n; i++)
329 if (!strcmp(s, sarr[i]))
330 return i;
331 break;
332 case G_VARIANT_CLASS_UINT64:
333 u64 = g_variant_get_uint64(data);
334 u64arr = arr;
335
336 for (i = 0; i < n; i++)
337 if (u64 == u64arr[i])
338 return i;
339 break;
340 case G_VARIANT_CLASS_BYTE:
341 u8 = g_variant_get_byte(data);
342 u8arr = arr;
343
344 for (i = 0; i < n; i++)
345 if (u8 == u8arr[i])
346 return i;
347 default:
348 break;
349 }
350
351 return -1;
352}
353
354static int reverse_map(uint8_t u, const uint8_t *arr, int n)
355{
356 GVariant *v = g_variant_new_byte(u);
357 int i = find_in_array(v, G_VARIANT_TYPE_BYTE, arr, n);
358 g_variant_unref(v);
359 return i;
05ac4a98
DG
360}
361
362static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
363 const struct sr_channel_group *cg)
364{
c9404469
DG
365 struct dev_context *devc = sdi->priv;
366 struct parport *port;
367 int ret, i, ch = -1;
05ac4a98 368
c9404469
DG
369 if (cg) /* sr_config_get will validate cg using config_list */
370 ch = ((struct sr_channel *)cg->channels->data)->index;
05ac4a98
DG
371
372 ret = SR_OK;
373 switch (key) {
c9404469
DG
374 case SR_CONF_CONN:
375 port = sdi->conn;
376 *data = g_variant_new_string(port->name);
377 break;
378 case SR_CONF_LIMIT_FRAMES:
379 *data = g_variant_new_uint64(devc->frame_limit);
380 break;
381 case SR_CONF_SAMPLERATE:
382 *data = g_variant_new_uint64(samplerates[devc->rate]);
383 break;
384 case SR_CONF_TRIGGER_SOURCE:
385 i = reverse_map(devc->cctl[0] & 0xC0, trigger_sources_map,
386 ARRAY_SIZE(trigger_sources_map));
387 if (i == -1)
388 ret = SR_ERR;
389 else
390 *data = g_variant_new_string(trigger_sources[i]);
391 break;
392 case SR_CONF_TRIGGER_SLOPE:
393 if (devc->edge >= ARRAY_SIZE(trigger_slopes))
394 ret = SR_ERR;
395 else
396 *data = g_variant_new_string(trigger_slopes[devc->edge]);
397 break;
398 case SR_CONF_BUFFERSIZE:
399 *data = g_variant_new_uint64(buffersizes[devc->last_step]);
400 break;
401 case SR_CONF_VDIV:
402 if (ch == -1) {
403 ret = SR_ERR_CHANNEL_GROUP;
404 } else {
405 i = reverse_map(devc->cctl[ch] & 0x33, vdivs_map,
406 ARRAY_SIZE(vdivs_map));
407 if (i == -1)
408 ret = SR_ERR;
409 else
410 *data = g_variant_new("(tt)", vdivs[i][0],
411 vdivs[i][1]);
412 }
413 break;
414 case SR_CONF_COUPLING:
415 if (ch == -1) {
416 ret = SR_ERR_CHANNEL_GROUP;
417 } else {
418 i = reverse_map(devc->cctl[ch] & 0x0C, coupling_map,
419 ARRAY_SIZE(coupling_map));
420 if (i == -1)
421 ret = SR_ERR;
422 else
423 *data = g_variant_new_string(coupling[i]);
424 }
425 break;
426 case SR_CONF_PROBE_FACTOR:
427 if (ch == -1)
428 ret = SR_ERR_CHANNEL_GROUP;
429 else
430 *data = g_variant_new_uint64(devc->probe[ch]);
431 break;
05ac4a98 432 default:
c9404469 433 ret = SR_ERR_NA;
05ac4a98
DG
434 }
435
436 return ret;
437}
438
439static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
440 const struct sr_channel_group *cg)
441{
c9404469
DG
442 struct dev_context *devc = sdi->priv;
443 int ret, i, ch = -1;
444 uint64_t u, v;
05ac4a98 445
c9404469
DG
446 if (cg) /* sr_config_set will validate cg using config_list */
447 ch = ((struct sr_channel *)cg->channels->data)->index;
05ac4a98
DG
448
449 if (sdi->status != SR_ST_ACTIVE)
450 return SR_ERR_DEV_CLOSED;
451
452 ret = SR_OK;
453 switch (key) {
c9404469
DG
454 case SR_CONF_LIMIT_FRAMES:
455 devc->frame_limit = g_variant_get_uint64(data);
456 break;
457 case SR_CONF_SAMPLERATE:
458 i = find_in_array(data, G_VARIANT_TYPE_UINT64,
459 samplerates, ARRAY_SIZE(samplerates));
460 if (i == -1)
461 ret = SR_ERR_ARG;
462 else
463 devc->rate = i;
464 break;
465 case SR_CONF_TRIGGER_SOURCE:
466 i = find_in_array(data, G_VARIANT_TYPE_STRING,
467 trigger_sources, ARRAY_SIZE(trigger_sources));
468 if (i == -1)
469 ret = SR_ERR_ARG;
470 else
471 devc->cctl[0] = (devc->cctl[0] & 0x3F)
472 | trigger_sources_map[i];
473 break;
474 case SR_CONF_TRIGGER_SLOPE:
475 i = find_in_array(data, G_VARIANT_TYPE_STRING,
476 trigger_slopes, ARRAY_SIZE(trigger_slopes));
477 if (i == -1)
478 ret = SR_ERR_ARG;
479 else
480 devc->edge = i;
481 break;
482 case SR_CONF_BUFFERSIZE:
483 i = find_in_array(data, G_VARIANT_TYPE_UINT64,
484 buffersizes, ARRAY_SIZE(buffersizes));
485 if (i == -1)
486 ret = SR_ERR_ARG;
487 else
488 devc->last_step = i;
489 break;
490 case SR_CONF_VDIV:
491 if (ch == -1) {
492 ret = SR_ERR_CHANNEL_GROUP;
493 } else if (!g_variant_is_of_type(data, G_VARIANT_TYPE("(tt)"))) {
494 ret = SR_ERR_ARG;
495 } else {
496 g_variant_get(data, "(tt)", &u, &v);
497 for (i = 0; i < (int)ARRAY_SIZE(vdivs); i++)
498 if (vdivs[i][0] == u && vdivs[i][1] == v)
499 break;
500 if (i == ARRAY_SIZE(vdivs))
501 ret = SR_ERR_ARG;
502 else
503 devc->cctl[ch] = (devc->cctl[ch] & 0xCC)
504 | vdivs_map[i];
505 }
506 break;
507 case SR_CONF_COUPLING:
508 if (ch == -1) {
509 ret = SR_ERR_CHANNEL_GROUP;
510 } else {
511 i = find_in_array(data, G_VARIANT_TYPE_STRING,
512 coupling, ARRAY_SIZE(coupling));
513 if (i == -1)
514 ret = SR_ERR_ARG;
515 else
516 devc->cctl[ch] = (devc->cctl[ch] & 0xF3)
517 | coupling_map[i];
518 }
519 break;
520 case SR_CONF_PROBE_FACTOR:
521 if (ch == -1) {
522 ret = SR_ERR_CHANNEL_GROUP;
523 } else {
524 u = g_variant_get_uint64(data);
525 if (!u)
526 ret = SR_ERR_ARG;
527 else
528 devc->probe[ch] = u;
529 }
530 break;
05ac4a98
DG
531 default:
532 ret = SR_ERR_NA;
533 }
534
535 return ret;
536}
537
c9404469
DG
538static int config_channel_set(const struct sr_dev_inst *sdi,
539 struct sr_channel *ch,
540 unsigned int changes)
541{
542 struct dev_context *devc = sdi->priv;
543 uint8_t v;
544
545 if (changes & SR_CHANNEL_SET_ENABLED) {
546 if (ch->enabled) {
547 v = devc->channel | (1 << ch->index);
548 if (v & (v - 1))
549 return SR_ERR;
550 devc->channel = v;
551 devc->enabled_channel->data = ch;
552 } else {
553 devc->channel &= ~(1 << ch->index);
554 }
555 }
556 return SR_OK;
557}
558
559static int config_commit(const struct sr_dev_inst *sdi)
05ac4a98 560{
c9404469 561 uint8_t state = hung_chang_dso_2100_read_mbox(sdi->conn, 0.02);
05ac4a98
DG
562 int ret;
563
c9404469
DG
564 if (sdi->status != SR_ST_ACTIVE)
565 return SR_ERR_DEV_CLOSED;
566
567 switch (state) {
568 case 0x03:
569 case 0x14:
570 case 0x21:
571 /* we will travel the complete config path on our way to state 1 */
572 break;
573 case 0x00:
574 state = 0x01;
575 default:
576 ret = hung_chang_dso_2100_move_to(sdi, 1);
577 if (ret != SR_OK)
578 return ret;
579 case 0x01:
580 hung_chang_dso_2100_write_mbox(sdi->conn, 4);
581 }
582 ret = hung_chang_dso_2100_move_to(sdi, 1);
583 if (ret != SR_OK)
584 return ret;
585 return hung_chang_dso_2100_move_to(sdi, state);
586}
587
588static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
589 const struct sr_channel_group *cg)
590{
591 GVariantBuilder gvb;
592 GVariant *gvar, *rational[2];
593 GSList *l;
594 int i;
05ac4a98 595
05ac4a98 596 switch (key) {
c9404469
DG
597 case SR_CONF_SCAN_OPTIONS:
598 case SR_CONF_DEVICE_OPTIONS:
599 break;
600 case SR_CONF_SAMPLERATE:
601 case SR_CONF_TRIGGER_SOURCE:
602 case SR_CONF_TRIGGER_SLOPE:
603 case SR_CONF_BUFFERSIZE:
604 if (!sdi || cg)
605 return SR_ERR_NA;
606 break;
607 case SR_CONF_VDIV:
608 case SR_CONF_COUPLING:
609 if (!sdi)
610 return SR_ERR_NA;
611 if (!cg)
612 return SR_ERR_CHANNEL_GROUP;
613 l = g_slist_find(sdi->channel_groups, cg);
614 if (!l)
615 return SR_ERR_ARG;
616 break;
05ac4a98
DG
617 default:
618 return SR_ERR_NA;
619 }
620
c9404469
DG
621 switch (key) {
622 case SR_CONF_SCAN_OPTIONS:
623 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
624 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
625 break;
626 case SR_CONF_DEVICE_OPTIONS:
627 if (!sdi)
628 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
629 drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
630 else if (!cg)
631 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
632 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
633 else
634 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
635 cgopts, ARRAY_SIZE(cgopts), sizeof(uint32_t));
636 break;
637 case SR_CONF_SAMPLERATE:
638 g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
639 gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"),
640 samplerates, ARRAY_SIZE(samplerates), sizeof(uint64_t));
641 g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar);
642 *data = g_variant_builder_end(&gvb);
643 break;
644 case SR_CONF_TRIGGER_SOURCE:
645 *data = g_variant_new_strv(trigger_sources, ARRAY_SIZE(trigger_sources));
646 break;
647 case SR_CONF_TRIGGER_SLOPE:
648 *data = g_variant_new_strv(trigger_slopes, ARRAY_SIZE(trigger_slopes));
649 break;
650 case SR_CONF_BUFFERSIZE:
651 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT64,
652 buffersizes, ARRAY_SIZE(buffersizes), sizeof(uint64_t));
653 break;
654 case SR_CONF_VDIV:
655 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
656 for (i = 0; i < (int)ARRAY_SIZE(vdivs); i++) {
657 rational[0] = g_variant_new_uint64(vdivs[i][0]);
658 rational[1] = g_variant_new_uint64(vdivs[i][1]);
659 gvar = g_variant_new_tuple(rational, 2);
660 g_variant_builder_add_value(&gvb, gvar);
661 }
662 *data = g_variant_builder_end(&gvb);
663 break;
664 case SR_CONF_COUPLING:
665 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
666 break;
667 }
668
669 return SR_OK;
05ac4a98
DG
670}
671
695dc859 672static int dev_acquisition_start(const struct sr_dev_inst *sdi)
05ac4a98 673{
c9404469
DG
674 struct dev_context *devc = sdi->priv;
675 int ret;
05ac4a98
DG
676
677 if (sdi->status != SR_ST_ACTIVE)
678 return SR_ERR_DEV_CLOSED;
679
c9404469
DG
680 if (devc->channel) {
681 static const float res_array[] = {0.5, 1, 2, 5};
682 static const uint8_t relays[] = {100, 10, 10, 1};
683 devc->factor = devc->probe[devc->channel - 1] / 32.0;
684 devc->factor *= res_array[devc->cctl[devc->channel - 1] & 0x03];
685 devc->factor /= relays[(devc->cctl[devc->channel - 1] >> 4) & 0x03];
686 }
687 devc->frame = 0;
c9404469
DG
688 devc->state_known = TRUE;
689 devc->step = 0;
690 devc->adc2 = FALSE;
691 devc->retries = MAX_RETRIES;
692
693 ret = hung_chang_dso_2100_move_to(sdi, 0x21);
694 if (ret != SR_OK)
695 return ret;
696
695dc859 697 std_session_send_df_header(sdi, LOG_PREFIX);
c9404469 698
b165a242 699 sr_session_source_add(sdi->session, -1, 0, 8,
c9404469 700 hung_chang_dso_2100_poll, (void *)sdi);
05ac4a98
DG
701
702 return SR_OK;
703}
704
695dc859 705SR_PRIV int hung_chang_dso_2100_dev_acquisition_stop(const struct sr_dev_inst *sdi)
05ac4a98 706{
05ac4a98
DG
707 if (sdi->status != SR_ST_ACTIVE)
708 return SR_ERR_DEV_CLOSED;
709
695dc859 710 std_session_send_df_end(sdi, LOG_PREFIX);
b165a242 711 sr_session_source_remove(sdi->session, -1);
c9404469 712 hung_chang_dso_2100_move_to(sdi, 1);
05ac4a98
DG
713
714 return SR_OK;
715}
716
695dc859 717static int dev_acquisition_stop(struct sr_dev_inst *sdi)
c9404469 718{
695dc859 719 return hung_chang_dso_2100_dev_acquisition_stop(sdi);
c9404469
DG
720}
721
05ac4a98
DG
722SR_PRIV struct sr_dev_driver hung_chang_dso_2100_driver_info = {
723 .name = "hung-chang-dso-2100",
724 .longname = "Hung-Chang DSO-2100",
725 .api_version = 1,
726 .init = init,
700d6b64 727 .cleanup = std_cleanup,
05ac4a98 728 .scan = scan,
c01bf34c 729 .dev_list = std_dev_list,
05ac4a98
DG
730 .dev_clear = dev_clear,
731 .config_get = config_get,
732 .config_set = config_set,
c9404469
DG
733 .config_channel_set = config_channel_set,
734 .config_commit = config_commit,
05ac4a98
DG
735 .config_list = config_list,
736 .dev_open = dev_open,
737 .dev_close = dev_close,
738 .dev_acquisition_start = dev_acquisition_start,
739 .dev_acquisition_stop = dev_acquisition_stop,
740 .context = NULL,
741};