diff --git a/CMakeLists.txt b/CMakeLists.txt
index bfd4ab24..e3d6f8dd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -182,6 +182,9 @@ endif()
 # Find libhidapi
 
 find_library(HAVE_LIBHID NAMES hid)
+if(HAVE_LIBHID)
+    set(LIB_LIBHID ${HAVE_LIBHID})
+endif()
 
 find_library(HAVE_LIBHIDAPI NAMES ${PREFERRED_LIBHIDAPI})
 if(HAVE_LIBHIDAPI)
diff --git a/NEWS b/NEWS
index 8f21dfb7..341aa642 100644
--- a/NEWS
+++ b/NEWS
@@ -131,6 +131,7 @@ Changes since version 6.4:
     - Add fuse name aliases to avrdude.conf + tweak update.c #869
     - Print JTAG3 clocks after configuration + string formatting #853
     - Tweak programmer info formatting strings #872
+    - Remove libhid support in ser_avrdoper.c in favor of libhidapi #882
 
   * Internals:
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2c8ee2f1..a8e0262b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -239,6 +239,7 @@ target_link_libraries(libavrdude
     ${LIB_LIBELF}
     ${LIB_LIBUSB}
     ${LIB_LIBUSB_1_0}
+    ${LIB_LIBHID}
     ${LIB_LIBHIDAPI}
     ${LIB_LIBFTDI}
     ${LIB_LIBFTDI1}
diff --git a/src/ser_avrdoper.c b/src/ser_avrdoper.c
index 2e90f0eb..a8414403 100644
--- a/src/ser_avrdoper.c
+++ b/src/ser_avrdoper.c
@@ -26,11 +26,12 @@
 
 #include "ac_cfg.h"
 
-#if defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID))
+#if defined(HAVE_LIBHIDAPI)
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <hidapi/hidapi.h>
 
 #include "avrdude.h"
 #include "libavrdude.h"
@@ -64,12 +65,6 @@ static int              avrdoperRxPosition = 0; /* amount of bytes already consu
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
 
-#if defined(HAVE_LIBHIDAPI)
-
-#include <hidapi/hidapi.h>
-
-/* ------------------------------------------------------------------------- */
-
 static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
 			 int product, char *productName, int doReportIDs)
 {
@@ -154,181 +149,6 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
 
-#else /* !defined(HAVE_LIBHIDAPI) */
-
-/* ------------------------------------------------------------------------ */
-/* ------------------------------------------------------------------------ */
-/* ------------------------------------------------------------------------ */
-
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <setupapi.h>
-#include <hidsdi.h>
-#include <hidpi.h>
-
-#ifdef USB_DEBUG
-#define DEBUG_PRINT(arg)    printf arg
-#else
-#define DEBUG_PRINT(arg)
-#endif
-
-/* ------------------------------------------------------------------------ */
-
-static void convertUniToAscii(char *buffer)
-{
-    unsigned short  *uni = (void *)buffer;
-    char            *ascii = buffer;
-
-    while(*uni != 0){
-        if(*uni >= 256){
-            *ascii++ = '?';
-            uni++;
-        }else{
-            *ascii++ = *uni++;
-        }
-    }
-    *ascii++ = 0;
-}
-
-static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
-			 int product, char *productName, int usesReportIDs)
-{
-    GUID                                hidGuid;        /* GUID for HID driver */
-    HDEVINFO                            deviceInfoList;
-    SP_DEVICE_INTERFACE_DATA            deviceInfo;
-    SP_DEVICE_INTERFACE_DETAIL_DATA     *deviceDetails = NULL;
-    DWORD                               size;
-    int                                 i, openFlag = 0;  /* may be FILE_FLAG_OVERLAPPED */
-    int                                 errorCode = USB_ERROR_NOTFOUND;
-    HANDLE                              handle = INVALID_HANDLE_VALUE;
-    HIDD_ATTRIBUTES                     deviceAttributes;
-
-    HidD_GetHidGuid(&hidGuid);
-    deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
-					 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
-    deviceInfo.cbSize = sizeof(deviceInfo);
-    for(i=0;;i++){
-        if(handle != INVALID_HANDLE_VALUE){
-            CloseHandle(handle);
-            handle = INVALID_HANDLE_VALUE;
-        }
-        if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))
-            break;  /* no more entries */
-        /* first do a dummy call just to determine the actual size required */
-        SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
-        if(deviceDetails != NULL)
-            free(deviceDetails);
-        deviceDetails = malloc(size);
-        deviceDetails->cbSize = sizeof(*deviceDetails);
-        /* this call is for real: */
-        SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails,
-					size, &size, NULL);
-        DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath));
-        /* attempt opening for R/W -- we don't care about devices which can't be accessed */
-        handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE,
-			    FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
-			    openFlag, NULL);
-        if(handle == INVALID_HANDLE_VALUE){
-            DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError()));
-            /* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */
-            continue;
-        }
-        deviceAttributes.Size = sizeof(deviceAttributes);
-        HidD_GetAttributes(handle, &deviceAttributes);
-        DEBUG_PRINT(("device attributes: vid=%d pid=%d\n",
-		     deviceAttributes.VendorID, deviceAttributes.ProductID));
-        if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)
-            continue;   /* ignore this device */
-        errorCode = USB_ERROR_NOTFOUND;
-        if(vendorName != NULL && productName != NULL){
-            char    buffer[512];
-            if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){
-                DEBUG_PRINT(("error obtaining vendor name\n"));
-                errorCode = USB_ERROR_IO;
-                continue;
-            }
-            convertUniToAscii(buffer);
-            DEBUG_PRINT(("vendorName = \"%s\"\n", buffer));
-            if(strcmp(vendorName, buffer) != 0)
-                continue;
-            if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){
-                DEBUG_PRINT(("error obtaining product name\n"));
-                errorCode = USB_ERROR_IO;
-                continue;
-            }
-            convertUniToAscii(buffer);
-            DEBUG_PRINT(("productName = \"%s\"\n", buffer));
-            if(strcmp(productName, buffer) != 0)
-                continue;
-        }
-        break;  /* we have found the device we are looking for! */
-    }
-    SetupDiDestroyDeviceInfoList(deviceInfoList);
-    if(deviceDetails != NULL)
-        free(deviceDetails);
-    if(handle != INVALID_HANDLE_VALUE){
-	fdp->pfd = (void *)handle;
-	errorCode = 0;
-    }
-    return errorCode;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static void    usbCloseDevice(union filedescriptor *fdp)
-{
-    CloseHandle((HANDLE)fdp->pfd);
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
-{
-    HANDLE  handle = (HANDLE)fdp->pfd;
-    BOOLEAN rval = 0;
-    DWORD   bytesWritten;
-
-    switch(reportType){
-    case USB_HID_REPORT_TYPE_INPUT:
-        break;
-    case USB_HID_REPORT_TYPE_OUTPUT:
-        rval = WriteFile(handle, buffer, len, &bytesWritten, NULL);
-        break;
-    case USB_HID_REPORT_TYPE_FEATURE:
-        rval = HidD_SetFeature(handle, buffer, len);
-        break;
-    }
-    return rval == 0 ? USB_ERROR_IO : 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
-			char *buffer, int *len)
-{
-    HANDLE  handle = (HANDLE)fdp->pfd;
-    BOOLEAN rval = 0;
-    DWORD   bytesRead;
-
-    switch(reportType){
-    case USB_HID_REPORT_TYPE_INPUT:
-        buffer[0] = reportNumber;
-        rval = ReadFile(handle, buffer, *len, &bytesRead, NULL);
-        if(rval)
-            *len = bytesRead;
-        break;
-    case USB_HID_REPORT_TYPE_OUTPUT:
-        break;
-    case USB_HID_REPORT_TYPE_FEATURE:
-        buffer[0] = reportNumber;
-        rval = HidD_GetFeature(handle, buffer, *len);
-        break;
-    }
-    return rval == 0 ? USB_ERROR_IO : 0;
-}
-
-#endif  /* WIN32 */
 
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
@@ -551,4 +371,4 @@ struct serial_device avrdoper_serdev =
   .flags = SERDEV_FL_NONE,
 };
 
