X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=hardware%2Fhantek-dso%2Fapi.c;h=d1b2f9b6c2cb2e6474634008fe519edbefb16281;hb=58453e5876ffae9153e9f4ddc2ad8dc244c7f26d;hp=8a7e9f744a434167b189eca699470e0aade44690;hpb=45c59c8bdd01954f9214fe7b869d92c55415d109;p=libsigrok.git diff --git a/hardware/hantek-dso/api.c b/hardware/hantek-dso/api.c index 8a7e9f74..d1b2f9b6 100644 --- a/hardware/hantek-dso/api.c +++ b/hardware/hantek-dso/api.c @@ -145,7 +145,8 @@ static const char *coupling[] = { }; SR_PRIV libusb_context *usb_context = NULL; -SR_PRIV GSList *dev_insts = NULL; +SR_PRIV struct sr_dev_driver hantek_dso_driver_info; +static struct sr_dev_driver *hdi = &hantek_dso_driver_info; static struct sr_dev_inst *dso_dev_new(int index, const struct dso_profile *prof) { @@ -156,6 +157,7 @@ static struct sr_dev_inst *dso_dev_new(int index, const struct dso_profile *prof prof->vendor, prof->model, NULL); if (!sdi) return NULL; + sdi->driver = hdi; if (!(ctx = g_try_malloc0(sizeof(struct context)))) { sr_err("hantek-dso: ctx malloc failed"); @@ -178,7 +180,7 @@ static struct sr_dev_inst *dso_dev_new(int index, const struct dso_profile *prof ctx->triggersource = g_strdup(DEFAULT_TRIGGER_SOURCE); ctx->triggerposition = DEFAULT_HORIZ_TRIGGERPOS; sdi->priv = ctx; - dev_insts = g_slist_append(dev_insts, sdi); + hdi->instances = g_slist_append(hdi->instances, sdi); return sdi; } @@ -200,29 +202,69 @@ static int configure_probes(struct context *ctx, const GSList *probes) return SR_OK; } -static int hw_init(const char *devinfo) +/* Properly close and free all devices. */ +static void clear_instances(void) { struct sr_dev_inst *sdi; - struct libusb_device_descriptor des; - const struct dso_profile *prof; struct context *ctx; - libusb_device **devlist; - int err, devcnt, i, j; + GSList *l; - /* Avoid compiler warnings. */ - (void)devinfo; + for (l = hdi->instances; l; l = l->next) { + if (!(sdi = l->data)) { + /* Log error, but continue cleaning up the rest. */ + sr_err("hantek-dso: %s: sdi was NULL, continuing", __func__); + continue; + } + if (!(ctx = sdi->priv)) { + /* Log error, but continue cleaning up the rest. */ + sr_err("hantek-dso: %s: sdi->priv was NULL, continuing", __func__); + continue; + } + dso_close(sdi); + sr_usb_dev_inst_free(ctx->usb); + g_free(ctx->triggersource); + + sr_dev_inst_free(sdi); + } + + g_slist_free(hdi->instances); + hdi->instances = NULL; + +} + +static int hw_init(void) +{ if (libusb_init(&usb_context) != 0) { sr_err("hantek-dso: Failed to initialize USB."); - return 0; + return SR_ERR; } - /* Find all Hantek DSO devices and upload firmware to all of them. */ + return SR_OK; +} + +static GSList *hw_scan(GSList *options) +{ + struct sr_dev_inst *sdi; + const struct dso_profile *prof; + struct context *ctx; + GSList *devices; + struct libusb_device_descriptor des; + libusb_device **devlist; + int devcnt, ret, i, j; + + (void)options; devcnt = 0; + devices = 0; + hdi->instances = NULL; + + clear_instances(); + + /* Find all Hantek DSO devices and upload firmware to all of them. */ libusb_get_device_list(usb_context, &devlist); for (i = 0; devlist[i]; i++) { - if ((err = libusb_get_device_descriptor(devlist[i], &des))) { - sr_err("hantek-dso: failed to get device descriptor: %d", err); + if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { + sr_err("hantek-dso: failed to get device descriptor: %d", ret); continue; } @@ -234,6 +276,7 @@ static int hw_init(const char *devinfo) prof = &dev_profiles[j]; sr_dbg("hantek-dso: Found a %s %s.", prof->vendor, prof->model); sdi = dso_dev_new(devcnt, prof); + devices = g_slist_append(devices, sdi); ctx = sdi->priv; if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, prof->firmware) == SR_OK) @@ -254,6 +297,7 @@ static int hw_init(const char *devinfo) sr_dbg("hantek-dso: Found a %s %s.", prof->vendor, prof->model); sdi = dso_dev_new(devcnt, prof); sdi->status = SR_ST_INACTIVE; + devices = g_slist_append(devices, sdi); ctx = sdi->priv; ctx->usb = sr_usb_dev_inst_new( libusb_get_bus_number(devlist[i]), @@ -268,7 +312,7 @@ static int hw_init(const char *devinfo) } libusb_free_device_list(devlist, 1); - return devcnt; + return devices; } static int hw_dev_open(int dev_index) @@ -278,7 +322,7 @@ static int hw_dev_open(int dev_index) int64_t timediff_us, timediff_ms; int err; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) + if (!(sdi = sr_dev_inst_get(hdi->instances, dev_index))) return SR_ERR_ARG; ctx = sdi->priv; @@ -323,7 +367,7 @@ static int hw_dev_close(int dev_index) { struct sr_dev_inst *sdi; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) + if (!(sdi = sr_dev_inst_get(hdi->instances, dev_index))) return SR_ERR_ARG; dso_close(sdi); @@ -333,31 +377,8 @@ static int hw_dev_close(int dev_index) static int hw_cleanup(void) { - GSList *l; - struct sr_dev_inst *sdi; - struct context *ctx; - /* Properly close and free all devices. */ - for (l = dev_insts; l; l = l->next) { - if (!(sdi = l->data)) { - /* Log error, but continue cleaning up the rest. */ - sr_err("hantek-dso: %s: sdi was NULL, continuing", __func__); - continue; - } - if (!(ctx = sdi->priv)) { - /* Log error, but continue cleaning up the rest. */ - sr_err("hantek-dso: %s: sdi->priv was NULL, continuing", __func__); - continue; - } - dso_close(sdi); - sr_usb_dev_inst_free(ctx->usb); - g_free(ctx->triggersource); - - sr_dev_inst_free(sdi); - } - - g_slist_free(dev_insts); - dev_insts = NULL; + clear_instances(); if (usb_context) libusb_exit(usb_context); @@ -366,71 +387,66 @@ static int hw_cleanup(void) return SR_OK; } -static const void *hw_dev_info_get(int dev_index, int dev_info_id) +static int hw_info_get(int info_id, const void **data, + const struct sr_dev_inst *sdi) { - struct sr_dev_inst *sdi; - const void *info; uint64_t tmp; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return NULL; - - info = NULL; - switch (dev_info_id) { + switch (info_id) { case SR_DI_INST: - info = sdi; + *data = sdi; + break; + case SR_DI_HWCAPS: + *data = hwcaps; break; case SR_DI_NUM_PROBES: - info = GINT_TO_POINTER(NUM_PROBES); + *data = GINT_TO_POINTER(NUM_PROBES); break; case SR_DI_PROBE_NAMES: - info = probe_names; + *data = probe_names; break; case SR_DI_BUFFERSIZES: - info = buffersizes; + *data = buffersizes; break; case SR_DI_TIMEBASES: - info = timebases; + *data = timebases; break; case SR_DI_TRIGGER_SOURCES: - info = trigger_sources; + *data = trigger_sources; break; case SR_DI_FILTERS: - info = filter_targets; + *data = filter_targets; break; case SR_DI_VDIVS: - info = vdivs; + *data = vdivs; break; case SR_DI_COUPLING: - info = coupling; + *data = coupling; break; /* TODO remove this */ case SR_DI_CUR_SAMPLERATE: - info = &tmp; + *data = &tmp; break; + default: + return SR_ERR_ARG; } - return info; + return SR_OK; } static int hw_dev_status_get(int dev_index) { struct sr_dev_inst *sdi; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) + if (!(sdi = sr_dev_inst_get(hdi->instances, dev_index))) return SR_ST_NOT_FOUND; return sdi->status; } -static const int *hw_hwcap_get_all(void) +static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap, + const void *value) { - return hwcaps; -} - -static int hw_dev_config_set(int dev_index, int hwcap, const void *value) -{ - struct sr_dev_inst *sdi; struct context *ctx; struct sr_rational tmp_rat; float tmp_float; @@ -438,9 +454,6 @@ static int hw_dev_config_set(int dev_index, int hwcap, const void *value) int ret, i; char **targets; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) - return SR_ERR; - if (sdi->status != SR_ST_ACTIVE) return SR_ERR; @@ -791,7 +804,7 @@ static int hw_dev_acquisition_start(int dev_index, void *cb_data) struct context *ctx; int i; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) + if (!(sdi = sr_dev_inst_get(hdi->instances, dev_index))) return SR_ERR; if (sdi->status != SR_ST_ACTIVE) @@ -838,7 +851,7 @@ static int hw_dev_acquisition_stop(int dev_index, void *cb_data) struct sr_dev_inst *sdi; struct context *ctx; - if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) + if (!(sdi = sr_dev_inst_get(hdi->instances, dev_index))) return SR_ERR; if (sdi->status != SR_ST_ACTIVE) @@ -859,12 +872,13 @@ SR_PRIV struct sr_dev_driver hantek_dso_driver_info = { .api_version = 1, .init = hw_init, .cleanup = hw_cleanup, + .scan = hw_scan, .dev_open = hw_dev_open, .dev_close = hw_dev_close, - .dev_info_get = hw_dev_info_get, + .info_get = hw_info_get, .dev_status_get = hw_dev_status_get, - .hwcap_get_all = hw_hwcap_get_all, .dev_config_set = hw_dev_config_set, .dev_acquisition_start = hw_dev_acquisition_start, .dev_acquisition_stop = hw_dev_acquisition_stop, + .instances = NULL, };