]> sigrok.org Git - libsigrok.git/blame - src/hardware/kingst-la2016/api.c
device: provide glib compatible callback to free usb dev inst
[libsigrok.git] / src / hardware / kingst-la2016 / api.c
CommitLineData
f2cd2deb
FS
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2020 Florian Schmidt <schmidt_florian@gmx.de>
5 * Copyright (C) 2013 Marcus Comstedt <marcus@mc.pp.se>
6 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
7 * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
96dc954e
GS
23/*
24 * This driver implementation initially was derived from the
25 * src/hardware/saleae-logic16/ source code.
26 */
f2cd2deb
FS
27
28#include <config.h>
a7740b06 29
a7740b06 30#include <libsigrok/libsigrok.h>
f2cd2deb 31#include <string.h>
a7740b06 32
f2cd2deb
FS
33#include "libsigrok-internal.h"
34#include "protocol.h"
35
a38f0f5e
GS
36/*
37 * Default device configuration. Must be applicable to any of the
38 * supported devices (no model specific default values yet). Specific
39 * firmware implementation details unfortunately won't let us detect
40 * and keep using previously configured values.
41 */
42#define LA2016_DFLT_SAMPLERATE SR_MHZ(100)
43#define LA2016_DFLT_SAMPLEDEPTH (5 * 1000 * 1000)
44#define LA2016_DFLT_CAPT_RATIO 5 /* Capture ratio, in percent. */
45
f2cd2deb
FS
46static const uint32_t scanopts[] = {
47 SR_CONF_CONN,
48};
49
50static const uint32_t drvopts[] = {
51 SR_CONF_LOGIC_ANALYZER,
52};
53
54static const uint32_t devopts[] = {
55 /* TODO: SR_CONF_CONTINUOUS, */
56 SR_CONF_CONN | SR_CONF_GET,
57 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
a38f0f5e
GS
58 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
59 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
f2cd2deb
FS
60 SR_CONF_VOLTAGE_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
61 SR_CONF_LOGIC_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
62 SR_CONF_LOGIC_THRESHOLD_CUSTOM | SR_CONF_GET | SR_CONF_SET,
63 SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
64 SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
65};
66
67static const int32_t trigger_matches[] = {
68 SR_TRIGGER_ZERO,
69 SR_TRIGGER_ONE,
70 SR_TRIGGER_RISING,
71 SR_TRIGGER_FALLING,
72};
73
74static const char *channel_names[] = {
da25c287
GS
75 "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7",
76 "CH8", "CH9", "CH10", "CH11", "CH12", "CH13", "CH14", "CH15",
f2cd2deb
FS
77};
78
ea436ba7
GS
79/*
80 * The hardware uses a (model dependent) 100/200/500MHz base clock and
81 * a 16bit divider (common across all models). The range from 10kHz to
82 * 100/200/500MHz should be applicable to all devices. High rates may
83 * suffer from coarse resolution (e.g. in the "500MHz div 2" case) and
84 * may not provide the desired 1/2/5 steps. This is not an issue now,
85 * the 500MHz model is not supported yet by this driver.
86 */
87
8b172e78 88static const uint64_t samplerates_la2016[] = {
ea436ba7 89 SR_KHZ(10),
f2cd2deb
FS
90 SR_KHZ(20),
91 SR_KHZ(50),
92 SR_KHZ(100),
93 SR_KHZ(200),
94 SR_KHZ(500),
95 SR_MHZ(1),
96 SR_MHZ(2),
97 SR_MHZ(4),
98 SR_MHZ(5),
99 SR_MHZ(8),
100 SR_MHZ(10),
101 SR_MHZ(20),
102 SR_MHZ(50),
103 SR_MHZ(100),
104 SR_MHZ(200),
105};
106
8b172e78 107static const uint64_t samplerates_la1016[] = {
ea436ba7 108 SR_KHZ(10),
8b172e78
KG
109 SR_KHZ(20),
110 SR_KHZ(50),
111 SR_KHZ(100),
112 SR_KHZ(200),
113 SR_KHZ(500),
114 SR_MHZ(1),
115 SR_MHZ(2),
116 SR_MHZ(4),
117 SR_MHZ(5),
118 SR_MHZ(8),
119 SR_MHZ(10),
120 SR_MHZ(20),
121 SR_MHZ(50),
122 SR_MHZ(100),
123};
124
f2cd2deb
FS
125static const float logic_threshold_value[] = {
126 1.58,
127 2.5,
128 1.165,
129 1.5,
130 1.25,
131 0.9,
132 0.75,
133 0.60,
134 0.45,
135};
136
137static const char *logic_threshold[] = {
138 "TTL 5V",
139 "CMOS 5V",
140 "CMOS 3.3V",
141 "CMOS 3.0V",
142 "CMOS 2.5V",
143 "CMOS 1.8V",
144 "CMOS 1.5V",
145 "CMOS 1.2V",
146 "CMOS 0.9V",
147 "USER",
148};
149
da2cb50d 150#define LOGIC_THRESHOLD_IDX_USER (ARRAY_SIZE(logic_threshold) - 1)
f2cd2deb 151
f2cd2deb
FS
152static GSList *scan(struct sr_dev_driver *di, GSList *options)
153{
154 struct drv_context *drvc;
520a20e9 155 struct sr_context *ctx;
f2cd2deb
FS
156 struct dev_context *devc;
157 struct sr_dev_inst *sdi;
158 struct sr_usb_dev_inst *usb;
159 struct sr_config *src;
160 GSList *l;
161 GSList *devices;
162 GSList *conn_devices;
163 struct libusb_device_descriptor des;
520a20e9
GS
164 libusb_device **devlist, *dev;
165 size_t dev_count, dev_idx, ch_idx;
166 uint8_t bus, addr;
f2cd2deb 167 const char *conn;
520a20e9 168 char conn_id[64];
22cb067a 169 uint64_t fw_uploaded;
520a20e9 170 int ret;
f2cd2deb
FS
171
172 drvc = di->context;
520a20e9 173 ctx = drvc->sr_ctx;;
f2cd2deb
FS
174
175 conn = NULL;
176 for (l = options; l; l = l->next) {
177 src = l->data;
178 switch (src->key) {
179 case SR_CONF_CONN:
180 conn = g_variant_get_string(src->data, NULL);
181 break;
182 }
183 }
184 if (conn)
520a20e9 185 conn_devices = sr_usb_find(ctx->libusb_ctx, conn);
f2cd2deb
FS
186 else
187 conn_devices = NULL;
188
96dc954e 189 /* Find all LA2016 devices, optionally upload firmware to them. */
f2cd2deb 190 devices = NULL;
520a20e9
GS
191 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
192 if (ret < 0) {
193 sr_err("Cannot get device list: %s.", libusb_error_name(ret));
194 return devices;
195 }
196 dev_count = ret;
197 for (dev_idx = 0; dev_idx < dev_count; dev_idx++) {
198 dev = devlist[dev_idx];
199 bus = libusb_get_bus_number(dev);
200 addr = libusb_get_device_address(dev);
f2cd2deb
FS
201 if (conn) {
202 usb = NULL;
203 for (l = conn_devices; l; l = l->next) {
204 usb = l->data;
520a20e9 205 if (usb->bus == bus && usb->address == addr)
f2cd2deb
FS
206 break;
207 }
955ab604 208 if (!l) {
96dc954e
GS
209 /*
210 * A connection parameter was specified and
211 * this device does not match the filter.
212 */
f2cd2deb 213 continue;
955ab604 214 }
f2cd2deb
FS
215 }
216
520a20e9
GS
217 libusb_get_device_descriptor(dev, &des);
218 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
219 if (ret < 0)
f2cd2deb 220 continue;
f2cd2deb
FS
221 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
222 continue;
223
96dc954e 224 /* USB identification matches, a device was found. */
cf057ac4 225 sr_dbg("Found a device (USB identification).");
520a20e9 226 sdi = g_malloc0(sizeof(*sdi));
f2cd2deb 227 sdi->status = SR_ST_INITIALIZING;
520a20e9 228 sdi->connection_id = g_strdup(conn_id);
f2cd2deb 229
22cb067a 230 fw_uploaded = 0;
852c7d14 231 if (des.iProduct != LA2016_IPRODUCT_INDEX) {
520a20e9
GS
232 sr_info("Device at '%s' has no firmware loaded.",
233 conn_id);
f2cd2deb 234
520a20e9
GS
235 ret = la2016_upload_firmware(ctx, dev, des.idProduct);
236 if (ret != SR_OK) {
91f73872 237 sr_err("MCU firmware upload failed.");
f2cd2deb
FS
238 g_free(sdi->connection_id);
239 g_free(sdi);
240 continue;
241 }
22cb067a 242 fw_uploaded = g_get_monotonic_time();
96dc954e 243 /* Will re-enumerate. Mark as "unknown address yet". */
520a20e9 244 addr = 0xff;
f2cd2deb
FS
245 }
246
247 sdi->vendor = g_strdup("Kingst");
248 sdi->model = g_strdup("LA2016");
249
520a20e9
GS
250 for (ch_idx = 0; ch_idx < ARRAY_SIZE(channel_names); ch_idx++) {
251 sr_channel_new(sdi, ch_idx, SR_CHANNEL_LOGIC,
252 TRUE, channel_names[ch_idx]);
253 }
f2cd2deb
FS
254
255 devices = g_slist_append(devices, sdi);
256
520a20e9 257 devc = g_malloc0(sizeof(*devc));
f2cd2deb 258 sdi->priv = devc;
22cb067a 259 devc->fw_uploaded = fw_uploaded;
a38f0f5e
GS
260 sr_sw_limits_init(&devc->sw_limits);
261 devc->sw_limits.limit_samples = LA2016_DFLT_SAMPLEDEPTH;
262 devc->capture_ratio = LA2016_DFLT_CAPT_RATIO;
263 devc->cur_samplerate = LA2016_DFLT_SAMPLERATE;
f2cd2deb
FS
264 devc->threshold_voltage_idx = 0;
265 devc->threshold_voltage = logic_threshold_value[devc->threshold_voltage_idx];
266
267 sdi->status = SR_ST_INACTIVE;
268 sdi->inst_type = SR_INST_USB;
269
520a20e9 270 sdi->conn = sr_usb_dev_inst_new(bus, addr, NULL);
f2cd2deb
FS
271 }
272 libusb_free_device_list(devlist, 1);
273 g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free);
274
275 return std_scan_complete(di, devices);
276}
277
278static int la2016_dev_open(struct sr_dev_inst *sdi)
279{
280 struct sr_dev_driver *di;
520a20e9
GS
281 struct drv_context *drvc;
282 struct sr_context *ctx;
283 libusb_device **devlist, *dev;
f2cd2deb
FS
284 struct sr_usb_dev_inst *usb;
285 struct libusb_device_descriptor des;
520a20e9
GS
286 int ret;
287 size_t device_count, dev_idx;
288 gboolean check_conn;
289 char conn_id[64];
f2cd2deb
FS
290
291 di = sdi->driver;
292 drvc = di->context;
520a20e9 293 ctx = drvc->sr_ctx;;
f2cd2deb
FS
294 usb = sdi->conn;
295 ret = SR_ERR;
296
520a20e9
GS
297 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
298 if (ret < 0) {
299 sr_err("Cannot get device list: %s.", libusb_error_name(ret));
f2cd2deb
FS
300 return SR_ERR;
301 }
520a20e9
GS
302 device_count = ret;
303 if (!device_count) {
304 sr_warn("Device list is empty. Cannot open.");
305 return SR_ERR;
306 }
307 for (dev_idx = 0; dev_idx < device_count; dev_idx++) {
308 dev = devlist[dev_idx];
309 libusb_get_device_descriptor(dev, &des);
f2cd2deb 310
852c7d14
GS
311 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
312 continue;
313 if (des.iProduct != LA2016_IPRODUCT_INDEX)
f2cd2deb
FS
314 continue;
315
520a20e9
GS
316 check_conn = sdi->status == SR_ST_INITIALIZING;
317 check_conn |= sdi->status == SR_ST_INACTIVE;
318 if (check_conn) {
96dc954e 319 /* Check physical USB bus/port address. */
520a20e9
GS
320 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
321 if (ret < 0)
f2cd2deb 322 continue;
520a20e9 323 if (strcmp(sdi->connection_id, conn_id) != 0) {
96dc954e 324 /* Not the device we looked up before. */
f2cd2deb 325 continue;
96dc954e 326 }
f2cd2deb
FS
327 }
328
520a20e9
GS
329 ret = libusb_open(dev, &usb->devhdl);
330 if (ret != 0) {
331 sr_err("Cannot open device: %s.",
332 libusb_error_name(ret));
333 ret = SR_ERR_IO;
f2cd2deb
FS
334 break;
335 }
336
520a20e9
GS
337 if (usb->address == 0xff) {
338 /*
339 * First encounter after firmware upload.
340 * Grab current address after enumeration.
341 */
342 usb->address = libusb_get_device_address(dev);
343 }
344
f2cd2deb
FS
345 ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
346 if (ret == LIBUSB_ERROR_BUSY) {
91f73872 347 sr_err("Cannot claim USB interface. Another program or driver using it?");
f2cd2deb
FS
348 ret = SR_ERR;
349 break;
350 } else if (ret == LIBUSB_ERROR_NO_DEVICE) {
351 sr_err("Device has been disconnected.");
352 ret = SR_ERR;
353 break;
354 } else if (ret != 0) {
520a20e9
GS
355 sr_err("Cannot claim USB interface: %s.",
356 libusb_error_name(ret));
f2cd2deb
FS
357 ret = SR_ERR;
358 break;
359 }
360
361 if ((ret = la2016_init_device(sdi)) != SR_OK) {
91f73872 362 sr_err("Cannot initialize device.");
f2cd2deb
FS
363 break;
364 }
365
366 sr_info("Opened device on %d.%d (logical) / %s (physical), interface %d.",
367 usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
f2cd2deb 368 ret = SR_OK;
f2cd2deb
FS
369 break;
370 }
f2cd2deb
FS
371 libusb_free_device_list(devlist, 1);
372
373 if (ret != SR_OK) {
374 if (usb->devhdl) {
375 libusb_release_interface(usb->devhdl, USB_INTERFACE);
376 libusb_close(usb->devhdl);
377 usb->devhdl = NULL;
378 }
520a20e9 379 return ret;
f2cd2deb
FS
380 }
381
382 return SR_OK;
383}
384
385static int dev_open(struct sr_dev_inst *sdi)
386{
387 struct dev_context *devc;
22cb067a 388 uint64_t reset_done, now, elapsed_ms;
f2cd2deb
FS
389 int ret;
390
391 devc = sdi->priv;
392
393 /*
22cb067a
GS
394 * When the sigrok driver recently has uploaded MCU firmware,
395 * then wait for the FX2 to re-enumerate. Allow the USB device
396 * to vanish before it reappears. Timeouts are rough estimates
397 * after all, the imprecise time of the last check (potentially
398 * executes after the total check period) simplifies code paths
399 * with optional diagnostics. And increases the probability of
400 * successfully detecting "late/slow" devices.
f2cd2deb 401 */
22cb067a 402 if (devc->fw_uploaded) {
f2cd2deb 403 sr_info("Waiting for device to reset after firmware upload.");
f2cd2deb 404 now = g_get_monotonic_time();
22cb067a
GS
405 reset_done = devc->fw_uploaded + RENUM_GONE_DELAY_MS * 1000;
406 if (now < reset_done)
f2cd2deb 407 g_usleep(reset_done - now);
22cb067a
GS
408 do {
409 now = g_get_monotonic_time();
410 elapsed_ms = (now - devc->fw_uploaded) / 1000;
411 sr_spew("Waited %" PRIu64 "ms.", elapsed_ms);
412 ret = la2016_dev_open(sdi);
413 if (ret == SR_OK) {
414 devc->fw_uploaded = 0;
f2cd2deb 415 break;
22cb067a
GS
416 }
417 g_usleep(RENUM_POLL_INTERVAL_MS * 1000);
418 } while (elapsed_ms < RENUM_CHECK_PERIOD_MS);
f2cd2deb
FS
419 if (ret != SR_OK) {
420 sr_err("Device failed to re-enumerate.");
520a20e9 421 return ret;
f2cd2deb 422 }
22cb067a 423 sr_info("Device came back after %" PRIi64 "ms.", elapsed_ms);
955ab604 424 } else {
f2cd2deb 425 ret = la2016_dev_open(sdi);
955ab604 426 }
f2cd2deb
FS
427
428 if (ret != SR_OK) {
91f73872 429 sr_err("Cannot open device.");
520a20e9 430 return ret;
f2cd2deb
FS
431 }
432
433 return SR_OK;
434}
435
436static int dev_close(struct sr_dev_inst *sdi)
437{
438 struct sr_usb_dev_inst *usb;
439
440 usb = sdi->conn;
441
442 if (!usb->devhdl)
443 return SR_ERR_BUG;
444
445 la2016_deinit_device(sdi);
446
447 sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
448 usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
449 libusb_release_interface(usb->devhdl, USB_INTERFACE);
450 libusb_close(usb->devhdl);
451 usb->devhdl = NULL;
452
453 return SR_OK;
454}
455
955ab604
GS
456static int config_get(uint32_t key, GVariant **data,
457 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
458{
459 struct dev_context *devc;
460 struct sr_usb_dev_inst *usb;
461 double rounded;
da2cb50d 462 const char *label;
f2cd2deb
FS
463
464 (void)cg;
465
466 if (!sdi)
467 return SR_ERR_ARG;
468 devc = sdi->priv;
469
470 switch (key) {
471 case SR_CONF_CONN:
472 if (!sdi->conn)
473 return SR_ERR_ARG;
474 usb = sdi->conn;
96dc954e
GS
475 if (usb->address == 0xff) {
476 /*
477 * Device still needs to re-enumerate after firmware
478 * upload, so we don't know its (future) address.
479 */
f2cd2deb 480 return SR_ERR;
955ab604 481 }
f2cd2deb
FS
482 *data = g_variant_new_printf("%d.%d", usb->bus, usb->address);
483 break;
484 case SR_CONF_SAMPLERATE:
485 *data = g_variant_new_uint64(devc->cur_samplerate);
486 break;
487 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
488 case SR_CONF_LIMIT_MSEC:
489 return sr_sw_limits_config_get(&devc->sw_limits, key, data);
f2cd2deb
FS
490 case SR_CONF_CAPTURE_RATIO:
491 *data = g_variant_new_uint64(devc->capture_ratio);
492 break;
493 case SR_CONF_VOLTAGE_THRESHOLD:
494 rounded = (int)(devc->threshold_voltage / 0.1) * 0.1;
495 *data = std_gvar_tuple_double(rounded, rounded + 0.1);
496 return SR_OK;
497 case SR_CONF_LOGIC_THRESHOLD:
da2cb50d
GS
498 label = logic_threshold[devc->threshold_voltage_idx];
499 *data = g_variant_new_string(label);
f2cd2deb
FS
500 break;
501 case SR_CONF_LOGIC_THRESHOLD_CUSTOM:
502 *data = g_variant_new_double(devc->threshold_voltage);
503 break;
955ab604 504
f2cd2deb
FS
505 default:
506 return SR_ERR_NA;
507 }
508
509 return SR_OK;
510}
511
955ab604
GS
512static int config_set(uint32_t key, GVariant *data,
513 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
514{
515 struct dev_context *devc;
516 double low, high;
517 int idx;
518
519 (void)cg;
520
521 devc = sdi->priv;
522
523 switch (key) {
524 case SR_CONF_SAMPLERATE:
525 devc->cur_samplerate = g_variant_get_uint64(data);
526 break;
527 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
528 case SR_CONF_LIMIT_MSEC:
529 return sr_sw_limits_config_set(&devc->sw_limits, key, data);
f2cd2deb
FS
530 case SR_CONF_CAPTURE_RATIO:
531 devc->capture_ratio = g_variant_get_uint64(data);
532 break;
533 case SR_CONF_VOLTAGE_THRESHOLD:
534 g_variant_get(data, "(dd)", &low, &high);
535 devc->threshold_voltage = (low + high) / 2.0;
da2cb50d 536 devc->threshold_voltage_idx = LOGIC_THRESHOLD_IDX_USER;
f2cd2deb
FS
537 break;
538 case SR_CONF_LOGIC_THRESHOLD: {
411ad77c
GS
539 idx = std_str_idx(data, ARRAY_AND_SIZE(logic_threshold));
540 if (idx < 0)
f2cd2deb 541 return SR_ERR_ARG;
da2cb50d 542 if (idx != LOGIC_THRESHOLD_IDX_USER) {
f2cd2deb
FS
543 devc->threshold_voltage = logic_threshold_value[idx];
544 }
545 devc->threshold_voltage_idx = idx;
546 break;
547 }
548 case SR_CONF_LOGIC_THRESHOLD_CUSTOM:
549 devc->threshold_voltage = g_variant_get_double(data);
550 break;
551 default:
552 return SR_ERR_NA;
553 }
554
555 return SR_OK;
556}
557
955ab604
GS
558static int config_list(uint32_t key, GVariant **data,
559 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb 560{
8b172e78
KG
561 struct dev_context *devc;
562
a38f0f5e
GS
563 devc = sdi ? sdi->priv : NULL;
564
f2cd2deb
FS
565 switch (key) {
566 case SR_CONF_SCAN_OPTIONS:
567 case SR_CONF_DEVICE_OPTIONS:
411ad77c
GS
568 return STD_CONFIG_LIST(key, data, sdi, cg,
569 scanopts, drvopts, devopts);
f2cd2deb 570 case SR_CONF_SAMPLERATE:
fb28e72d
MW
571 if (!sdi)
572 return SR_ERR_ARG;
8b172e78
KG
573 if (devc->max_samplerate == SR_MHZ(200)) {
574 *data = std_gvar_samplerates(ARRAY_AND_SIZE(samplerates_la2016));
1ed93110 575 } else {
8b172e78
KG
576 *data = std_gvar_samplerates(ARRAY_AND_SIZE(samplerates_la1016));
577 }
f2cd2deb
FS
578 break;
579 case SR_CONF_LIMIT_SAMPLES:
411ad77c
GS
580 *data = std_gvar_tuple_u64(LA2016_NUM_SAMPLES_MIN,
581 LA2016_NUM_SAMPLES_MAX);
f2cd2deb
FS
582 break;
583 case SR_CONF_VOLTAGE_THRESHOLD:
584 *data = std_gvar_min_max_step_thresholds(
585 LA2016_THR_VOLTAGE_MIN,
586 LA2016_THR_VOLTAGE_MAX, 0.1);
587 break;
588 case SR_CONF_TRIGGER_MATCH:
589 *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
590 break;
591 case SR_CONF_LOGIC_THRESHOLD:
da2cb50d 592 *data = g_variant_new_strv(ARRAY_AND_SIZE(logic_threshold));
f2cd2deb
FS
593 break;
594 default:
595 return SR_ERR_NA;
596 }
597
598 return SR_OK;
599}
600
f2cd2deb
FS
601static int dev_acquisition_start(const struct sr_dev_inst *sdi)
602{
603 struct sr_dev_driver *di;
604 struct drv_context *drvc;
520a20e9 605 struct sr_context *ctx;
f2cd2deb
FS
606 struct dev_context *devc;
607 int ret;
608
609 di = sdi->driver;
610 drvc = di->context;
520a20e9 611 ctx = drvc->sr_ctx;;
f2cd2deb
FS
612 devc = sdi->priv;
613
a38f0f5e
GS
614 if (!devc->feed_queue) {
615 devc->feed_queue = feed_queue_logic_alloc(sdi,
616 LA2016_CONVBUFFER_SIZE, sizeof(uint16_t));
617 if (!devc->feed_queue) {
618 sr_err("Cannot allocate buffer for session feed.");
619 return SR_ERR_MALLOC;
620 }
f2cd2deb
FS
621 }
622
a38f0f5e
GS
623 sr_sw_limits_acquisition_start(&devc->sw_limits);
624
411ad77c
GS
625 ret = la2016_setup_acquisition(sdi);
626 if (ret != SR_OK) {
a38f0f5e
GS
627 feed_queue_logic_free(devc->feed_queue);
628 devc->feed_queue = NULL;
f2cd2deb
FS
629 return ret;
630 }
631
411ad77c
GS
632 ret = la2016_start_acquisition(sdi);
633 if (ret != SR_OK) {
3ebc1cb2 634 la2016_abort_acquisition(sdi);
a38f0f5e
GS
635 feed_queue_logic_free(devc->feed_queue);
636 devc->feed_queue = NULL;
f2cd2deb
FS
637 return ret;
638 }
639
cf057ac4 640 devc->completion_seen = FALSE;
520a20e9 641 usb_source_add(sdi->session, ctx, 50,
388438e4 642 la2016_receive_data, (void *)sdi);
f2cd2deb
FS
643
644 std_session_send_df_header(sdi);
645
646 return SR_OK;
647}
648
649static int dev_acquisition_stop(struct sr_dev_inst *sdi)
650{
651 int ret;
652
653 ret = la2016_abort_acquisition(sdi);
f2cd2deb
FS
654
655 return ret;
656}
657
658static struct sr_dev_driver kingst_la2016_driver_info = {
659 .name = "kingst-la2016",
660 .longname = "Kingst LA2016",
661 .api_version = 1,
662 .init = std_init,
663 .cleanup = std_cleanup,
664 .scan = scan,
665 .dev_list = std_dev_list,
666 .dev_clear = std_dev_clear,
667 .config_get = config_get,
668 .config_set = config_set,
669 .config_list = config_list,
670 .dev_open = dev_open,
671 .dev_close = dev_close,
672 .dev_acquisition_start = dev_acquisition_start,
673 .dev_acquisition_stop = dev_acquisition_stop,
674 .context = NULL,
675};
676SR_REGISTER_DEV_DRIVER(kingst_la2016_driver_info);