Save device release number. Allow writing of eeprom buffer, that was read from device.
[libftdi] / src / ftdi.c
index 95028e5..6d4a64b 100644 (file)
@@ -2,7 +2,7 @@
                           ftdi.c  -  description
                              -------------------
     begin                : Fri Apr 4 2003
-    copyright            : (C) 2003-2011 by Intra2net AG and the libftdi developers
+    copyright            : (C) 2003-2013 by Intra2net AG and the libftdi developers
     email                : opensource@intra2net.com
  ***************************************************************************/
 
@@ -2392,7 +2392,32 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer,
         }
         eeprom->size = -1;
     }
-    eeprom->initialized_for_connected_device = 1;
+    switch (ftdi->type)
+    {
+        case TYPE_AM:
+            eeprom->release_number = 0x0200;
+            break;
+        case TYPE_BM:
+            eeprom->release_number = 0x0400;
+            break;
+        case TYPE_2232C:
+            eeprom->release_number = 0x0500;
+            break;
+        case TYPE_R:
+            eeprom->release_number = 0x0600;
+            break;
+        case TYPE_2232H:
+            eeprom->release_number = 0x0700;
+            break;
+        case TYPE_4232H:
+            eeprom->release_number = 0x0800;
+            break;
+        case TYPE_232H:
+            eeprom->release_number = 0x0900;
+            break;
+        default:
+            eeprom->release_number = 0x00;
+    }
     return 0;
 }
 /*FTD2XX doesn't check for values not fitting in the ACBUS Signal oprtions*/
@@ -2539,33 +2564,8 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
     output[0x05] = eeprom->product_id >> 8;
 
     // Addr 06: Device release number (0400h for BM features)
-    output[0x06] = 0x00;
-    switch (ftdi->type)
-    {
-        case TYPE_AM:
-            output[0x07] = 0x02;
-            break;
-        case TYPE_BM:
-            output[0x07] = 0x04;
-            break;
-        case TYPE_2232C:
-            output[0x07] = 0x05;
-            break;
-        case TYPE_R:
-            output[0x07] = 0x06;
-            break;
-        case TYPE_2232H:
-            output[0x07] = 0x07;
-            break;
-        case TYPE_4232H:
-            output[0x07] = 0x08;
-            break;
-        case TYPE_232H:
-            output[0x07] = 0x09;
-            break;
-        default:
-            output[0x07] = 0x00;
-    }
+    output[0x06] = eeprom->release_number;
+    output[0x07] = eeprom->release_number >> 8;
 
     // Addr 08: Config descriptor
     // Bit 7: always 1
@@ -2573,9 +2573,9 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
     // Bit 5: 1 if this device uses remote wakeup
     // Bit 4-0: reserved - 0
     j = 0x80;
-    if (eeprom->self_powered == 1)
+    if (eeprom->self_powered)
         j |= 0x40;
-    if (eeprom->remote_wakeup == 1)
+    if (eeprom->remote_wakeup)
         j |= 0x20;
     output[0x08] = j;
 
@@ -2595,9 +2595,9 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
         // Bit 0: 1 - In EndPoint is Isochronous
         //
         j = 0;
-        if (eeprom->in_is_isochronous == 1)
+        if (eeprom->in_is_isochronous)
             j = j | 1;
-        if (eeprom->out_is_isochronous == 1)
+        if (eeprom->out_is_isochronous)
             j = j | 2;
         output[0x0A] = j;
     }
@@ -2721,15 +2721,15 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
             else
                 output[0x01] &= ~HIGH_CURRENT_DRIVE;
 
-            if (eeprom->in_is_isochronous == 1)
+            if (eeprom->in_is_isochronous)
                 output[0x0A] |= 0x1;
             else
                 output[0x0A] &= ~0x1;
-            if (eeprom->out_is_isochronous == 1)
+            if (eeprom->out_is_isochronous)
                 output[0x0A] |= 0x2;
             else
                 output[0x0A] &= ~0x2;
-            if (eeprom->suspend_pull_downs == 1)
+            if (eeprom->suspend_pull_downs)
                 output[0x0A] |= 0x4;
             else
                 output[0x0A] &= ~0x4;
@@ -2747,7 +2747,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
                 output[0x00] |= HIGH_CURRENT_DRIVE_R;
             output[0x01] = 0x40; /* Hard coded Endpoint Size*/
 
-            if (eeprom->suspend_pull_downs == 1)
+            if (eeprom->suspend_pull_downs)
                 output[0x0A] |= 0x4;
             else
                 output[0x0A] &= ~0x4;
@@ -2797,7 +2797,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
             else
                 output[0x01] &= ~SUSPEND_DBUS7_BIT;
 
-            if (eeprom->suspend_pull_downs == 1)
+            if (eeprom->suspend_pull_downs)
                 output[0x0A] |= 0x4;
             else
                 output[0x0A] &= ~0x4;
@@ -2859,7 +2859,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
             else
                 output[0x01] &= ~(DRIVER_VCP << 4);
 
-            if (eeprom->suspend_pull_downs == 1)
+            if (eeprom->suspend_pull_downs)
                 output[0x0a] |= 0x4;
             else
                 output[0x0a] &= ~0x4;
@@ -2983,6 +2983,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
     output[eeprom->size-2] = checksum;
     output[eeprom->size-1] = checksum >> 8;
 
+    eeprom->initialized_for_connected_device = 1;
     return user_area_size;
 }
 /* Decode the encoded EEPROM field for the FTDI Mode into a value for the abstracted 
@@ -3025,7 +3026,6 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
     int eeprom_size;
     struct ftdi_eeprom *eeprom;
     unsigned char *buf = ftdi->eeprom->buf;
-    int release;
 
     if (ftdi == NULL)
         ftdi_error_return(-1,"No context");
@@ -3041,7 +3041,8 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
     // Addr 04: Product ID
     eeprom->product_id = buf[0x04] + (buf[0x05] << 8);
 
-    release = buf[0x06] + (buf[0x07]<<8);
+    // Addr 06: Device release number
+    eeprom->release_number = buf[0x06] + (buf[0x07]<<8);
 
     // Addr 08: Config descriptor
     // Bit 7: always 1
@@ -3262,7 +3263,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
         char *channel_mode[] = {"UART", "FIFO", "CPU", "OPTO", "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, "Release: 0x%04x\n",eeprom->release_number);
 
         if (eeprom->self_powered)
             fprintf(stdout, "Self-Powered%s", (eeprom->remote_wakeup)?", USB Remote Wake Up\n":"\n");
@@ -3417,6 +3418,9 @@ int ftdi_get_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value valu
         case PRODUCT_ID:
             *value = ftdi->eeprom->product_id;
             break;
+        case RELEASE_NUMBER:
+            *value = ftdi->eeprom->release_number;
+            break;
         case SELF_POWERED:
             *value = ftdi->eeprom->self_powered;
             break;
@@ -3604,6 +3608,9 @@ int ftdi_set_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value valu
         case PRODUCT_ID:
             ftdi->eeprom->product_id = value;
             break;
+        case RELEASE_NUMBER:
+            ftdi->eeprom->release_number = value;
+            break;
         case SELF_POWERED:
             ftdi->eeprom->self_powered = value;
             break;
@@ -3765,6 +3772,7 @@ int ftdi_set_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value valu
         default :
             ftdi_error_return(-1, "Request to unknown EEPROM value");
     }
+    eeprom->initialized_for_connected_device = 0;
     return 0;
 }