Index: Makefile.am
===================================================================
--- Makefile.am	(revision 1395)
+++ Makefile.am	(working copy)
@@ -124,6 +124,8 @@
 	freebsd_ppi.h \
 	ft245r.c \
 	ft245r.h \
+	ftdi_bb.c \
+	ftdi_bb.h \
 	jtagmkI.c \
 	jtagmkI.h \
 	jtagmkI_private.h \
Index: avrdude.conf.in
===================================================================
--- avrdude.conf.in	(revision 1395)
+++ avrdude.conf.in	(working copy)
@@ -771,6 +771,18 @@
   reset = 7;  # RI  X3(4)
 ;
 
+programmer
+  id    = "tc2030";
+  desc  = "Tag-Connect TC2030";
+  type  = "ftdi_bb";
+  connection_type = usb;
+  #                      FOR TPI devices:
+  mosi  = 1;  # TxD = D0 (wire to TPIDATA via 1k resistor)
+  miso  = 2;  # RxD = D1 (wire to TPIDATA directly)
+  sck   = 3;  # RTS = D2 (wire to SCK)
+  reset = 4;  # CTS = D3 (wire to ~RESET)
+;
+
 # website mentioned above uses this id
 programmer parent "arduino-ft232r"
   id    = "diecimila";
Index: configure.ac
===================================================================
--- configure.ac	(revision 1395)
+++ configure.ac	(working copy)
@@ -169,6 +169,8 @@
 AC_SUBST(LIBHIDAPI, $LIBHIDAPI)
 
 
+AH_TEMPLATE([HAVE_LIBFTD2XX],
+	    [Define if FTDI support is enabled via FTDI D2XX driver])
 AH_TEMPLATE([HAVE_LIBFTDI1],
             [Define if FTDI support is enabled via libftdi1])
 AH_TEMPLATE([HAVE_LIBFTDI],
@@ -177,6 +179,7 @@
             [Define if libftdi supports FT232H, libftdi version >= 0.20])
 AC_CHECK_LIB([ftdi1], [ftdi_new], [have_libftdi1=yes], [], [$LIBUSB_1_0])
 AC_CHECK_LIB([ftdi], [ftdi_usb_get_strings], [have_libftdi=yes], [], [-lusb])
+AC_CHECK_LIB([ftd2xx], [FT_Open], [have_libftd2xx=yes], [], [])
 if test x$have_libftdi1 = xyes; then
    LIBFTDI1="-lftdi1"
    AC_DEFINE([HAVE_LIBFTDI1])
@@ -190,6 +193,10 @@
       if test x$have_libftdi_FT232H = xyes; then
          AC_DEFINE([HAVE_LIBFTDI_TYPE_232H])
       fi
+   else
+      LIBFTD2XX="-lftd2xx"
+      AC_DEFINE([HAVE_LIBFTD2XX])
+      AC_SUBST(LIBFTD2XX, $LIBFTD2XX)
    fi
 fi
 AC_CHECK_HEADERS([pthread.h])
@@ -534,6 +541,16 @@
    echo "DON'T HAVE libftdi"
 fi
 
+if test x$have_libftd2xx = xyes; then
+   if test x$have_libftdi1 = xyes -o x$have_libftdi = xyes; then
+       echo "DO HAVE    libftd2xx (but prefer to use libftdi/libftdi1)"
+   else
+       echo "DO HAVE    libftd2xx"
+   fi
+else
+   echo "DON'T HAVE libftd2xx"
+fi
+
 if test x$have_libhid = xyes; then
    echo "DO HAVE    libhid"
 else
