]> sigrok.org Git - libsigrok.git/blobdiff - hardware/chronovu-la8/api.c
hantek-dso: instance list fix
[libsigrok.git] / hardware / chronovu-la8 / api.c
index 7d746889498f44f2b5e5db7f902bf900d50a8e39..7b671ab70a78e41ce6c5fe99db5fda95e82db40e 100644 (file)
 #include <ftdi.h>
 #include <glib.h>
 #include <string.h>
-#include "sigrok.h"
-#include "sigrok-internal.h"
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
 #include "driver.h"
 
-static GSList *dev_insts = NULL;
+SR_PRIV struct sr_dev_driver chronovu_la8_driver_info;
+static struct sr_dev_driver *cdi = &chronovu_la8_driver_info;
+
+/*
+ * The ChronoVu LA8 can have multiple PIDs. Older versions shipped with
+ * a standard FTDI USB VID/PID of 0403:6001, newer ones have 0403:8867.
+ */ 
+static const uint16_t usb_pids[] = {
+       0x6001,
+       0x8867,
+};
 
 /* Function prototypes. */
 static int hw_dev_acquisition_stop(int dev_index, void *cb_data);
 
-static int hw_init(const char *devinfo)
+static int hw_init(void)
+{
+
+       /* Nothing to do. */
+
+       return SR_OK;
+}
+
+static int hw_scan(void)
 {
        int ret;
        struct sr_dev_inst *sdi;
        struct context *ctx;
-
-       /* Avoid compiler errors. */
-       (void)devinfo;
+       unsigned int i;
 
        /* Allocate memory for our private driver context. */
        if (!(ctx = g_try_malloc(sizeof(struct context)))) {
@@ -60,6 +76,7 @@ static int hw_init(const char *devinfo)
        ctx->done = 0;
        ctx->block_counter = 0;
        ctx->divcount = 0; /* 10ns sample period == 100MHz samplerate */
+       ctx->usb_pid = 0;
 
        /* Allocate memory where we'll store the de-mangled data. */
        if (!(ctx->final_buf = g_try_malloc(SDRAM_SIZE))) {
@@ -74,13 +91,20 @@ static int hw_init(const char *devinfo)
        }
 
        /* Check for the device and temporarily open it. */
-       if ((ret = ftdi_usb_open_desc(ctx->ftdic, USB_VENDOR_ID,
-                       USB_PRODUCT_ID, USB_DESCRIPTION, NULL)) < 0) {
-               (void) la8_close_usb_reset_sequencer(ctx); /* Ignore errors. */
-               goto err_free_ftdic;
+       for (i = 0; i < ARRAY_SIZE(usb_pids); i++) {
+               sr_dbg("la8: Probing for VID/PID %04x:%04x.", USB_VENDOR_ID,
+                      usb_pids[i]);
+               ret = ftdi_usb_open_desc(ctx->ftdic, USB_VENDOR_ID,
+                                        usb_pids[i], USB_DESCRIPTION, NULL);
+               if (ret == 0) {
+                       sr_dbg("la8: Found LA8 device (%04x:%04x).",
+                              USB_VENDOR_ID, usb_pids[i]);
+                       ctx->usb_pid = usb_pids[i];
+               }
        }
-       sr_dbg("la8: Found LA8 device (%04x:%04x).", USB_VENDOR_ID,
-              USB_PRODUCT_ID);
+
+       if (ctx->usb_pid == 0)
+               goto err_free_ftdic;
 
        /* Register the device with libsigrok. */
        sdi = sr_dev_inst_new(0, SR_ST_INITIALIZING,
@@ -92,7 +116,7 @@ static int hw_init(const char *devinfo)
 
        sdi->priv = ctx;
 
-       dev_insts = g_slist_append(dev_insts, sdi);
+       cdi->instances = g_slist_append(cdi->instances, sdi);
 
        sr_spew("la8: Device init successful.");
 
@@ -120,7 +144,7 @@ static int hw_dev_open(int dev_index)
        struct sr_dev_inst *sdi;
        struct context *ctx;
 
-       if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+       if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
                sr_err("la8: %s: sdi was NULL", __func__);
                return SR_ERR_BUG;
        }
@@ -131,11 +155,11 @@ static int hw_dev_open(int dev_index)
        }
 
        sr_dbg("la8: Opening LA8 device (%04x:%04x).", USB_VENDOR_ID,
-              USB_PRODUCT_ID);
+              ctx->usb_pid);
 
        /* Open the device. */
        if ((ret = ftdi_usb_open_desc(ctx->ftdic, USB_VENDOR_ID,
-                       USB_PRODUCT_ID, USB_DESCRIPTION, NULL)) < 0) {
+                       ctx->usb_pid, USB_DESCRIPTION, NULL)) < 0) {
                sr_err("la8: %s: ftdi_usb_open_desc: (%d) %s",
                       __func__, ret, ftdi_get_error_string(ctx->ftdic));
                (void) la8_close_usb_reset_sequencer(ctx); /* Ignore errors. */
@@ -178,7 +202,7 @@ static int hw_dev_close(int dev_index)
        struct sr_dev_inst *sdi;
        struct context *ctx;
 
-       if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+       if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
                sr_err("la8: %s: sdi was NULL", __func__);
                return SR_ERR_BUG;
        }
