struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(dev, &desc) < 0)
- ftdi_error_return(-6, "libusb_get_device_descriptor() failed");
+ ftdi_error_return_free_device_list(-6, "libusb_get_device_descriptor() failed", devs);
if (desc.idVendor == vendor && desc.idProduct == product)
{
*curdev = (struct ftdi_device_list*)malloc(sizeof(struct ftdi_device_list));
if (!*curdev)
- ftdi_error_return(-3, "out of memory");
+ ftdi_error_return_free_device_list(-3, "out of memory", devs);
(*curdev)->next = NULL;
(*curdev)->dev = dev;
count++;
}
}
-
+ libusb_free_device_list(devs,1);
return count;
}
// Determine maximum packet size. Init with default value.
// New hi-speed devices from FTDI use a packet size of 512 bytes
// but could be connected to a normal speed USB hub -> 64 bytes packet size.
- if (ftdi->type == TYPE_2232H || ftdi->type == TYPE_4232H)
+ if (ftdi->type == TYPE_2232H || ftdi->type == TYPE_4232H || ftdi->type == TYPE_232H )
packet_size = 512;
else
packet_size = 64;
ftdi->type = TYPE_2232H;
else if (desc.bcdDevice == 0x800)
ftdi->type = TYPE_4232H;
+ else if (desc.bcdDevice == 0x900)
+ ftdi->type = TYPE_232H;
// Determine maximum packet size
ftdi->max_packet_size = _ftdi_determine_max_packet_size(ftdi, dev);
if ((ftdi->type == TYPE_AM) || (ftdi->type == TYPE_BM) ||
(ftdi->type == TYPE_R))
eeprom->product_id = 0x6001;
+ else if (ftdi->type == TYPE_4232H)
+ eeprom->product_id = 0x6011;
+ else if (ftdi->type == TYPE_232H)
+ eeprom->product_id = 0x6014;
else
eeprom->product_id = 0x6010;
if (ftdi->type == TYPE_AM)
if (eeprom->product)
free (eeprom->product);
eeprom->product = NULL;
+ if(product)
{
eeprom->product = malloc(strlen(product)+1);
if (eeprom->product)
case TYPE_4232H:
output[0x07] = 0x08;
break;
+ case TYPE_232H:
+ output[0x07] = 0x09;
+ break;
default:
output[0x07] = 0x00;
}
// Dynamic content
// Strings start at 0x94 (TYPE_AM, TYPE_BM)
// 0x96 (TYPE_2232C), 0x98 (TYPE_R) and 0x9a (TYPE_x232H)
+ // 0xa0 (TYPE_232H)
i = 0;
switch (ftdi->type)
{
+ case TYPE_232H:
+ i += 2;
case TYPE_2232H:
case TYPE_4232H:
i += 2;
break;
case TYPE_4232H:
+ output[0x18] = eeprom->chip;
fprintf(stderr,"FIXME: Build FT4232H specific EEPROM settings\n");
+ break;
+ case TYPE_232H:
+ output[0x00] = (eeprom->channel_a_type);
+ if ( eeprom->channel_a_driver == DRIVER_VCP)
+ output[0x00] |= DRIVER_VCPH;
+ else
+ output[0x00] &= ~DRIVER_VCPH;
+ if (eeprom->powersave)
+ output[0x01] |= POWER_SAVE_DISABLE_H;
+ else
+ output[0x01] &= ~POWER_SAVE_DISABLE_H;
+
+ if (eeprom->group0_drive > DRIVE_16MA)
+ output[0x0c] |= DRIVE_16MA;
+ else
+ output[0x0c] |= eeprom->group0_drive;
+ if (eeprom->group0_schmitt == IS_SCHMITT)
+ output[0x0c] |= IS_SCHMITT;
+ if (eeprom->group0_slew == SLOW_SLEW)
+ output[0x0c] |= SLOW_SLEW;
+
+ if (eeprom->group1_drive > DRIVE_16MA)
+ output[0x0d] |= DRIVE_16MA;
+ else
+ output[0x0d] |= eeprom->group1_drive;
+ if (eeprom->group1_schmitt == IS_SCHMITT)
+ output[0x0d] |= IS_SCHMITT;
+ if (eeprom->group1_slew == SLOW_SLEW)
+ output[0x0d] |= SLOW_SLEW;
+
+ output[0x1e] = eeprom->chip;
+ fprintf(stderr,"FIXME: Build FT232H specific EEPROM settings\n");
+ break;
+
}
// calculate checksum
eeprom->group3_schmitt = (buf[0x0d] >> 4) & IS_SCHMITT;
eeprom->group3_slew = (buf[0x0d] >> 4) & SLOW_SLEW;
}
+ else if (ftdi->type == TYPE_232H)
+ {
+ eeprom->channel_a_type = buf[0x00] & 0xf;
+ eeprom->channel_a_driver = (buf[0x00] & DRIVER_VCPH)?DRIVER_VCP:0;
+ eeprom->powersave = buf[0x01] & POWER_SAVE_DISABLE_H;
+ eeprom->group0_drive = buf[0x0c] & DRIVE_16MA;
+ eeprom->group0_schmitt = buf[0x0c] & IS_SCHMITT;
+ eeprom->group0_slew = buf[0x0c] & SLOW_SLEW;
+ eeprom->group1_drive = buf[0x0d] & DRIVE_16MA;
+ eeprom->group1_schmitt = buf[0x0d] & IS_SCHMITT;
+ eeprom->group1_slew = buf[0x0d] & SLOW_SLEW;
+
+ eeprom->chip = buf[0x1e];
+ /*FIXME: Decipher more values*/
+ }
if (verbose)
{
- char *channel_mode[] = {"UART","245","CPU", "unknown", "OPTO"};
+ char *channel_mode[] = {"UART","245","CPU", "unknown", "OPTO", "unknown1","unknown2","unknown3","FT1284"};
fprintf(stdout, "VID: 0x%04x\n",eeprom->vendor_id);
fprintf(stdout, "PID: 0x%04x\n",eeprom->product_id);
fprintf(stdout, "Release: 0x%04x\n",release);
fprintf(stdout, "Suspend on DBUS7\n");
if (eeprom->suspend_pull_downs)
fprintf(stdout, "Pull IO pins low during suspend\n");
+ if(eeprom->powersave)
+ {
+ if(ftdi->type >= TYPE_232H)
+ fprintf(stdout,"Enter low power state on ACBUS7\n");
+ }
if (eeprom->remote_wakeup)
fprintf(stdout, "Enable Remote Wake Up\n");
fprintf(stdout, "PNP: %d\n",(eeprom->is_not_pnp)?0:1);
channel_mode[eeprom->channel_a_type],
(eeprom->channel_a_driver)?" VCP":"",
(eeprom->high_current_a)?" High Current IO":"");
- if ((ftdi->type >= TYPE_2232C) && (ftdi->type != TYPE_R))
+ if ((ftdi->type >= TYPE_2232C) && (ftdi->type != TYPE_R) && (ftdi->type != TYPE_232H))
fprintf(stdout,"Channel B has Mode %s%s%s\n",
channel_mode[eeprom->channel_b_type],
(eeprom->channel_b_driver)?" VCP":"",
(eeprom->group3_schmitt)?" Schmitt Input":"",
(eeprom->group3_slew)?" Slow Slew":"");
}
+ else if (ftdi->type == TYPE_232H)
+ {
+ fprintf(stdout,"ACBUS has %d mA drive%s%s\n",
+ (eeprom->group0_drive+1) *4,
+ (eeprom->group0_schmitt)?" Schmitt Input":"",
+ (eeprom->group0_slew)?" Slow Slew":"");
+ fprintf(stdout,"ADBUS has %d mA drive%s%s\n",
+ (eeprom->group1_drive+1) *4,
+ (eeprom->group1_schmitt)?" Schmitt Input":"",
+ (eeprom->group1_slew)?" Slow Slew":"");
+ }
+
if (ftdi->type == TYPE_R)
{
char *cbus_mux[] = {"TXDEN","PWREN","RXLED", "TXLED","TX+RXLED",
case GROUP3_SLEW:
*value = ftdi->eeprom->group3_slew;
break;
+ case POWER_SAVE:
+ *value = ftdi->eeprom->powersave;
+ break;
case CHIP_TYPE:
*value = ftdi->eeprom->chip;
break;
case CHIP_TYPE:
ftdi->eeprom->chip = value;
break;
+ case POWER_SAVE:
+ ftdi->eeprom->powersave = value;
+ break;
case CHIP_SIZE:
ftdi_error_return(-2, "EEPROM Value can't be changed");
default :
case TYPE_4232H:
chip_type_location = 0x18;
break;
+ case TYPE_232H:
+ chip_type_location = 0x1e;
+ break;
default:
ftdi_error_return(-4, "Device can't access unprotected area");
}