Skip to content

Commit

Permalink
Correctly determine Microchip pid:vid 04d8:000a device class
Browse files Browse the repository at this point in the history
According to the Linux kernel tree [1], Microchip pid:vid 04d8:000a
is generally a CDC ACM device, implemented by a demo firmware
application.

However, some vendors have re-used this vid:pid for other types of
firmware, emulating FTDI chips. The Linux kernel attempts to detect
such cases by matching on interface class/subclass/proto. If these
are ff/ff/00 it uses FTDI, otherwise CDC.

Mimic the Linux kernel's logic in determining whether the Microchip
device is CDC or FTDI.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f08dea734844aa42ec57c229b0b73b3d7d21f810
  • Loading branch information
Sven Van Asbroeck authored and Sven Van Asbroeck committed Jul 2, 2019
1 parent 91a5368 commit 6180eb4
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
24 changes: 22 additions & 2 deletions usbserial/src/main/java/com/felhr/deviceids/FTDISioIds.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.felhr.deviceids;

import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbInterface;

import static com.felhr.deviceids.Helpers.createTable;
import static com.felhr.deviceids.Helpers.createDevice;

Expand Down Expand Up @@ -251,7 +254,6 @@ private FTDISioIds()
createDevice(0x03eb, 0x2109),
createDevice(0x0456, 0xf000),
createDevice(0x0456, 0xf001),
createDevice(0x04d8, 0x000a),
createDevice(0x0584, 0xb020),
createDevice(0x0647, 0x0100),
createDevice(0x06CE, 0x8311),
Expand Down Expand Up @@ -560,7 +562,25 @@ private FTDISioIds()
createDevice(0x0403, 0x0) //fake FTDI reprogrammed by driver
);

public static boolean isDeviceSupported(int vendorId, int productId) {
private static boolean isMicrochipFtdi(UsbDevice dev) {
if (dev.getVendorId() != 0x04d8 || dev.getProductId() != 0x000a)
return false;
for (int i = 0; i < dev.getInterfaceCount(); i++) {
UsbInterface intf = dev.getInterface(i);
if (intf.getInterfaceClass() == 0xff && intf.getInterfaceSubclass() == 0xff &&
intf.getInterfaceProtocol() == 0x00)
return true;
}
return false;
}

public static boolean isDeviceSupported(UsbDevice dev) {
return Helpers.exists(ftdiDevices, dev.getVendorId(), dev.getProductId()) ||
isMicrochipFtdi(dev);

}

static boolean isDeviceIdSupported(int vendorId, int productId) {
return Helpers.exists(ftdiDevices, vendorId, productId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public static UsbSerialDevice createUsbSerialDevice(UsbDevice device, UsbDeviceC
int vid = device.getVendorId();
int pid = device.getProductId();

if(FTDISioIds.isDeviceSupported(vid, pid))
if(FTDISioIds.isDeviceSupported(device))
return new FTDISerialDevice(device, connection, iface);
else if(CP210xIds.isDeviceSupported(vid, pid))
return new CP2102SerialDevice(device, connection, iface);
Expand Down Expand Up @@ -107,7 +107,7 @@ public static boolean isSupported(UsbDevice device)
int vid = device.getVendorId();
int pid = device.getProductId();

if(FTDISioIds.isDeviceSupported(vid, pid))
if(FTDISioIds.isDeviceSupported(device))
return true;
else if(CP210xIds.isDeviceSupported(vid, pid))
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void testLongPacking() {

for (TestCase tc : cases) {
Assert.assertTrue(CP210xIds.isDeviceSupported(tc.vendor, tc.product));
Assert.assertFalse(FTDISioIds.isDeviceSupported(tc.vendor, tc.product));
Assert.assertFalse(FTDISioIds.isDeviceIdSupported(tc.vendor, tc.product));
}
}

Expand Down

0 comments on commit 6180eb4

Please sign in to comment.