]> sigrok.org Git - libsigrok.git/blame - src/hardware/kingst-la2016/api.c
kingst-la2016: complete hardware setup in probe, set features in open
[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
36static const uint32_t scanopts[] = {
37 SR_CONF_CONN,
38};
39
40static const uint32_t drvopts[] = {
41 SR_CONF_LOGIC_ANALYZER,
42};
43
44static const uint32_t devopts[] = {
45 /* TODO: SR_CONF_CONTINUOUS, */
46 SR_CONF_CONN | SR_CONF_GET,
47 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
a38f0f5e
GS
48 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
49 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
f2cd2deb
FS
50 SR_CONF_VOLTAGE_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
51 SR_CONF_LOGIC_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
52 SR_CONF_LOGIC_THRESHOLD_CUSTOM | SR_CONF_GET | SR_CONF_SET,
53 SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
54 SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
55};
56
57static const int32_t trigger_matches[] = {
58 SR_TRIGGER_ZERO,
59 SR_TRIGGER_ONE,
60 SR_TRIGGER_RISING,
61 SR_TRIGGER_FALLING,
62};
63
d466f61c 64static const char *channel_names_logic[] = {
da25c287
GS
65 "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7",
66 "CH8", "CH9", "CH10", "CH11", "CH12", "CH13", "CH14", "CH15",
d466f61c
GS
67 "CH16", "CH17", "CH18", "CH19", "CH20", "CH21", "CH22", "CH23",
68 "CH24", "CH25", "CH26", "CH27", "CH28", "CH29", "CH30", "CH31",
f2cd2deb
FS
69};
70
ea436ba7 71/*
330853ba 72 * The hardware uses a 100/200/500MHz base clock (model dependent) and
ea436ba7
GS
73 * a 16bit divider (common across all models). The range from 10kHz to
74 * 100/200/500MHz should be applicable to all devices. High rates may
75 * suffer from coarse resolution (e.g. in the "500MHz div 2" case) and
330853ba
GS
76 * may not provide the desired 1/2/5 steps. Fortunately this exclusively
77 * affects the 500MHz model where 250MHz is used instead of 200MHz and
78 * the 166MHz and 125MHz rates are not presented to users. Deep memory
79 * of these models and hardware compression reduce the necessity to let
80 * users pick from a huge list of possible rates.
81 *
ea436ba7
GS
82 */
83
330853ba
GS
84static const uint64_t rates_500mhz[] = {
85 SR_KHZ(10),
86 SR_KHZ(20),
87 SR_KHZ(50),
88 SR_KHZ(100),
89 SR_KHZ(200),
90 SR_KHZ(500),
91 SR_MHZ(1),
92 SR_MHZ(2),
93 SR_MHZ(5),
94 SR_MHZ(10),
95 SR_MHZ(20),
96 SR_MHZ(50),
97 SR_MHZ(100),
98 SR_MHZ(250),
99 SR_MHZ(500),
100};
101
102static const uint64_t rates_200mhz[] = {
ea436ba7 103 SR_KHZ(10),
f2cd2deb
FS
104 SR_KHZ(20),
105 SR_KHZ(50),
106 SR_KHZ(100),
107 SR_KHZ(200),
108 SR_KHZ(500),
109 SR_MHZ(1),
110 SR_MHZ(2),
f2cd2deb 111 SR_MHZ(5),
f2cd2deb
FS
112 SR_MHZ(10),
113 SR_MHZ(20),
114 SR_MHZ(50),
115 SR_MHZ(100),
116 SR_MHZ(200),
117};
118
330853ba 119static const uint64_t rates_100mhz[] = {
ea436ba7 120 SR_KHZ(10),
8b172e78
KG
121 SR_KHZ(20),
122 SR_KHZ(50),
123 SR_KHZ(100),
124 SR_KHZ(200),
125 SR_KHZ(500),
126 SR_MHZ(1),
127 SR_MHZ(2),
8b172e78 128 SR_MHZ(5),
8b172e78
KG
129 SR_MHZ(10),
130 SR_MHZ(20),
131 SR_MHZ(50),
132 SR_MHZ(100),
133};
134
f2cd2deb
FS
135static const float logic_threshold_value[] = {
136 1.58,
137 2.5,
138 1.165,
139 1.5,
140 1.25,
141 0.9,
142 0.75,
143 0.60,
144 0.45,
145};
146
147static const char *logic_threshold[] = {
148 "TTL 5V",
149 "CMOS 5V",
150 "CMOS 3.3V",
151 "CMOS 3.0V",
152 "CMOS 2.5V",
153 "CMOS 1.8V",
154 "CMOS 1.5V",
155 "CMOS 1.2V",
156 "CMOS 0.9V",
157 "USER",
158};
159
da2cb50d 160#define LOGIC_THRESHOLD_IDX_USER (ARRAY_SIZE(logic_threshold) - 1)
f2cd2deb 161
d466f61c
GS
162/* Convenience. Release an allocated devc from error paths. */
163static void kingst_la2016_free_devc(struct dev_context *devc)
164{
165 if (!devc)
166 return;
167 g_free(devc->mcu_firmware);
168 g_free(devc->fpga_bitstream);
169 g_free(devc);
170}
171
172/* Convenience. Release an allocated sdi from error paths. */
173static void kingst_la2016_free_sdi(struct sr_dev_inst *sdi)
174{
175 if (!sdi)
176 return;
177 g_free(sdi->vendor);
178 g_free(sdi->model);
179 g_free(sdi->version);
180 g_free(sdi->serial_num);
181 g_free(sdi->connection_id);
182 sr_usb_dev_inst_free(sdi->conn);
183 kingst_la2016_free_devc(sdi->priv);
184}
185
186/* Convenience. Open a USB device (including claiming an interface). */
187static int la2016_open_usb(struct sr_usb_dev_inst *usb,
188 libusb_device *dev, gboolean show_message)
189{
190 int ret;
191
192 ret = libusb_open(dev, &usb->devhdl);
193 if (ret != 0) {
194 if (show_message) {
195 sr_err("Cannot open device: %s.",
196 libusb_error_name(ret));
197 }
198 return SR_ERR_IO;
199 }
200
201 if (usb->address == 0xff) {
202 /*
203 * First encounter after firmware upload.
204 * Grab current address after enumeration.
205 */
206 usb->address = libusb_get_device_address(dev);
207 }
208
209 ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
210 if (ret == LIBUSB_ERROR_BUSY) {
211 sr_err("Cannot claim USB interface. Another program or driver using it?");
212 return SR_ERR_IO;
213 } else if (ret == LIBUSB_ERROR_NO_DEVICE) {
214 sr_err("Device has been disconnected.");
215 return SR_ERR_IO;
216 } else if (ret != 0) {
217 sr_err("Cannot claim USB interface: %s.",
218 libusb_error_name(ret));
219 return SR_ERR_IO;
220 }
221
222 return SR_OK;
223}
224
225/* Convenience. Close an opened USB device (and release the interface). */
226static void la2016_close_usb(struct sr_usb_dev_inst *usb)
227{
228
229 if (!usb)
230 return;
231
232 if (usb->devhdl) {
233 libusb_release_interface(usb->devhdl, USB_INTERFACE);
234 libusb_close(usb->devhdl);
235 usb->devhdl = NULL;
236 }
237}
238
239/* Communicate to an USB device to identify the Kingst LA model. */
240static int la2016_identify_read(struct sr_dev_inst *sdi,
241 struct sr_usb_dev_inst *usb, libusb_device *dev,
242 gboolean show_message)
243{
244 int ret;
245
246 ret = la2016_open_usb(usb, dev, show_message);
247 if (ret != SR_OK) {
248 if (show_message)
249 sr_err("Cannot communicate to MCU firmware.");
250 return ret;
251 }
6d53e949
GS
252
253 /*
254 * Also complete the hardware configuration (FPGA bitstream)
255 * when MCU firmware communication became operational. Either
256 * failure is considered fatal when probing for the device.
257 */
d466f61c 258 ret = la2016_identify_device(sdi, show_message);
6d53e949
GS
259 if (ret == SR_OK) {
260 ret = la2016_init_hardware(sdi);
261 }
262
d466f61c
GS
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 570 sr_sw_limits_init(&devc->sw_limits);
d8fbfcd9
GS
571 devc->sw_limits.limit_samples = 0;
572 devc->capture_ratio = 50;
573 devc->cur_samplerate = devc->model->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
6d53e949
GS
595 /*
596 * Setup a default configuration of device features. This
597 * affects the logic threshold, PWM channels, and similar.
598 */
599 ret = la2016_init_params(sdi);
600 if (ret != SR_OK) {
601 sr_err("Cannot initialize device's hardware.");
602 return ret;
603 }
604
f2cd2deb
FS
605 return SR_OK;
606}
607
608static int dev_close(struct sr_dev_inst *sdi)
609{
610 struct sr_usb_dev_inst *usb;
611
612 usb = sdi->conn;
613
614 if (!usb->devhdl)
615 return SR_ERR_BUG;
616
6d53e949 617 la2016_deinit_hardware(sdi);
f2cd2deb
FS
618
619 sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
620 usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
d466f61c 621 la2016_close_usb(sdi->conn);
f2cd2deb
FS
622
623 return SR_OK;
624}
625
955ab604
GS
626static int config_get(uint32_t key, GVariant **data,
627 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
628{
629 struct dev_context *devc;
630 struct sr_usb_dev_inst *usb;
631 double rounded;
da2cb50d 632 const char *label;
f2cd2deb
FS
633
634 (void)cg;
635
636 if (!sdi)
637 return SR_ERR_ARG;
638 devc = sdi->priv;
639
640 switch (key) {
641 case SR_CONF_CONN:
642 if (!sdi->conn)
643 return SR_ERR_ARG;
644 usb = sdi->conn;
96dc954e
GS
645 if (usb->address == 0xff) {
646 /*
647 * Device still needs to re-enumerate after firmware
648 * upload, so we don't know its (future) address.
649 */
f2cd2deb 650 return SR_ERR;
955ab604 651 }
f2cd2deb
FS
652 *data = g_variant_new_printf("%d.%d", usb->bus, usb->address);
653 break;
654 case SR_CONF_SAMPLERATE:
655 *data = g_variant_new_uint64(devc->cur_samplerate);
656 break;
657 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
658 case SR_CONF_LIMIT_MSEC:
659 return sr_sw_limits_config_get(&devc->sw_limits, key, data);
f2cd2deb
FS
660 case SR_CONF_CAPTURE_RATIO:
661 *data = g_variant_new_uint64(devc->capture_ratio);
662 break;
663 case SR_CONF_VOLTAGE_THRESHOLD:
664 rounded = (int)(devc->threshold_voltage / 0.1) * 0.1;
665 *data = std_gvar_tuple_double(rounded, rounded + 0.1);
666 return SR_OK;
667 case SR_CONF_LOGIC_THRESHOLD:
da2cb50d
GS
668 label = logic_threshold[devc->threshold_voltage_idx];
669 *data = g_variant_new_string(label);
f2cd2deb
FS
670 break;
671 case SR_CONF_LOGIC_THRESHOLD_CUSTOM:
672 *data = g_variant_new_double(devc->threshold_voltage);
673 break;
955ab604 674
f2cd2deb
FS
675 default:
676 return SR_ERR_NA;
677 }
678
679 return SR_OK;
680}
681
955ab604
GS
682static int config_set(uint32_t key, GVariant *data,
683 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
684{
685 struct dev_context *devc;
686 double low, high;
687 int idx;
688
689 (void)cg;
690
691 devc = sdi->priv;
692
693 switch (key) {
694 case SR_CONF_SAMPLERATE:
695 devc->cur_samplerate = g_variant_get_uint64(data);
696 break;
697 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
698 case SR_CONF_LIMIT_MSEC:
699 return sr_sw_limits_config_set(&devc->sw_limits, key, data);
f2cd2deb
FS
700 case SR_CONF_CAPTURE_RATIO:
701 devc->capture_ratio = g_variant_get_uint64(data);
702 break;
703 case SR_CONF_VOLTAGE_THRESHOLD:
704 g_variant_get(data, "(dd)", &low, &high);
705 devc->threshold_voltage = (low + high) / 2.0;
da2cb50d 706 devc->threshold_voltage_idx = LOGIC_THRESHOLD_IDX_USER;
f2cd2deb
FS
707 break;
708 case SR_CONF_LOGIC_THRESHOLD: {
411ad77c
GS
709 idx = std_str_idx(data, ARRAY_AND_SIZE(logic_threshold));
710 if (idx < 0)
f2cd2deb 711 return SR_ERR_ARG;
da2cb50d 712 if (idx != LOGIC_THRESHOLD_IDX_USER) {
f2cd2deb
FS
713 devc->threshold_voltage = logic_threshold_value[idx];
714 }
715 devc->threshold_voltage_idx = idx;
716 break;
717 }
718 case SR_CONF_LOGIC_THRESHOLD_CUSTOM:
719 devc->threshold_voltage = g_variant_get_double(data);
720 break;
721 default:
722 return SR_ERR_NA;
723 }
724
725 return SR_OK;
726}
727
955ab604
GS
728static int config_list(uint32_t key, GVariant **data,
729 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb 730{
8b172e78
KG
731 struct dev_context *devc;
732
a38f0f5e
GS
733 devc = sdi ? sdi->priv : NULL;
734
f2cd2deb
FS
735 switch (key) {
736 case SR_CONF_SCAN_OPTIONS:
737 case SR_CONF_DEVICE_OPTIONS:
411ad77c
GS
738 return STD_CONFIG_LIST(key, data, sdi, cg,
739 scanopts, drvopts, devopts);
f2cd2deb 740 case SR_CONF_SAMPLERATE:
fb28e72d
MW
741 if (!sdi)
742 return SR_ERR_ARG;
d466f61c 743 if (devc->model->samplerate == SR_MHZ(500))
330853ba 744 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_500mhz));
d466f61c 745 else if (devc->model->samplerate == SR_MHZ(200))
330853ba
GS
746 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_200mhz));
747 else
748 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_100mhz));
f2cd2deb
FS
749 break;
750 case SR_CONF_LIMIT_SAMPLES:
d8fbfcd9 751 *data = std_gvar_tuple_u64(0, LA2016_NUM_SAMPLES_MAX);
f2cd2deb
FS
752 break;
753 case SR_CONF_VOLTAGE_THRESHOLD:
754 *data = std_gvar_min_max_step_thresholds(
755 LA2016_THR_VOLTAGE_MIN,
756 LA2016_THR_VOLTAGE_MAX, 0.1);
757 break;
758 case SR_CONF_TRIGGER_MATCH:
759 *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
760 break;
761 case SR_CONF_LOGIC_THRESHOLD:
da2cb50d 762 *data = g_variant_new_strv(ARRAY_AND_SIZE(logic_threshold));
f2cd2deb
FS
763 break;
764 default:
765 return SR_ERR_NA;
766 }
767
768 return SR_OK;
769}
770
f2cd2deb
FS
771static int dev_acquisition_start(const struct sr_dev_inst *sdi)
772{
773 struct sr_dev_driver *di;
774 struct drv_context *drvc;
520a20e9 775 struct sr_context *ctx;
f2cd2deb
FS
776 struct dev_context *devc;
777 int ret;
778
779 di = sdi->driver;
780 drvc = di->context;
520a20e9 781 ctx = drvc->sr_ctx;;
f2cd2deb
FS
782 devc = sdi->priv;
783
a38f0f5e
GS
784 if (!devc->feed_queue) {
785 devc->feed_queue = feed_queue_logic_alloc(sdi,
786 LA2016_CONVBUFFER_SIZE, sizeof(uint16_t));
787 if (!devc->feed_queue) {
788 sr_err("Cannot allocate buffer for session feed.");
789 return SR_ERR_MALLOC;
790 }
f2cd2deb
FS
791 }
792
a38f0f5e
GS
793 sr_sw_limits_acquisition_start(&devc->sw_limits);
794
411ad77c
GS
795 ret = la2016_setup_acquisition(sdi);
796 if (ret != SR_OK) {
a38f0f5e
GS
797 feed_queue_logic_free(devc->feed_queue);
798 devc->feed_queue = NULL;
f2cd2deb
FS
799 return ret;
800 }
801
411ad77c
GS
802 ret = la2016_start_acquisition(sdi);
803 if (ret != SR_OK) {
3ebc1cb2 804 la2016_abort_acquisition(sdi);
a38f0f5e
GS
805 feed_queue_logic_free(devc->feed_queue);
806 devc->feed_queue = NULL;
f2cd2deb
FS
807 return ret;
808 }
809
cf057ac4 810 devc->completion_seen = FALSE;
520a20e9 811 usb_source_add(sdi->session, ctx, 50,
388438e4 812 la2016_receive_data, (void *)sdi);
f2cd2deb
FS
813
814 std_session_send_df_header(sdi);
815
816 return SR_OK;
817}
818
819static int dev_acquisition_stop(struct sr_dev_inst *sdi)
820{
821 int ret;
822
823 ret = la2016_abort_acquisition(sdi);
f2cd2deb
FS
824
825 return ret;
826}
827
828static struct sr_dev_driver kingst_la2016_driver_info = {
829 .name = "kingst-la2016",
830 .longname = "Kingst LA2016",
831 .api_version = 1,
832 .init = std_init,
833 .cleanup = std_cleanup,
834 .scan = scan,
835 .dev_list = std_dev_list,
836 .dev_clear = std_dev_clear,
837 .config_get = config_get,
838 .config_set = config_set,
839 .config_list = config_list,
840 .dev_open = dev_open,
841 .dev_close = dev_close,
842 .dev_acquisition_start = dev_acquisition_start,
843 .dev_acquisition_stop = dev_acquisition_stop,
844 .context = NULL,
845};
846SR_REGISTER_DEV_DRIVER(kingst_la2016_driver_info);