]> sigrok.org Git - libsigrok.git/blob - hardware/fx2lafw/fx2lafw.c
fx2lafw: Added probing for fx2lafw devices
[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 <glib.h>
23 #include <libusb.h>
24
25 #include "config.h"
26 #include "sigrok.h"
27 #include "sigrok-internal.h"
28 #include "fx2lafw.h"
29
30 static struct fx2lafw_profile supported_fx2[] = {
31         /* USBee AX */
32         { 0x08a9, 0x0014, "CWAV", "USBee AX", NULL, 8 },
33         { 0, 0, 0, 0, 0, 0 }
34 };
35
36 static GSList *device_instances = NULL;
37 static libusb_context *usb_context = NULL;
38
39 static struct fx2lafw_device* fx2lafw_device_new(void)
40 {
41         struct fx2lafw_device *fx2lafw;
42
43         if (!(fx2lafw = g_try_malloc0(sizeof(struct fx2lafw_device)))) {
44                 sr_err("fx2lafw: %s: fx2lafw_device malloc failed", __func__);
45                 return NULL;
46         }
47
48         return fx2lafw;
49 }
50
51 /*
52  * API callbacks
53  */
54
55 static int hw_init(const char *deviceinfo)
56 {
57         struct sr_dev_inst *sdi;
58         struct libusb_device_descriptor des;
59         struct fx2lafw_profile *fx2lafw_prof;
60         struct fx2lafw_device *fx2lafw_dev;
61         libusb_device **devlist;
62         int err;
63         int devcnt = 0;
64         int i, j;
65
66         /* Avoid compiler warnings. */
67         (void)deviceinfo;
68
69         if (libusb_init(&usb_context) != 0) {
70                 sr_warn("Failed to initialize USB.");
71                 return 0;
72         }
73
74         /* Find all fx2lafw compatible devices and upload firware to all of them. */
75         libusb_get_device_list(usb_context, &devlist);
76         for (i = 0; devlist[i]; i++) {
77
78                 if ((err = libusb_get_device_descriptor(
79                         devlist[i], &des)) != 0) {
80                         sr_warn("failed to get device descriptor: %d", err);
81                         continue;
82                 }
83
84                 fx2lafw_prof = NULL;
85                 for (j = 0; supported_fx2[j].vid; j++) {
86                         if (des.idVendor == supported_fx2[j].vid &&
87                                 des.idProduct == supported_fx2[j].pid) {
88                                 fx2lafw_prof = &supported_fx2[j];
89                         }
90                 }
91
92                 /* Skip if the device was not found */
93                 if(!fx2lafw_prof)
94                         continue;
95
96                 sdi = sr_dev_inst_new(devcnt, SR_ST_INITIALIZING,
97                         fx2lafw_prof->vendor, fx2lafw_prof->model,
98                         fx2lafw_prof->model_version);
99                 if(!sdi)
100                         return 0;
101
102                 fx2lafw_dev = fx2lafw_device_new();
103                 fx2lafw_dev->profile = fx2lafw_prof;
104                 sdi->priv = fx2lafw_dev;
105                 device_instances = g_slist_append(device_instances, sdi);
106
107                 devcnt++;
108         }
109         libusb_free_device_list(devlist, 1);
110
111         return devcnt;
112 }
113
114 static int hw_dev_open(int device_index)
115 {
116         (void)device_index;
117         return SR_OK;
118 }
119
120 static int hw_dev_close(int device_index)
121 {
122         (void)device_index;
123         return SR_OK;
124 }
125
126 static int hw_cleanup(void)
127 {
128         GSList *l;
129         struct sr_dev_inst *sdi;
130
131         for(l = device_instances; l; l = l->next) {
132                 sdi = l->data;
133                 sr_dev_inst_free(sdi);
134         }
135
136         g_slist_free(device_instances);
137         device_instances = NULL;
138
139         if(usb_context)
140                 libusb_exit(usb_context);
141         usb_context = NULL;
142
143         return SR_OK;
144 }
145
146 static void *hw_dev_info_get(int device_index, int device_info_id)
147 {
148         (void)device_index;
149         (void)device_info_id;
150         return NULL;
151 }
152
153 static int hw_dev_status_get(int device_index)
154 {
155         (void)device_index;
156         return SR_ST_NOT_FOUND;
157 }
158
159 static int *hw_hwcap_get_all(void)
160 {
161         return NULL;
162 }
163
164 static int hw_dev_config_set(int dev_index, int capability, void *value)
165 {
166         (void)dev_index;
167         (void)capability;
168         (void)value;
169         return SR_OK;
170 }
171
172 static int hw_dev_acquisition_start(int dev_index, gpointer session_data)
173 {
174         (void)dev_index;
175         (void)session_data;
176         return SR_OK;
177 }
178
179 /* This stops acquisition on ALL devices, ignoring device_index. */
180 static int hw_dev_acquisition_stop(int dev_index, gpointer session_data)
181 {
182         (void)dev_index;
183         (void)session_data;
184         return SR_OK;
185 }
186
187 SR_PRIV struct sr_dev_plugin fx2lafw_plugin_info = {
188         .name = "fx2lafw",
189         .longname = "fx2lafw",
190         .api_version = 1,
191         .init = hw_init,
192         .cleanup = hw_cleanup,
193         .dev_open = hw_dev_open,
194         .dev_close = hw_dev_close,
195         .dev_info_get = hw_dev_info_get,
196         .dev_status_get = hw_dev_status_get,
197         .hwcap_get_all = hw_hwcap_get_all,
198         .dev_config_set = hw_dev_config_set,
199         .dev_acquisition_start = hw_dev_acquisition_start,
200         .dev_acquisition_stop = hw_dev_acquisition_stop,
201 };