-#endif /* defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID)) */
+#endif /* defined(HAVE_LIBHIDAPI) */
diff --git a/src/stk500v2.c b/src/stk500v2.c
index 11aa9a94..92e59516 100644
--- a/src/stk500v2.c
+++ b/src/stk500v2.c
@@ -1613,11 +1613,11 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
   PDATA(pgm)->pgmtype = PGMTYPE_UNKNOWN;
 
   if(strcasecmp(port, "avrdoper") == 0){
-#if defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID))
+#if defined(HAVE_LIBHIDAPI)
     serdev = &avrdoper_serdev;
     PDATA(pgm)->pgmtype = PGMTYPE_STK500;
 #else
-    avrdude_message(MSG_INFO, "avrdoper requires avrdude with hid support.\n");
+    avrdude_message(MSG_INFO, "avrdoper requires avrdude with libhidapi support.\n");
     return -1;
 #endif
   }
diff --git a/src/updi_link.c b/src/updi_link.c
index f87f8a83..684b6b8d 100644
--- a/src/updi_link.c
+++ b/src/updi_link.c
@@ -161,6 +161,11 @@ static int updi_physical_send_double_break(PROGRAMMER * pgm)
 
   updi_set_rtsdtr_mode(pgm);
 
+  /*
+   * drain any extraneous input
+   */
+  serial_drain(&pgm->fd, 0);
+
   return 0;
 }