Index: ftdi_bb.c
===================================================================
--- ftdi_bb.c	(nonexistent)
+++ ftdi_bb.c	(working copy)
@@ -0,0 +1,510 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Support for bitbanging pins via the FTDI bitbang interface
+ *
+ * Copyright (C) 2017 David Mosberger <davidm@egauge.net>
+	Adapted from linuxgpio.c and ft245r.c.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#define DEBUG 0
+
+#include "ac_cfg.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "bitbang.h"
+#include "usbdevs.h"
+
+#if defined(HAVE_LIBFTDI1) && defined(HAVE_LIBUSB_1_0)
+# if defined(HAVE_LIBUSB_1_0_LIBUSB_H)
+#  include <libusb-1.0/libusb.h>
+# else
+#  include <libusb.h>
+# endif
+# include <libftdi1/ftdi.h>
+#elif defined(HAVE_LIBFTDI)
+# include <ftdi.h>
+#elif defined(HAVE_LIBFTD2XX)
+# include <ftd2xx.h>
+#else
+#warning No libftdi support. \
+	Install libftdi1 or libftdi and run configure/make again.
+# define DO_NOT_BUILD_FTDI_BB
+#endif
+
+const char ftdi_bb_desc[] = "Bitbanging via FTDI bitbang interface";
+
+#ifdef DO_NOT_BUILD_FTDI_BB
+
+void
+ftdi_bb_initpgm(PROGRAMMER *pgm)
+{
+  avrdude_message(MSG_INFO,
+		  "%s: FTDI support not available in this "
+		  "configuration\n", progname);
+}
+
+#else /* !DO_NOT_BUILD_FTDI_BB */
+
+#ifdef HAVE_LIBFTD2XX
+
+/* Emulate libftdi interface using FTD2XX API.  */
+
+struct ftdi_context {
+  FT_HANDLE handle;
+  FT_STATUS last_error;
+};
+
+#define BITMODE_RESET	FT_BITMODE_RESET
+#define BITMODE_BITBANG	FT_BITMODE_ASYNC_BITBANG
+
+static int
+ftdi_write_data(struct ftdi_context *ftdi, const unsigned char *buf, int size)
+{
+  FT_STATUS status;
+  DWORD nwritten;
+
+  status = FT_Write(ftdi->handle, (void *) buf, size, &nwritten);
+  if (status != FT_OK) {
+    ftdi->last_error = status;
+    return -1;
+  }
+  if (nwritten != size) {
+    ftdi->last_error = FT_IO_ERROR;
+    return -1;
+  }
+  return nwritten;
+}
+
+static int
+ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins)
+{
+  FT_STATUS status;
+
+  status = FT_GetBitMode(ftdi->handle, pins);
+  if (status != FT_OK) {
+    ftdi->last_error = status;
+    return -1;
+  }
+  return 0;
+}
+
+static int
+ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate)
+{
+  FT_STATUS status;
+
+  status = FT_SetBaudRate(ftdi->handle, 4*baudrate);
+  if (status != FT_OK) {
+    ftdi->last_error = status;
+    return -1;
+  }
+  return 0;
+}
+
+static int
+ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask,
+		 unsigned char mode)
+{
+  FT_STATUS status;
+
+  status = FT_SetBitMode(ftdi->handle, bitmask, mode);
+  if (status != FT_OK) {
+    ftdi->last_error = status;
+    return -1;
+  }
+  return 0;
+}
+
+static int
+ftdi_usb_close(struct ftdi_context *ftdi)
+{
+  FT_STATUS status;
+
+  status = FT_Close(ftdi->handle);
+  if (status != FT_OK) {
+    ftdi->last_error = status;
+    return -1;
+  }
+  return 0;
+}
+
+static void
+ftdi_deinit(struct ftdi_context *ftdi)
+{
+  return;
+}
+
+static const char *
+ftdi_get_error_string(struct ftdi_context *ftdi)
+{
+  switch (ftdi->last_error)
+    {
+    case FT_OK:			return "OK";
+    case FT_INVALID_HANDLE:	return "invalid handle";
+    case FT_DEVICE_NOT_FOUND:	return "device not found";
+    case FT_DEVICE_NOT_OPENED:	return "device not opened";
+    case FT_IO_ERROR:		return "I/O error";
+    case FT_INSUFFICIENT_RESOURCES: return "insufficient resources";
+    case FT_INVALID_PARAMETER:	return "invalid parameter";
+    case FT_INVALID_BAUD_RATE:	return "invalid baudrate";
+    case FT_DEVICE_NOT_OPENED_FOR_ERASE: return "device not opened for erase";
+    case FT_DEVICE_NOT_OPENED_FOR_WRITE: return "device not opened for write";
+    case FT_FAILED_TO_WRITE_DEVICE: return "failed to write device";
+    case FT_EEPROM_READ_FAILED:	return "EEPROM read failed";
+    case FT_EEPROM_WRITE_FAILED:return "EEPROM write failed";
+    case FT_EEPROM_ERASE_FAILED:return "EEPROM erase failed";
+    case FT_EEPROM_NOT_PRESENT:	return "EEPROM not present";
+    case FT_EEPROM_NOT_PROGRAMMED: return "EEPROM not programmed";
+    case FT_INVALID_ARGS:	return "invalid arguments";
+    case FT_NOT_SUPPORTED:	return "not supported";
+    case FT_OTHER_ERROR:	return "other error";
+    case FT_DEVICE_LIST_NOT_READY:
+      return "device list not ready";
+    default:
+      return "unknown error";
+    }
+}
+
+#endif /* !HAVE_LIBFTD2XX */
+
+#define FTDI_BB_TX_BUF_LEN	4096
+
+/* Current state of the FTDI chip: */
+struct ftdi_bb_pgm {
+  struct ftdi_context ctx;
+  uint8_t ddr;	// data-direction-register
+  uint8_t out;
+  uint8_t prev_out;
+  uint8_t in;
+  struct {
+    uint8_t buf[FTDI_BB_TX_BUF_LEN];
+    int len;
+  } tx;
+};
+
+static int
+ftdi_bb_flush(PROGRAMMER *pgm)
+{
+  struct ftdi_bb_pgm *ftdi_pgm = pgm->cookie;
+  int rv, len = ftdi_pgm->tx.len;
+
+  if (!len)
+    return 0;
+
+#if DEBUG
+  avrdude_message(MSG_INFO, "%s: tx_len=%d\n", __func__, len);
+#endif
+
+  rv = ftdi_write_data(&ftdi_pgm->ctx, ftdi_pgm->tx.buf, len);
+  if (rv != len) {
+    avrdude_message(MSG_INFO, "%s: write returned %d (expected %d)\n",
+		    __func__, rv, len);
+    return -1;
+  }
+  ftdi_pgm->tx.len = 0;
+  return 0;
+}
+
+static int
+ftdi_bb_setbits(PROGRAMMER *pgm)
+{
+  struct ftdi_bb_pgm *ftdi_pgm = pgm->cookie;
+  uint8_t byte = (ftdi_pgm->out >> 1);
+
+#if DEBUG
+  avrdude_message(MSG_INFO, "%s: out 0x%02x\n", __func__, byte);
+#endif
+
+  if (ftdi_pgm->tx.len > 0 && ftdi_pgm->tx.buf[ftdi_pgm->tx.len - 1] == byte)
+    return 1;	// no change, no need to send this byte...
+
+  ftdi_pgm->tx.buf[ftdi_pgm->tx.len++] = byte;
+  if (ftdi_pgm->tx.len >= FTDI_BB_TX_BUF_LEN)
+    ftdi_bb_flush(pgm);
+  return 1;
+}
+
+static int
+ftdi_bb_getbits(PROGRAMMER *pgm)
+{
+  struct ftdi_bb_pgm *ftdi_pgm = pgm->cookie;
+  uint8_t byte;
+
+  ftdi_bb_flush(pgm);
+  if (ftdi_read_pins(&ftdi_pgm->ctx, &byte) != 0)
+    return -1;
+  if (DEBUG)
+    avrdude_message(MSG_INFO, "%s:  in 0x%02x\n", __func__, byte);
+  ftdi_pgm->in = (byte << 1);
+  return 1;
+}
+
+static int
+ftdi_bb_set_bitclock(PROGRAMMER *pgm)
+{
+  struct ftdi_bb_pgm *ftdi_pgm = pgm->cookie;
+  int rate = 0;
+
+  /* Note: this is the clock which drives updating the bit, not the
+     clock at which the data gets sent/received.  That one is driven
+     by bitbang.c.  We want to update the pins as quickly as possible,
+     so we use the max. allowed baudrate of 3MHz.  */
+  rate = 3000000;
+  // libftdi1 multiplies bitbang baudrate by 4...
+  if (ftdi_set_baudrate(&ftdi_pgm->ctx, rate / 4)) {
+    avrdude_message(MSG_INFO,
+		    "%s: Set baudrate (%uHz) failed with error '%s'.\n",
+		    progname, rate, ftdi_get_error_string(&ftdi_pgm->ctx));
+    return -1;
+  }
+  return 0;
+}
+
+static int
+ftdi_bb_drain(PROGRAMMER *pgm, int display)
+{
+  struct ftdi_bb_pgm *ftdi_pgm = pgm->cookie;
+
+  if (ftdi_set_bitmode(&ftdi_pgm->ctx, 0, BITMODE_RESET))
+    return -1;
+  if (ftdi_set_bitmode(&ftdi_pgm->ctx, ftdi_pgm->ddr >> 1, BITMODE_BITBANG)) {
+    avrdude_message(MSG_INFO, "%s: bitbang mode is not supported (%s)\n",
+		    progname, ftdi_get_error_string(&ftdi_pgm->ctx));
+    return -1;
+  }
+  return 0;
+}
+
+static int
+ftdi_bb_setpin(PROGRAMMER *pgm, int pinname, int val)
+{
+  struct ftdi_bb_pgm *ftdi_pgm = pgm->cookie;
+  int rv;
+
+  if (pgm->pin[pinname].mask[0] == 0) {
+    /* Ignore undefined pins (might be the led or vcc or buff if not
+       needed). */
+    return 0;
+  }
+  ftdi_pgm->out = SET_BITS_0(ftdi_pgm->out, pgm, pinname, val);
+  rv = ftdi_bb_setbits(pgm);
+
+  if (pgm->ispdelay > 1)
+    bitbang_delay(pgm->ispdelay);
+  return rv;
+}
+
+static int
+ftdi_bb_getpin(PROGRAMMER *pgm, int pinname)
+{
+  struct ftdi_bb_pgm *ftdi_pgm = pgm->cookie;
+
+  if (ftdi_bb_getbits(pgm) != 1)
+    return -1;
+  return GET_BITS_0(ftdi_pgm->in, pgm, pinname) != 0;
+}
+
+static int
+ftdi_bb_highpulsepin(PROGRAMMER *pgm, int pinname)
+{
+  ftdi_bb_setpin(pgm, pinname, 1);
+  ftdi_bb_setpin(pgm, pinname, 0);
+  return 0;
+}
+
+static void
+ftdi_bb_display(PROGRAMMER *pgm, const char *p)
+{
+    avrdude_message(MSG_INFO, "%sPin assignment  : 0..7 = DBUS0..7\n", p);
+    pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS);
+}
+
+static void
+ftdi_bb_nop(PROGRAMMER *pgm)
+{
+  /* nothing */
+}
+
+static int
+ftdi_bb_open(PROGRAMMER *pgm, char *port)
+{
+  struct ftdi_bb_pgm *ftdi_pgm = pgm->cookie;
+  int rv, devnum = -1;
+
+  if (bitbang_check_prerequisites(pgm) < 0)
+    return -1;
+
+  strcpy(pgm->port, port);
+
+  if (strcmp(port, DEFAULT_USB) != 0) {
+    if (strncasecmp("ft", port, 2) == 0) {
+      char *startptr = port + 2;
+      char *endptr = NULL;
+      devnum = strtol(startptr, &endptr, 10);
+      if ((startptr==endptr) || (*endptr != '\0'))
+	devnum = -1;
+    }
+    if (devnum < 0) {
+      avrdude_message(MSG_INFO,
+		      "%s: invalid portname '%s': use 'ft[0-9]+'\n",
+		      progname, port);
+      return -1;
+    }
+  } else
+    devnum = 0;
+
+#ifdef HAVE_LIBFTD2XX
+  if (FT_Open(devnum, ftdi_pgm->ctx.handle) != FT_OK) {
+    avrdude_message(MSG_INFO, "%s: can't open FTDI device %d\n",
+		    progname, devnum);
+    goto cleanup_no_usb;
+  }
+#else
+  const char *desc, *sn;
+  LNODEID usbpid;
+  int vid, pid;
+
+  rv = ftdi_init(&ftdi_pgm->ctx);
+  if (rv != 0) {
+    avrdude_message(MSG_INFO, "%s: can't open FTDI device %d (%s)\n",
+		    progname, devnum,
+		    ftdi_get_error_string(&ftdi_pgm->ctx));
+    goto cleanup_no_usb;
+  }
+  usbpid = lfirst(pgm->usbpid);
+  if (usbpid) {
+    pid = *(int *)(ldata(usbpid));
+    if (lnext(usbpid))
+      avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, "
+		      "ignoring remaining PIDs in list\n",
+		      progname, pid);
+  } else
+    pid = USB_DEVICE_FT245;
+  vid = pgm->usbvid ? pgm->usbvid : USB_VENDOR_FTDI;
+  desc = pgm->usbproduct[0] ? pgm->usbproduct : NULL;
+  sn = pgm->usbsn[0] ? pgm->usbsn : NULL;
+  rv = ftdi_usb_open_desc_index(&ftdi_pgm->ctx, vid, pid, desc, sn,
+				devnum);
+  if (rv) {
+    avrdude_message(MSG_INFO, "%s: can't open FTDI device %d (%s)\n",
+		    progname, devnum,
+		    ftdi_get_error_string(&ftdi_pgm->ctx));
+    goto cleanup_no_usb;
+  }
+#endif
+
+  ftdi_pgm->ddr = (  pgm->pin[PIN_AVR_SCK].mask[0]
+		   | pgm->pin[PIN_AVR_MOSI].mask[0]
+		   | pgm->pin[PIN_AVR_RESET].mask[0]
+		   | pgm->pin[PPI_AVR_BUFF].mask[0]
+		   | pgm->pin[PPI_AVR_VCC].mask[0]
+		   | pgm->pin[PIN_LED_ERR].mask[0]
+		   | pgm->pin[PIN_LED_RDY].mask[0]
+		   | pgm->pin[PIN_LED_PGM].mask[0]
+		   | pgm->pin[PIN_LED_VFY].mask[0]);
+
+  /* set initial values for outputs, no reset, everything else is
+     off: */
+  ftdi_pgm->out = 0;
+  ftdi_pgm->out = SET_BITS_0(ftdi_pgm->out, pgm, PIN_AVR_RESET,1);
+  ftdi_pgm->out = SET_BITS_0(ftdi_pgm->out, pgm, PIN_AVR_SCK,0);
+  ftdi_pgm->out = SET_BITS_0(ftdi_pgm->out, pgm, PIN_AVR_MOSI,0);
+  ftdi_pgm->out = SET_BITS_0(ftdi_pgm->out, pgm, PPI_AVR_BUFF,0);
+  ftdi_pgm->out = SET_BITS_0(ftdi_pgm->out, pgm, PPI_AVR_VCC,0);
+  ftdi_pgm->out = SET_BITS_0(ftdi_pgm->out, pgm, PIN_LED_ERR,0);
+  ftdi_pgm->out = SET_BITS_0(ftdi_pgm->out, pgm, PIN_LED_RDY,0);
+  ftdi_pgm->out = SET_BITS_0(ftdi_pgm->out, pgm, PIN_LED_PGM,0);
+  ftdi_pgm->out = SET_BITS_0(ftdi_pgm->out, pgm, PIN_LED_VFY,0);
+
+  // drain any extraneous input:
+  ftdi_bb_drain(pgm, 0);
+
+  rv = ftdi_bb_set_bitclock(pgm);
+  if (rv)
+    goto cleanup;
+
+  ftdi_bb_setbits(pgm);
+  ftdi_bb_getbits(pgm);
+  return 0;
+
+ cleanup:
+  ftdi_usb_close(&ftdi_pgm->ctx);
+ cleanup_no_usb:
+  ftdi_deinit(&ftdi_pgm->ctx);
+  return -1;
+}
+
+static void
+ftdi_bb_close(PROGRAMMER *pgm)
+{
+  struct ftdi_bb_pgm *ftdi_pgm = pgm->cookie;
+
+  ftdi_set_bitmode(&ftdi_pgm->ctx, 0, BITMODE_RESET);
+  ftdi_usb_close(&ftdi_pgm->ctx);
+  ftdi_deinit(&ftdi_pgm->ctx);
+}
+
+void
+ftdi_bb_initpgm(PROGRAMMER *pgm)
+{
+  struct ftdi_bb_pgm *ftdi_pgm;
+
+  ftdi_pgm = calloc(sizeof(*ftdi_pgm), 1);
+  if (!ftdi_pgm) {
+    avrdude_message(MSG_INFO, "%s: out of memory\n", __func__);
+    exit(1);
+  }
+  pgm->cookie = ftdi_pgm;
+
+  strcpy(pgm->type, "ftdi_bb");
+
+  // TODO to be removed if old pin data no longer needed:
+  pgm_fill_old_pins(pgm);
+
+  pgm->rdy_led        = bitbang_rdy_led;
+  pgm->err_led        = bitbang_err_led;
+  pgm->pgm_led        = bitbang_pgm_led;
+  pgm->vfy_led        = bitbang_vfy_led;
+  pgm->initialize     = bitbang_initialize;
+  pgm->display        = ftdi_bb_display;
+  pgm->enable         = ftdi_bb_nop;
+  pgm->disable        = ftdi_bb_nop;
+  pgm->powerup        = ftdi_bb_nop;
+  pgm->powerdown      = ftdi_bb_nop;
+  pgm->program_enable = bitbang_program_enable;
+  pgm->chip_erase     = bitbang_chip_erase;
+  pgm->cmd            = bitbang_cmd;
+  pgm->cmd_tpi        = bitbang_cmd_tpi;
+  pgm->open           = ftdi_bb_open;
+  pgm->close          = ftdi_bb_close;
+  pgm->setpin         = ftdi_bb_setpin;
+  pgm->getpin         = ftdi_bb_getpin;
+  pgm->highpulsepin   = ftdi_bb_highpulsepin;
+  pgm->read_byte      = avr_read_byte_default;
+  pgm->write_byte     = avr_write_byte_default;
+}
+
+#endif /* !DO_NOT_BUILD_FTDI_BB */
Index: ftdi_bb.h
===================================================================
--- ftdi_bb.h	(nonexistent)
+++ ftdi_bb.h	(working copy)
@@ -0,0 +1,36 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2013 Radoslav Kolev <radoslav@kolev.info>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* $Id: par.h 722 2007-01-24 22:43:46Z joerg_wunsch $ */
+
+#ifndef ftdi_bb_h
+#define ftdi_bb_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char ftdi_bb_desc[];
+void ftdi_bb_initpgm        (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: pgm_type.c
===================================================================
--- pgm_type.c	(revision 1395)
+++ pgm_type.c	(working copy)
@@ -36,6 +36,7 @@
 #include "flip1.h"
 #include "flip2.h"
 #include "ft245r.h"
+#include "ftdi_bb.h"
 #include "jtagmkI.h"
 #include "jtagmkII.h"
 #include "jtag3.h"
@@ -68,6 +69,7 @@
         {"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc},
         {"flip1", flip1_initpgm, flip1_desc},
         {"flip2", flip2_initpgm, flip2_desc},
+        {"ftdi_bb", ftdi_bb_initpgm, ftdi_bb_desc},
         {"ftdi_syncbb", ft245r_initpgm, ft245r_desc},
         {"jtagmki", jtagmkI_initpgm, jtagmkI_desc},
         {"jtagmkii", jtagmkII_initpgm, jtagmkII_desc},