@@ -213,7 +237,7 @@ static int hw_cleanup(void)
        int ret = SR_OK;
 
        /* Properly close all devices. */
-       for (l = dev_insts; l; l = l->next) {
+       for (l = cdi->instances; l; l = l->next) {
                if (!(sdi = l->data)) {
                        /* Log error, but continue cleaning up the rest. */
                        sr_err("la8: %s: sdi was NULL, continuing", __func__);
@@ -222,8 +246,8 @@ static int hw_cleanup(void)
                }
                sr_dev_inst_free(sdi); /* Returns void. */
        }
-       g_slist_free(dev_insts); /* Returns void. */
-       dev_insts = NULL;
+       g_slist_free(cdi->instances); /* Returns void. */
+       cdi->instances = NULL;
 
        return ret;
 }
@@ -234,7 +258,7 @@ static const void *hw_dev_info_get(int dev_index, int dev_info_id)
        struct context *ctx;
        const void *info;
 
-       if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+       if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
                sr_err("la8: %s: sdi was NULL", __func__);
                return NULL;
        }
@@ -267,7 +291,7 @@ static const void *hw_dev_info_get(int dev_index, int dev_info_id)
                sr_spew("la8: %s: Returning samplerates.", __func__);
                break;
        case SR_DI_TRIGGER_TYPES:
-               info = (char *)TRIGGER_TYPES;
+               info = TRIGGER_TYPES;
                sr_spew("la8: %s: Returning trigger types: %s.", __func__,
                        TRIGGER_TYPES);
                break;
@@ -290,7 +314,7 @@ 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(cdi->instances, dev_index))) {
                sr_err("la8: %s: sdi was NULL, device not found", __func__);
                return SR_ST_NOT_FOUND;
        }
@@ -312,7 +336,7 @@ static int hw_dev_config_set(int dev_index, int hwcap, const void *value)
        struct sr_dev_inst *sdi;
        struct context *ctx;
 
-       if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+       if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
                sr_err("la8: %s: sdi was NULL", __func__);
                return SR_ERR_BUG;
        }
@@ -424,7 +448,7 @@ static int hw_dev_acquisition_start(int dev_index, void *cb_data)
        uint8_t buf[4];
        int bytes_written;
 
-       if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+       if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
                sr_err("la8: %s: sdi was NULL", __func__);
                return SR_ERR_BUG;
        }
@@ -503,7 +527,7 @@ static int hw_dev_acquisition_stop(int dev_index, void *cb_data)
 
        sr_dbg("la8: Stopping acquisition.");
 
-       if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+       if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
                sr_err("la8: %s: sdi was NULL", __func__);
                return SR_ERR_BUG;
        }
@@ -527,6 +551,7 @@ SR_PRIV struct sr_dev_driver chronovu_la8_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,
@@ -535,4 +560,5 @@ SR_PRIV struct sr_dev_driver chronovu_la8_driver_info = {
        .dev_config_set = hw_dev_config_set,
        .dev_acquisition_start = hw_dev_acquisition_start,
        .dev_acquisition_stop = hw_dev_acquisition_stop,
+       .instances = NULL,
 };