]> sigrok.org Git - libsigrok.git/blame - hardware/serial-dmm/api.c
Add a struct sr_context * parameter to sr_driver_init()
[libsigrok.git] / hardware / serial-dmm / api.c
CommitLineData
7dc55d93
AG
1/*
2 * This file is part of the sigrok project.
3 *
4 * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
5 * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
729b01f9 6 * Copyright (C) 2012 Uwe Hermann <uwe@hermann-uwe.de>
7dc55d93
AG
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <glib.h>
7dc55d93
AG
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <string.h>
27#include <errno.h>
bbabddbd
UH
28#include "libsigrok.h"
29#include "libsigrok-internal.h"
30#include "protocol.h"
7dc55d93
AG
31
32static const int hwopts[] = {
33 SR_HWOPT_CONN,
34 SR_HWOPT_SERIALCOMM,
35 0,
36};
37
38static const int hwcaps[] = {
39 SR_HWCAP_MULTIMETER,
40 SR_HWCAP_LIMIT_SAMPLES,
41 SR_HWCAP_CONTINUOUS,
42 0,
43};
44
45static const char *probe_names[] = {
46 "Probe",
47 NULL,
48};
49
f086b830 50SR_PRIV struct sr_dev_driver digitek_dt4000zc_driver_info;
729b01f9 51SR_PRIV struct sr_dev_driver tekpower_tp4000zc_driver_info;
ce3777ad 52SR_PRIV struct sr_dev_driver metex_me31_driver_info;
f0ac4929 53SR_PRIV struct sr_dev_driver peaktech_3410_driver_info;
5887c9cc 54SR_PRIV struct sr_dev_driver mastech_mas345_driver_info;
6dca2f16 55SR_PRIV struct sr_dev_driver va_va18b_driver_info;
a53da082 56SR_PRIV struct sr_dev_driver metex_m3640d_driver_info;
a376ffea 57SR_PRIV struct sr_dev_driver peaktech_4370_driver_info;
d4bd66a0 58SR_PRIV struct sr_dev_driver pce_pce_dm32_driver_info;
d5ce233f 59SR_PRIV struct sr_dev_driver radioshack_22_168_driver_info;
21829e67 60SR_PRIV struct sr_dev_driver radioshack_22_812_driver_info;
f086b830 61
ce3777ad
UH
62static struct sr_dev_driver *di_dt4000zc = &digitek_dt4000zc_driver_info;
63static struct sr_dev_driver *di_tp4000zc = &tekpower_tp4000zc_driver_info;
64static struct sr_dev_driver *di_me31 = &metex_me31_driver_info;
f0ac4929 65static struct sr_dev_driver *di_3410 = &peaktech_3410_driver_info;
5887c9cc 66static struct sr_dev_driver *di_mas345 = &mastech_mas345_driver_info;
6dca2f16 67static struct sr_dev_driver *di_va18b = &va_va18b_driver_info;
a53da082 68static struct sr_dev_driver *di_m3640d = &metex_m3640d_driver_info;
a376ffea 69static struct sr_dev_driver *di_4370 = &peaktech_4370_driver_info;
d4bd66a0 70static struct sr_dev_driver *di_pce_dm32 = &pce_pce_dm32_driver_info;
d5ce233f 71static struct sr_dev_driver *di_22_168 = &radioshack_22_168_driver_info;
21829e67 72static struct sr_dev_driver *di_22_812 = &radioshack_22_812_driver_info;
729b01f9
UH
73
74/* After hw_init() this will point to a device-specific entry (see above). */
75static struct sr_dev_driver *di = NULL;
76
77SR_PRIV struct dmm_info dmms[] = {
f086b830 78 {
ce3777ad
UH
79 "Digitek", "DT4000ZC", "2400/8n1", 2400,
80 FS9721_PACKET_SIZE, NULL,
81 sr_fs9721_packet_valid, sr_fs9721_parse,
f086b830
UH
82 dmm_details_dt4000zc,
83 },
729b01f9 84 {
ce3777ad
UH
85 "TekPower", "TP4000ZC", "2400/8n1", 2400,
86 FS9721_PACKET_SIZE, NULL,
87 sr_fs9721_packet_valid, sr_fs9721_parse,
729b01f9
UH
88 dmm_details_tp4000zc,
89 },
ce3777ad
UH
90 {
91 "Metex", "ME-31", "600/7n2/rts=0/dtr=1", 600,
92 METEX14_PACKET_SIZE, sr_metex14_packet_request,
93 sr_metex14_packet_valid, sr_metex14_parse,
94 NULL,
95 },
f0ac4929
UH
96 {
97 "Peaktech", "3410", "600/7n2/rts=0/dtr=1", 600,
98 METEX14_PACKET_SIZE, sr_metex14_packet_request,
99 sr_metex14_packet_valid, sr_metex14_parse,
100 NULL,
101 },
5887c9cc
UH
102 {
103 "MASTECH", "MAS345", "600/7n2/rts=0/dtr=1", 600,
104 METEX14_PACKET_SIZE, sr_metex14_packet_request,
105 sr_metex14_packet_valid, sr_metex14_parse,
106 NULL,
107 },
6dca2f16
UH
108 {
109 "V&A", "VA18B", "2400/8n1", 2400,
110 FS9721_PACKET_SIZE, NULL,
111 sr_fs9721_packet_valid, sr_fs9721_parse,
112 dmm_details_va18b,
113 },
a53da082
UH
114 {
115 "Metex", "M-3640D", "1200/7n2/rts=0/dtr=1", 1200,
116 METEX14_PACKET_SIZE, sr_metex14_packet_request,
117 sr_metex14_packet_valid, sr_metex14_parse,
118 NULL,
119 },
a376ffea
UH
120 {
121 "PeakTech", "4370", "1200/7n2/rts=0/dtr=1", 1200,
122 METEX14_PACKET_SIZE, sr_metex14_packet_request,
123 sr_metex14_packet_valid, sr_metex14_parse,
124 NULL,
125 },
d4bd66a0
UH
126 {
127 "PCE", "PCE-DM32", "2400/8n1", 2400,
128 FS9721_PACKET_SIZE, NULL,
129 sr_fs9721_packet_valid, sr_fs9721_parse,
130 dmm_details_pce_dm32,
131 },
d5ce233f
AG
132 {
133 "RadioShack", "22-168", "1200/7n2/rts=0/dtr=1", 1200,
134 METEX14_PACKET_SIZE, sr_metex14_packet_request,
135 sr_metex14_packet_valid, sr_metex14_parse,
136 NULL,
137 },
21829e67
AG
138 {
139 "RadioShack", "22-812", "4800/8n1/rts=0/dtr=1", 4800,
140 RS9LCD_PACKET_SIZE, NULL,
141 sr_rs9lcd_packet_valid, sr_rs9lcd_parse,
142 NULL,
143 },
729b01f9 144};
7dc55d93
AG
145
146/* Properly close and free all devices. */
147static int clear_instances(void)
148{
149 struct sr_dev_inst *sdi;
150 struct drv_context *drvc;
151 struct dev_context *devc;
152 GSList *l;
153
154 if (!(drvc = di->priv))
155 return SR_OK;
156
157 drvc = di->priv;
158 for (l = drvc->instances; l; l = l->next) {
159 if (!(sdi = l->data))
160 continue;
161 if (!(devc = sdi->priv))
162 continue;
163 sr_serial_dev_inst_free(devc->serial);
164 sr_dev_inst_free(sdi);
165 }
166 g_slist_free(drvc->instances);
167 drvc->instances = NULL;
168
169 return SR_OK;
170}
171
729b01f9 172static int hw_init(int dmm)
7dc55d93
AG
173{
174 struct drv_context *drvc;
175
176 if (!(drvc = g_try_malloc0(sizeof(struct drv_context)))) {
bbabddbd
UH
177 sr_err("Driver context malloc failed.");
178 return SR_ERR_MALLOC;
7dc55d93
AG
179 }
180
f086b830 181 if (dmm == DIGITEK_DT4000ZC)
ce3777ad 182 di = di_dt4000zc;
729b01f9 183 if (dmm == TEKPOWER_TP4000ZC)
ce3777ad
UH
184 di = di_tp4000zc;
185 if (dmm == METEX_ME31)
186 di = di_me31;
f0ac4929
UH
187 if (dmm == PEAKTECH_3410)
188 di = di_3410;
5887c9cc
UH
189 if (dmm == MASTECH_MAS345)
190 di = di_mas345;
6dca2f16
UH
191 if (dmm == VA_VA18B)
192 di = di_va18b;
a53da082
UH
193 if (dmm == METEX_M3640D)
194 di = di_m3640d;
a376ffea
UH
195 if (dmm == PEAKTECH_4370)
196 di = di_4370;
d4bd66a0
UH
197 if (dmm == PCE_PCE_DM32)
198 di = di_pce_dm32;
d5ce233f
AG
199 if (dmm == RADIOSHACK_22_168)
200 di = di_22_168;
21829e67
AG
201 if (dmm == RADIOSHACK_22_812)
202 di = di_22_812;
729b01f9
UH
203 sr_dbg("Selected '%s' subdriver.", di->name);
204
7dc55d93
AG
205 di->priv = drvc;
206
207 return SR_OK;
208}
209
f086b830
UH
210static int hw_init_digitek_dt4000zc(void)
211{
212 return hw_init(DIGITEK_DT4000ZC);
213}
214
729b01f9
UH
215static int hw_init_tekpower_tp4000zc(void)
216{
217 return hw_init(TEKPOWER_TP4000ZC);
218}
219
ce3777ad
UH
220static int hw_init_metex_me31(void)
221{
222 return hw_init(METEX_ME31);
223}
224
f0ac4929
UH
225static int hw_init_peaktech_3410(void)
226{
227 return hw_init(PEAKTECH_3410);
228}
229
5887c9cc
UH
230static int hw_init_mastech_mas345(void)
231{
232 return hw_init(MASTECH_MAS345);
233}
234
6dca2f16
UH
235static int hw_init_va_va18b(void)
236{
237 return hw_init(VA_VA18B);
238}
239
a53da082
UH
240static int hw_init_metex_m3640d(void)
241{
242 return hw_init(METEX_M3640D);
243}
244
a376ffea
UH
245static int hw_init_peaktech_4370(void)
246{
247 return hw_init(PEAKTECH_4370);
248}
249
d4bd66a0
UH
250static int hw_init_pce_pce_dm32(void)
251{
252 return hw_init(PCE_PCE_DM32);
253}
254
d5ce233f
AG
255static int hw_init_radioshack_22_168(void)
256{
257 return hw_init(RADIOSHACK_22_168);
258}
259
21829e67
AG
260static int hw_init_radioshack_22_812(void)
261{
262 return hw_init(RADIOSHACK_22_812);
263}
264
729b01f9 265static GSList *scan(const char *conn, const char *serialcomm, int dmm)
7dc55d93
AG
266{
267 struct sr_dev_inst *sdi;
268 struct drv_context *drvc;
269 struct dev_context *devc;
270 struct sr_probe *probe;
d35afa87 271 struct sr_serial_dev_inst *serial;
7dc55d93 272 GSList *devices;
2546b05c
AG
273 int dropped, ret;
274 size_t len;
275 uint8_t buf[128];
7dc55d93 276
d35afa87 277 if (!(serial = sr_serial_dev_inst_new(conn, serialcomm)))
7dc55d93 278 return NULL;
d35afa87 279
ce3777ad 280 if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
7dc55d93 281 return NULL;
7dc55d93 282
ce3777ad 283 sr_info("Probing port %s.", conn);
7dc55d93
AG
284
285 drvc = di->priv;
7dc55d93 286 devices = NULL;
d35afa87 287 serial_flush(serial);
bbabddbd
UH
288
289 /*
290 * There's no way to get an ID from the multimeter. It just sends data
291 * periodically, so the best we can do is check if the packets match
292 * the expected format.
293 */
7dc55d93 294
2546b05c
AG
295 /* Let's get a bit of data and see if we can find a packet. */
296 len = sizeof(buf);
7dc55d93 297
ce3777ad
UH
298 /* Request a packet if the DMM requires this. */
299 if (dmms[dmm].packet_request) {
300 if ((ret = dmms[dmm].packet_request(serial)) < 0) {
301 sr_err("Failed to request packet: %d.", ret);
302 return FALSE;
303 }
304 }
305
729b01f9
UH
306 ret = serial_stream_detect(serial, buf, &len, dmms[dmm].packet_size,
307 dmms[dmm].packet_valid, 1000,
308 dmms[dmm].baudrate);
2546b05c
AG
309 if (ret != SR_OK)
310 goto scan_cleanup;
7dc55d93 311
2546b05c
AG
312 /*
313 * If we dropped more than two packets worth of data, something is
314 * wrong. We shouldn't quit however, since the dropped bytes might be
315 * just zeroes at the beginning of the stream. Those can occur as a
316 * combination of the nonstandard cable that ships with this device and
317 * the serial port or USB to serial adapter.
318 */
729b01f9
UH
319 dropped = len - dmms[dmm].packet_size;
320 if (dropped > 2 * dmms[dmm].packet_size)
6bef68a7 321 sr_warn("Had to drop too much data.");
7dc55d93 322
2546b05c 323 sr_info("Found device on port %s.", conn);
7dc55d93 324
729b01f9
UH
325 if (!(sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, dmms[dmm].vendor,
326 dmms[dmm].device, "")))
2546b05c 327 goto scan_cleanup;
6bef68a7 328
2546b05c
AG
329 if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
330 sr_err("Device context malloc failed.");
331 goto scan_cleanup;
7dc55d93
AG
332 }
333
2546b05c
AG
334 devc->serial = serial;
335
336 sdi->priv = devc;
337 sdi->driver = di;
338 if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1")))
339 goto scan_cleanup;
340 sdi->probes = g_slist_append(sdi->probes, probe);
341 drvc->instances = g_slist_append(drvc->instances, sdi);
342 devices = g_slist_append(devices, sdi);
343
344scan_cleanup:
d35afa87 345 serial_close(serial);
2546b05c 346
7dc55d93
AG
347 return devices;
348}
349
350static GSList *hw_scan(GSList *options)
351{
352 struct sr_hwopt *opt;
353 GSList *l, *devices;
354 const char *conn, *serialcomm;
729b01f9 355 int dmm;
7dc55d93
AG
356
357 conn = serialcomm = NULL;
358 for (l = options; l; l = l->next) {
359 opt = l->data;
360 switch (opt->hwopt) {
361 case SR_HWOPT_CONN:
362 conn = opt->value;
363 break;
364 case SR_HWOPT_SERIALCOMM:
365 serialcomm = opt->value;
366 break;
367 }
368 }
369 if (!conn)
370 return NULL;
371
f086b830 372 if (!strcmp(di->name, "digitek-dt4000zc"))
729b01f9 373 dmm = 0;
f086b830
UH
374 if (!strcmp(di->name, "tekpower-tp4000zc"))
375 dmm = 1;
ce3777ad
UH
376 if (!strcmp(di->name, "metex-me31"))
377 dmm = 2;
f0ac4929
UH
378 if (!strcmp(di->name, "peaktech-3410"))
379 dmm = 3;
5887c9cc
UH
380 if (!strcmp(di->name, "mastech-mas345"))
381 dmm = 4;
6dca2f16
UH
382 if (!strcmp(di->name, "va-va18b"))
383 dmm = 5;
a53da082
UH
384 if (!strcmp(di->name, "metex-m3640d"))
385 dmm = 6;
a376ffea
UH
386 if (!strcmp(di->name, "peaktech-4370"))
387 dmm = 7;
d4bd66a0
UH
388 if (!strcmp(di->name, "pce-pce-dm32"))
389 dmm = 8;
d5ce233f
AG
390 if (!strcmp(di->name, "radioshack-22-168"))
391 dmm = 9;
21829e67
AG
392 if (!strcmp(di->name, "radioshack-22-812"))
393 dmm = 10;
729b01f9 394
7dc55d93
AG
395 if (serialcomm) {
396 /* Use the provided comm specs. */
729b01f9 397 devices = scan(conn, serialcomm, dmm);
7dc55d93 398 } else {
d35afa87 399 /* Try the default. */
729b01f9 400 devices = scan(conn, dmms[dmm].conn, dmm);
7dc55d93
AG
401 }
402
403 return devices;
404}
405
406static GSList *hw_dev_list(void)
407{
408 struct drv_context *drvc;
409
410 drvc = di->priv;
411
412 return drvc->instances;
413}
414
415static int hw_dev_open(struct sr_dev_inst *sdi)
416{
417 struct dev_context *devc;
418
419 if (!(devc = sdi->priv)) {
420 sr_err("sdi->priv was NULL.");
421 return SR_ERR_BUG;
422 }
423
ce3777ad 424 if (serial_open(devc->serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
7dc55d93 425 return SR_ERR;
bbabddbd 426
7dc55d93
AG
427 sdi->status = SR_ST_ACTIVE;
428
429 return SR_OK;
430}
431
432static int hw_dev_close(struct sr_dev_inst *sdi)
433{
434 struct dev_context *devc;
435
436 if (!(devc = sdi->priv)) {
437 sr_err("sdi->priv was NULL.");
438 return SR_ERR_BUG;
439 }
440
441 if (devc->serial && devc->serial->fd != -1) {
d35afa87 442 serial_close(devc->serial);
7dc55d93
AG
443 sdi->status = SR_ST_INACTIVE;
444 }
445
446 return SR_OK;
447}
448
449static int hw_cleanup(void)
450{
451 clear_instances();
452
453 return SR_OK;
454}
455
456static int hw_info_get(int info_id, const void **data,
bbabddbd 457 const struct sr_dev_inst *sdi)
7dc55d93 458{
bbabddbd 459 (void)sdi;
7dc55d93
AG
460
461 switch (info_id) {
462 case SR_DI_HWOPTS:
463 *data = hwopts;
464 break;
465 case SR_DI_HWCAPS:
466 *data = hwcaps;
467 break;
468 case SR_DI_NUM_PROBES:
469 *data = GINT_TO_POINTER(1);
470 break;
471 case SR_DI_PROBE_NAMES:
472 *data = probe_names;
473 break;
474 default:
475 return SR_ERR_ARG;
476 }
477
478 return SR_OK;
479}
480
481static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
bbabddbd 482 const void *value)
7dc55d93
AG
483{
484 struct dev_context *devc;
485
486 if (sdi->status != SR_ST_ACTIVE)
487 return SR_ERR;
488
489 if (!(devc = sdi->priv)) {
490 sr_err("sdi->priv was NULL.");
491 return SR_ERR_BUG;
492 }
493
494 switch (hwcap) {
495 case SR_HWCAP_LIMIT_SAMPLES:
496 devc->limit_samples = *(const uint64_t *)value;
497 sr_dbg("Setting sample limit to %" PRIu64 ".",
498 devc->limit_samples);
499 break;
500 default:
501 sr_err("Unknown capability: %d.", hwcap);
502 return SR_ERR;
503 break;
504 }
505
506 return SR_OK;
507}
508
509static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
bbabddbd 510 void *cb_data)
7dc55d93
AG
511{
512 struct sr_datafeed_packet packet;
513 struct sr_datafeed_header header;
514 struct sr_datafeed_meta_analog meta;
515 struct dev_context *devc;
729b01f9 516 int (*receive_data)(int, int, void *) = NULL;
7dc55d93
AG
517
518 if (!(devc = sdi->priv)) {
519 sr_err("sdi->priv was NULL.");
520 return SR_ERR_BUG;
521 }
522
523 sr_dbg("Starting acquisition.");
524
525 devc->cb_data = cb_data;
526
bbabddbd
UH
527 /*
528 * Reset the number of samples to take. If we've already collected our
7dc55d93 529 * quota, but we start a new session, and don't reset this, we'll just
bbabddbd
UH
530 * quit without acquiring any new samples.
531 */
7dc55d93
AG
532 devc->num_samples = 0;
533
534 /* Send header packet to the session bus. */
535 sr_dbg("Sending SR_DF_HEADER.");
536 packet.type = SR_DF_HEADER;
537 packet.payload = (uint8_t *)&header;
538 header.feed_version = 1;
539 gettimeofday(&header.starttime, NULL);
540 sr_session_send(devc->cb_data, &packet);
541
542 /* Send metadata about the SR_DF_ANALOG packets to come. */
543 sr_dbg("Sending SR_DF_META_ANALOG.");
544 packet.type = SR_DF_META_ANALOG;
545 packet.payload = &meta;
546 meta.num_probes = 1;
547 sr_session_send(devc->cb_data, &packet);
548
f086b830
UH
549 if (!strcmp(di->name, "digitek-dt4000zc"))
550 receive_data = digitek_dt4000zc_receive_data;
729b01f9
UH
551 if (!strcmp(di->name, "tekpower-tp4000zc"))
552 receive_data = tekpower_tp4000zc_receive_data;
ce3777ad
UH
553 if (!strcmp(di->name, "metex-me31"))
554 receive_data = metex_me31_receive_data;
f0ac4929
UH
555 if (!strcmp(di->name, "peaktech-3410"))
556 receive_data = peaktech_3410_receive_data;
5887c9cc
UH
557 if (!strcmp(di->name, "mastech-mas345"))
558 receive_data = mastech_mas345_receive_data;
6dca2f16
UH
559 if (!strcmp(di->name, "va-va18b"))
560 receive_data = va_va18b_receive_data;
a53da082
UH
561 if (!strcmp(di->name, "metex-m3640d"))
562 receive_data = metex_m3640d_receive_data;
a376ffea
UH
563 if (!strcmp(di->name, "peaktech-4370"))
564 receive_data = peaktech_4370_receive_data;
d4bd66a0
UH
565 if (!strcmp(di->name, "pce-pce-dm32"))
566 receive_data = pce_pce_dm32_receive_data;
d5ce233f
AG
567 if (!strcmp(di->name, "radioshack-22-168"))
568 receive_data = radioshack_22_168_receive_data;
21829e67
AG
569 if (!strcmp(di->name, "radioshack-22-812"))
570 receive_data = radioshack_22_812_receive_data;
729b01f9 571
bbabddbd 572 /* Poll every 50ms, or whenever some data comes in. */
7dc55d93 573 sr_source_add(devc->serial->fd, G_IO_IN, 50,
729b01f9 574 receive_data, (void *)sdi);
7dc55d93
AG
575
576 return SR_OK;
577}
578
69b07d14 579static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
7dc55d93
AG
580{
581 struct sr_datafeed_packet packet;
582 struct dev_context *devc;
583
584 if (sdi->status != SR_ST_ACTIVE)
585 return SR_ERR;
586
587 if (!(devc = sdi->priv)) {
588 sr_err("sdi->priv was NULL.");
589 return SR_ERR_BUG;
590 }
591
592 sr_dbg("Stopping acquisition.");
593
594 sr_source_remove(devc->serial->fd);
595 hw_dev_close((struct sr_dev_inst *)sdi);
596
597 /* Send end packet to the session bus. */
598 sr_dbg("Sending SR_DF_END.");
599 packet.type = SR_DF_END;
600 sr_session_send(cb_data, &packet);
601
602 return SR_OK;
603}
604
f086b830
UH
605SR_PRIV struct sr_dev_driver digitek_dt4000zc_driver_info = {
606 .name = "digitek-dt4000zc",
607 .longname = "Digitek DT4000ZC",
608 .api_version = 1,
609 .init = hw_init_digitek_dt4000zc,
610 .cleanup = hw_cleanup,
611 .scan = hw_scan,
612 .dev_list = hw_dev_list,
613 .dev_clear = clear_instances,
614 .dev_open = hw_dev_open,
615 .dev_close = hw_dev_close,
616 .info_get = hw_info_get,
617 .dev_config_set = hw_dev_config_set,
618 .dev_acquisition_start = hw_dev_acquisition_start,
619 .dev_acquisition_stop = hw_dev_acquisition_stop,
620 .priv = NULL,
621};
622
729b01f9
UH
623SR_PRIV struct sr_dev_driver tekpower_tp4000zc_driver_info = {
624 .name = "tekpower-tp4000zc",
625 .longname = "TekPower TP4000ZC",
7dc55d93 626 .api_version = 1,
729b01f9 627 .init = hw_init_tekpower_tp4000zc,
7dc55d93
AG
628 .cleanup = hw_cleanup,
629 .scan = hw_scan,
630 .dev_list = hw_dev_list,
631 .dev_clear = clear_instances,
632 .dev_open = hw_dev_open,
633 .dev_close = hw_dev_close,
634 .info_get = hw_info_get,
635 .dev_config_set = hw_dev_config_set,
636 .dev_acquisition_start = hw_dev_acquisition_start,
637 .dev_acquisition_stop = hw_dev_acquisition_stop,
638 .priv = NULL,
639};
ce3777ad
UH
640
641SR_PRIV struct sr_dev_driver metex_me31_driver_info = {
642 .name = "metex-me31",
643 .longname = "Metex ME-31",
644 .api_version = 1,
645 .init = hw_init_metex_me31,
646 .cleanup = hw_cleanup,
647 .scan = hw_scan,
648 .dev_list = hw_dev_list,
649 .dev_clear = clear_instances,
650 .dev_open = hw_dev_open,
651 .dev_close = hw_dev_close,
652 .info_get = hw_info_get,
653 .dev_config_set = hw_dev_config_set,
654 .dev_acquisition_start = hw_dev_acquisition_start,
655 .dev_acquisition_stop = hw_dev_acquisition_stop,
656 .priv = NULL,
657};
f0ac4929
UH
658
659SR_PRIV struct sr_dev_driver peaktech_3410_driver_info = {
660 .name = "peaktech-3410",
661 .longname = "PeakTech 3410",
662 .api_version = 1,
663 .init = hw_init_peaktech_3410,
664 .cleanup = hw_cleanup,
665 .scan = hw_scan,
666 .dev_list = hw_dev_list,
667 .dev_clear = clear_instances,
668 .dev_open = hw_dev_open,
669 .dev_close = hw_dev_close,
670 .info_get = hw_info_get,
671 .dev_config_set = hw_dev_config_set,
672 .dev_acquisition_start = hw_dev_acquisition_start,
673 .dev_acquisition_stop = hw_dev_acquisition_stop,
674 .priv = NULL,
675};
5887c9cc
UH
676
677SR_PRIV struct sr_dev_driver mastech_mas345_driver_info = {
678 .name = "mastech-mas345",
679 .longname = "MASTECH MAS345",
680 .api_version = 1,
681 .init = hw_init_mastech_mas345,
682 .cleanup = hw_cleanup,
683 .scan = hw_scan,
684 .dev_list = hw_dev_list,
685 .dev_clear = clear_instances,
686 .dev_open = hw_dev_open,
687 .dev_close = hw_dev_close,
688 .info_get = hw_info_get,
689 .dev_config_set = hw_dev_config_set,
690 .dev_acquisition_start = hw_dev_acquisition_start,
691 .dev_acquisition_stop = hw_dev_acquisition_stop,
692 .priv = NULL,
693};
6dca2f16
UH
694
695SR_PRIV struct sr_dev_driver va_va18b_driver_info = {
696 .name = "va-va18b",
697 .longname = "V&A VA18B",
698 .api_version = 1,
699 .init = hw_init_va_va18b,
700 .cleanup = hw_cleanup,
701 .scan = hw_scan,
702 .dev_list = hw_dev_list,
703 .dev_clear = clear_instances,
704 .dev_open = hw_dev_open,
705 .dev_close = hw_dev_close,
706 .info_get = hw_info_get,
707 .dev_config_set = hw_dev_config_set,
708 .dev_acquisition_start = hw_dev_acquisition_start,
709 .dev_acquisition_stop = hw_dev_acquisition_stop,
710 .priv = NULL,
711};
a53da082
UH
712
713SR_PRIV struct sr_dev_driver metex_m3640d_driver_info = {
714 .name = "metex-m3640d",
715 .longname = "Metex M-3640D",
716 .api_version = 1,
717 .init = hw_init_metex_m3640d,
718 .cleanup = hw_cleanup,
719 .scan = hw_scan,
720 .dev_list = hw_dev_list,
721 .dev_clear = clear_instances,
722 .dev_open = hw_dev_open,
723 .dev_close = hw_dev_close,
724 .info_get = hw_info_get,
725 .dev_config_set = hw_dev_config_set,
726 .dev_acquisition_start = hw_dev_acquisition_start,
727 .dev_acquisition_stop = hw_dev_acquisition_stop,
728 .priv = NULL,
729};
a376ffea
UH
730
731SR_PRIV struct sr_dev_driver peaktech_4370_driver_info = {
732 .name = "peaktech-4370",
733 .longname = "PeakTech 4370",
734 .api_version = 1,
735 .init = hw_init_peaktech_4370,
736 .cleanup = hw_cleanup,
737 .scan = hw_scan,
738 .dev_list = hw_dev_list,
739 .dev_clear = clear_instances,
740 .dev_open = hw_dev_open,
741 .dev_close = hw_dev_close,
742 .info_get = hw_info_get,
743 .dev_config_set = hw_dev_config_set,
744 .dev_acquisition_start = hw_dev_acquisition_start,
745 .dev_acquisition_stop = hw_dev_acquisition_stop,
746 .priv = NULL,
747};
d4bd66a0
UH
748
749SR_PRIV struct sr_dev_driver pce_pce_dm32_driver_info = {
750 .name = "pce-pce-dm32",
751 .longname = "PCE PCE-DM32",
752 .api_version = 1,
753 .init = hw_init_pce_pce_dm32,
754 .cleanup = hw_cleanup,
755 .scan = hw_scan,
756 .dev_list = hw_dev_list,
757 .dev_clear = clear_instances,
758 .dev_open = hw_dev_open,
759 .dev_close = hw_dev_close,
760 .info_get = hw_info_get,
761 .dev_config_set = hw_dev_config_set,
762 .dev_acquisition_start = hw_dev_acquisition_start,
763 .dev_acquisition_stop = hw_dev_acquisition_stop,
764 .priv = NULL,
765};
766
d5ce233f
AG
767SR_PRIV struct sr_dev_driver radioshack_22_168_driver_info = {
768 .name = "radioshack-22-168",
769 .longname = "RadioShack 22-168",
770 .api_version = 1,
771 .init = hw_init_radioshack_22_168,
772 .cleanup = hw_cleanup,
773 .scan = hw_scan,
774 .dev_list = hw_dev_list,
775 .dev_clear = clear_instances,
776 .dev_open = hw_dev_open,
777 .dev_close = hw_dev_close,
778 .info_get = hw_info_get,
779 .dev_config_set = hw_dev_config_set,
780 .dev_acquisition_start = hw_dev_acquisition_start,
781 .dev_acquisition_stop = hw_dev_acquisition_stop,
782 .priv = NULL,
783};
21829e67
AG
784
785SR_PRIV struct sr_dev_driver radioshack_22_812_driver_info = {
786 .name = "radioshack-22-812",
787 .longname = "RadioShack 22-812",
788 .api_version = 1,
789 .init = hw_init_radioshack_22_812,
790 .cleanup = hw_cleanup,
791 .scan = hw_scan,
792 .dev_list = hw_dev_list,
793 .dev_clear = clear_instances,
794 .dev_open = hw_dev_open,
795 .dev_close = hw_dev_close,
796 .info_get = hw_info_get,
797 .dev_config_set = hw_dev_config_set,
798 .dev_acquisition_start = hw_dev_acquisition_start,
799 .dev_acquisition_stop = hw_dev_acquisition_stop,
800 .priv = NULL,
801};