]> sigrok.org Git - libsigrok.git/blob - hardware/fx2lafw/fx2lafw.c
fx2lafw: Renamed dev_insts variable in hw_init
[libsigrok.git] / hardware / fx2lafw / fx2lafw.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
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>
22 #include <inttypes.h>
23 #include <glib.h>
24 #include <libusb.h>
25
26 #include "config.h"
27 #include "sigrok.h"
28 #include "sigrok-internal.h"
29 #include "fx2lafw.h"
30
31 static struct fx2lafw_profile supported_fx2[] = {
32         /* USBee AX */
33         { 0x08a9, 0x0014, "CWAV", "USBee AX", NULL, 8 },
34         { 0, 0, 0, 0, 0, 0 }
35 };
36
37 static int fx2lafw_capabilities[] = {
38         SR_HWCAP_LOGIC_ANALYZER,
39         SR_HWCAP_SAMPLERATE,
40
41         /* These are really implemented in the driver, not the hardware. */
42         SR_HWCAP_LIMIT_SAMPLES,
43         SR_HWCAP_CONTINUOUS,
44         0
45 };
46
47 static const char *fx2lafw_probe_names[] = {
48         "D0",
49         "D1",
50         "D2",
51         "D3",
52         "D4",
53         "D5",
54         "D6",
55         "D7",
56         NULL
57 };
58
59 static uint64_t fx2lafw_supported_samplerates[] = {
60         SR_MHZ(1),
61         SR_MHZ(2),
62         SR_MHZ(3),
63         SR_MHZ(4),
64         SR_MHZ(6),
65         SR_MHZ(8),
66         SR_MHZ(12),
67         SR_MHZ(16),
68         SR_MHZ(24)
69 };
70
71 static struct sr_samplerates fx2lafw_samplerates = {
72         SR_MHZ(1),
73         SR_MHZ(24),
74         SR_HZ(0),
75         fx2lafw_supported_samplerates
76 };
77
78 static GSList *dev_insts = NULL;
79 static libusb_context *usb_context = NULL;
80
81 static struct fx2lafw_device* fx2lafw_device_new(void)
82 {
83         struct fx2lafw_device *fx2lafw;
84
85         if (!(fx2lafw = g_try_malloc0(sizeof(struct fx2lafw_device)))) {
86                 sr_err("fx2lafw: %s: fx2lafw_device malloc failed", __func__);
87                 return NULL;
88         }
89
90         return fx2lafw;
91 }
92
93 /*
94  * API callbacks
95  */
96
97 static int hw_init(const char *deviceinfo)
98 {
99         struct sr_dev_inst *sdi;
100         struct libusb_device_descriptor des;
101         struct fx2lafw_profile *fx2lafw_prof;
102         struct fx2lafw_device *fx2lafw_dev;
103         libusb_device **devlist;
104         int err;
105         int devcnt = 0;
106         int i, j;
107
108         /* Avoid compiler warnings. */
109         (void)deviceinfo;
110
111         if (libusb_init(&usb_context) != 0) {
112                 sr_warn("Failed to initialize USB.");
113                 return 0;
114         }
115
116         /* Find all fx2lafw compatible devices and upload firware to all of them. */
117         libusb_get_device_list(usb_context, &devlist);
118         for (i = 0; devlist[i]; i++) {
119
120                 if ((err = libusb_get_device_descriptor(
121                         devlist[i], &des)) != 0) {
122                         sr_warn("failed to get device descriptor: %d", err);
123                         continue;
124                 }
125
126                 fx2lafw_prof = NULL;
127                 for (j = 0; supported_fx2[j].vid; j++) {
128                         if (des.idVendor == supported_fx2[j].vid &&
129                                 des.idProduct == supported_fx2[j].pid) {
130                                 fx2lafw_prof = &supported_fx2[j];
131                         }
132                 }
133
134                 /* Skip if the device was not found */
135                 if(!fx2lafw_prof)
136                         continue;
137
138                 sdi = sr_dev_inst_new(devcnt, SR_ST_INITIALIZING,
139                         fx2lafw_prof->vendor, fx2lafw_prof->model,
140                         fx2lafw_prof->model_version);
141                 if(!sdi)
142                         return 0;
143
144                 fx2lafw_dev = fx2lafw_device_new();
145                 fx2lafw_dev->profile = fx2lafw_prof;
146                 sdi->priv = fx2lafw_dev;
147                 device_instances = g_slist_append(dev_insts, sdi);
148
149                 devcnt++;
150         }
151         libusb_free_device_list(devlist, 1);
152
153         return devcnt;
154 }
155
156 static int hw_dev_open(int device_index)
157 {
158         (void)device_index;
159         return SR_OK;
160 }
161
162 static int hw_dev_close(int device_index)
163 {
164         (void)device_index;
165         return SR_OK;
166 }
167
168 static int hw_cleanup(void)
169 {
170         GSList *l;
171         struct sr_dev_inst *sdi;
172
173         for(l = device_instances; l; l = l->next) {
174                 sdi = l->data;
175                 sr_dev_inst_free(sdi);
176         }
177
178         g_slist_free(device_instances);
179         device_instances = NULL;
180
181         if(usb_context)
182                 libusb_exit(usb_context);
183         usb_context = NULL;
184
185         return SR_OK;
186 }
187
188 static void *hw_dev_info_get(int device_index, int device_info_id)
189 {
190         struct sr_dev_inst *sdi;
191         struct fx2lafw_device *fx2lafw_dev;
192
193         if (!(sdi = sr_dev_inst_get(dev_insts, device_index)))
194                 return NULL;
195         fx2lafw_dev = sdi->priv;
196
197         switch (device_info_id) {
198         case SR_DI_INST:
199                 return sdi;
200         case SR_DI_NUM_PROBES:
201                 return GINT_TO_POINTER(fx2lafw_dev->profile->num_probes);
202         case SR_DI_PROBE_NAMES:
203                 return fx2lafw_probe_names;
204         case SR_DI_SAMPLERATES:
205                 return &fx2lafw_samplerates;
206         case SR_DI_TRIGGER_TYPES:
207                 return TRIGGER_TYPES;
208         }
209
210         return NULL;
211 }
212
213 static int hw_dev_status_get(int device_index)
214 {
215         const struct sr_dev_inst *const sdi =
216                 sr_dev_inst_get(dev_insts, device_index);
217
218         if (!sdi)
219                 return SR_ST_NOT_FOUND;
220
221         return sdi->status;
222 }
223
224 static int *hw_hwcap_get_all(void)
225 {
226         return fx2lafw_capabilities;
227 }
228
229 static int hw_dev_config_set(int dev_index, int capability, void *value)
230 {
231         (void)dev_index;
232         (void)capability;
233         (void)value;
234         return SR_OK;
235 }
236
237 static int hw_dev_acquisition_start(int dev_index, gpointer session_data)
238 {
239         (void)dev_index;
240         (void)session_data;
241         return SR_OK;
242 }
243
244 /* This stops acquisition on ALL devices, ignoring device_index. */
245 static int hw_dev_acquisition_stop(int dev_index, gpointer session_data)
246 {
247         (void)dev_index;
248         (void)session_data;
249         return SR_OK;
250 }
251
252 SR_PRIV struct sr_dev_plugin fx2lafw_plugin_info = {
253         .name = "fx2lafw",
254         .longname = "fx2lafw",
255         .api_version = 1,
256         .init = hw_init,
257         .cleanup = hw_cleanup,
258         .dev_open = hw_dev_open,
259         .dev_close = hw_dev_close,
260         .dev_info_get = hw_dev_info_get,
261         .dev_status_get = hw_dev_status_get,
262         .hwcap_get_all = hw_hwcap_get_all,
263         .dev_config_set = hw_dev_config_set,
264         .dev_acquisition_start = hw_dev_acquisition_start,
265         .dev_acquisition_stop = hw_dev_acquisition_stop,
266 };