]> sigrok.org Git - libsigrok.git/blame - src/hardware/kingst-la2016/api.c
kingst-la2016: keep FPGA active after device close
[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,
331277e0 42 SR_CONF_SIGNAL_GENERATOR,
f2cd2deb
FS
43};
44
45static const uint32_t devopts[] = {
46 /* TODO: SR_CONF_CONTINUOUS, */
47 SR_CONF_CONN | SR_CONF_GET,
48 SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
a38f0f5e
GS
49 SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
50 SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,
9270f8f4 51#if WITH_THRESHOLD_DEVCFG
f2cd2deb 52 SR_CONF_VOLTAGE_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
9270f8f4 53#endif
f2cd2deb
FS
54 SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
55 SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
56};
57
9270f8f4
GS
58static const uint32_t devopts_cg_logic[] = {
59#if !WITH_THRESHOLD_DEVCFG
60 SR_CONF_VOLTAGE_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
61#endif
62};
63
331277e0
GS
64static const uint32_t devopts_cg_pwm[] = {
65 SR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,
66 SR_CONF_OUTPUT_FREQUENCY | SR_CONF_GET | SR_CONF_SET,
67 SR_CONF_DUTY_CYCLE | SR_CONF_GET | SR_CONF_SET,
68};
69
f2cd2deb
FS
70static const int32_t trigger_matches[] = {
71 SR_TRIGGER_ZERO,
72 SR_TRIGGER_ONE,
73 SR_TRIGGER_RISING,
74 SR_TRIGGER_FALLING,
75};
76
d466f61c 77static const char *channel_names_logic[] = {
da25c287
GS
78 "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7",
79 "CH8", "CH9", "CH10", "CH11", "CH12", "CH13", "CH14", "CH15",
d466f61c
GS
80 "CH16", "CH17", "CH18", "CH19", "CH20", "CH21", "CH22", "CH23",
81 "CH24", "CH25", "CH26", "CH27", "CH28", "CH29", "CH30", "CH31",
f2cd2deb
FS
82};
83
331277e0
GS
84static const char *channel_names_pwm[] = {
85 "PWM1", "PWM2",
86};
87
ea436ba7 88/*
330853ba 89 * The hardware uses a 100/200/500MHz base clock (model dependent) and
ea436ba7
GS
90 * a 16bit divider (common across all models). The range from 10kHz to
91 * 100/200/500MHz should be applicable to all devices. High rates may
92 * suffer from coarse resolution (e.g. in the "500MHz div 2" case) and
330853ba
GS
93 * may not provide the desired 1/2/5 steps. Fortunately this exclusively
94 * affects the 500MHz model where 250MHz is used instead of 200MHz and
95 * the 166MHz and 125MHz rates are not presented to users. Deep memory
96 * of these models and hardware compression reduce the necessity to let
97 * users pick from a huge list of possible rates.
98 *
ea436ba7
GS
99 */
100
330853ba
GS
101static const uint64_t rates_500mhz[] = {
102 SR_KHZ(10),
103 SR_KHZ(20),
104 SR_KHZ(50),
105 SR_KHZ(100),
106 SR_KHZ(200),
107 SR_KHZ(500),
108 SR_MHZ(1),
109 SR_MHZ(2),
110 SR_MHZ(5),
111 SR_MHZ(10),
112 SR_MHZ(20),
113 SR_MHZ(50),
114 SR_MHZ(100),
115 SR_MHZ(250),
116 SR_MHZ(500),
117};
118
119static const uint64_t rates_200mhz[] = {
ea436ba7 120 SR_KHZ(10),
f2cd2deb
FS
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),
f2cd2deb 128 SR_MHZ(5),
f2cd2deb
FS
129 SR_MHZ(10),
130 SR_MHZ(20),
131 SR_MHZ(50),
132 SR_MHZ(100),
133 SR_MHZ(200),
134};
135
330853ba 136static const uint64_t rates_100mhz[] = {
ea436ba7 137 SR_KHZ(10),
8b172e78
KG
138 SR_KHZ(20),
139 SR_KHZ(50),
140 SR_KHZ(100),
141 SR_KHZ(200),
142 SR_KHZ(500),
143 SR_MHZ(1),
144 SR_MHZ(2),
8b172e78 145 SR_MHZ(5),
8b172e78
KG
146 SR_MHZ(10),
147 SR_MHZ(20),
148 SR_MHZ(50),
149 SR_MHZ(100),
150};
151
9270f8f4
GS
152/*
153 * Only list a few discrete voltages, to form a useful set which covers
154 * most logic families. Too many choices can make some applications use
155 * a slider again. Which may lack a scale for the current value, and
156 * leave users without feedback what the currently used value might be.
157 */
158static const double threshold_ranges[][2] = {
159 { 0.4, 0.4, },
160 { 0.6, 0.6, },
161 { 0.9, 0.9, },
162 { 1.2, 1.2, },
163 { 1.4, 1.4, }, /* Default, 1.4V, index 4. */
164 { 2.0, 2.0, },
165 { 2.5, 2.5, },
166 { 4.0, 4.0, },
167};
168#define LOGIC_THRESHOLD_IDX_DFLT 4
169
170static double threshold_voltage(const struct sr_dev_inst *sdi, double *high)
171{
172 struct dev_context *devc;
173 size_t idx;
174 double voltage;
175
176 devc = sdi->priv;
177 idx = devc->threshold_voltage_idx;
178 voltage = threshold_ranges[idx][0];
179 if (high)
180 *high = threshold_ranges[idx][1];
181
182 return voltage;
183}
184
d466f61c
GS
185/* Convenience. Release an allocated devc from error paths. */
186static void kingst_la2016_free_devc(struct dev_context *devc)
187{
188 if (!devc)
189 return;
190 g_free(devc->mcu_firmware);
191 g_free(devc->fpga_bitstream);
192 g_free(devc);
193}
194
195/* Convenience. Release an allocated sdi from error paths. */
196static void kingst_la2016_free_sdi(struct sr_dev_inst *sdi)
197{
198 if (!sdi)
199 return;
200 g_free(sdi->vendor);
201 g_free(sdi->model);
202 g_free(sdi->version);
203 g_free(sdi->serial_num);
204 g_free(sdi->connection_id);
205 sr_usb_dev_inst_free(sdi->conn);
206 kingst_la2016_free_devc(sdi->priv);
207}
208
209/* Convenience. Open a USB device (including claiming an interface). */
210static int la2016_open_usb(struct sr_usb_dev_inst *usb,
211 libusb_device *dev, gboolean show_message)
212{
213 int ret;
214
215 ret = libusb_open(dev, &usb->devhdl);
216 if (ret != 0) {
217 if (show_message) {
218 sr_err("Cannot open device: %s.",
219 libusb_error_name(ret));
220 }
221 return SR_ERR_IO;
222 }
223
224 if (usb->address == 0xff) {
225 /*
226 * First encounter after firmware upload.
227 * Grab current address after enumeration.
228 */
229 usb->address = libusb_get_device_address(dev);
230 }
231
232 ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
233 if (ret == LIBUSB_ERROR_BUSY) {
234 sr_err("Cannot claim USB interface. Another program or driver using it?");
235 return SR_ERR_IO;
236 } else if (ret == LIBUSB_ERROR_NO_DEVICE) {
237 sr_err("Device has been disconnected.");
238 return SR_ERR_IO;
239 } else if (ret != 0) {
240 sr_err("Cannot claim USB interface: %s.",
241 libusb_error_name(ret));
242 return SR_ERR_IO;
243 }
244
245 return SR_OK;
246}
247
248/* Convenience. Close an opened USB device (and release the interface). */
249static void la2016_close_usb(struct sr_usb_dev_inst *usb)
250{
251
252 if (!usb)
253 return;
254
255 if (usb->devhdl) {
256 libusb_release_interface(usb->devhdl, USB_INTERFACE);
257 libusb_close(usb->devhdl);
258 usb->devhdl = NULL;
259 }
260}
261
262/* Communicate to an USB device to identify the Kingst LA model. */
263static int la2016_identify_read(struct sr_dev_inst *sdi,
264 struct sr_usb_dev_inst *usb, libusb_device *dev,
265 gboolean show_message)
266{
267 int ret;
268
269 ret = la2016_open_usb(usb, dev, show_message);
270 if (ret != SR_OK) {
271 if (show_message)
272 sr_err("Cannot communicate to MCU firmware.");
273 return ret;
274 }
6d53e949
GS
275
276 /*
277 * Also complete the hardware configuration (FPGA bitstream)
278 * when MCU firmware communication became operational. Either
279 * failure is considered fatal when probing for the device.
280 */
d466f61c 281 ret = la2016_identify_device(sdi, show_message);
6d53e949
GS
282 if (ret == SR_OK) {
283 ret = la2016_init_hardware(sdi);
284 }
285
d466f61c
GS
286 la2016_close_usb(usb);
287
288 return ret;
289}
290
291/* Find given conn_id in another USB enum. Identify Kingst LA model. */
292static int la2016_identify_enum(struct sr_dev_inst *sdi)
293{
294 struct sr_dev_driver *di;
295 struct drv_context *drvc;
296 struct sr_context *ctx;
297 libusb_device **devlist, *dev;
298 struct libusb_device_descriptor des;
299 int ret, id_ret;
300 size_t device_count, dev_idx;
301 char conn_id[64];
302
303 di = sdi->driver;
304 drvc = di->context;
305 ctx = drvc->sr_ctx;;
306
307 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
308 if (ret < 0)
309 return SR_ERR_IO;
310 device_count = ret;
311 if (!device_count)
312 return SR_ERR_IO;
313 id_ret = SR_ERR_IO;
314 for (dev_idx = 0; dev_idx < device_count; dev_idx++) {
315 dev = devlist[dev_idx];
316 libusb_get_device_descriptor(dev, &des);
317 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
318 continue;
319 if (des.iProduct != LA2016_IPRODUCT_INDEX)
320 continue;
321 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
322 if (ret < 0)
323 continue;
324 if (strcmp(sdi->connection_id, conn_id) != 0)
325 continue;
326 id_ret = la2016_identify_read(sdi, sdi->conn, dev, FALSE);
327 break;
328 }
329 libusb_free_device_list(devlist, 1);
330
331 return id_ret;
332}
333
334/* Wait for a device to re-appear after firmware upload. */
335static int la2016_identify_wait(struct sr_dev_inst *sdi)
336{
337 struct dev_context *devc;
338 uint64_t reset_done, now, elapsed_ms;
339 int ret;
340
341 devc = sdi->priv;
342
343 sr_info("Waiting for device to reset after firmware upload.");
344 now = g_get_monotonic_time();
345 reset_done = devc->fw_uploaded + RENUM_GONE_DELAY_MS * 1000;
346 if (now < reset_done)
347 g_usleep(reset_done - now);
348 do {
349 now = g_get_monotonic_time();
350 elapsed_ms = (now - devc->fw_uploaded) / 1000;
351 sr_spew("Waited %" PRIu64 "ms.", elapsed_ms);
352 ret = la2016_identify_enum(sdi);
353 if (ret == SR_OK) {
354 devc->fw_uploaded = 0;
355 break;
356 }
357 g_usleep(RENUM_POLL_INTERVAL_MS * 1000);
358 } while (elapsed_ms < RENUM_CHECK_PERIOD_MS);
359 if (ret != SR_OK) {
360 sr_err("Device failed to re-enumerate.");
361 return ret;
362 }
363 sr_info("Device came back after %" PRIi64 "ms.", elapsed_ms);
364
365 return SR_OK;
366}
367
368/*
369 * Open given conn_id from another USB enum. Used by dev_open(). Similar
370 * to, and should be kept in sync with la2016_identify_enum().
371 */
372static int la2016_open_enum(struct sr_dev_inst *sdi)
373{
374 struct sr_dev_driver *di;
375 struct drv_context *drvc;
376 struct sr_context *ctx;
377 libusb_device **devlist, *dev;
378 struct libusb_device_descriptor des;
379 int ret, open_ret;
380 size_t device_count, dev_idx;
381 char conn_id[64];
382
383 di = sdi->driver;
384 drvc = di->context;
385 ctx = drvc->sr_ctx;;
386
387 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
388 if (ret < 0)
389 return SR_ERR_IO;
390 device_count = ret;
391 if (!device_count)
392 return SR_ERR_IO;
393 open_ret = SR_ERR_IO;
394 for (dev_idx = 0; dev_idx < device_count; dev_idx++) {
395 dev = devlist[dev_idx];
396 libusb_get_device_descriptor(dev, &des);
397 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
398 continue;
399 if (des.iProduct != LA2016_IPRODUCT_INDEX)
400 continue;
401 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
402 if (ret < 0)
403 continue;
404 if (strcmp(sdi->connection_id, conn_id) != 0)
405 continue;
406 open_ret = la2016_open_usb(sdi->conn, dev, TRUE);
407 break;
408 }
409 libusb_free_device_list(devlist, 1);
410
411 return open_ret;
412}
413
f2cd2deb
FS
414static GSList *scan(struct sr_dev_driver *di, GSList *options)
415{
416 struct drv_context *drvc;
520a20e9 417 struct sr_context *ctx;
f2cd2deb
FS
418 struct dev_context *devc;
419 struct sr_dev_inst *sdi;
420 struct sr_usb_dev_inst *usb;
421 struct sr_config *src;
422 GSList *l;
d466f61c 423 GSList *devices, *found_devices, *renum_devices;
f2cd2deb
FS
424 GSList *conn_devices;
425 struct libusb_device_descriptor des;
520a20e9
GS
426 libusb_device **devlist, *dev;
427 size_t dev_count, dev_idx, ch_idx;
428 uint8_t bus, addr;
d466f61c 429 uint16_t pid;
f2cd2deb 430 const char *conn;
520a20e9 431 char conn_id[64];
520a20e9 432 int ret;
d466f61c 433 size_t ch_off, ch_max;
331277e0
GS
434 struct sr_channel *ch;
435 struct sr_channel_group *cg;
f2cd2deb
FS
436
437 drvc = di->context;
520a20e9 438 ctx = drvc->sr_ctx;;
f2cd2deb
FS
439
440 conn = NULL;
d466f61c 441 conn_devices = NULL;
f2cd2deb
FS
442 for (l = options; l; l = l->next) {
443 src = l->data;
444 switch (src->key) {
445 case SR_CONF_CONN:
446 conn = g_variant_get_string(src->data, NULL);
447 break;
448 }
449 }
450 if (conn)
520a20e9 451 conn_devices = sr_usb_find(ctx->libusb_ctx, conn);
d466f61c
GS
452 if (conn && !conn_devices) {
453 sr_err("Cannot find the specified connection '%s'.", conn);
454 return NULL;
455 }
f2cd2deb 456
d466f61c
GS
457 /*
458 * Find all LA2016 devices, optionally upload firmware to them.
459 * Defer completion of sdi/devc creation until all (selected)
460 * devices were found in a usable state, and their models got
461 * identified which affect their feature set. It appears that
462 * we cannot communicate to the device within the same USB enum
463 * cycle, needs another USB enumeration after firmware upload.
464 */
f2cd2deb 465 devices = NULL;
d466f61c
GS
466 found_devices = NULL;
467 renum_devices = NULL;
520a20e9
GS
468 ret = libusb_get_device_list(ctx->libusb_ctx, &devlist);
469 if (ret < 0) {
470 sr_err("Cannot get device list: %s.", libusb_error_name(ret));
471 return devices;
472 }
473 dev_count = ret;
474 for (dev_idx = 0; dev_idx < dev_count; dev_idx++) {
475 dev = devlist[dev_idx];
476 bus = libusb_get_bus_number(dev);
477 addr = libusb_get_device_address(dev);
d466f61c
GS
478
479 /* Filter by connection when externally specified. */
480 for (l = conn_devices; l; l = l->next) {
481 usb = l->data;
482 if (usb->bus == bus && usb->address == addr)
483 break;
484 }
485 if (conn_devices && !l) {
486 sr_spew("Bus %hhu, addr %hhu do not match specified filter.",
487 bus, addr);
488 continue;
f2cd2deb
FS
489 }
490
d466f61c 491 /* Check USB VID:PID. Get the connection string. */
520a20e9 492 libusb_get_device_descriptor(dev, &des);
d466f61c
GS
493 if (des.idVendor != LA2016_VID || des.idProduct != LA2016_PID)
494 continue;
495 pid = des.idProduct;
520a20e9
GS
496 ret = usb_get_port_path(dev, conn_id, sizeof(conn_id));
497 if (ret < 0)
f2cd2deb 498 continue;
d466f61c
GS
499 sr_dbg("USB enum found %04x:%04x at path %s, %d.%d.",
500 des.idVendor, des.idProduct, conn_id, bus, addr);
501 usb = sr_usb_dev_inst_new(bus, addr, NULL);
f2cd2deb 502
520a20e9 503 sdi = g_malloc0(sizeof(*sdi));
d466f61c 504 sdi->driver = di;
f2cd2deb 505 sdi->status = SR_ST_INITIALIZING;
d466f61c 506 sdi->inst_type = SR_INST_USB;
520a20e9 507 sdi->connection_id = g_strdup(conn_id);
d466f61c 508 sdi->conn = usb;
f2cd2deb 509
d466f61c
GS
510 devc = g_malloc0(sizeof(*devc));
511 sdi->priv = devc;
f2cd2deb 512
d466f61c
GS
513 /*
514 * Load MCU firmware if it is currently missing. Which
515 * makes the device disappear and renumerate in USB.
516 * We need to come back another time to communicate to
517 * this device.
518 */
519 devc->fw_uploaded = 0;
520 if (des.iProduct != LA2016_IPRODUCT_INDEX) {
521 sr_info("Uploading MCU firmware to '%s'.", conn_id);
522 ret = la2016_upload_firmware(sdi, ctx, dev, pid);
520a20e9 523 if (ret != SR_OK) {
91f73872 524 sr_err("MCU firmware upload failed.");
d466f61c 525 kingst_la2016_free_sdi(sdi);
f2cd2deb
FS
526 continue;
527 }
d466f61c
GS
528 devc->fw_uploaded = g_get_monotonic_time();
529 usb->address = 0xff;
530 renum_devices = g_slist_append(renum_devices, sdi);
531 continue;
f2cd2deb
FS
532 }
533
d466f61c
GS
534 /*
535 * Communicate to the MCU firmware to access EEPROM data
536 * which lets us identify the device type. Then stop, to
537 * share remaining sdi/devc creation with those devices
538 * which had their MCU firmware uploaded above and which
539 * get revisited later.
540 */
541 ret = la2016_identify_read(sdi, usb, dev, TRUE);
542 if (ret != SR_OK || !devc->model) {
543 sr_err("Unknown or unsupported device type.");
544 kingst_la2016_free_sdi(sdi);
545 continue;
546 }
547 found_devices = g_slist_append(found_devices, sdi);
548 }
549 libusb_free_device_list(devlist, 1);
550 g_slist_free_full(conn_devices, sr_usb_dev_inst_free_cb);
f2cd2deb 551
d466f61c
GS
552 /*
553 * Wait for devices to re-appear after firmware upload. Append
554 * the yet unidentified device to the list of found devices, or
555 * release the previously allocated sdi/devc.
556 */
557 for (l = renum_devices; l; l = l->next) {
558 sdi = l->data;
559 devc = sdi->priv;
560 ret = la2016_identify_wait(sdi);
561 if (ret != SR_OK || !devc->model) {
562 sr_dbg("Skipping unusable '%s'.", sdi->connection_id);
563 kingst_la2016_free_sdi(sdi);
564 continue;
520a20e9 565 }
d466f61c
GS
566 found_devices = g_slist_append(found_devices, sdi);
567 }
568 g_slist_free(renum_devices);
f2cd2deb 569
d466f61c
GS
570 /*
571 * All found devices got identified, their type is known here.
572 * Complete the sdi/devc creation. Assign default settings
573 * because the vendor firmware would not let us read back the
574 * previously written configuration.
575 */
576 for (l = found_devices; l; l = l->next) {
577 sdi = l->data;
578 devc = sdi->priv;
579
580 sdi->vendor = g_strdup("Kingst");
581 sdi->model = g_strdup(devc->model->name);
582 ch_off = 0;
583
331277e0 584 /* Create the "Logic" channel group. */
d466f61c
GS
585 ch_max = ARRAY_SIZE(channel_names_logic);
586 if (ch_max > devc->model->channel_count)
587 ch_max = devc->model->channel_count;
331277e0
GS
588 cg = sr_channel_group_new(sdi, "Logic", NULL);
589 devc->cg_logic = cg;
d466f61c 590 for (ch_idx = 0; ch_idx < ch_max; ch_idx++) {
331277e0 591 ch = sr_channel_new(sdi, ch_off,
d466f61c
GS
592 SR_CHANNEL_LOGIC, TRUE,
593 channel_names_logic[ch_idx]);
594 ch_off++;
331277e0
GS
595 cg->channels = g_slist_append(cg->channels, ch);
596 }
597
598 /* Create the "PWMx" channel groups. */
599 ch_max = ARRAY_SIZE(channel_names_pwm);
600 for (ch_idx = 0; ch_idx < ch_max; ch_idx++) {
601 const char *name;
602 name = channel_names_pwm[ch_idx];
603 cg = sr_channel_group_new(sdi, name, NULL);
604 if (!devc->cg_pwm)
605 devc->cg_pwm = cg;
606 ch = sr_channel_new(sdi, ch_off,
607 SR_CHANNEL_ANALOG, FALSE, name);
608 ch_off++;
609 cg->channels = g_slist_append(cg->channels, ch);
d466f61c 610 }
f2cd2deb 611
08a49848
GS
612 /*
613 * Ideally we'd get the previous configuration from the
614 * hardware, but this device is write-only. So we have
615 * to assign a fixed set of initial configuration values.
616 */
a38f0f5e 617 sr_sw_limits_init(&devc->sw_limits);
d8fbfcd9
GS
618 devc->sw_limits.limit_samples = 0;
619 devc->capture_ratio = 50;
edc0b015 620 devc->samplerate = devc->model->samplerate;
9270f8f4 621 devc->threshold_voltage_idx = LOGIC_THRESHOLD_IDX_DFLT;
08a49848
GS
622 if (ARRAY_SIZE(devc->pwm_setting) >= 1) {
623 devc->pwm_setting[0].enabled = FALSE;
624 devc->pwm_setting[0].freq = SR_KHZ(1);
625 devc->pwm_setting[0].duty = 50;
626 }
627 if (ARRAY_SIZE(devc->pwm_setting) >= 2) {
628 devc->pwm_setting[1].enabled = FALSE;
629 devc->pwm_setting[1].freq = SR_KHZ(100);
630 devc->pwm_setting[1].duty = 50;
631 }
f2cd2deb
FS
632
633 sdi->status = SR_ST_INACTIVE;
d466f61c 634 devices = g_slist_append(devices, sdi);
f2cd2deb 635 }
d466f61c 636 g_slist_free(found_devices);
f2cd2deb
FS
637
638 return std_scan_complete(di, devices);
639}
640
f2cd2deb
FS
641static int dev_open(struct sr_dev_inst *sdi)
642{
08a49848 643 struct dev_context *devc;
f2cd2deb 644 int ret;
08a49848
GS
645 size_t ch;
646
647 devc = sdi->priv;
f2cd2deb 648
d466f61c 649 ret = la2016_open_enum(sdi);
f2cd2deb 650 if (ret != SR_OK) {
91f73872 651 sr_err("Cannot open device.");
520a20e9 652 return ret;
f2cd2deb
FS
653 }
654
08a49848
GS
655 /* Send most recent PWM configuration to the device. */
656 for (ch = 0; ch < ARRAY_SIZE(devc->pwm_setting); ch++) {
657 ret = la2016_write_pwm_config(sdi, ch);
658 if (ret != SR_OK)
659 return ret;
6d53e949
GS
660 }
661
f2cd2deb
FS
662 return SR_OK;
663}
664
665static int dev_close(struct sr_dev_inst *sdi)
666{
667 struct sr_usb_dev_inst *usb;
668
669 usb = sdi->conn;
670
671 if (!usb->devhdl)
672 return SR_ERR_BUG;
673
66a24ab5
GS
674 if (WITH_DEINIT_IN_CLOSE)
675 la2016_deinit_hardware(sdi);
f2cd2deb
FS
676
677 sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
678 usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
d466f61c 679 la2016_close_usb(sdi->conn);
f2cd2deb
FS
680
681 return SR_OK;
682}
683
331277e0
GS
684/* Config API helper. Get type and index of a channel group. */
685static int get_cg_index(const struct sr_dev_inst *sdi,
686 const struct sr_channel_group *cg,
687 int *type, size_t *logic, size_t *analog)
688{
689 struct dev_context *devc;
690 GSList *l;
691 size_t idx;
692
693 /* Preset return values. */
694 if (type)
695 *type = 0;
696 if (logic)
697 *logic = 0;
698 if (analog)
699 *analog = 0;
700
701 /* Start categorizing the received cg. */
702 if (!sdi)
703 return SR_ERR_ARG;
704 devc = sdi->priv;
705 if (!cg)
706 return SR_OK;
707 l = sdi->channel_groups;
708
709 /* First sdi->channelgroups item is "Logic". */
710 if (!l)
711 return SR_ERR_BUG;
712 if (cg == l->data) {
713 if (type)
714 *type = SR_CHANNEL_LOGIC;
715 if (logic)
716 *logic = 0;
717 return SR_OK;
718 }
719 l = l->next;
720
721 /* Next sdi->channelgroups items are "PWMx". */
722 idx = 0;
723 while (l && l->data != cg) {
724 idx++;
725 l = l->next;
726 }
727 if (l && idx < ARRAY_SIZE(devc->pwm_setting)) {
728 if (type)
729 *type = SR_CHANNEL_ANALOG;
730 if (analog)
731 *analog = idx;
732 return SR_OK;
733 }
734
735 return SR_ERR_ARG;
736}
737
955ab604
GS
738static int config_get(uint32_t key, GVariant **data,
739 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
740{
741 struct dev_context *devc;
331277e0
GS
742 int ret, cg_type;
743 size_t logic_idx, analog_idx;
744 struct pwm_setting *pwm;
f2cd2deb 745 struct sr_usb_dev_inst *usb;
9270f8f4 746 double voltage, rounded;
f2cd2deb 747
9270f8f4
GS
748 (void)rounded;
749 (void)voltage;
750
f2cd2deb
FS
751 if (!sdi)
752 return SR_ERR_ARG;
753 devc = sdi->priv;
754
331277e0
GS
755 /* Check for types (and index) of channel groups. */
756 ret = get_cg_index(sdi, cg, &cg_type, &logic_idx, &analog_idx);
757 if (cg && ret != SR_OK)
758 return SR_ERR_ARG;
759
760 /* Handle requests for the "Logic" channel group. */
761 if (cg && cg_type == SR_CHANNEL_LOGIC) {
9270f8f4
GS
762 switch (key) {
763#if !WITH_THRESHOLD_DEVCFG
9270f8f4
GS
764 case SR_CONF_VOLTAGE_THRESHOLD:
765 voltage = threshold_voltage(sdi, NULL);
766 *data = std_gvar_tuple_double(voltage, voltage);
767 break;
9270f8f4
GS
768#endif /* WITH_THRESHOLD_DEVCFG */
769 default:
770 return SR_ERR_NA;
771 }
772 return SR_OK;
331277e0
GS
773 }
774
775 /* Handle requests for the "PWMx" channel groups. */
776 if (cg && cg_type == SR_CHANNEL_ANALOG) {
777 pwm = &devc->pwm_setting[analog_idx];
778 switch (key) {
779 case SR_CONF_ENABLED:
780 *data = g_variant_new_boolean(pwm->enabled);
781 break;
782 case SR_CONF_OUTPUT_FREQUENCY:
783 *data = g_variant_new_double(pwm->freq);
784 break;
785 case SR_CONF_DUTY_CYCLE:
786 *data = g_variant_new_double(pwm->duty);
787 break;
788 default:
789 return SR_ERR_NA;
790 }
791 return SR_OK;
792 }
793
f2cd2deb
FS
794 switch (key) {
795 case SR_CONF_CONN:
f2cd2deb 796 usb = sdi->conn;
f2cd2deb
FS
797 *data = g_variant_new_printf("%d.%d", usb->bus, usb->address);
798 break;
799 case SR_CONF_SAMPLERATE:
edc0b015 800 *data = g_variant_new_uint64(devc->samplerate);
f2cd2deb
FS
801 break;
802 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
803 case SR_CONF_LIMIT_MSEC:
804 return sr_sw_limits_config_get(&devc->sw_limits, key, data);
f2cd2deb
FS
805 case SR_CONF_CAPTURE_RATIO:
806 *data = g_variant_new_uint64(devc->capture_ratio);
807 break;
9270f8f4 808#if WITH_THRESHOLD_DEVCFG
9270f8f4
GS
809 case SR_CONF_VOLTAGE_THRESHOLD:
810 voltage = threshold_voltage(sdi, NULL);
811 *data = std_gvar_tuple_double(voltage, voltage);
812 break;
9270f8f4 813#endif /* WITH_THRESHOLD_DEVCFG */
f2cd2deb
FS
814 default:
815 return SR_ERR_NA;
816 }
817
818 return SR_OK;
819}
820
955ab604
GS
821static int config_set(uint32_t key, GVariant *data,
822 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
823{
824 struct dev_context *devc;
331277e0
GS
825 int ret, cg_type;
826 size_t logic_idx, analog_idx;
827 struct pwm_setting *pwm;
c35baf6e 828 double value_f;
f2cd2deb
FS
829 int idx;
830
f2cd2deb
FS
831 devc = sdi->priv;
832
331277e0
GS
833 /* Check for types (and index) of channel groups. */
834 ret = get_cg_index(sdi, cg, &cg_type, &logic_idx, &analog_idx);
835 if (cg && ret != SR_OK)
836 return SR_ERR_ARG;
837
838 /* Handle requests for the "Logic" channel group. */
839 if (cg && cg_type == SR_CHANNEL_LOGIC) {
9270f8f4
GS
840 switch (key) {
841#if !WITH_THRESHOLD_DEVCFG
9270f8f4
GS
842 case SR_CONF_LOGIC_THRESHOLD:
843 idx = std_double_tuple_idx(data,
844 ARRAY_AND_SIZE(threshold_ranges));
845 if (idx < 0)
846 return SR_ERR_ARG;
847 devc->threshold_voltage_idx = idx;
848 break;
9270f8f4
GS
849#endif /* WITH_THRESHOLD_DEVCFG */
850 default:
851 return SR_ERR_NA;
852 }
853 return SR_OK;
331277e0
GS
854 }
855
856 /* Handle requests for the "PWMx" channel groups. */
857 if (cg && cg_type == SR_CHANNEL_ANALOG) {
858 pwm = &devc->pwm_setting[analog_idx];
859 switch (key) {
860 case SR_CONF_ENABLED:
861 pwm->enabled = g_variant_get_boolean(data);
862 ret = la2016_write_pwm_config(sdi, analog_idx);
863 if (ret != SR_OK)
864 return ret;
865 break;
866 case SR_CONF_OUTPUT_FREQUENCY:
c35baf6e
GS
867 value_f = g_variant_get_double(data);
868 if (value_f <= 0.0 || value_f > MAX_PWM_FREQ)
869 return SR_ERR_ARG;
870 pwm->freq = value_f;
331277e0
GS
871 ret = la2016_write_pwm_config(sdi, analog_idx);
872 if (ret != SR_OK)
873 return ret;
874 break;
875 case SR_CONF_DUTY_CYCLE:
c35baf6e
GS
876 value_f = g_variant_get_double(data);
877 if (value_f <= 0.0 || value_f > 100.0)
878 return SR_ERR_ARG;
879 pwm->duty = value_f;
331277e0
GS
880 ret = la2016_write_pwm_config(sdi, analog_idx);
881 if (ret != SR_OK)
882 return ret;
883 break;
884 default:
885 return SR_ERR_NA;
886 }
887 return SR_OK;
888 }
889
f2cd2deb
FS
890 switch (key) {
891 case SR_CONF_SAMPLERATE:
edc0b015 892 devc->samplerate = g_variant_get_uint64(data);
f2cd2deb
FS
893 break;
894 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
895 case SR_CONF_LIMIT_MSEC:
896 return sr_sw_limits_config_set(&devc->sw_limits, key, data);
f2cd2deb
FS
897 case SR_CONF_CAPTURE_RATIO:
898 devc->capture_ratio = g_variant_get_uint64(data);
899 break;
9270f8f4 900#if WITH_THRESHOLD_DEVCFG
9270f8f4
GS
901 case SR_CONF_VOLTAGE_THRESHOLD:
902 idx = std_double_tuple_idx(data,
903 ARRAY_AND_SIZE(threshold_ranges));
904 if (idx < 0)
905 return SR_ERR_ARG;
906 devc->threshold_voltage_idx = idx;
907 break;
9270f8f4 908#endif /* WITH_THRESHOLD_DEVCFG */
f2cd2deb
FS
909 default:
910 return SR_ERR_NA;
911 }
912
913 return SR_OK;
914}
915
955ab604
GS
916static int config_list(uint32_t key, GVariant **data,
917 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb 918{
8b172e78 919 struct dev_context *devc;
331277e0
GS
920 int ret, cg_type;
921 size_t logic_idx, analog_idx;
8b172e78 922
a38f0f5e
GS
923 devc = sdi ? sdi->priv : NULL;
924
331277e0
GS
925 /* Check for types (and index) of channel groups. */
926 ret = get_cg_index(sdi, cg, &cg_type, &logic_idx, &analog_idx);
927 if (cg && ret != SR_OK)
928 return SR_ERR_ARG;
929
930 /* Handle requests for the "Logic" channel group. */
931 if (cg && cg_type == SR_CHANNEL_LOGIC) {
9270f8f4
GS
932 switch (key) {
933 case SR_CONF_DEVICE_OPTIONS:
934 if (ARRAY_SIZE(devopts_cg_logic) == 0)
935 return SR_ERR_NA;
936 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
937 devopts_cg_logic, ARRAY_SIZE(devopts_cg_logic),
938 sizeof(devopts_cg_logic[0]));
939 break;
940#if !WITH_THRESHOLD_DEVCFG
9270f8f4
GS
941 case SR_CONF_VOLTAGE_THRESHOLD:
942 *data = std_gvar_thresholds(ARRAY_AND_SIZE(threshold_ranges));
943 break;
9270f8f4
GS
944#endif /* WITH_THRESHOLD_DEVCFG */
945 default:
946 return SR_ERR_NA;
947 }
948 return SR_OK;
331277e0
GS
949 }
950
951 /* Handle requests for the "PWMx" channel groups. */
952 if (cg && cg_type == SR_CHANNEL_ANALOG) {
953 switch (key) {
954 case SR_CONF_DEVICE_OPTIONS:
955 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
956 devopts_cg_pwm, ARRAY_SIZE(devopts_cg_pwm),
957 sizeof(devopts_cg_pwm[0]));
958 break;
959 default:
960 return SR_ERR_NA;
961 }
962 return SR_OK;
963 }
964
f2cd2deb
FS
965 switch (key) {
966 case SR_CONF_SCAN_OPTIONS:
967 case SR_CONF_DEVICE_OPTIONS:
411ad77c
GS
968 return STD_CONFIG_LIST(key, data, sdi, cg,
969 scanopts, drvopts, devopts);
f2cd2deb 970 case SR_CONF_SAMPLERATE:
fb28e72d
MW
971 if (!sdi)
972 return SR_ERR_ARG;
d466f61c 973 if (devc->model->samplerate == SR_MHZ(500))
330853ba 974 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_500mhz));
d466f61c 975 else if (devc->model->samplerate == SR_MHZ(200))
330853ba
GS
976 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_200mhz));
977 else
978 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_100mhz));
f2cd2deb
FS
979 break;
980 case SR_CONF_LIMIT_SAMPLES:
d8fbfcd9 981 *data = std_gvar_tuple_u64(0, LA2016_NUM_SAMPLES_MAX);
f2cd2deb 982 break;
9270f8f4 983#if WITH_THRESHOLD_DEVCFG
9270f8f4
GS
984 case SR_CONF_VOLTAGE_THRESHOLD:
985 *data = std_gvar_thresholds(ARRAY_AND_SIZE(threshold_ranges));
986 break;
9270f8f4 987#endif /* WITH_THRESHOLD_DEVCFG */
f2cd2deb
FS
988 case SR_CONF_TRIGGER_MATCH:
989 *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
990 break;
f2cd2deb
FS
991 default:
992 return SR_ERR_NA;
993 }
994
995 return SR_OK;
996}
997
f2cd2deb
FS
998static int dev_acquisition_start(const struct sr_dev_inst *sdi)
999{
1000 struct sr_dev_driver *di;
1001 struct drv_context *drvc;
520a20e9 1002 struct sr_context *ctx;
f2cd2deb 1003 struct dev_context *devc;
9270f8f4 1004 double voltage;
f2cd2deb
FS
1005 int ret;
1006
1007 di = sdi->driver;
1008 drvc = di->context;
520a20e9 1009 ctx = drvc->sr_ctx;;
f2cd2deb
FS
1010 devc = sdi->priv;
1011
a38f0f5e
GS
1012 if (!devc->feed_queue) {
1013 devc->feed_queue = feed_queue_logic_alloc(sdi,
1014 LA2016_CONVBUFFER_SIZE, sizeof(uint16_t));
1015 if (!devc->feed_queue) {
1016 sr_err("Cannot allocate buffer for session feed.");
1017 return SR_ERR_MALLOC;
1018 }
f2cd2deb
FS
1019 }
1020
a38f0f5e
GS
1021 sr_sw_limits_acquisition_start(&devc->sw_limits);
1022
9270f8f4
GS
1023 voltage = threshold_voltage(sdi, NULL);
1024 ret = la2016_setup_acquisition(sdi, voltage);
411ad77c 1025 if (ret != SR_OK) {
a38f0f5e
GS
1026 feed_queue_logic_free(devc->feed_queue);
1027 devc->feed_queue = NULL;
f2cd2deb
FS
1028 return ret;
1029 }
1030
411ad77c
GS
1031 ret = la2016_start_acquisition(sdi);
1032 if (ret != SR_OK) {
3ebc1cb2 1033 la2016_abort_acquisition(sdi);
a38f0f5e
GS
1034 feed_queue_logic_free(devc->feed_queue);
1035 devc->feed_queue = NULL;
f2cd2deb
FS
1036 return ret;
1037 }
1038
cf057ac4 1039 devc->completion_seen = FALSE;
520a20e9 1040 usb_source_add(sdi->session, ctx, 50,
388438e4 1041 la2016_receive_data, (void *)sdi);
f2cd2deb
FS
1042
1043 std_session_send_df_header(sdi);
1044
1045 return SR_OK;
1046}
1047
1048static int dev_acquisition_stop(struct sr_dev_inst *sdi)
1049{
1050 int ret;
1051
1052 ret = la2016_abort_acquisition(sdi);
f2cd2deb
FS
1053
1054 return ret;
1055}
1056
1057static struct sr_dev_driver kingst_la2016_driver_info = {
1058 .name = "kingst-la2016",
1059 .longname = "Kingst LA2016",
1060 .api_version = 1,
1061 .init = std_init,
1062 .cleanup = std_cleanup,
1063 .scan = scan,
1064 .dev_list = std_dev_list,
1065 .dev_clear = std_dev_clear,
1066 .config_get = config_get,
1067 .config_set = config_set,
1068 .config_list = config_list,
1069 .dev_open = dev_open,
1070 .dev_close = dev_close,
1071 .dev_acquisition_start = dev_acquisition_start,
1072 .dev_acquisition_stop = dev_acquisition_stop,
1073 .context = NULL,
1074};
1075SR_REGISTER_DEV_DRIVER(kingst_la2016_driver_info);