[EDGE_NEGATIVE] = "f",
};
-/* Initialize the SysClk LWLA driver.
- */
-static int init(struct sr_dev_driver *di, struct sr_context *sr_ctx)
-{
- return std_init(sr_ctx, di, LOG_PREFIX);
-}
-
/* Create a new sigrok device instance for the indicated LWLA model.
*/
static struct sr_dev_inst *dev_inst_new(const struct model_info *model)
const struct model_info *model;
struct sr_dev_inst *sdi;
struct libusb_device_descriptor des;
- int bus, address;
+ int bus, address, ret;
unsigned int vid, pid;
- int ret;
bus = libusb_get_bus_number(dev);
address = libusb_get_device_address(dev);
continue; /* no match */
/* Register device instance with driver. */
- sdi->driver = di;
- drvc->instances = g_slist_append(drvc->instances, sdi);
devices = g_slist_append(devices, sdi);
}
libusb_free_device_list(devlist, 1);
g_slist_free_full(conn_devices, (GDestroyNotify)&sr_usb_dev_inst_free);
- return devices;
-}
-
-/* Return the list of devices found during scan.
- */
-static GSList *dev_list(const struct sr_dev_driver *di)
-{
- struct drv_context *drvc;
-
- drvc = di->context;
-
- return drvc->instances;
+ return std_scan_complete(di, devices);
}
/* Destroy the private device context.
if (devc->acquisition) {
sr_err("Cannot clear device context during acquisition!");
- return; /* leak and pray */
+ return; /* Leak and pray. */
}
sr_dbg("Device context cleared.");
*/
static int drain_usb(struct sr_usb_dev_inst *usb, unsigned int endpoint)
{
- int drained, xfer_len;
- int ret;
+ int drained, xfer_len, ret;
unsigned char buf[512];
-
const unsigned int drain_timeout_ms = 10;
drained = 0;
sr_warn("Drained %d bytes from USB endpoint %u.",
drained, endpoint & (LIBUSB_ENDPOINT_IN - 1));
}
+
return SR_OK;
}
struct drv_context *drvc;
struct dev_context *devc;
struct sr_usb_dev_inst *usb;
- int ret;
+ int i, ret;
drvc = sdi->driver->context;
devc = sdi->priv;
usb = sdi->conn;
- if (!drvc) {
- sr_err("Driver was not initialized.");
- return SR_ERR;
- }
if (sdi->status != SR_ST_INACTIVE) {
sr_err("Device already open.");
return SR_ERR;
}
- ret = sr_usb_open(drvc->sr_ctx->libusb_ctx, usb);
- if (ret != SR_OK)
- return ret;
+ /* Try the whole shebang three times, fingers crossed. */
+ for (i = 0; i < 3; i++) {
+ ret = sr_usb_open(drvc->sr_ctx->libusb_ctx, usb);
+ if (ret != SR_OK)
+ return ret;
- ret = libusb_set_configuration(usb->devhdl, USB_CONFIG);
- if (ret != LIBUSB_SUCCESS) {
- sr_err("Failed to set USB configuration: %s.",
- libusb_error_name(ret));
- sr_usb_close(usb);
- return SR_ERR;
- }
+ ret = libusb_set_configuration(usb->devhdl, USB_CONFIG);
+ if (ret != LIBUSB_SUCCESS) {
+ sr_err("Failed to set USB configuration: %s.",
+ libusb_error_name(ret));
+ sr_usb_close(usb);
+ return SR_ERR;
+ }
- ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
- if (ret != LIBUSB_SUCCESS) {
- sr_err("Failed to claim interface: %s.",
- libusb_error_name(ret));
- sr_usb_close(usb);
- return SR_ERR;
- }
+ ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
+ if (ret != LIBUSB_SUCCESS) {
+ sr_err("Failed to claim interface: %s.",
+ libusb_error_name(ret));
+ sr_usb_close(usb);
+ return SR_ERR;
+ }
- ret = drain_usb(usb, EP_REPLY);
- if (ret != SR_OK) {
- sr_usb_close(usb);
- return ret;
- }
- /* This delay appears to be necessary for reliable operation. */
- g_usleep(30 * 1000);
+ ret = drain_usb(usb, EP_REPLY);
+ if (ret != SR_OK) {
+ sr_usb_close(usb);
+ return ret;
+ }
+ /* This delay appears to be necessary for reliable operation. */
+ g_usleep(30 * 1000);
- sdi->status = SR_ST_ACTIVE;
+ sdi->status = SR_ST_ACTIVE;
- devc->active_fpga_config = FPGA_NOCONF;
- devc->short_transfer_quirk = FALSE;
- devc->state = STATE_IDLE;
+ devc->active_fpga_config = FPGA_NOCONF;
+ devc->short_transfer_quirk = FALSE;
+ devc->state = STATE_IDLE;
- ret = (*devc->model->apply_fpga_config)(sdi);
+ ret = (*devc->model->apply_fpga_config)(sdi);
- if (ret == SR_OK)
- ret = (*devc->model->device_init_check)(sdi);
+ if (ret == SR_OK)
+ ret = (*devc->model->device_init_check)(sdi);
+ if (ret == SR_OK)
+ break;
- if (ret != SR_OK) {
+ /* Rinse and repeat. */
sdi->status = SR_ST_INACTIVE;
sr_usb_close(usb);
- return ret;
}
- if (devc->short_transfer_quirk)
+
+ if (ret == SR_OK && devc->short_transfer_quirk)
sr_warn("Short transfer quirk detected! "
"Memory reads will be slow.");
- return SR_OK;
+ return ret;
}
/* Shutdown and close device.
*/
static int dev_close(struct sr_dev_inst *sdi)
{
- struct drv_context *drvc;
struct dev_context *devc;
struct sr_usb_dev_inst *usb;
int ret;
- drvc = sdi->driver->context;
devc = sdi->priv;
usb = sdi->conn;
- if (!drvc) {
- sr_err("Driver was not initialized.");
- return SR_ERR;
- }
if (sdi->status == SR_ST_INACTIVE) {
sr_dbg("Device already closed.");
return SR_OK;
if ((model->devopts[i] & (SR_CONF_MASK | key)) == key)
return TRUE;
}
+
return FALSE;
}
return -1;
/* Linear search is fine for very small tables. */
- for (i = 0; i < len; ++i) {
+ for (i = 0; i < len; i++) {
if (strcmp(entry, table[i]) == 0)
return i;
}
+
return -1;
}
*/
static int prepare_trigger_masks(const struct sr_dev_inst *sdi)
{
- uint64_t trigger_mask;
- uint64_t trigger_values;
- uint64_t trigger_edge_mask;
+ uint64_t trigger_mask, trigger_values, trigger_edge_mask;
uint64_t level_bit, type_bit;
struct dev_context *devc;
struct sr_trigger *trigger;
match = node->data;
if (!match->channel->enabled)
- continue; /* ignore disabled channel */
+ continue; /* Ignore disabled channel. */
idx = match->channel->index;
trg = match->match;
if (idx < 0 || idx >= devc->model->num_channels) {
sr_err("Channel index %d out of range.", idx);
- return SR_ERR_BUG; /* should not happen */
+ return SR_ERR_BUG; /* Should not happen. */
}
if (trg != SR_TRIGGER_ZERO
&& trg != SR_TRIGGER_ONE
if (key == SR_CONF_SCAN_OPTIONS) {
*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
- scanopts, ARRAY_SIZE(scanopts),
- sizeof(scanopts[0]));
+ scanopts, ARRAY_SIZE(scanopts), sizeof(scanopts[0]));
return SR_OK;
}
if (!sdi) {
/* List driver capabilities. */
*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
- drvopts, ARRAY_SIZE(drvopts),
- sizeof(drvopts[0]));
+ drvopts, ARRAY_SIZE(drvopts), sizeof(drvopts[0]));
return SR_OK;
}
/* List the model's device options. */
if (key == SR_CONF_DEVICE_OPTIONS) {
*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
- devc->model->devopts,
- devc->model->num_devopts,
- sizeof(devc->model->devopts[0]));
+ devc->model->devopts, devc->model->num_devopts,
+ sizeof(devc->model->devopts[0]));
return SR_OK;
}
case SR_CONF_SAMPLERATE:
g_variant_builder_init(&gvb, G_VARIANT_TYPE_VARDICT);
gvar = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT64,
- devc->model->samplerates,
- devc->model->num_samplerates,
- sizeof(devc->model->samplerates[0]));
+ devc->model->samplerates, devc->model->num_samplerates,
+ sizeof(devc->model->samplerates[0]));
g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar);
*data = g_variant_builder_end(&gvb);
break;
case SR_CONF_TRIGGER_MATCH:
*data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
- trigger_matches,
- ARRAY_SIZE(trigger_matches),
- sizeof(trigger_matches[0]));
+ trigger_matches, ARRAY_SIZE(trigger_matches),
+ sizeof(trigger_matches[0]));
break;
case SR_CONF_TRIGGER_SOURCE:
*data = g_variant_new_strv(trigger_source_names,
- ARRAY_SIZE(trigger_source_names));
+ ARRAY_SIZE(trigger_source_names));
break;
case SR_CONF_TRIGGER_SLOPE:
case SR_CONF_CLOCK_EDGE:
*data = g_variant_new_strv(signal_edge_names,
- ARRAY_SIZE(signal_edge_names));
+ ARRAY_SIZE(signal_edge_names));
break;
default:
/* Must not happen for a key listed in devopts. */
* configured trigger conditions are met, or immediately if no triggers
* are configured.
*/
-static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
+static int dev_acquisition_start(const struct sr_dev_inst *sdi)
{
- (void)cb_data;
-
if (sdi->status != SR_ST_ACTIVE)
return SR_ERR_DEV_CLOSED;
/* Request that a running capture operation be stopped.
*/
-static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
+static int dev_acquisition_stop(struct sr_dev_inst *sdi)
{
struct dev_context *devc;
- (void)cb_data;
devc = sdi->priv;
if (sdi->status != SR_ST_ACTIVE)
devc->cancel_requested = TRUE;
sr_dbg("Stopping acquisition.");
}
+
return SR_OK;
}
/* SysClk LWLA driver descriptor.
*/
-SR_PRIV struct sr_dev_driver sysclk_lwla_driver_info = {
+static struct sr_dev_driver sysclk_lwla_driver_info = {
.name = "sysclk-lwla",
.longname = "SysClk LWLA series",
.api_version = 1,
- .init = init,
- .cleanup = dev_clear,
+ .init = std_init,
+ .cleanup = std_cleanup,
.scan = scan,
- .dev_list = dev_list,
+ .dev_list = std_dev_list,
.dev_clear = dev_clear,
.config_get = config_get,
.config_set = config_set,
.dev_acquisition_stop = dev_acquisition_stop,
.context = NULL,
};
+SR_REGISTER_DEV_DRIVER(sysclk_lwla_driver_info);