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