]> sigrok.org Git - libsigrok.git/blame - hardware/zeroplus-logic-cube/zeroplus.c
ols: use new driver info_get() API call
[libsigrok.git] / hardware / zeroplus-logic-cube / zeroplus.c
CommitLineData
a1bb33af
UH
1/*
2 * This file is part of the sigrok project.
3 *
c73d2ea4 4 * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
a1bb33af
UH
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
c31e9ef4 22#include <string.h>
a1bb33af
UH
23#include <sys/time.h>
24#include <inttypes.h>
25#include <glib.h>
26#include <libusb.h>
c31e9ef4 27#include "config.h"
45c59c8b
BV
28#include "libsigrok.h"
29#include "libsigrok-internal.h"
a1bb33af
UH
30#include "analyzer.h"
31
fed16f06 32#define USB_VENDOR 0x0c12
8fdecced
UH
33
34#define VENDOR_NAME "ZEROPLUS"
35#define MODEL_NAME "Logic Cube LAP-C"
36#define MODEL_VERSION NULL
a1bb33af 37
6752905e 38#define NUM_PROBES 16
a1bb33af
UH
39#define USB_INTERFACE 0
40#define USB_CONFIGURATION 1
41#define NUM_TRIGGER_STAGES 4
42#define TRIGGER_TYPES "01"
43
fed16f06 44#define PACKET_SIZE 2048 /* ?? */
a1bb33af
UH
45
46typedef struct {
47 unsigned short pid;
48 char model_name[64];
49 unsigned int channels;
fed16f06 50 unsigned int sample_depth; /* In Ksamples/channel */
a1bb33af
UH
51 unsigned int max_sampling_freq;
52} model_t;
53
fed16f06
UH
54/*
55 * Note -- 16032, 16064 and 16128 *usually* -- but not always -- have the
56 * same 128K sample depth.
57 */
29cbfeaf 58static model_t zeroplus_models[] = {
a1bb33af
UH
59 {0x7009, "LAP-C(16064)", 16, 64, 100},
60 {0x700A, "LAP-C(16128)", 16, 128, 200},
61 {0x700B, "LAP-C(32128)", 32, 128, 200},
62 {0x700C, "LAP-C(321000)", 32, 1024, 200},
63 {0x700D, "LAP-C(322000)", 32, 2048, 200},
64 {0x700E, "LAP-C(16032)", 16, 32, 100},
65 {0x7016, "LAP-C(162000)", 16, 2048, 200},
66};
67
915f7cc8 68static const int hwcaps[] = {
5a2326a7
UH
69 SR_HWCAP_LOGIC_ANALYZER,
70 SR_HWCAP_SAMPLERATE,
71 SR_HWCAP_PROBECONFIG,
72 SR_HWCAP_CAPTURE_RATIO,
a1bb33af 73
fed16f06 74 /* These are really implemented in the driver, not the hardware. */
5a2326a7 75 SR_HWCAP_LIMIT_SAMPLES,
fed16f06 76 0,
a1bb33af
UH
77};
78
d261dbbf
UH
79/*
80 * ZEROPLUS LAP-C (16032) numbers the 16 probes A0-A7 and B0-B7.
81 * We currently ignore other untested/unsupported devices here.
82 */
6752905e 83static const char *probe_names[NUM_PROBES + 1] = {
d261dbbf
UH
84 "A0",
85 "A1",
86 "A2",
87 "A3",
88 "A4",
89 "A5",
90 "A6",
91 "A7",
92 "B0",
93 "B1",
94 "B2",
95 "B3",
96 "B4",
97 "B5",
98 "B6",
99 "B7",
464d12c7
KS
100 NULL,
101};
102
e7eb703f 103/* List of struct sr_dev_inst, maintained by dev_open()/dev_close(). */
32756547
BV
104SR_PRIV struct sr_dev_driver zeroplus_logic_cube_driver_info;
105static struct sr_dev_driver *zdi = &zeroplus_logic_cube_driver_info;
a1bb33af
UH
106
107static libusb_context *usb_context = NULL;
108
fed16f06
UH
109/*
110 * The hardware supports more samplerates than these, but these are the
111 * options hardcoded into the vendor's Windows GUI.
112 */
a1bb33af 113
fed16f06
UH
114/*
115 * TODO: We shouldn't support 150MHz and 200MHz on devices that don't go up
116 * that high.
117 */
a533743d 118static const uint64_t supported_samplerates[] = {
c9140419
UH
119 SR_HZ(100),
120 SR_HZ(500),
59df0c77
UH
121 SR_KHZ(1),
122 SR_KHZ(5),
123 SR_KHZ(25),
124 SR_KHZ(50),
125 SR_KHZ(100),
126 SR_KHZ(200),
127 SR_KHZ(400),
128 SR_KHZ(800),
129 SR_MHZ(1),
130 SR_MHZ(10),
131 SR_MHZ(25),
132 SR_MHZ(50),
133 SR_MHZ(80),
134 SR_MHZ(100),
135 SR_MHZ(150),
136 SR_MHZ(200),
fed16f06 137 0,
a1bb33af
UH
138};
139
a533743d 140static const struct sr_samplerates samplerates = {
590b9f9a
UH
141 0,
142 0,
143 0,
fed16f06 144 supported_samplerates,
a1bb33af
UH
145};
146
ea9cfed7
UH
147/* Private, per-device-instance driver context. */
148struct context {
bf43ea23 149 uint64_t cur_samplerate;
bf43ea23
UH
150 uint64_t limit_samples;
151 int num_channels; /* TODO: This isn't initialized before it's needed :( */
152 uint64_t memory_size;
153 uint8_t probe_mask;
154 uint8_t trigger_mask[NUM_TRIGGER_STAGES];
155 uint8_t trigger_value[NUM_TRIGGER_STAGES];
156 // uint8_t trigger_buffer[NUM_TRIGGER_STAGES];
69890f73 157
7da6f9d5 158 /* TODO: this belongs in the device instance */
d68e2d1a 159 struct sr_usb_dev_inst *usb;
bf43ea23 160};
a1bb33af 161
1b79df2f 162static int hw_dev_config_set(int dev_index, int hwcap, const void *value);
a1bb33af
UH
163
164static unsigned int get_memory_size(int type)
165{
fed16f06
UH
166 if (type == MEMORY_SIZE_8K)
167 return 8 * 1024;
168 else if (type == MEMORY_SIZE_64K)
169 return 64 * 1024;
170 else if (type == MEMORY_SIZE_128K)
171 return 128 * 1024;
172 else if (type == MEMORY_SIZE_512K)
173 return 512 * 1024;
174 else
175 return 0;
a1bb33af
UH
176}
177
d68e2d1a 178static int opendev4(struct sr_dev_inst **sdi, libusb_device *dev,
408e7199
UH
179 struct libusb_device_descriptor *des)
180{
ea9cfed7 181 struct context *ctx;
9a498834 182 unsigned int i;
ebc34738 183 int ret;
408e7199 184
bf43ea23
UH
185 /* Note: sdi is non-NULL, the caller already checked this. */
186
ea9cfed7 187 if (!(ctx = (*sdi)->priv)) {
bf43ea23
UH
188 sr_err("zp: %s: (*sdi)->priv was NULL", __func__);
189 return -1;
190 }
191
ebc34738
UH
192 if ((ret = libusb_get_device_descriptor(dev, des))) {
193 sr_err("zp: failed to get device descriptor: %d", ret);
408e7199
UH
194 return -1;
195 }
196
9a498834 197 if (des->idVendor != USB_VENDOR)
408e7199
UH
198 return 0;
199
ea9cfed7
UH
200 if (libusb_get_bus_number(dev) == ctx->usb->bus
201 && libusb_get_device_address(dev) == ctx->usb->address) {
408e7199 202
9a498834
UH
203 for (i = 0; i < ARRAY_SIZE(zeroplus_models); i++) {
204 if (!(des->idProduct == zeroplus_models[i].pid))
408e7199
UH
205 continue;
206
8fdecced 207 sr_info("zp: Found ZEROPLUS device 0x%04x (%s)",
7b48d6e1 208 des->idProduct, zeroplus_models[i].model_name);
ea9cfed7
UH
209 ctx->num_channels = zeroplus_models[i].channels;
210 ctx->memory_size = zeroplus_models[i].sample_depth * 1024;
408e7199
UH
211 break;
212 }
213
ea9cfed7 214 if (ctx->num_channels == 0) {
8fdecced 215 sr_err("zp: Unknown ZEROPLUS device 0x%04x",
7b48d6e1 216 des->idProduct);
408e7199
UH
217 return -2;
218 }
219
220 /* Found it. */
ebc34738 221 if (!(ret = libusb_open(dev, &(ctx->usb->devhdl)))) {
5a2326a7 222 (*sdi)->status = SR_ST_ACTIVE;
7b48d6e1 223 sr_info("zp: opened device %d on %d.%d interface %d",
ea9cfed7
UH
224 (*sdi)->index, ctx->usb->bus,
225 ctx->usb->address, USB_INTERFACE);
408e7199 226 } else {
ebc34738 227 sr_err("zp: failed to open device: %d", ret);
408e7199
UH
228 *sdi = NULL;
229 }
230 }
231
232 return 0;
233}
234
bb7ef793 235static struct sr_dev_inst *zp_open_dev(int dev_index)
a1bb33af 236{
d68e2d1a 237 struct sr_dev_inst *sdi;
a1bb33af
UH
238 libusb_device **devlist;
239 struct libusb_device_descriptor des;
2285cf9b 240 int i;
a1bb33af 241
32756547 242 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index)))
a1bb33af
UH
243 return NULL;
244
245 libusb_get_device_list(usb_context, &devlist);
5a2326a7 246 if (sdi->status == SR_ST_INACTIVE) {
fed16f06 247 /* Find the device by vendor, product, bus and address. */
a1bb33af 248 libusb_get_device_list(usb_context, &devlist);
fed16f06 249 for (i = 0; devlist[i]; i++) {
408e7199 250 /* TODO: Error handling. */
2285cf9b 251 opendev4(&sdi, devlist[i], &des);
a1bb33af 252 }
fed16f06 253 } else {
5a2326a7 254 /* Status must be SR_ST_ACTIVE, i.e. already in use... */
a1bb33af
UH
255 sdi = NULL;
256 }
257 libusb_free_device_list(devlist, 1);
258
5a2326a7 259 if (sdi && sdi->status != SR_ST_ACTIVE)
a1bb33af
UH
260 sdi = NULL;
261
262 return sdi;
263}
264
bb7ef793 265static void close_dev(struct sr_dev_inst *sdi)
a1bb33af 266{
ea9cfed7 267 struct context *ctx;
69890f73 268
ea9cfed7 269 if (!(ctx = sdi->priv)) {
69890f73
UH
270 sr_err("zp: %s: sdi->priv was NULL", __func__);
271 return; /* FIXME */
272 }
273
ea9cfed7 274 if (!ctx->usb->devhdl)
408e7199
UH
275 return;
276
7b48d6e1 277 sr_info("zp: closing device %d on %d.%d interface %d", sdi->index,
ea9cfed7
UH
278 ctx->usb->bus, ctx->usb->address, USB_INTERFACE);
279 libusb_release_interface(ctx->usb->devhdl, USB_INTERFACE);
280 libusb_reset_device(ctx->usb->devhdl);
281 libusb_close(ctx->usb->devhdl);
282 ctx->usb->devhdl = NULL;
185ae2c5 283 /* TODO: Call libusb_exit() here or only in hw_cleanup()? */
5a2326a7 284 sdi->status = SR_ST_INACTIVE;
a1bb33af
UH
285}
286
1b79df2f 287static int configure_probes(struct sr_dev_inst *sdi, const GSList *probes)
a1bb33af 288{
ea9cfed7 289 struct context *ctx;
1b79df2f
JH
290 const struct sr_probe *probe;
291 const GSList *l;
a1bb33af
UH
292 int probe_bit, stage, i;
293 char *tc;
294
bf43ea23 295 /* Note: sdi and sdi->priv are non-NULL, the caller checked this. */
ea9cfed7 296 ctx = sdi->priv;
bf43ea23 297
ea9cfed7 298 ctx->probe_mask = 0;
fed16f06 299 for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
ea9cfed7
UH
300 ctx->trigger_mask[i] = 0;
301 ctx->trigger_value[i] = 0;
a1bb33af
UH
302 }
303
304 stage = -1;
fed16f06 305 for (l = probes; l; l = l->next) {
1afe8989 306 probe = (struct sr_probe *)l->data;
fed16f06 307 if (probe->enabled == FALSE)
a1bb33af
UH
308 continue;
309 probe_bit = 1 << (probe->index - 1);
ea9cfed7 310 ctx->probe_mask |= probe_bit;
fed16f06
UH
311
312 if (probe->trigger) {
a1bb33af 313 stage = 0;
fed16f06 314 for (tc = probe->trigger; *tc; tc++) {
ea9cfed7 315 ctx->trigger_mask[stage] |= probe_bit;
fed16f06 316 if (*tc == '1')
ea9cfed7 317 ctx->trigger_value[stage] |= probe_bit;
a1bb33af 318 stage++;
fed16f06 319 if (stage > NUM_TRIGGER_STAGES)
e46b8fb1 320 return SR_ERR;
a1bb33af
UH
321 }
322 }
323 }
324
e46b8fb1 325 return SR_OK;
a1bb33af
UH
326}
327
7da6f9d5
BV
328static void clear_instances(void)
329{
330 GSList *l;
331 struct sr_dev_inst *sdi;
332
333 for (l = zdi->instances; l; l = l->next) {
334 sdi = l->data;
335 /* Properly close all devices... */
336 close_dev(sdi);
337 /* ...and free all their memory. */
338 sr_dev_inst_free(sdi);
339 }
340 g_slist_free(zdi->instances);
341 zdi->instances = NULL;
342
343}
344
a1bb33af
UH
345/*
346 * API callbacks
347 */
348
40dda2c3 349static int hw_init(void)
61136ea6
BV
350{
351
7da6f9d5
BV
352 if (libusb_init(&usb_context) != 0) {
353 sr_err("zp: Failed to initialize USB.");
354 return 0;
355 }
61136ea6
BV
356
357 return SR_OK;
358}
359
4ca38984 360static GSList *hw_scan(GSList *options)
a1bb33af 361{
d68e2d1a 362 struct sr_dev_inst *sdi;
a1bb33af 363 struct libusb_device_descriptor des;
4ca38984 364 GSList *devices;
a1bb33af 365 libusb_device **devlist;
ebc34738 366 int ret, devcnt, i;
ea9cfed7 367 struct context *ctx;
a1bb33af 368
4ca38984
BV
369 (void)options;
370 devices = NULL;
371
7da6f9d5
BV
372 clear_instances();
373
bf43ea23 374 /* Allocate memory for our private driver context. */
ea9cfed7
UH
375 if (!(ctx = g_try_malloc(sizeof(struct context)))) {
376 sr_err("zp: %s: ctx malloc failed", __func__);
bf43ea23
UH
377 return 0;
378 }
379
380 /* Set some sane defaults. */
ea9cfed7
UH
381 ctx->cur_samplerate = 0;
382 ctx->limit_samples = 0;
6752905e
UH
383 /* TODO: num_channels isn't initialized before it's needed :( */
384 ctx->num_channels = NUM_PROBES;
ea9cfed7
UH
385 ctx->memory_size = 0;
386 ctx->probe_mask = 0;
387 memset(ctx->trigger_mask, 0, NUM_TRIGGER_STAGES);
388 memset(ctx->trigger_value, 0, NUM_TRIGGER_STAGES);
389 // memset(ctx->trigger_buffer, 0, NUM_TRIGGER_STAGES);
bf43ea23 390
8fdecced 391 /* Find all ZEROPLUS analyzers and add them to device list. */
a1bb33af 392 devcnt = 0;
185ae2c5 393 libusb_get_device_list(usb_context, &devlist); /* TODO: Errors. */
fed16f06
UH
394
395 for (i = 0; devlist[i]; i++) {
ebc34738
UH
396 ret = libusb_get_device_descriptor(devlist[i], &des);
397 if (ret != 0) {
398 sr_err("zp: failed to get device descriptor: %d", ret);
a1bb33af
UH
399 continue;
400 }
401
fed16f06
UH
402 if (des.idVendor == USB_VENDOR) {
403 /*
8fdecced 404 * Definitely a ZEROPLUS.
fed16f06 405 * TODO: Any way to detect specific model/version in
8fdecced 406 * the ZEROPLUS range?
fed16f06 407 */
bf43ea23 408 /* Register the device with libsigrok. */
d68e2d1a 409 if (!(sdi = sr_dev_inst_new(devcnt,
8fdecced
UH
410 SR_ST_INACTIVE, VENDOR_NAME,
411 MODEL_NAME, MODEL_VERSION))) {
d68e2d1a 412 sr_err("zp: %s: sr_dev_inst_new failed",
bf43ea23 413 __func__);
a1bb33af 414 return 0;
bf43ea23
UH
415 }
416
ea9cfed7 417 sdi->priv = ctx;
bf43ea23 418
4ca38984 419 devices = g_slist_append(devices, sdi);
32756547 420 zdi->instances = g_slist_append(zdi->instances, sdi);
ea9cfed7 421 ctx->usb = sr_usb_dev_inst_new(
fed16f06
UH
422 libusb_get_bus_number(devlist[i]),
423 libusb_get_device_address(devlist[i]), NULL);
a1bb33af
UH
424 devcnt++;
425 }
426 }
427 libusb_free_device_list(devlist, 1);
428
4ca38984 429 return devices;
a1bb33af
UH
430}
431
e7eb703f 432static int hw_dev_open(int dev_index)
a1bb33af 433{
d68e2d1a 434 struct sr_dev_inst *sdi;
ea9cfed7 435 struct context *ctx;
ebc34738 436 int ret;
a1bb33af 437
bb7ef793 438 if (!(sdi = zp_open_dev(dev_index))) {
7b48d6e1 439 sr_err("zp: unable to open device");
e46b8fb1 440 return SR_ERR;
a1bb33af
UH
441 }
442
bb7ef793 443 /* TODO: Note: sdi is retrieved in zp_open_dev(). */
bf43ea23 444
ea9cfed7 445 if (!(ctx = sdi->priv)) {
bf43ea23
UH
446 sr_err("zp: %s: sdi->priv was NULL", __func__);
447 return SR_ERR_ARG;
448 }
449
ebc34738
UH
450 ret = libusb_set_configuration(ctx->usb->devhdl, USB_CONFIGURATION);
451 if (ret < 0) {
133a37bf 452 sr_err("zp: Unable to set USB configuration %d: %d",
ebc34738 453 USB_CONFIGURATION, ret);
185ae2c5
UH
454 return SR_ERR;
455 }
456
ebc34738
UH
457 ret = libusb_claim_interface(ctx->usb->devhdl, USB_INTERFACE);
458 if (ret != 0) {
459 sr_err("zp: Unable to claim interface: %d", ret);
e46b8fb1 460 return SR_ERR;
a1bb33af 461 }
185ae2c5 462
ea9cfed7
UH
463 analyzer_reset(ctx->usb->devhdl);
464 analyzer_initialize(ctx->usb->devhdl);
a1bb33af
UH
465
466 analyzer_set_memory_size(MEMORY_SIZE_512K);
fed16f06 467 // analyzer_set_freq(g_freq, g_freq_scale);
a1bb33af 468 analyzer_set_trigger_count(1);
408e7199
UH
469 // analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger)
470 // * get_memory_size(g_memory_size)) / 100) >> 2);
fed16f06
UH
471 analyzer_set_ramsize_trigger_address(
472 (100 * get_memory_size(MEMORY_SIZE_512K) / 100) >> 2);
a1bb33af 473
fed16f06
UH
474#if 0
475 if (g_double_mode == 1)
a1bb33af
UH
476 analyzer_set_compression(COMPRESSION_DOUBLE);
477 else if (g_compression == 1)
478 analyzer_set_compression(COMPRESSION_ENABLE);
fed16f06
UH
479 else
480#endif
481 analyzer_set_compression(COMPRESSION_NONE);
a1bb33af 482
ea9cfed7 483 if (ctx->cur_samplerate == 0) {
408e7199 484 /* Samplerate hasn't been set. Default to the slowest one. */
a9a245b4 485 if (hw_dev_config_set(dev_index, SR_HWCAP_SAMPLERATE,
73017cf9 486 &samplerates.list[0]) == SR_ERR)
e46b8fb1 487 return SR_ERR;
a1bb33af
UH
488 }
489
e46b8fb1 490 return SR_OK;
a1bb33af
UH
491}
492
e7eb703f 493static int hw_dev_close(int dev_index)
a1bb33af 494{
d68e2d1a 495 struct sr_dev_inst *sdi;
a1bb33af 496
32756547 497 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index))) {
bf43ea23 498 sr_err("zp: %s: sdi was NULL", __func__);
697785d1
UH
499 return SR_ERR; /* TODO: SR_ERR_ARG? */
500 }
501
502 /* TODO */
bb7ef793 503 close_dev(sdi);
697785d1
UH
504
505 return SR_OK;
a1bb33af
UH
506}
507
57ab7d9f 508static int hw_cleanup(void)
a1bb33af 509{
a1bb33af 510
7da6f9d5 511 clear_instances();
a1bb33af 512
fed16f06 513 if (usb_context)
a1bb33af
UH
514 libusb_exit(usb_context);
515 usb_context = NULL;
57ab7d9f
UH
516
517 return SR_OK;
a1bb33af
UH
518}
519
b7f578be 520static const void *hw_dev_info_get(int dev_index, int dev_info_id)
a1bb33af 521{
d68e2d1a 522 struct sr_dev_inst *sdi;
ea9cfed7 523 struct context *ctx;
b7f578be 524 const void *info;
a1bb33af 525
32756547 526 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index))) {
bf43ea23 527 sr_err("zp: %s: sdi was NULL", __func__);
a1bb33af 528 return NULL;
bf43ea23
UH
529 }
530
ea9cfed7 531 if (!(ctx = sdi->priv)) {
bf43ea23
UH
532 sr_err("zp: %s: sdi->priv was NULL", __func__);
533 return NULL;
534 }
a1bb33af 535
6752905e
UH
536 sr_spew("zp: %s: dev_index %d, dev_info_id %d.", __func__,
537 dev_index, dev_info_id);
538
bb7ef793 539 switch (dev_info_id) {
1d9a8a5f 540 case SR_DI_INST:
a1bb33af 541 info = sdi;
6752905e 542 sr_spew("zp: %s: Returning sdi.", __func__);
a1bb33af 543 break;
5a2326a7 544 case SR_DI_NUM_PROBES:
ea9cfed7 545 info = GINT_TO_POINTER(ctx->num_channels);
6752905e
UH
546 sr_spew("zp: %s: Returning number of probes: %d.", __func__,
547 NUM_PROBES);
a1bb33af 548 break;
464d12c7
KS
549 case SR_DI_PROBE_NAMES:
550 info = probe_names;
6752905e 551 sr_spew("zp: %s: Returning probenames.", __func__);
464d12c7 552 break;
5a2326a7 553 case SR_DI_SAMPLERATES:
a1bb33af 554 info = &samplerates;
6752905e 555 sr_spew("zp: %s: Returning samplerates.", __func__);
a1bb33af 556 break;
5a2326a7 557 case SR_DI_TRIGGER_TYPES:
a1bb33af 558 info = TRIGGER_TYPES;
6752905e 559 sr_spew("zp: %s: Returning triggertypes: %s.", __func__, info);
a1bb33af 560 break;
5a2326a7 561 case SR_DI_CUR_SAMPLERATE:
ea9cfed7 562 info = &ctx->cur_samplerate;
6752905e
UH
563 sr_spew("zp: %s: Returning samplerate: %" PRIu64 "Hz.",
564 __func__, ctx->cur_samplerate);
bf43ea23
UH
565 break;
566 default:
567 /* Unknown device info ID, return NULL. */
568 sr_err("zp: %s: Unknown device info ID", __func__);
569 info = NULL;
a1bb33af
UH
570 break;
571 }
572
573 return info;
574}
575
e7eb703f 576static int hw_dev_status_get(int dev_index)
a1bb33af 577{
d68e2d1a 578 struct sr_dev_inst *sdi;
a1bb33af 579
32756547 580 sdi = sr_dev_inst_get(zdi->instances, dev_index);
fed16f06 581 if (sdi)
a1bb33af
UH
582 return sdi->status;
583 else
5a2326a7 584 return SR_ST_NOT_FOUND;
a1bb33af
UH
585}
586
915f7cc8 587static const int *hw_hwcap_get_all(void)
a1bb33af 588{
ffedd0bf 589 return hwcaps;
a1bb33af
UH
590}
591
a9a245b4 592static int set_samplerate(struct sr_dev_inst *sdi, uint64_t samplerate)
a1bb33af 593{
ea9cfed7 594 struct context *ctx;
bf43ea23
UH
595
596 if (!sdi) {
597 sr_err("zp: %s: sdi was NULL", __func__);
598 return SR_ERR_ARG;
599 }
600
ea9cfed7 601 if (!(ctx = sdi->priv)) {
bf43ea23
UH
602 sr_err("zp: %s: sdi->priv was NULL", __func__);
603 return SR_ERR_ARG;
604 }
605
73017cf9
UH
606 sr_info("zp: Setting samplerate to %" PRIu64 "Hz.", samplerate);
607
59df0c77
UH
608 if (samplerate > SR_MHZ(1))
609 analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ);
610 else if (samplerate > SR_KHZ(1))
611 analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ);
a1bb33af 612 else
fed16f06 613 analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
a1bb33af 614
ea9cfed7 615 ctx->cur_samplerate = samplerate;
a1bb33af 616
e46b8fb1 617 return SR_OK;
a1bb33af
UH
618}
619
1b79df2f 620static int hw_dev_config_set(int dev_index, int hwcap, const void *value)
a1bb33af 621{
d68e2d1a 622 struct sr_dev_inst *sdi;
ea9cfed7 623 struct context *ctx;
a1bb33af 624
32756547 625 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index))) {
bf43ea23 626 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 627 return SR_ERR;
bf43ea23
UH
628 }
629
ea9cfed7 630 if (!(ctx = sdi->priv)) {
bf43ea23
UH
631 sr_err("zp: %s: sdi->priv was NULL", __func__);
632 return SR_ERR_ARG;
633 }
a1bb33af 634
ffedd0bf 635 switch (hwcap) {
5a2326a7 636 case SR_HWCAP_SAMPLERATE:
1b79df2f 637 return set_samplerate(sdi, *(const uint64_t *)value);
5a2326a7 638 case SR_HWCAP_PROBECONFIG:
1b79df2f 639 return configure_probes(sdi, (const GSList *)value);
5a2326a7 640 case SR_HWCAP_LIMIT_SAMPLES:
1b79df2f 641 ctx->limit_samples = *(const uint64_t *)value;
e46b8fb1 642 return SR_OK;
fed16f06 643 default:
e46b8fb1 644 return SR_ERR;
a1bb33af
UH
645 }
646}
647
3cd3a20b 648static int hw_dev_acquisition_start(int dev_index, void *cb_data)
a1bb33af 649{
d68e2d1a 650 struct sr_dev_inst *sdi;
b9c735a2 651 struct sr_datafeed_packet packet;
9c939c51 652 struct sr_datafeed_logic logic;
b9c735a2 653 struct sr_datafeed_header header;
f366e86c 654 struct sr_datafeed_meta_logic meta;
9c939c51 655 uint64_t samples_read;
a1bb33af 656 int res;
afc8e4de 657 unsigned int packet_num;
a1bb33af 658 unsigned char *buf;
ea9cfed7 659 struct context *ctx;
a1bb33af 660
32756547 661 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index))) {
bf43ea23 662 sr_err("zp: %s: sdi was NULL", __func__);
e46b8fb1 663 return SR_ERR;
bf43ea23
UH
664 }
665
ea9cfed7 666 if (!(ctx = sdi->priv)) {
bf43ea23
UH
667 sr_err("zp: %s: sdi->priv was NULL", __func__);
668 return SR_ERR_ARG;
669 }
a1bb33af 670
a143e4e5 671 /* push configured settings to device */
ea9cfed7 672 analyzer_configure(ctx->usb->devhdl);
a143e4e5 673
ea9cfed7 674 analyzer_start(ctx->usb->devhdl);
7b48d6e1 675 sr_info("zp: Waiting for data");
ea9cfed7 676 analyzer_wait_data(ctx->usb->devhdl);
a1bb33af 677
7b48d6e1 678 sr_info("zp: Stop address = 0x%x",
ea9cfed7 679 analyzer_get_stop_address(ctx->usb->devhdl));
7b48d6e1 680 sr_info("zp: Now address = 0x%x",
ea9cfed7 681 analyzer_get_now_address(ctx->usb->devhdl));
7b48d6e1 682 sr_info("zp: Trigger address = 0x%x",
ea9cfed7 683 analyzer_get_trigger_address(ctx->usb->devhdl));
a1bb33af 684
5a2326a7 685 packet.type = SR_DF_HEADER;
9c939c51 686 packet.payload = &header;
a1bb33af
UH
687 header.feed_version = 1;
688 gettimeofday(&header.starttime, NULL);
f366e86c
BV
689 sr_session_send(cb_data, &packet);
690
691 /* Send metadata about the SR_DF_LOGIC packets to come. */
692 packet.type = SR_DF_META_LOGIC;
693 packet.payload = &meta;
694 meta.samplerate = ctx->cur_samplerate;
695 meta.num_probes = ctx->num_channels;
3cd3a20b 696 sr_session_send(cb_data, &packet);
a1bb33af 697
b53738ba 698 if (!(buf = g_try_malloc(PACKET_SIZE))) {
bf43ea23 699 sr_err("zp: %s: buf malloc failed", __func__);
b53738ba
UH
700 return SR_ERR_MALLOC;
701 }
702
9c939c51 703 samples_read = 0;
ea9cfed7 704 analyzer_read_start(ctx->usb->devhdl);
fed16f06 705 /* Send the incoming transfer to the session bus. */
ea9cfed7 706 for (packet_num = 0; packet_num < (ctx->memory_size * 4 / PACKET_SIZE);
fed16f06 707 packet_num++) {
ea9cfed7 708 res = analyzer_read_data(ctx->usb->devhdl, buf, PACKET_SIZE);
7b48d6e1 709 sr_info("zp: Tried to read %llx bytes, actually read %x bytes",
b08024a8 710 PACKET_SIZE, res);
a1bb33af 711
5a2326a7 712 packet.type = SR_DF_LOGIC;
9c939c51
BV
713 packet.payload = &logic;
714 logic.length = PACKET_SIZE;
715 logic.unitsize = 4;
716 logic.data = buf;
3cd3a20b 717 sr_session_send(cb_data, &packet);
9c939c51 718 samples_read += res / 4;
a1bb33af 719 }
ea9cfed7 720 analyzer_read_stop(ctx->usb->devhdl);
a1bb33af
UH
721 g_free(buf);
722
5a2326a7 723 packet.type = SR_DF_END;
3cd3a20b 724 sr_session_send(cb_data, &packet);
a1bb33af 725
e46b8fb1 726 return SR_OK;
a1bb33af
UH
727}
728
3cd3a20b
UH
729/* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
730static int hw_dev_acquisition_stop(int dev_index, void *cb_data)
a1bb33af 731{
b9c735a2 732 struct sr_datafeed_packet packet;
d68e2d1a 733 struct sr_dev_inst *sdi;
ea9cfed7 734 struct context *ctx;
a1bb33af 735
5a2326a7 736 packet.type = SR_DF_END;
3cd3a20b 737 sr_session_send(cb_data, &packet);
a1bb33af 738
32756547 739 if (!(sdi = sr_dev_inst_get(zdi->instances, dev_index))) {
69890f73 740 sr_err("zp: %s: sdi was NULL", __func__);
3010f21c 741 return SR_ERR_BUG;
69890f73
UH
742 }
743
ea9cfed7 744 if (!(ctx = sdi->priv)) {
69890f73 745 sr_err("zp: %s: sdi->priv was NULL", __func__);
3010f21c 746 return SR_ERR_BUG;
69890f73 747 }
a1bb33af 748
ea9cfed7 749 analyzer_reset(ctx->usb->devhdl);
fed16f06 750 /* TODO: Need to cancel and free any queued up transfers. */
3010f21c
UH
751
752 return SR_OK;
a1bb33af
UH
753}
754
c09f0b57 755SR_PRIV struct sr_dev_driver zeroplus_logic_cube_driver_info = {
e519ba86 756 .name = "zeroplus-logic-cube",
8fdecced 757 .longname = "ZEROPLUS Logic Cube LAP-C series",
e519ba86
UH
758 .api_version = 1,
759 .init = hw_init,
760 .cleanup = hw_cleanup,
61136ea6 761 .scan = hw_scan,
e7eb703f
UH
762 .dev_open = hw_dev_open,
763 .dev_close = hw_dev_close,
5097b0d0 764 .dev_info_get = hw_dev_info_get,
e7eb703f 765 .dev_status_get = hw_dev_status_get,
ffedd0bf 766 .hwcap_get_all = hw_hwcap_get_all,
a9a245b4 767 .dev_config_set = hw_dev_config_set,
69040b7c
UH
768 .dev_acquisition_start = hw_dev_acquisition_start,
769 .dev_acquisition_stop = hw_dev_acquisition_stop,
32756547 770 .instances = NULL,
a1bb33af 771};