Fix compile warning on some gcc versions:
[libftdi] / src / ftdi.c
index 16f8f1f..e6f96cb 100644 (file)
@@ -63,7 +63,7 @@
 */
 int ftdi_init(struct ftdi_context *ftdi)
 {
-    int i;
+    unsigned int i;
 
     ftdi->usb_dev = NULL;
     ftdi->usb_read_timeout = 5000;
@@ -110,7 +110,7 @@ int ftdi_init(struct ftdi_context *ftdi)
 
     \return a pointer to a new ftdi_context, or NULL on failure
 */
-struct ftdi_context *ftdi_new()
+struct ftdi_context *ftdi_new(void)
 {
     struct ftdi_context * ftdi = (struct ftdi_context *)malloc(sizeof(struct ftdi_context));
 
@@ -132,7 +132,7 @@ struct ftdi_context *ftdi_new()
     Open selected channels on a chip, otherwise use first channel.
 
     \param ftdi pointer to ftdi_context
-    \param interface Interface to use for FT2232C chips.
+    \param interface Interface to use for FT2232C/2232H/4232H chips.
 
     \retval  0: all fine
     \retval -1: unknown interface
@@ -151,6 +151,18 @@ int ftdi_set_interface(struct ftdi_context *ftdi, enum ftdi_interface interface)
             ftdi->in_ep     = 0x04;
             ftdi->out_ep    = 0x83;
             break;
+        case INTERFACE_C:
+            ftdi->interface = 2;
+            ftdi->index     = INTERFACE_C;
+            ftdi->in_ep     = 0x06;
+            ftdi->out_ep    = 0x85;
+            break;
+        case INTERFACE_D:
+            ftdi->interface = 3;
+            ftdi->index     = INTERFACE_D;
+            ftdi->in_ep     = 0x08;
+            ftdi->out_ep    = 0x87;
+            break;
         default:
             ftdi_error_return(-1, "Unknown interface");
     }
@@ -431,13 +443,26 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct usb_device *dev)
     else if (dev->descriptor.bcdDevice == 0x200)
         ftdi->type = TYPE_AM;
     else if (dev->descriptor.bcdDevice == 0x500)
-    {
         ftdi->type = TYPE_2232C;
-        if (!ftdi->index)
-            ftdi->index = INTERFACE_A;
-    }
     else if (dev->descriptor.bcdDevice == 0x600)
         ftdi->type = TYPE_R;
+    else if (dev->descriptor.bcdDevice == 0x700)
+        ftdi->type = TYPE_2232H;
+    else if (dev->descriptor.bcdDevice == 0x800)
+        ftdi->type = TYPE_4232H;
+
+    // Set default interface on dual/quad type chips
+    switch(ftdi->type)
+    {
+        case TYPE_2232C:
+        case TYPE_2232H:
+        case TYPE_4232H:
+            if (!ftdi->index)
+                ftdi->index = INTERFACE_A;
+            break;
+        default:
+            break;
+    }
 
     ftdi_error_return(0, "all fine");
 }
@@ -960,7 +985,7 @@ static int _usb_get_async_urbs_pending(struct ftdi_context *ftdi)
 {
     struct usbdevfs_urb *urb;
     int pending=0;
-    int i;
+    unsigned int i;
 
     for (i=0; i < ftdi->async_usb_buffer_size; i++)
     {
@@ -1053,8 +1078,8 @@ static int _usb_bulk_write_async(struct ftdi_context *ftdi, int ep, char *bytes,
 {
     struct usbdevfs_urb *urb;
     int bytesdone = 0, requested;
-    int ret, i;
-    int cleanup_count;
+    int ret, cleanup_count;
+    unsigned int i;
 
     do
     {
@@ -1202,6 +1227,13 @@ int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunk
 int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size)
 {
     int offset = 0, ret = 1, i, num_of_chunks, chunk_remains;
+    int packet_size;
+
+    // New hi-speed devices from FTDI use a packet size of 512 bytes
+    if (ftdi->type == TYPE_2232H || ftdi->type == TYPE_4232H)
+        packet_size = 512;
+    else
+        packet_size = 64;
 
     // everything we want is still in the readbuffer?
     if (size <= ftdi->readbuffer_remaining)
@@ -1238,23 +1270,23 @@ int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size)
         {
             // skip FTDI status bytes.
             // Maybe stored in the future to enable modem use
-            num_of_chunks = ret / 64;
-            chunk_remains = ret % 64;
+            num_of_chunks = ret / packet_size;
+            chunk_remains = ret % packet_size;
             //printf("ret = %X, num_of_chunks = %X, chunk_remains = %X, readbuffer_offset = %X\n", ret, num_of_chunks, chunk_remains, ftdi->readbuffer_offset);
 
             ftdi->readbuffer_offset += 2;
             ret -= 2;
 
-            if (ret > 62)
+            if (ret > packet_size - 2)
             {
                 for (i = 1; i < num_of_chunks; i++)
-                    memmove (ftdi->readbuffer+ftdi->readbuffer_offset+62*i,
-                             ftdi->readbuffer+ftdi->readbuffer_offset+64*i,
-                             62);
+                    memmove (ftdi->readbuffer+ftdi->readbuffer_offset+(packet_size - 2)*i,
+                             ftdi->readbuffer+ftdi->readbuffer_offset+packet_size*i,
+                             packet_size - 2);
                 if (chunk_remains > 2)
                 {
-                    memmove (ftdi->readbuffer+ftdi->readbuffer_offset+62*i,
-                             ftdi->readbuffer+ftdi->readbuffer_offset+64*i,
+                    memmove (ftdi->readbuffer+ftdi->readbuffer_offset+(packet_size - 2)*i,
+                             ftdi->readbuffer+ftdi->readbuffer_offset+packet_size*i,
                              chunk_remains-2);
                     ret -= 2*num_of_chunks;
                 }
@@ -1954,7 +1986,8 @@ int ftdi_eeprom_decode(struct ftdi_eeprom *eeprom, unsigned char *buf, int size)
     // Addr 04: Product ID
     eeprom->product_id = buf[0x04] + (buf[0x05] << 8);
 
-    switch (buf[0x06] + (buf[0x07]<<8))
+    value = buf[0x06] + (buf[0x07]<<8);
+    switch (value)
     {
         case 0x0400:
             eeprom->BM_type_chip = 1;
@@ -2183,12 +2216,15 @@ int ftdi_read_eeprom_getsize(struct ftdi_context *ftdi, unsigned char *eeprom, i
 int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom)
 {
     unsigned short usb_val, status;
-    int i;
+    int i, ret;
 
     /* These commands were traced while running MProg */
-    ftdi_usb_reset(ftdi);
-    ftdi_poll_modem_status(ftdi, &status);
-    ftdi_set_latency_timer(ftdi, 0x77);
+    if ((ret = ftdi_usb_reset(ftdi)) != 0)
+        return ret;
+    if ((ret = ftdi_poll_modem_status(ftdi, &status)) != 0)
+        return ret;
+    if ((ret = ftdi_set_latency_timer(ftdi, 0x77)) != 0)
+        return ret;
 
     for (i = 0; i < ftdi->eeprom_size/2; i++)
     {