]> sigrok.org Git - libsigrok.git/blame - src/hardware/kingst-la2016/api.c
kingst-la2016: remove complex logic threshold voltage support
[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;
620 devc->cur_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
6d53e949 674 la2016_deinit_hardware(sdi);
f2cd2deb
FS
675
676 sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
677 usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
d466f61c 678 la2016_close_usb(sdi->conn);
f2cd2deb
FS
679
680 return SR_OK;
681}
682
331277e0
GS
683/* Config API helper. Get type and index of a channel group. */
684static int get_cg_index(const struct sr_dev_inst *sdi,
685 const struct sr_channel_group *cg,
686 int *type, size_t *logic, size_t *analog)
687{
688 struct dev_context *devc;
689 GSList *l;
690 size_t idx;
691
692 /* Preset return values. */
693 if (type)
694 *type = 0;
695 if (logic)
696 *logic = 0;
697 if (analog)
698 *analog = 0;
699
700 /* Start categorizing the received cg. */
701 if (!sdi)
702 return SR_ERR_ARG;
703 devc = sdi->priv;
704 if (!cg)
705 return SR_OK;
706 l = sdi->channel_groups;
707
708 /* First sdi->channelgroups item is "Logic". */
709 if (!l)
710 return SR_ERR_BUG;
711 if (cg == l->data) {
712 if (type)
713 *type = SR_CHANNEL_LOGIC;
714 if (logic)
715 *logic = 0;
716 return SR_OK;
717 }
718 l = l->next;
719
720 /* Next sdi->channelgroups items are "PWMx". */
721 idx = 0;
722 while (l && l->data != cg) {
723 idx++;
724 l = l->next;
725 }
726 if (l && idx < ARRAY_SIZE(devc->pwm_setting)) {
727 if (type)
728 *type = SR_CHANNEL_ANALOG;
729 if (analog)
730 *analog = idx;
731 return SR_OK;
732 }
733
734 return SR_ERR_ARG;
735}
736
955ab604
GS
737static int config_get(uint32_t key, GVariant **data,
738 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
739{
740 struct dev_context *devc;
331277e0
GS
741 int ret, cg_type;
742 size_t logic_idx, analog_idx;
743 struct pwm_setting *pwm;
f2cd2deb 744 struct sr_usb_dev_inst *usb;
9270f8f4 745 double voltage, rounded;
f2cd2deb 746
9270f8f4
GS
747 (void)rounded;
748 (void)voltage;
749
f2cd2deb
FS
750 if (!sdi)
751 return SR_ERR_ARG;
752 devc = sdi->priv;
753
331277e0
GS
754 /* Check for types (and index) of channel groups. */
755 ret = get_cg_index(sdi, cg, &cg_type, &logic_idx, &analog_idx);
756 if (cg && ret != SR_OK)
757 return SR_ERR_ARG;
758
759 /* Handle requests for the "Logic" channel group. */
760 if (cg && cg_type == SR_CHANNEL_LOGIC) {
9270f8f4
GS
761 switch (key) {
762#if !WITH_THRESHOLD_DEVCFG
9270f8f4
GS
763 case SR_CONF_VOLTAGE_THRESHOLD:
764 voltage = threshold_voltage(sdi, NULL);
765 *data = std_gvar_tuple_double(voltage, voltage);
766 break;
9270f8f4
GS
767#endif /* WITH_THRESHOLD_DEVCFG */
768 default:
769 return SR_ERR_NA;
770 }
771 return SR_OK;
331277e0
GS
772 }
773
774 /* Handle requests for the "PWMx" channel groups. */
775 if (cg && cg_type == SR_CHANNEL_ANALOG) {
776 pwm = &devc->pwm_setting[analog_idx];
777 switch (key) {
778 case SR_CONF_ENABLED:
779 *data = g_variant_new_boolean(pwm->enabled);
780 break;
781 case SR_CONF_OUTPUT_FREQUENCY:
782 *data = g_variant_new_double(pwm->freq);
783 break;
784 case SR_CONF_DUTY_CYCLE:
785 *data = g_variant_new_double(pwm->duty);
786 break;
787 default:
788 return SR_ERR_NA;
789 }
790 return SR_OK;
791 }
792
f2cd2deb
FS
793 switch (key) {
794 case SR_CONF_CONN:
f2cd2deb 795 usb = sdi->conn;
f2cd2deb
FS
796 *data = g_variant_new_printf("%d.%d", usb->bus, usb->address);
797 break;
798 case SR_CONF_SAMPLERATE:
799 *data = g_variant_new_uint64(devc->cur_samplerate);
800 break;
801 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
802 case SR_CONF_LIMIT_MSEC:
803 return sr_sw_limits_config_get(&devc->sw_limits, key, data);
f2cd2deb
FS
804 case SR_CONF_CAPTURE_RATIO:
805 *data = g_variant_new_uint64(devc->capture_ratio);
806 break;
9270f8f4 807#if WITH_THRESHOLD_DEVCFG
9270f8f4
GS
808 case SR_CONF_VOLTAGE_THRESHOLD:
809 voltage = threshold_voltage(sdi, NULL);
810 *data = std_gvar_tuple_double(voltage, voltage);
811 break;
9270f8f4 812#endif /* WITH_THRESHOLD_DEVCFG */
f2cd2deb
FS
813 default:
814 return SR_ERR_NA;
815 }
816
817 return SR_OK;
818}
819
955ab604
GS
820static int config_set(uint32_t key, GVariant *data,
821 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb
FS
822{
823 struct dev_context *devc;
331277e0
GS
824 int ret, cg_type;
825 size_t logic_idx, analog_idx;
826 struct pwm_setting *pwm;
c35baf6e 827 double value_f;
f2cd2deb
FS
828 int idx;
829
f2cd2deb
FS
830 devc = sdi->priv;
831
331277e0
GS
832 /* Check for types (and index) of channel groups. */
833 ret = get_cg_index(sdi, cg, &cg_type, &logic_idx, &analog_idx);
834 if (cg && ret != SR_OK)
835 return SR_ERR_ARG;
836
837 /* Handle requests for the "Logic" channel group. */
838 if (cg && cg_type == SR_CHANNEL_LOGIC) {
9270f8f4
GS
839 switch (key) {
840#if !WITH_THRESHOLD_DEVCFG
9270f8f4
GS
841 case SR_CONF_LOGIC_THRESHOLD:
842 idx = std_double_tuple_idx(data,
843 ARRAY_AND_SIZE(threshold_ranges));
844 if (idx < 0)
845 return SR_ERR_ARG;
846 devc->threshold_voltage_idx = idx;
847 break;
9270f8f4
GS
848#endif /* WITH_THRESHOLD_DEVCFG */
849 default:
850 return SR_ERR_NA;
851 }
852 return SR_OK;
331277e0
GS
853 }
854
855 /* Handle requests for the "PWMx" channel groups. */
856 if (cg && cg_type == SR_CHANNEL_ANALOG) {
857 pwm = &devc->pwm_setting[analog_idx];
858 switch (key) {
859 case SR_CONF_ENABLED:
860 pwm->enabled = g_variant_get_boolean(data);
861 ret = la2016_write_pwm_config(sdi, analog_idx);
862 if (ret != SR_OK)
863 return ret;
864 break;
865 case SR_CONF_OUTPUT_FREQUENCY:
c35baf6e
GS
866 value_f = g_variant_get_double(data);
867 if (value_f <= 0.0 || value_f > MAX_PWM_FREQ)
868 return SR_ERR_ARG;
869 pwm->freq = value_f;
331277e0
GS
870 ret = la2016_write_pwm_config(sdi, analog_idx);
871 if (ret != SR_OK)
872 return ret;
873 break;
874 case SR_CONF_DUTY_CYCLE:
c35baf6e
GS
875 value_f = g_variant_get_double(data);
876 if (value_f <= 0.0 || value_f > 100.0)
877 return SR_ERR_ARG;
878 pwm->duty = value_f;
331277e0
GS
879 ret = la2016_write_pwm_config(sdi, analog_idx);
880 if (ret != SR_OK)
881 return ret;
882 break;
883 default:
884 return SR_ERR_NA;
885 }
886 return SR_OK;
887 }
888
f2cd2deb
FS
889 switch (key) {
890 case SR_CONF_SAMPLERATE:
891 devc->cur_samplerate = g_variant_get_uint64(data);
892 break;
893 case SR_CONF_LIMIT_SAMPLES:
a38f0f5e
GS
894 case SR_CONF_LIMIT_MSEC:
895 return sr_sw_limits_config_set(&devc->sw_limits, key, data);
f2cd2deb
FS
896 case SR_CONF_CAPTURE_RATIO:
897 devc->capture_ratio = g_variant_get_uint64(data);
898 break;
9270f8f4 899#if WITH_THRESHOLD_DEVCFG
9270f8f4
GS
900 case SR_CONF_VOLTAGE_THRESHOLD:
901 idx = std_double_tuple_idx(data,
902 ARRAY_AND_SIZE(threshold_ranges));
903 if (idx < 0)
904 return SR_ERR_ARG;
905 devc->threshold_voltage_idx = idx;
906 break;
9270f8f4 907#endif /* WITH_THRESHOLD_DEVCFG */
f2cd2deb
FS
908 default:
909 return SR_ERR_NA;
910 }
911
912 return SR_OK;
913}
914
955ab604
GS
915static int config_list(uint32_t key, GVariant **data,
916 const struct sr_dev_inst *sdi, const struct sr_channel_group *cg)
f2cd2deb 917{
8b172e78 918 struct dev_context *devc;
331277e0
GS
919 int ret, cg_type;
920 size_t logic_idx, analog_idx;
8b172e78 921
a38f0f5e
GS
922 devc = sdi ? sdi->priv : NULL;
923
331277e0
GS
924 /* Check for types (and index) of channel groups. */
925 ret = get_cg_index(sdi, cg, &cg_type, &logic_idx, &analog_idx);
926 if (cg && ret != SR_OK)
927 return SR_ERR_ARG;
928
929 /* Handle requests for the "Logic" channel group. */
930 if (cg && cg_type == SR_CHANNEL_LOGIC) {
9270f8f4
GS
931 switch (key) {
932 case SR_CONF_DEVICE_OPTIONS:
933 if (ARRAY_SIZE(devopts_cg_logic) == 0)
934 return SR_ERR_NA;
935 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
936 devopts_cg_logic, ARRAY_SIZE(devopts_cg_logic),
937 sizeof(devopts_cg_logic[0]));
938 break;
939#if !WITH_THRESHOLD_DEVCFG
9270f8f4
GS
940 case SR_CONF_VOLTAGE_THRESHOLD:
941 *data = std_gvar_thresholds(ARRAY_AND_SIZE(threshold_ranges));
942 break;
9270f8f4
GS
943#endif /* WITH_THRESHOLD_DEVCFG */
944 default:
945 return SR_ERR_NA;
946 }
947 return SR_OK;
331277e0
GS
948 }
949
950 /* Handle requests for the "PWMx" channel groups. */
951 if (cg && cg_type == SR_CHANNEL_ANALOG) {
952 switch (key) {
953 case SR_CONF_DEVICE_OPTIONS:
954 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
955 devopts_cg_pwm, ARRAY_SIZE(devopts_cg_pwm),
956 sizeof(devopts_cg_pwm[0]));
957 break;
958 default:
959 return SR_ERR_NA;
960 }
961 return SR_OK;
962 }
963
f2cd2deb
FS
964 switch (key) {
965 case SR_CONF_SCAN_OPTIONS:
966 case SR_CONF_DEVICE_OPTIONS:
411ad77c
GS
967 return STD_CONFIG_LIST(key, data, sdi, cg,
968 scanopts, drvopts, devopts);
f2cd2deb 969 case SR_CONF_SAMPLERATE:
fb28e72d
MW
970 if (!sdi)
971 return SR_ERR_ARG;
d466f61c 972 if (devc->model->samplerate == SR_MHZ(500))
330853ba 973 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_500mhz));
d466f61c 974 else if (devc->model->samplerate == SR_MHZ(200))
330853ba
GS
975 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_200mhz));
976 else
977 *data = std_gvar_samplerates(ARRAY_AND_SIZE(rates_100mhz));
f2cd2deb
FS
978 break;
979 case SR_CONF_LIMIT_SAMPLES:
d8fbfcd9 980 *data = std_gvar_tuple_u64(0, LA2016_NUM_SAMPLES_MAX);
f2cd2deb 981 break;
9270f8f4 982#if WITH_THRESHOLD_DEVCFG
9270f8f4
GS
983 case SR_CONF_VOLTAGE_THRESHOLD:
984 *data = std_gvar_thresholds(ARRAY_AND_SIZE(threshold_ranges));
985 break;
9270f8f4 986#endif /* WITH_THRESHOLD_DEVCFG */
f2cd2deb
FS
987 case SR_CONF_TRIGGER_MATCH:
988 *data = std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
989 break;
f2cd2deb
FS
990 default:
991 return SR_ERR_NA;
992 }
993
994 return SR_OK;
995}
996
f2cd2deb
FS
997static int dev_acquisition_start(const struct sr_dev_inst *sdi)
998{
999 struct sr_dev_driver *di;
1000 struct drv_context *drvc;
520a20e9 1001 struct sr_context *ctx;
f2cd2deb 1002 struct dev_context *devc;
9270f8f4 1003 double voltage;
f2cd2deb
FS
1004 int ret;
1005
1006 di = sdi->driver;
1007 drvc = di->context;
520a20e9 1008 ctx = drvc->sr_ctx;;
f2cd2deb
FS
1009 devc = sdi->priv;
1010
a38f0f5e
GS
1011 if (!devc->feed_queue) {
1012 devc->feed_queue = feed_queue_logic_alloc(sdi,
1013 LA2016_CONVBUFFER_SIZE, sizeof(uint16_t));
1014 if (!devc->feed_queue) {
1015 sr_err("Cannot allocate buffer for session feed.");
1016 return SR_ERR_MALLOC;
1017 }
f2cd2deb
FS
1018 }
1019
a38f0f5e
GS
1020 sr_sw_limits_acquisition_start(&devc->sw_limits);
1021
9270f8f4
GS
1022 voltage = threshold_voltage(sdi, NULL);
1023 ret = la2016_setup_acquisition(sdi, voltage);
411ad77c 1024 if (ret != SR_OK) {
a38f0f5e
GS
1025 feed_queue_logic_free(devc->feed_queue);
1026 devc->feed_queue = NULL;
f2cd2deb
FS
1027 return ret;
1028 }
1029
411ad77c
GS
1030 ret = la2016_start_acquisition(sdi);
1031 if (ret != SR_OK) {
3ebc1cb2 1032 la2016_abort_acquisition(sdi);
a38f0f5e
GS
1033 feed_queue_logic_free(devc->feed_queue);
1034 devc->feed_queue = NULL;
f2cd2deb
FS
1035 return ret;
1036 }
1037
cf057ac4 1038 devc->completion_seen = FALSE;
520a20e9 1039 usb_source_add(sdi->session, ctx, 50,
388438e4 1040 la2016_receive_data, (void *)sdi);
f2cd2deb
FS
1041
1042 std_session_send_df_header(sdi);
1043
1044 return SR_OK;
1045}
1046
1047static int dev_acquisition_stop(struct sr_dev_inst *sdi)
1048{
1049 int ret;
1050
1051 ret = la2016_abort_acquisition(sdi);
f2cd2deb
FS
1052
1053 return ret;
1054}
1055
1056static struct sr_dev_driver kingst_la2016_driver_info = {
1057 .name = "kingst-la2016",
1058 .longname = "Kingst LA2016",
1059 .api_version = 1,
1060 .init = std_init,
1061 .cleanup = std_cleanup,
1062 .scan = scan,
1063 .dev_list = std_dev_list,
1064 .dev_clear = std_dev_clear,
1065 .config_get = config_get,
1066 .config_set = config_set,
1067 .config_list = config_list,
1068 .dev_open = dev_open,
1069 .dev_close = dev_close,
1070 .dev_acquisition_start = dev_acquisition_start,
1071 .dev_acquisition_stop = dev_acquisition_stop,
1072 .context = NULL,
1073};
1074SR_REGISTER_DEV_DRIVER(kingst_la2016_driver_info);