+ struct dev_context *devc;
+ int ret;
+
+ devc = sdi->priv;
+
+ /* Select interface A, otherwise communication will fail. */
+ ret = ftdi_set_interface(devc->ftdic, INTERFACE_A);
+ if (ret < 0) {
+ sr_err("Failed to set FTDI interface A (%d): %s", ret,
+ ftdi_get_error_string(devc->ftdic));
+ return SR_ERR;
+ }
+ sr_dbg("FTDI chip interface A set successfully.");
+
+ /* Open the device. */
+ ret = ftdi_usb_open_desc(devc->ftdic, USB_VENDOR_ID, USB_DEVICE_ID,
+ USB_IPRODUCT, NULL);
+ if (ret < 0) {
+ sr_err("Failed to open device (%d): %s", ret,
+ ftdi_get_error_string(devc->ftdic));
+ return SR_ERR;
+ }
+ sr_dbg("FTDI device opened successfully.");
+
+ /* Purge RX/TX buffers in the FTDI chip. */
+ if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0) {
+ sr_err("Failed to purge FTDI RX/TX buffers (%d): %s.",
+ ret, ftdi_get_error_string(devc->ftdic));
+ goto err_dev_open_close_ftdic;
+ }
+ sr_dbg("FTDI chip buffers purged successfully.");
+
+ /* Reset the FTDI bitmode. */
+ ret = ftdi_set_bitmode(devc->ftdic, 0xff, BITMODE_RESET);
+ if (ret < 0) {
+ sr_err("Failed to reset the FTDI chip bitmode (%d): %s.",
+ ret, ftdi_get_error_string(devc->ftdic));
+ goto err_dev_open_close_ftdic;
+ }
+ sr_dbg("FTDI chip bitmode reset successfully.");
+
+ /* Set FTDI bitmode to "sync FIFO". */
+ ret = ftdi_set_bitmode(devc->ftdic, 0xff, BITMODE_SYNCFF);
+ if (ret < 0) {
+ sr_err("Failed to put FTDI chip into sync FIFO mode (%d): %s.",
+ ret, ftdi_get_error_string(devc->ftdic));
+ goto err_dev_open_close_ftdic;
+ }
+ sr_dbg("FTDI chip sync FIFO mode entered successfully.");
+
+ /* Set the FTDI latency timer to 2. */
+ ret = ftdi_set_latency_timer(devc->ftdic, 2);
+ if (ret < 0) {
+ sr_err("Failed to set FTDI latency timer (%d): %s.",
+ ret, ftdi_get_error_string(devc->ftdic));
+ goto err_dev_open_close_ftdic;
+ }
+ sr_dbg("FTDI chip latency timer set successfully.");
+
+ /* Set the FTDI read data chunk size to 64kB. */
+ ret = ftdi_read_data_set_chunksize(devc->ftdic, 64 * 1024);
+ if (ret < 0) {
+ sr_err("Failed to set FTDI read data chunk size (%d): %s.",
+ ret, ftdi_get_error_string(devc->ftdic));
+ goto err_dev_open_close_ftdic;
+ }
+ sr_dbg("FTDI chip read data chunk size set successfully.");
+
+ /* Get the ScanaPLUS device ID from the FTDI EEPROM. */
+ if ((ret = scanaplus_get_device_id(devc)) < 0) {
+ sr_err("Failed to get ScanaPLUS device ID: %d.", ret);
+ goto err_dev_open_close_ftdic;
+ }
+ sr_dbg("Received ScanaPLUS device ID successfully: %02x %02x %02x.",
+ devc->devid[0], devc->devid[1], devc->devid[2]);