]> sigrok.org Git - libsigrok.git/blame - src/hardware/kingst-la2016/api.c
kingst-la2016: identify device type in scan() already
[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
d466f61c 74static const char *channel_names_logic[] = {
da25c287
GS
75 "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7",
76 "CH8", "CH9", "CH10", "CH11", "CH12", "CH13", "CH14", "CH15",
d466f61c
GS
77 "CH16", "CH17", "CH18", "CH19", "CH20", "CH21", "CH22", "CH23",
78 "CH24", "CH25", "CH26", "CH27", "CH28", "CH29", "CH30", "CH31",
f2cd2deb
FS
79};
80
ea436ba7 81/*
330853ba 82 * The hardware uses a 100/200/500MHz base clock (model dependent) and
ea436ba7
GS
83 * a 16bit divider (common across all models). The range from 10kHz to
84 * 100/200/500MHz should be applicable to all devices. High rates may
85 * suffer from coarse resolution (e.g. in the "500MHz div 2" case) and
330853ba
GS
86 * may not provide the desired 1/2/5 steps. Fortunately this exclusively
87 * affects the 500MHz model where 250MHz is used instead of 200MHz and
88 * the 166MHz and 125MHz rates are not presented to users. Deep memory
89 * of these models and hardware compression reduce the necessity to let
90 * users pick from a huge list of possible rates.
91 *
ea436ba7
GS
92 */
93
330853ba
GS
94static const uint64_t rates_500mhz[] = {
95 SR_KHZ(10),
96 SR_KHZ(20),
97 SR_KHZ(50),
98 SR_KHZ(100),
99 SR_KHZ(200),
100 SR_KHZ(500),
101 SR_MHZ(1),
102 SR_MHZ(2),
103 SR_MHZ(5),
104 SR_MHZ(10),
105 SR_MHZ(20),
106 SR_MHZ(50),
107 SR_MHZ(100),
108 SR_MHZ(250),
109 SR_MHZ(500),
110};
111
112static const uint64_t rates_200mhz[] = {
ea436ba7 113 SR_KHZ(10),
f2cd2deb
FS
114 SR_KHZ(20),
115 SR_KHZ(50),
116 SR_KHZ(100),
117 SR_KHZ(200),
118 SR_KHZ(500),
119 SR_MHZ(1),
120 SR_MHZ(2),
f2cd2deb 121 SR_MHZ(5),
f2cd2deb
FS
122 SR_MHZ(10),
123 SR_MHZ(20),
124 SR_MHZ(50),
125 SR_MHZ(100),
126 SR_MHZ(200),
127};
128
330853ba 129static const uint64_t rates_100mhz[] = {
ea436ba7 130 SR_KHZ(10),
8b172e78
KG
131 SR_KHZ(20),
132 SR_KHZ(50),
133 SR_KHZ(100),
134 SR_KHZ(200),
135 SR_KHZ(500),
136 SR_MHZ(1),
137 SR_MHZ(2),
8b172e78 138 SR_MHZ(5),
8b172e78
KG
139 SR_MHZ(10),
140 SR_MHZ(20),
141 SR_MHZ(50),
142 SR_MHZ(100),
143};
144
f2cd2deb
FS
145static const float logic_threshold_value[] = {
146 1.58,
147 2.5,
148 1.165,
149 1.5,
150 1.25,
151 0.9,
152 0.75,
153 0.60,
154 0.45,
155};
156
157static const char *logic_threshold[] = {
158 "TTL 5V",
159 "CMOS 5V",
160 "CMOS 3.3V",
161 "CMOS 3.0V",
162 "CMOS 2.5V",
163 "CMOS 1.8V",
164 "CMOS 1.5V",
165 "CMOS 1.2V",
166 "CMOS 0.9V",
167 "USER",
168};
169
da2cb50d 170#define LOGIC_THRESHOLD_IDX_USER (ARRAY_SIZE(logic_threshold) - 1)
f2cd2deb 171
d466f61c
GS
172/* Convenience. Release an allocated devc from error paths. */
173static void kingst_la2016_free_devc(struct dev_context *devc)
174{
175 if (!devc)
176 return;
177 g_free(devc->mcu_firmware);
178 g_free(devc->fpga_bitstream);
179 g_free(devc);
180}
181
182/* Convenience. Release an allocated sdi from error paths. */
183static void kingst_la2016_free_sdi(struct sr_dev_inst *sdi)
184{
185 if (!sdi)
186 return;
187 g_free(sdi->vendor);
188 g_free(sdi->model);
189 g_free(sdi->version);
190 g_free(sdi->serial_num);
191 g_free(sdi->connection_id);
192 sr_usb_dev_inst_free(sdi->conn);
193 kingst_la2016_free_devc(sdi->priv);
194}
195
196/* Convenience. Open a USB device (including claiming an interface). */
197static int la2016_open_usb(struct sr_usb_dev_inst *usb,
198 libusb_device *dev, gboolean show_message)
199{
200 int ret;
201
202 ret = libusb_open(dev, &usb->devhdl);
203 if (ret != 0) {
204 if (show_message) {
205 sr_err("Cannot open device: %s.",
206 libusb_error_name(ret));
207 }
208 return SR_ERR_IO;
209 }
210
211 if (usb->address == 0xff) {
212 /*
213 * First encounter after firmware upload.
214 * Grab current address after enumeration.
215 */
216 usb->address = libusb_get_device_address(dev);
217 }
218
219 ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
220 if (ret == LIBUSB_ERROR_BUSY) {
221 sr_err("Cannot claim USB interface. Another program or driver using it?");
222 return SR_ERR_IO;
223 } else if (ret == LIBUSB_ERROR_NO_DEVICE) {
224 sr_err("Device has been disconnected.");
225 return SR_ERR_IO;
226 } else if (ret != 0) {
227 sr_err("Cannot claim USB interface: %s.",
228 libusb_error_name(ret));
229 return SR_ERR_IO;
230 }
231
232 return SR_OK;
233}
234
235/* Convenience. Close an opened USB device (and release the interface). */
236static void la2016_close_usb(struct sr_usb_dev_inst *usb)
237{
238
239 if (!usb)
240 return;
241
242 if (usb->devhdl) {
243 libusb_release_interface(usb->devhdl, USB_INTERFACE);
244 libusb_close(usb->devhdl);
245 usb->devhdl = NULL;
246 }
247}
248
249/* Communicate to an USB device to identify the Kingst LA model. */
250static int la2016_identify_read(struct sr_dev_inst *sdi,
251 struct sr_usb_dev_inst *usb, libusb_device *dev,
252 gboolean show_message)
253{
254 int ret;
255
256 ret = la2016_open_usb(usb, dev, show_message);
257 if (ret != SR_OK) {
258 if (show_message)
259 sr_err("Cannot communicate to MCU firmware.");
260 return ret;
261 }
262 ret = la2016_identify_device(sdi, show_message);
263 la2016_close_usb(usb);
264
265 return ret;
266}
267
268/* Find given conn_id in another USB enum. Identify Kingst LA model. */
269static int la2016_identify_enum(struct sr_dev_inst *sdi)
270{
271 struct sr_dev_driver *di;
272 struct drv_context *drvc;
273 struct sr_context *ctx;
274 libusb_device **devlist, *dev;
275 struct libusb_device_descriptor des;
276 int ret, id_ret;
277 size_t device_count, dev_idx;
278 char conn_id[64];
279
280 di = sdi->driver;
281 drvc = di->context;
282 ctx = drvc->sr_ctx;;
283
284 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
285 if (ret < 0)
286 return SR_ERR_IO;
287 device_count = ret;
288 if (!device_count)
289 return SR_ERR_IO;
290 id_ret = SR_ERR_IO;
291 for (dev_idx = 0; dev_idx < device_count; dev_idx++) {
292 dev = devlist[dev_idx];
293 libusb_get_device_descriptor(dev, &des);
294 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
295 continue;
296 if (des.iProduct != LA2016_IPRODUCT_INDEX)
297 continue;
298 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
299 if (ret < 0)
300 continue;
301 if (strcmp(sdi->connection_id, conn_id) != 0)
302 continue;
303 id_ret = la2016_identify_read(sdi, sdi->conn, dev, FALSE);
304 break;
305 }
306 libusb_free_device_list(devlist, 1);
307
308 return id_ret;
309}
310
311/* Wait for a device to re-appear after firmware upload. */
312static int la2016_identify_wait(struct sr_dev_inst *sdi)
313{
314 struct dev_context *devc;
315 uint64_t reset_done, now, elapsed_ms;
316 int ret;
317
318 devc = sdi->priv;
319
320 sr_info("Waiting for device to reset after firmware upload.");
321 now = g_get_monotonic_time();
322 reset_done = devc->fw_uploaded + RENUM_GONE_DELAY_MS * 1000;
323 if (now < reset_done)
324 g_usleep(reset_done - now);
325 do {
326 now = g_get_monotonic_time();
327 elapsed_ms = (now - devc->fw_uploaded) / 1000;
328 sr_spew("Waited %" PRIu64 "ms.", elapsed_ms);
329 ret = la2016_identify_enum(sdi);
330 if (ret == SR_OK) {
331 devc->fw_uploaded = 0;
332 break;
333 }
334 g_usleep(RENUM_POLL_INTERVAL_MS * 1000);
335 } while (elapsed_ms < RENUM_CHECK_PERIOD_MS);
336 if (ret != SR_OK) {
337 sr_err("Device failed to re-enumerate.");
338 return ret;
339 }
340 sr_info("Device came back after %" PRIi64 "ms.", elapsed_ms);
341
342 return SR_OK;
343}
344
345/*
346 * Open given conn_id from another USB enum. Used by dev_open(). Similar
347 * to, and should be kept in sync with la2016_identify_enum().
348 */
349static int la2016_open_enum(struct sr_dev_inst *sdi)
350{
351 struct sr_dev_driver *di;
352 struct drv_context *drvc;
353 struct sr_context *ctx;
354 libusb_device **devlist, *dev;
355 struct libusb_device_descriptor des;
356 int ret, open_ret;
357 size_t device_count, dev_idx;
358 char conn_id[64];
359
360 di = sdi->driver;
361 drvc = di->context;
362 ctx = drvc->sr_ctx;;
363
364 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
365 if (ret < 0)
366 return SR_ERR_IO;
367 device_count = ret;
368 if (!device_count)
369 return SR_ERR_IO;
370 open_ret = SR_ERR_IO;
371 for (dev_idx = 0; dev_idx < device_count; dev_idx++) {
372 dev = devlist[dev_idx];
373 libusb_get_device_descriptor(dev, &des);
374 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
375 continue;
376 if (des.iProduct != LA2016_IPRODUCT_INDEX)
377 continue;
378 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
379 if (ret < 0)
380 continue;
381 if (strcmp(sdi->connection_id, conn_id) != 0)
382 continue;
383 open_ret = la2016_open_usb(sdi->conn, dev, TRUE);
384 break;
385 }
386 libusb_free_device_list(devlist, 1);
387
388 return open_ret;
389}
390
f2cd2deb
FS
391static GSList *scan(struct sr_dev_driver *di, GSList *options)
392{
393 struct drv_context *drvc;
520a20e9 394 struct sr_context *ctx;
f2cd2deb
FS
395 struct dev_context *devc;
396 struct sr_dev_inst *sdi;
397 struct sr_usb_dev_inst *usb;
398 struct sr_config *src;
399 GSList *l;
d466f61c 400 GSList *devices, *found_devices, *renum_devices;
f2cd2deb
FS
401 GSList *conn_devices;
402 struct libusb_device_descriptor des;
520a20e9
GS
403 libusb_device **devlist, *dev;
404 size_t dev_count, dev_idx, ch_idx;
405 uint8_t bus, addr;
d466f61c 406 uint16_t pid;
f2cd2deb 407 const char *conn;
520a20e9 408 char conn_id[64];
520a20e9 409 int ret;
d466f61c 410 size_t ch_off, ch_max;
f2cd2deb
FS
411
412 drvc = di->context;
520a20e9 413 ctx = drvc->sr_ctx;;
f2cd2deb
FS
414
415 conn = NULL;
d466f61c 416 conn_devices = NULL;
f2cd2deb
FS
417 for (l = options; l; l = l->next) {
418 src = l->data;
419 switch (src->key) {
420 case SR_CONF_CONN:
421 conn = g_variant_get_string(src->data, NULL);
422 break;
423 }
424 }
425 if (conn)
520a20e9 426 conn_devices = sr_usb_find(ctx->libusb_ctx, conn);
d466f61c
GS
427 if (conn && !conn_devices) {
428 sr_err("Cannot find the specified connection '%s'.", conn);
429 return NULL;
430 }
f2cd2deb 431
d466f61c
GS
432 /*
433 * Find all LA2016 devices, optionally upload firmware to them.
434 * Defer completion of sdi/devc creation until all (selected)
435 * devices were found in a usable state, and their models got
436 * identified which affect their feature set. It appears that
437 * we cannot communicate to the device within the same USB enum
438 * cycle, needs another USB enumeration after firmware upload.
439 */
f2cd2deb 440 devices = NULL;
d466f61c
GS
441 found_devices = NULL;
442 renum_devices = NULL;
520a20e9
GS
443 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
444 if (ret < 0) {
445 sr_err("Cannot get device list: %s.", libusb_error_name(ret));
446 return devices;
447 }
448 dev_count = ret;
449 for (dev_idx = 0; dev_idx < dev_count; dev_idx++) {
450 dev = devlist[dev_idx];
451 bus = libusb_get_bus_number(dev);
452 addr = libusb_get_device_address(dev);
d466f61c
GS
453
454 /* Filter by connection when externally specified. */
455 for (l = conn_devices; l; l = l->next) {
456 usb = l->data;
457 if (usb->bus == bus && usb->address == addr)
458 break;
459 }
460 if (conn_devices && !l) {
461 sr_spew("Bus %hhu, addr %hhu do not match specified filter.",
462 bus, addr);
463 continue;
f2cd2deb
FS
464 }
465
d466f61c 466 /* Check USB VID:PID. Get the connection string. */
520a20e9 467 libusb_get_device_descriptor(dev, &des);
d466f61c
GS
468 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
469 continue;
470 pid = des.idProduct;
520a20e9
GS
471 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
472 if (ret < 0)
f2cd2deb 473 continue;
d466f61c
GS
474 sr_dbg("USB enum found %04x:%04x at path %s, %d.%d.",
475 des.idVendor, des.idProduct, conn_id, bus, addr);
476 usb = sr_usb_dev_inst_new(bus, addr, NULL);
f2cd2deb 477
520a20e9 478 sdi = g_malloc0(sizeof(*sdi));
d466f61c 479 sdi->driver = di;
f2cd2deb 480 sdi->status = SR_ST_INITIALIZING;
d466f61c 481 sdi->inst_type = SR_INST_USB;
520a20e9 482 sdi->connection_id = g_strdup(conn_id);
d466f61c 483 sdi->conn = usb;
f2cd2deb 484
d466f61c
GS
485 devc = g_malloc0(sizeof(*devc));
486 sdi->priv = devc;
f2cd2deb 487
d466f61c
GS
488 /*
489 * Load MCU firmware if it is currently missing. Which
490 * makes the device disappear and renumerate in USB.
491 * We need to come back another time to communicate to
492 * this device.
493 */
494 devc->fw_uploaded = 0;
495 if (des.iProduct != LA2016_IPRODUCT_INDEX) {
496 sr_info("Uploading MCU firmware to '%s'.", conn_id);
497 ret = la2016_upload_firmware(sdi, ctx, dev, pid);
520a20e9 498 if (ret != SR_OK) {
91f73872 499 sr_err("MCU firmware upload failed.");
d466f61c 500 kingst_la2016_free_sdi(sdi);
f2cd2deb
FS
501 continue;
502 }
d466f61c
GS
503 devc->fw_uploaded = g_get_monotonic_time();
504 usb->address = 0xff;
505 renum_devices = g_slist_append(renum_devices, sdi);
506 continue;
f2cd2deb
FS
507 }
508
d466f61c
GS
509 /*
510 * Communicate to the MCU firmware to access EEPROM data
511 * which lets us identify the device type. Then stop, to
512 * share remaining sdi/devc creation with those devices
513 * which had their MCU firmware uploaded above and which
514 * get revisited later.
515 */
516 ret = la2016_identify_read(sdi, usb, dev, TRUE);
517 if (ret != SR_OK || !devc->model) {
518 sr_err("Unknown or unsupported device type.");
519 kingst_la2016_free_sdi(sdi);
520 continue;
521 }
522 found_devices = g_slist_append(found_devices, sdi);
523 }
524 libusb_free_device_list(devlist, 1);
525 g_slist_free_full(conn_devices, sr_usb_dev_inst_free_cb);
f2cd2deb 526
d466f61c
GS
527 /*
528 * Wait for devices to re-appear after firmware upload. Append
529 * the yet unidentified device to the list of found devices, or
530 * release the previously allocated sdi/devc.
531 */
532 for (l = renum_devices; l; l = l->next) {
533 sdi = l->data;
534 devc = sdi->priv;
535 ret = la2016_identify_wait(sdi);
536 if (ret != SR_OK || !devc->model) {
537 sr_dbg("Skipping unusable '%s'.", sdi->connection_id);
538 kingst_la2016_free_sdi(sdi);
539 continue;
520a20e9 540 }
d466f61c
GS
541 found_devices = g_slist_append(found_devices, sdi);
542 }
543 g_slist_free(renum_devices);
f2cd2deb 544
d466f61c
GS
545 /*
546 * All found devices got identified, their type is known here.
547 * Complete the sdi/devc creation. Assign default settings
548 * because the vendor firmware would not let us read back the
549 * previously written configuration.
550 */
551 for (l = found_devices; l; l = l->next) {
552 sdi = l->data;
553 devc = sdi->priv;
554
555 sdi->vendor = g_strdup("Kingst");
556 sdi->model = g_strdup(devc->model->name);
557 ch_off = 0;
558
559 /* Create the logic channels. */
560 ch_max = ARRAY_SIZE(channel_names_logic);
561 if (ch_max > devc->model->channel_count)
562 ch_max = devc->model->channel_count;
563 for (ch_idx = 0; ch_idx < ch_max; ch_idx++) {
564 sr_channel_new(sdi, ch_off,
565 SR_CHANNEL_LOGIC, TRUE,
566 channel_names_logic[ch_idx]);
567 ch_off++;
568 }
f2cd2deb 569
a38f0f5e
GS
570 sr_sw_limits_init(&devc->sw_limits);
571 devc->sw_limits.limit_samples = LA2016_DFLT_SAMPLEDEPTH;
572 devc->capture_ratio = LA2016_DFLT_CAPT_RATIO;
573 devc->cur_samplerate = LA2016_DFLT_SAMPLERATE;
f2cd2deb
FS
574 devc->threshold_voltage_idx = 0;
575 devc->threshold_voltage = logic_threshold_value[devc->threshold_voltage_idx];
576
577 sdi->status = SR_ST_INACTIVE;
d466f61c 578 devices = g_slist_append(devices, sdi);
f2cd2deb 579 }
d466f61c 580 g_slist_free(found_devices);
f2cd2deb
FS
581
582 return std_scan_complete(di, devices);
583}
584
f2cd2deb
FS
585static int dev_open(struct sr_dev_inst *sdi)
586{
f2cd2deb
FS
587 int ret;
588
d466f61c 589 ret = la2016_open_enum(sdi);
f2cd2deb 590 if (ret != SR_OK) {
91f73872 591 sr_err("Cannot open device.");
520a20e9 592 return ret;
f2cd2deb
FS
593 }
594
595 return SR_OK;
596}
597
598static int dev_close(struct sr_dev_inst *sdi)
599{
600 struct sr_usb_dev_inst *usb;
601
602 usb = sdi->conn;
603
604 if (!usb->devhdl)
605 return SR_ERR_BUG;
606
607 la2016_deinit_device(sdi);
608
609 sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
610 usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
d466f61c 611 la2016_close_usb(sdi->conn);
f2cd2deb
FS
612
613 return SR_OK;
614}
615
955ab604
GS
616static int config_get(uint32_t key, GVariant **data,
617 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
618{
619 struct dev_context *devc;
620 struct sr_usb_dev_inst *usb;
621 double rounded;
da2cb50d 622 const char *label;
f2cd2deb
FS
623
624 (void)cg;
625
626 if (!sdi)
627 return SR_ERR_ARG;
628 devc = sdi->priv;
629
630 switch (key) {
631 case SR_CONF_CONN:
632 if (!sdi->conn)
633 return SR_ERR_ARG;
634 usb = sdi->conn;
96dc954e
GS
635 if (usb->address == 0xff) {
636 /*
637 * Device still needs to re-enumerate after firmware
638 * upload, so we don't know its (future) address.
639 */
f2cd2deb 640 return SR_ERR;
955ab604 641 }
f2cd2deb
FS
642 *data = g_variant_new_printf("%d.%d", usb->bus, usb->address);
643 break;
644 case SR_CONF_SAMPLERATE:
645 *data = g_variant_new_uint64(devc->cur_samplerate);
646 break;
647 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
648 case SR_CONF_LIMIT_MSEC:
649 return sr_sw_limits_config_get(&devc->sw_limits, key, data);
f2cd2deb
FS
650 case SR_CONF_CAPTURE_RATIO:
651 *data = g_variant_new_uint64(devc->capture_ratio);
652 break;
653 case SR_CONF_VOLTAGE_THRESHOLD:
654 rounded = (int)(devc->threshold_voltage / 0.1) * 0.1;
655 *data = std_gvar_tuple_double(rounded, rounded + 0.1);
656 return SR_OK;
657 case SR_CONF_LOGIC_THRESHOLD:
da2cb50d
GS
658 label = logic_threshold[devc->threshold_voltage_idx];
659 *data = g_variant_new_string(label);
f2cd2deb
FS
660 break;
661 case SR_CONF_LOGIC_THRESHOLD_CUSTOM:
662 *data = g_variant_new_double(devc->threshold_voltage);
663 break;
955ab604 664
f2cd2deb
FS
665 default:
666 return SR_ERR_NA;
667 }
668
669 return SR_OK;
670}
671
955ab604
GS
672static int config_set(uint32_t key, GVariant *data,
673 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
674{
675 struct dev_context *devc;
676 double low, high;
677 int idx;
678
679 (void)cg;
680
681 devc = sdi->priv;
682
683 switch (key) {
684 case SR_CONF_SAMPLERATE:
685 devc->cur_samplerate = g_variant_get_uint64(data);
686 break;
687 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
688 case SR_CONF_LIMIT_MSEC:
689 return sr_sw_limits_config_set(&devc->sw_limits, key, data);
f2cd2deb
FS
690 case SR_CONF_CAPTURE_RATIO:
691 devc->capture_ratio = g_variant_get_uint64(data);
692 break;
693 case SR_CONF_VOLTAGE_THRESHOLD:
694 g_variant_get(data, "(dd)", &low, &high);
695 devc->threshold_voltage = (low + high) / 2.0;
da2cb50d 696 devc->threshold_voltage_idx = LOGIC_THRESHOLD_IDX_USER;
f2cd2deb
FS
697 break;
698 case SR_CONF_LOGIC_THRESHOLD: {
411ad77c
GS
699 idx = std_str_idx(data, ARRAY_AND_SIZE(logic_threshold));
700 if (idx < 0)
f2cd2deb 701 return SR_ERR_ARG;
da2cb50d 702 if (idx != LOGIC_THRESHOLD_IDX_USER) {
f2cd2deb
FS
703 devc->threshold_voltage = logic_threshold_value[idx];
704 }
705 devc->threshold_voltage_idx = idx;
706 break;
707 }
708 case SR_CONF_LOGIC_THRESHOLD_CUSTOM:
709 devc->threshold_voltage = g_variant_get_double(data);
710 break;
711 default:
712 return SR_ERR_NA;
713 }
714
715 return SR_OK;
716}
717
955ab604
GS
718static int config_list(uint32_t key, GVariant **data,
719 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb 720{
8b172e78
KG
721 struct dev_context *devc;
722
a38f0f5e
GS
723 devc = sdi ? sdi->priv : NULL;
724
f2cd2deb
FS
725 switch (key) {
726 case SR_CONF_SCAN_OPTIONS:
727 case SR_CONF_DEVICE_OPTIONS:
411ad77c
GS
728 return STD_CONFIG_LIST(key, data, sdi, cg,
729 scanopts, drvopts, devopts);
f2cd2deb 730 case SR_CONF_SAMPLERATE:
fb28e72d
MW
731 if (!sdi)
732 return SR_ERR_ARG;
d466f61c 733 if (devc->model->samplerate == SR_MHZ(500))
330853ba 734 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_500mhz));
d466f61c 735 else if (devc->model->samplerate == SR_MHZ(200))
330853ba
GS
736 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_200mhz));
737 else
738 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_100mhz));
f2cd2deb
FS
739 break;
740 case SR_CONF_LIMIT_SAMPLES:
411ad77c
GS
741 *data = std_gvar_tuple_u64(LA2016_NUM_SAMPLES_MIN,
742 LA2016_NUM_SAMPLES_MAX);
f2cd2deb
FS
743 break;
744 case SR_CONF_VOLTAGE_THRESHOLD:
745 *data = std_gvar_min_max_step_thresholds(
746 LA2016_THR_VOLTAGE_MIN,
747 LA2016_THR_VOLTAGE_MAX, 0.1);
748 break;
749 case SR_CONF_TRIGGER_MATCH:
750 *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
751 break;
752 case SR_CONF_LOGIC_THRESHOLD:
da2cb50d 753 *data = g_variant_new_strv(ARRAY_AND_SIZE(logic_threshold));
f2cd2deb
FS
754 break;
755 default:
756 return SR_ERR_NA;
757 }
758
759 return SR_OK;
760}
761
f2cd2deb
FS
762static int dev_acquisition_start(const struct sr_dev_inst *sdi)
763{
764 struct sr_dev_driver *di;
765 struct drv_context *drvc;
520a20e9 766 struct sr_context *ctx;
f2cd2deb
FS
767 struct dev_context *devc;
768 int ret;
769
770 di = sdi->driver;
771 drvc = di->context;
520a20e9 772 ctx = drvc->sr_ctx;;
f2cd2deb
FS
773 devc = sdi->priv;
774
a38f0f5e
GS
775 if (!devc->feed_queue) {
776 devc->feed_queue = feed_queue_logic_alloc(sdi,
777 LA2016_CONVBUFFER_SIZE, sizeof(uint16_t));
778 if (!devc->feed_queue) {
779 sr_err("Cannot allocate buffer for session feed.");
780 return SR_ERR_MALLOC;
781 }
f2cd2deb
FS
782 }
783
a38f0f5e
GS
784 sr_sw_limits_acquisition_start(&devc->sw_limits);
785
411ad77c
GS
786 ret = la2016_setup_acquisition(sdi);
787 if (ret != SR_OK) {
a38f0f5e
GS
788 feed_queue_logic_free(devc->feed_queue);
789 devc->feed_queue = NULL;
f2cd2deb
FS
790 return ret;
791 }
792
411ad77c
GS
793 ret = la2016_start_acquisition(sdi);
794 if (ret != SR_OK) {
3ebc1cb2 795 la2016_abort_acquisition(sdi);
a38f0f5e
GS
796 feed_queue_logic_free(devc->feed_queue);
797 devc->feed_queue = NULL;
f2cd2deb
FS
798 return ret;
799 }
800
cf057ac4 801 devc->completion_seen = FALSE;
520a20e9 802 usb_source_add(sdi->session, ctx, 50,
388438e4 803 la2016_receive_data, (void *)sdi);
f2cd2deb
FS
804
805 std_session_send_df_header(sdi);
806
807 return SR_OK;
808}
809
810static int dev_acquisition_stop(struct sr_dev_inst *sdi)
811{
812 int ret;
813
814 ret = la2016_abort_acquisition(sdi);
f2cd2deb
FS
815
816 return ret;
817}
818
819static struct sr_dev_driver kingst_la2016_driver_info = {
820 .name = "kingst-la2016",
821 .longname = "Kingst LA2016",
822 .api_version = 1,
823 .init = std_init,
824 .cleanup = std_cleanup,
825 .scan = scan,
826 .dev_list = std_dev_list,
827 .dev_clear = std_dev_clear,
828 .config_get = config_get,
829 .config_set = config_set,
830 .config_list = config_list,
831 .dev_open = dev_open,
832 .dev_close = dev_close,
833 .dev_acquisition_start = dev_acquisition_start,
834 .dev_acquisition_stop = dev_acquisition_stop,
835 .context = NULL,
836};
837SR_REGISTER_DEV_DRIVER(kingst_la2016_driver_info);