]> sigrok.org Git - libsigrok.git/blob - hardware/lascar-el-usb/api.c
lascar-el-usb: add scanning functionality
[libsigrok.git] / hardware / lascar-el-usb / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
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 <glib.h>
21 #include <libusb.h>
22 #include "libsigrok.h"
23 #include "libsigrok-internal.h"
24 #include "protocol.h"
25
26 SR_PRIV struct sr_dev_inst *lascar_scan(int bus, int address);
27 SR_PRIV struct sr_dev_driver lascar_el_usb_driver_info;
28 static struct sr_dev_driver *di = &lascar_el_usb_driver_info;
29 static int hw_dev_close(struct sr_dev_inst *sdi);
30 static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
31
32 static const int hwopts[] = {
33         SR_HWOPT_CONN,
34         0,
35 };
36
37 static const int hwcaps[] = {
38         SR_HWCAP_THERMOMETER,
39         SR_HWCAP_HYGROMETER,
40         SR_HWCAP_LIMIT_SAMPLES,
41         0
42 };
43
44 static const char *probe_names[] = {
45         "P1",
46 };
47
48
49 /* Properly close and free all devices. */
50 static int clear_instances(void)
51 {
52         struct sr_dev_inst *sdi;
53         struct drv_context *drvc;
54         struct dev_context *devc;
55         GSList *l;
56
57         if (!(drvc = di->priv))
58                 return SR_OK;
59
60         for (l = drvc->instances; l; l = l->next) {
61                 if (!(sdi = l->data))
62                         continue;
63                 if (!(devc = sdi->priv))
64                         continue;
65
66                 hw_dev_close(sdi);
67                 sr_usb_dev_inst_free(devc->usb);
68                 sr_dev_inst_free(sdi);
69         }
70
71         g_slist_free(drvc->instances);
72         drvc->instances = NULL;
73
74         return SR_OK;
75 }
76
77 static int hw_init(struct sr_context *sr_ctx)
78 {
79         struct drv_context *drvc;
80
81         if (!(drvc = g_try_malloc0(sizeof(struct drv_context)))) {
82                 sr_err("Driver context malloc failed.");
83                 return SR_ERR_MALLOC;
84         }
85
86         drvc->sr_ctx = sr_ctx;
87         di->priv = drvc;
88
89         return SR_OK;
90 }
91
92 static GSList *hw_scan(GSList *options)
93 {
94         struct drv_context *drvc;
95         struct dev_context *devc;
96         struct sr_dev_inst *sdi;
97         struct sr_usb_dev_inst *usb;
98         struct sr_probe *probe;
99         struct sr_hwopt *opt;
100         GSList *usb_devices, *devices, *l;
101         const char *conn;
102
103         (void)options;
104
105         if (!(drvc = di->priv)) {
106                 sr_err("Driver was not initialized.");
107                 return NULL;
108         }
109
110         /* USB scan is always authoritative. */
111         clear_instances();
112
113         conn = NULL;
114         for (l = options; l; l = l->next) {
115                 opt = l->data;
116                 switch (opt->hwopt) {
117                 case SR_HWOPT_CONN:
118                         conn = opt->value;
119                         break;
120                 }
121         }
122         if (!conn)
123                 return NULL;
124
125         devices = NULL;
126         if ((usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn))) {
127                 /* We have a list of sr_usb_dev_inst matching the connection
128                  * string. Wrap them in sr_dev_inst and we're done. */
129                 for (l = usb_devices; l; l = l->next) {
130                         usb = l->data;
131                         if (!(sdi = lascar_scan(usb->bus, usb->address))) {
132                                 /* Not a Lascar EL-USB. */
133                                 g_free(usb);
134                                 continue;
135                         }
136                         if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
137                                 sr_err("Device context malloc failed.");
138                                 return NULL;
139                         }
140                         devc->usb = usb;
141                         sdi->priv = devc;
142                         if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1")))
143                                 return NULL;
144                         sdi->probes = g_slist_append(sdi->probes, probe);
145                         drvc->instances = g_slist_append(drvc->instances, sdi);
146                         devices = g_slist_append(devices, sdi);
147                 }
148                 g_slist_free(usb_devices);
149         } else
150                 g_slist_free_full(usb_devices, g_free);
151
152         return devices;
153 }
154
155 static GSList *hw_dev_list(void)
156 {
157         struct drv_context *drvc;
158
159         drvc = di->priv;
160
161         return drvc->instances;
162 }
163
164 static int hw_dev_open(struct sr_dev_inst *sdi)
165 {
166         /* TODO */
167
168         return SR_OK;
169 }
170
171 static int hw_dev_close(struct sr_dev_inst *sdi)
172 {
173         /* TODO */
174
175         return SR_OK;
176 }
177
178 static int hw_cleanup(void)
179 {
180         clear_instances();
181
182         /* TODO */
183
184         return SR_OK;
185 }
186
187 static int hw_info_get(int info_id, const void **data,
188                 const struct sr_dev_inst *sdi)
189 {
190         switch (info_id) {
191         /* TODO */
192         default:
193                 sr_err("Unknown info_id: %d.", info_id);
194                 return SR_ERR_ARG;
195         }
196
197         return SR_OK;
198 }
199
200 static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
201                 const void *value)
202 {
203         int ret;
204
205         if (sdi->status != SR_ST_ACTIVE) {
206                 sr_err("Device inactive, can't set config options.");
207                 return SR_ERR;
208         }
209
210         ret = SR_OK;
211         switch (hwcap) {
212         /* TODO */
213         default:
214                 sr_err("Unknown hardware capability: %d.", hwcap);
215                 ret = SR_ERR_ARG;
216         }
217
218         return ret;
219 }
220
221 static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
222                 void *cb_data)
223 {
224         /* TODO */
225
226         return SR_OK;
227 }
228
229 static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
230 {
231         (void)cb_data;
232
233         if (sdi->status != SR_ST_ACTIVE) {
234                 sr_err("Device inactive, can't stop acquisition.");
235                 return SR_ERR;
236         }
237
238         /* TODO */
239
240         return SR_OK;
241 }
242
243 SR_PRIV struct sr_dev_driver lascar_el_usb_driver_info = {
244         .name = "lascar-el-usb",
245         .longname = "Lascar EL-USB",
246         .api_version = 1,
247         .init = hw_init,
248         .cleanup = hw_cleanup,
249         .scan = hw_scan,
250         .dev_list = hw_dev_list,
251         .dev_clear = clear_instances,
252         .dev_open = hw_dev_open,
253         .dev_close = hw_dev_close,
254         .info_get = hw_info_get,
255         .dev_config_set = hw_dev_config_set,
256         .dev_acquisition_start = hw_dev_acquisition_start,
257         .dev_acquisition_stop = hw_dev_acquisition_stop,
258         .priv = NULL,
259 };