Fix indentation
[libftdi] / src / ftdi.c
index 9414c2d..0a7fb27 100644 (file)
@@ -2,8 +2,9 @@
                           ftdi.c  -  description
                              -------------------
     begin                : Fri Apr 4 2003
-    copyright            : (C) 2003-2017 by Intra2net AG and the libftdi developers
+    copyright            : (C) 2003-2020 by Intra2net AG and the libftdi developers
     email                : opensource@intra2net.com
+    SPDX-License-Identifier: LGPL-2.1-only
  ***************************************************************************/
 
 /***************************************************************************
@@ -484,27 +485,39 @@ int ftdi_usb_get_strings2(struct ftdi_context *ftdi, struct libusb_device *dev,
     if (libusb_get_device_descriptor(dev, &desc) < 0)
         ftdi_error_return(-11, "libusb_get_device_descriptor() failed");
 
-    if (manufacturer != NULL)
+    if (manufacturer != NULL && mnf_len > 0)
     {
-        if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iManufacturer, (unsigned char *)manufacturer, mnf_len) < 0)
+        if (desc.iManufacturer == 0)
+        {
+            manufacturer[0] = '\0';
+        }
+        else if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iManufacturer, (unsigned char *)manufacturer, mnf_len) < 0)
         {
             ftdi_usb_close_internal (ftdi);
             ftdi_error_return(-7, "libusb_get_string_descriptor_ascii() failed");
         }
     }
 
-    if (description != NULL)
+    if (description != NULL && desc_len > 0)
     {
-        if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iProduct, (unsigned char *)description, desc_len) < 0)
+        if (desc.iProduct == 0)
+        {
+            description[0] = '\0';
+        }
+        else if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iProduct, (unsigned char *)description, desc_len) < 0)
         {
             ftdi_usb_close_internal (ftdi);
             ftdi_error_return(-8, "libusb_get_string_descriptor_ascii() failed");
         }
     }
 
-    if (serial != NULL)
+    if (serial != NULL && serial_len > 0)
     {
-        if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iSerialNumber, (unsigned char *)serial, serial_len) < 0)
+        if (desc.iSerialNumber == 0)
+        {
+            serial[0] = '\0';
+        }
+        else if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iSerialNumber, (unsigned char *)serial, serial_len) < 0)
         {
             ftdi_usb_close_internal (ftdi);
             ftdi_error_return(-9, "libusb_get_string_descriptor_ascii() failed");
@@ -1327,7 +1340,7 @@ static int ftdi_to_clkbits_AM(int baudrate, unsigned long *encoded_divisor)
    AM Type chips have only four fractional subdivisors at value[15:14]
    for subdivisors 0, 0.5, 0.25, 0.125
 */
-static int ftdi_to_clkbits(int baudrate, unsigned int clk, int clk_div, unsigned long *encoded_divisor)
+static int ftdi_to_clkbits(int baudrate, int clk, int clk_div, unsigned long *encoded_divisor)
 {
     static const char frac_code[8] = {0, 3, 2, 4, 1, 5, 6, 7};
     int best_baud = 0;
@@ -1991,7 +2004,7 @@ int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunk
 /**
     Reads data in chunks (see ftdi_read_data_set_chunksize()) from the chip.
 
-    Automatically strips the two modem status bytes transfered during every read.
+    Automatically strips the two modem status bytes transferred during every read.
 
     \param ftdi pointer to ftdi_context
     \param buf Buffer to store data in
@@ -2575,8 +2588,8 @@ int ftdi_set_error_char(struct ftdi_context *ftdi,
     \retval -2: No struct ftdi_eeprom
     \retval -3: No connected device or device not yet opened
 */
-int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer,
-                             char * product, char * serial)
+int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, const char * manufacturer,
+                             const char * product, const char * serial)
 {
     struct ftdi_eeprom *eeprom;
 
@@ -2593,7 +2606,7 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer,
         ftdi_error_return(-3, "No connected device or device not yet opened");
 
     eeprom->vendor_id = 0x0403;
-    eeprom->use_serial = 1;
+    eeprom->use_serial = (serial != NULL);
     if ((ftdi->type == TYPE_AM) || (ftdi->type == TYPE_BM) ||
             (ftdi->type == TYPE_R))
         eeprom->product_id = 0x6001;
@@ -2723,8 +2736,8 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer,
     return 0;
 }
 
-int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, char * manufacturer,
-                            char * product, char * serial)
+int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, const char * manufacturer,
+                            const char * product, const char * serial)
 {
     struct ftdi_eeprom *eeprom;
 
@@ -3043,10 +3056,13 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
         case TYPE_2232H:
         case TYPE_4232H:
             i += 2;
+                       /* Fall through*/
         case TYPE_R:
             i += 2;
+                       /* Fall through*/
         case TYPE_2232C:
             i += 2;
+                       /* Fall through*/
         case TYPE_AM:
         case TYPE_BM:
             i += 0x94;
@@ -3085,19 +3101,23 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
     }
     output[0x11] = product_size*2 + 2;
 
-    // Addr 12: Offset of the serial string + 0x80, calculated later
-    // Addr 13: Length of serial string
-    output[0x12] = i | 0x80; // calculate offset
-    output[i & eeprom_size_mask] = serial_size*2 + 2, i++;
-    output[i & eeprom_size_mask] = 0x03, i++;
-    for (j = 0; j < serial_size; j++)
-    {
-        output[i & eeprom_size_mask] = eeprom->serial[j], i++;
-        output[i & eeprom_size_mask] = 0x00, i++;
+    if (eeprom->use_serial) {
+        // Addr 12: Offset of the serial string + 0x80, calculated later
+        // Addr 13: Length of serial string
+        output[0x12] = i | 0x80; // calculate offset
+        output[i & eeprom_size_mask] = serial_size*2 + 2, i++;
+        output[i & eeprom_size_mask] = 0x03, i++;
+        for (j = 0; j < serial_size; j++)
+        {
+            output[i & eeprom_size_mask] = eeprom->serial[j], i++;
+            output[i & eeprom_size_mask] = 0x00, i++;
+        }
+        output[0x13] = serial_size*2 + 2;
     }
 
     // Legacy port name and PnP fields for FT2232 and newer chips
-    if (ftdi->type > TYPE_BM)
+    // It doesn't appear when written with FT_Prog for FT4232H chip.
+    if (ftdi->type > TYPE_BM && ftdi->type != TYPE_4232H)
     {
         output[i & eeprom_size_mask] = 0x02; /* as seen when written with FTD2XX */
         i++;
@@ -3107,8 +3127,6 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
         i++;
     }
 
-    output[0x13] = serial_size*2 + 2;
-
     if (ftdi->type > TYPE_AM) /* use_serial not used in AM devices */
     {
         if (eeprom->use_serial)
@@ -3135,23 +3153,23 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
         case TYPE_2232C:
 
             output[0x00] = type2bit(eeprom->channel_a_type, TYPE_2232C);
-            if ( eeprom->channel_a_driver == DRIVER_VCP)
+            if (eeprom->channel_a_driver)
                 output[0x00] |= DRIVER_VCP;
             else
                 output[0x00] &= ~DRIVER_VCP;
 
-            if ( eeprom->high_current_a == HIGH_CURRENT_DRIVE)
+            if (eeprom->high_current_a)
                 output[0x00] |= HIGH_CURRENT_DRIVE;
             else
                 output[0x00] &= ~HIGH_CURRENT_DRIVE;
 
             output[0x01] = type2bit(eeprom->channel_b_type, TYPE_2232C);
-            if ( eeprom->channel_b_driver == DRIVER_VCP)
+            if (eeprom->channel_b_driver)
                 output[0x01] |= DRIVER_VCP;
             else
                 output[0x01] &= ~DRIVER_VCP;
 
-            if ( eeprom->high_current_b == HIGH_CURRENT_DRIVE)
+            if (eeprom->high_current_b)
                 output[0x01] |= HIGH_CURRENT_DRIVE;
             else
                 output[0x01] &= ~HIGH_CURRENT_DRIVE;
@@ -3179,8 +3197,15 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
             break;
         case TYPE_R:
             output[0x00] = type2bit(eeprom->channel_a_type, TYPE_R);
-            if (eeprom->high_current == HIGH_CURRENT_DRIVE_R)
+            if (eeprom->high_current)
                 output[0x00] |= HIGH_CURRENT_DRIVE_R;
+
+            /* Field is inverted for TYPE_R: Bit 00.3 set to 1 is D2XX, VCP is 0 */
+            if (eeprom->channel_a_driver)
+                output[0x00] &= ~DRIVER_VCP;
+            else
+                output[0x00] |= DRIVER_VCP;
+
             if (eeprom->external_oscillator)
                 output[0x00] |= 0x02;
             output[0x01] = 0x40; /* Hard coded Endpoint Size*/
@@ -3220,17 +3245,18 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
             break;
         case TYPE_2232H:
             output[0x00] = type2bit(eeprom->channel_a_type, TYPE_2232H);
-            if ( eeprom->channel_a_driver == DRIVER_VCP)
+            if (eeprom->channel_a_driver)
                 output[0x00] |= DRIVER_VCP;
             else
                 output[0x00] &= ~DRIVER_VCP;
 
             output[0x01] = type2bit(eeprom->channel_b_type, TYPE_2232H);
-            if ( eeprom->channel_b_driver == DRIVER_VCP)
+            if (eeprom->channel_b_driver)
                 output[0x01] |= DRIVER_VCP;
             else
                 output[0x01] &= ~DRIVER_VCP;
-            if (eeprom->suspend_dbus7 == SUSPEND_DBUS7_BIT)
+
+            if (eeprom->suspend_dbus7)
                 output[0x01] |= SUSPEND_DBUS7_BIT;
             else
                 output[0x01] &= ~SUSPEND_DBUS7_BIT;
@@ -3244,55 +3270,55 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
                 output[0x0c] |= DRIVE_16MA;
             else
                 output[0x0c] |= eeprom->group0_drive;
-            if (eeprom->group0_schmitt == IS_SCHMITT)
+            if (eeprom->group0_schmitt)
                 output[0x0c] |= IS_SCHMITT;
-            if (eeprom->group0_slew == SLOW_SLEW)
+            if (eeprom->group0_slew)
                 output[0x0c] |= SLOW_SLEW;
 
             if (eeprom->group1_drive > DRIVE_16MA)
                 output[0x0c] |= DRIVE_16MA<<4;
             else
                 output[0x0c] |= eeprom->group1_drive<<4;
-            if (eeprom->group1_schmitt == IS_SCHMITT)
+            if (eeprom->group1_schmitt)
                 output[0x0c] |= IS_SCHMITT<<4;
-            if (eeprom->group1_slew == SLOW_SLEW)
+            if (eeprom->group1_slew)
                 output[0x0c] |= SLOW_SLEW<<4;
 
             if (eeprom->group2_drive > DRIVE_16MA)
                 output[0x0d] |= DRIVE_16MA;
             else
                 output[0x0d] |= eeprom->group2_drive;
-            if (eeprom->group2_schmitt == IS_SCHMITT)
+            if (eeprom->group2_schmitt)
                 output[0x0d] |= IS_SCHMITT;
-            if (eeprom->group2_slew == SLOW_SLEW)
+            if (eeprom->group2_slew)
                 output[0x0d] |= SLOW_SLEW;
 
             if (eeprom->group3_drive > DRIVE_16MA)
                 output[0x0d] |= DRIVE_16MA<<4;
             else
                 output[0x0d] |= eeprom->group3_drive<<4;
-            if (eeprom->group3_schmitt == IS_SCHMITT)
+            if (eeprom->group3_schmitt)
                 output[0x0d] |= IS_SCHMITT<<4;
-            if (eeprom->group3_slew == SLOW_SLEW)
+            if (eeprom->group3_slew)
                 output[0x0d] |= SLOW_SLEW<<4;
 
             output[0x18] = eeprom->chip;
 
             break;
         case TYPE_4232H:
-            if (eeprom->channel_a_driver == DRIVER_VCP)
+            if (eeprom->channel_a_driver)
                 output[0x00] |= DRIVER_VCP;
             else
                 output[0x00] &= ~DRIVER_VCP;
-            if (eeprom->channel_b_driver == DRIVER_VCP)
+            if (eeprom->channel_b_driver)
                 output[0x01] |= DRIVER_VCP;
             else
                 output[0x01] &= ~DRIVER_VCP;
-            if (eeprom->channel_c_driver == DRIVER_VCP)
+            if (eeprom->channel_c_driver)
                 output[0x00] |= (DRIVER_VCP << 4);
             else
                 output[0x00] &= ~(DRIVER_VCP << 4);
-            if (eeprom->channel_d_driver == DRIVER_VCP)
+            if (eeprom->channel_d_driver)
                 output[0x01] |= (DRIVER_VCP << 4);
             else
                 output[0x01] &= ~(DRIVER_VCP << 4);
@@ -3323,36 +3349,36 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
                 output[0x0c] |= DRIVE_16MA;
             else
                 output[0x0c] |= eeprom->group0_drive;
-            if (eeprom->group0_schmitt == IS_SCHMITT)
+            if (eeprom->group0_schmitt)
                 output[0x0c] |= IS_SCHMITT;
-            if (eeprom->group0_slew == SLOW_SLEW)
+            if (eeprom->group0_slew)
                 output[0x0c] |= SLOW_SLEW;
 
             if (eeprom->group1_drive > DRIVE_16MA)
                 output[0x0c] |= DRIVE_16MA<<4;
             else
                 output[0x0c] |= eeprom->group1_drive<<4;
-            if (eeprom->group1_schmitt == IS_SCHMITT)
+            if (eeprom->group1_schmitt)
                 output[0x0c] |= IS_SCHMITT<<4;
-            if (eeprom->group1_slew == SLOW_SLEW)
+            if (eeprom->group1_slew)
                 output[0x0c] |= SLOW_SLEW<<4;
 
             if (eeprom->group2_drive > DRIVE_16MA)
                 output[0x0d] |= DRIVE_16MA;
             else
                 output[0x0d] |= eeprom->group2_drive;
-            if (eeprom->group2_schmitt == IS_SCHMITT)
+            if (eeprom->group2_schmitt)
                 output[0x0d] |= IS_SCHMITT;
-            if (eeprom->group2_slew == SLOW_SLEW)
+            if (eeprom->group2_slew)
                 output[0x0d] |= SLOW_SLEW;
 
             if (eeprom->group3_drive > DRIVE_16MA)
                 output[0x0d] |= DRIVE_16MA<<4;
             else
                 output[0x0d] |= eeprom->group3_drive<<4;
-            if (eeprom->group3_schmitt == IS_SCHMITT)
+            if (eeprom->group3_schmitt)
                 output[0x0d] |= IS_SCHMITT<<4;
-            if (eeprom->group3_slew == SLOW_SLEW)
+            if (eeprom->group3_slew)
                 output[0x0d] |= SLOW_SLEW<<4;
 
             output[0x18] = eeprom->chip;
@@ -3360,10 +3386,11 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
             break;
         case TYPE_232H:
             output[0x00] = type2bit(eeprom->channel_a_type, TYPE_232H);
-            if ( eeprom->channel_a_driver == DRIVER_VCP)
+            if (eeprom->channel_a_driver)
                 output[0x00] |= DRIVER_VCPH;
             else
                 output[0x00] &= ~DRIVER_VCPH;
+
             if (eeprom->powersave)
                 output[0x01] |= POWER_SAVE_DISABLE_H;
             else
@@ -3386,28 +3413,29 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
                 output[0x01] |= FT1284_FLOW_CONTROL;
             else
                 output[0x01] &= ~FT1284_FLOW_CONTROL;
+
             if (eeprom->group0_drive > DRIVE_16MA)
                 output[0x0c] |= DRIVE_16MA;
             else
                 output[0x0c] |= eeprom->group0_drive;
-            if (eeprom->group0_schmitt == IS_SCHMITT)
+            if (eeprom->group0_schmitt)
                 output[0x0c] |= IS_SCHMITT;
-            if (eeprom->group0_slew == SLOW_SLEW)
+            if (eeprom->group0_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)
+            if (eeprom->group1_schmitt)
                 output[0x0d] |= IS_SCHMITT;
-            if (eeprom->group1_slew == SLOW_SLEW)
+            if (eeprom->group1_slew)
                 output[0x0d] |= SLOW_SLEW;
 
             set_ft232h_cbus(eeprom, output);
 
             output[0x1e] = eeprom->chip;
-            fprintf(stderr,"FIXME: Build FT232H specific EEPROM settings\n");
+            /* FIXME: Build FT232H specific EEPROM settings */
             break;
         case TYPE_230X:
             output[0x00] = 0x80; /* Actually, leave the default value */
@@ -3427,15 +3455,20 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
     {
         case TYPE_230X:
             free_start += 2;
+                       /* Fall through*/
         case TYPE_232H:
             free_start += 6;
+                       /* Fall through*/
         case TYPE_2232H:
         case TYPE_4232H:
             free_start += 2;
+                       /* Fall through*/
         case TYPE_R:
             free_start += 2;
+                       /* Fall through*/
         case TYPE_2232C:
             free_start++;
+                       /* Fall through*/
         case TYPE_AM:
         case TYPE_BM:
             free_start += 0x14;
@@ -3565,8 +3598,8 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
     // Bit 7: always 1
     // Bit 6: 1 if this device is self powered, 0 if bus powered
     // Bit 5: 1 if this device uses remote wakeup
-    eeprom->self_powered = buf[0x08] & 0x40;
-    eeprom->remote_wakeup = buf[0x08] & 0x20;
+    eeprom->self_powered = !!(buf[0x08] & 0x40);
+    eeprom->remote_wakeup = !!(buf[0x08] & 0x20);
 
     // Addr 09: Max power consumption: max power = value * 2 mA
     eeprom->max_power = MAX_POWER_MILLIAMP_PER_UNIT * buf[0x09];
@@ -3581,9 +3614,9 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
     // Bit 1: 1 - Out EndPoint is Isochronous
     // Bit 0: 1 - In EndPoint is Isochronous
     //
-    eeprom->in_is_isochronous  = buf[0x0A]&0x01;
-    eeprom->out_is_isochronous = buf[0x0A]&0x02;
-    eeprom->suspend_pull_downs = buf[0x0A]&0x04;
+    eeprom->in_is_isochronous  = !!(buf[0x0A]&0x01);
+    eeprom->out_is_isochronous = !!(buf[0x0A]&0x02);
+    eeprom->suspend_pull_downs = !!(buf[0x0A]&0x04);
     eeprom->use_serial         = !!(buf[0x0A] & USE_SERIAL_NUM);
     eeprom->use_usb_version    = !!(buf[0x0A] & USE_USB_VERSION_BIT);
 
@@ -3687,19 +3720,19 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
     else if (ftdi->type == TYPE_2232C)
     {
         eeprom->channel_a_type   = bit2type(buf[0x00] & 0x7);
-        eeprom->channel_a_driver = buf[0x00] & DRIVER_VCP;
-        eeprom->high_current_a   = buf[0x00] & HIGH_CURRENT_DRIVE;
+        eeprom->channel_a_driver = !!(buf[0x00] & DRIVER_VCP);
+        eeprom->high_current_a   = !!(buf[0x00] & HIGH_CURRENT_DRIVE);
         eeprom->channel_b_type   = buf[0x01] & 0x7;
-        eeprom->channel_b_driver = buf[0x01] & DRIVER_VCP;
-        eeprom->high_current_b   = buf[0x01] & HIGH_CURRENT_DRIVE;
+        eeprom->channel_b_driver = !!(buf[0x01] & DRIVER_VCP);
+        eeprom->high_current_b   = !!(buf[0x01] & HIGH_CURRENT_DRIVE);
         eeprom->chip = buf[0x14];
     }
     else if (ftdi->type == TYPE_R)
     {
-        /* TYPE_R flags D2XX, not VCP as all others*/
-        eeprom->channel_a_driver = ~buf[0x00] & DRIVER_VCP;
-        eeprom->high_current     = buf[0x00] & HIGH_CURRENT_DRIVE_R;
-        eeprom->external_oscillator = buf[0x00] & 0x02;
+        /* TYPE_R flags D2XX, not VCP as all others */
+        eeprom->channel_a_driver = !(buf[0x00] & DRIVER_VCP);               /* note: inverted flag, use a single NOT */
+        eeprom->high_current     = !!(buf[0x00] & HIGH_CURRENT_DRIVE_R);
+        eeprom->external_oscillator = !!(buf[0x00] & 0x02);
         if ( (buf[0x01]&0x40) != 0x40)
             fprintf(stderr,
                     "TYPE_R EEPROM byte[0x01] Bit 6 unexpected Endpoint size."
@@ -3710,7 +3743,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
         eeprom->chip = buf[0x16];
         // Addr 0B: Invert data lines
         // Works only on FT232R, not FT245R, but no way to distinguish
-        eeprom->invert = buf[0x0B];
+        eeprom->invert = buf[0x0B];                                         /* note: not a bitflag */
         // Addr 14: CBUS function: CBUS0, CBUS1
         // Addr 15: CBUS function: CBUS2, CBUS3
         // Addr 16: CBUS function: CBUS5
@@ -3722,53 +3755,53 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
     }
     else if ((ftdi->type == TYPE_2232H) || (ftdi->type == TYPE_4232H))
     {
-        eeprom->channel_a_driver = buf[0x00] & DRIVER_VCP;
-        eeprom->channel_b_driver = buf[0x01] & DRIVER_VCP;
+        eeprom->channel_a_driver = !!(buf[0x00] & DRIVER_VCP);
+        eeprom->channel_b_driver = !!(buf[0x01] & DRIVER_VCP);
 
         if (ftdi->type == TYPE_2232H)
         {
             eeprom->channel_a_type   = bit2type(buf[0x00] & 0x7);
             eeprom->channel_b_type   = bit2type(buf[0x01] & 0x7);
-            eeprom->suspend_dbus7    = buf[0x01] & SUSPEND_DBUS7_BIT;
+            eeprom->suspend_dbus7    = !!(buf[0x01] & SUSPEND_DBUS7_BIT);
         }
         else
         {
-            eeprom->channel_c_driver = (buf[0x00] >> 4) & DRIVER_VCP;
-            eeprom->channel_d_driver = (buf[0x01] >> 4) & DRIVER_VCP;
-            eeprom->channel_a_rs485enable = buf[0x0b] & (CHANNEL_IS_RS485 << 0);
-            eeprom->channel_b_rs485enable = buf[0x0b] & (CHANNEL_IS_RS485 << 1);
-            eeprom->channel_c_rs485enable = buf[0x0b] & (CHANNEL_IS_RS485 << 2);
-            eeprom->channel_d_rs485enable = buf[0x0b] & (CHANNEL_IS_RS485 << 3);
+            eeprom->channel_c_driver = !!((buf[0x00] >> 4) & DRIVER_VCP);
+            eeprom->channel_d_driver = !!((buf[0x01] >> 4) & DRIVER_VCP);
+            eeprom->channel_a_rs485enable = !!(buf[0x0b] & (CHANNEL_IS_RS485 << 0));
+            eeprom->channel_b_rs485enable = !!(buf[0x0b] & (CHANNEL_IS_RS485 << 1));
+            eeprom->channel_c_rs485enable = !!(buf[0x0b] & (CHANNEL_IS_RS485 << 2));
+            eeprom->channel_d_rs485enable = !!(buf[0x0b] & (CHANNEL_IS_RS485 << 3));
         }
 
         eeprom->chip = buf[0x18];
-        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[0x0c] >> 4) & 0x3;
-        eeprom->group1_schmitt = (buf[0x0c] >> 4) & IS_SCHMITT;
-        eeprom->group1_slew    = (buf[0x0c] >> 4) & SLOW_SLEW;
-        eeprom->group2_drive   =  buf[0x0d]       & DRIVE_16MA;
-        eeprom->group2_schmitt =  buf[0x0d]       & IS_SCHMITT;
-        eeprom->group2_slew    =  buf[0x0d]       & SLOW_SLEW;
-        eeprom->group3_drive   = (buf[0x0d] >> 4) & DRIVE_16MA;
-        eeprom->group3_schmitt = (buf[0x0d] >> 4) & IS_SCHMITT;
-        eeprom->group3_slew    = (buf[0x0d] >> 4) & SLOW_SLEW;
+        eeprom->group0_drive   = buf[0x0c]       & DRIVE_16MA;              /* not a bitflag */
+        eeprom->group0_schmitt = !!(buf[0x0c]       & IS_SCHMITT);
+        eeprom->group0_slew    = !!(buf[0x0c]       & SLOW_SLEW);
+        eeprom->group1_drive   = (buf[0x0c] >> 4) & DRIVE_16MA;             /* not a bitflag */
+        eeprom->group1_schmitt = !!((buf[0x0c] >> 4) & IS_SCHMITT);
+        eeprom->group1_slew    = !!((buf[0x0c] >> 4) & SLOW_SLEW);
+        eeprom->group2_drive   = buf[0x0d]       & DRIVE_16MA;              /* not a bitflag */
+        eeprom->group2_schmitt = !!(buf[0x0d]       & IS_SCHMITT);
+        eeprom->group2_slew    = !!(buf[0x0d]       & SLOW_SLEW);
+        eeprom->group3_drive   = (buf[0x0d] >> 4) & DRIVE_16MA;             /* not a bitflag */
+        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->clock_polarity =  buf[0x01]       & FT1284_CLK_IDLE_STATE;
-        eeprom->data_order     =  buf[0x01]       & FT1284_DATA_LSB;
-        eeprom->flow_control   =  buf[0x01]       & FT1284_FLOW_CONTROL;
-        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->channel_a_driver = !!(buf[0x00] & DRIVER_VCPH);
+        eeprom->clock_polarity =  !!(buf[0x01]       & FT1284_CLK_IDLE_STATE);
+        eeprom->data_order     =  !!(buf[0x01]       & FT1284_DATA_LSB);
+        eeprom->flow_control   =  !!(buf[0x01]       & FT1284_FLOW_CONTROL);
+        eeprom->powersave      =  !!(buf[0x01]       & POWER_SAVE_DISABLE_H);
+        eeprom->group0_drive   =  buf[0x0c]       & DRIVE_16MA;             /* not a bitflag */
+        eeprom->group0_schmitt =  !!(buf[0x0c]       & IS_SCHMITT);
+        eeprom->group0_slew    =  !!(buf[0x0c]       & SLOW_SLEW);
+        eeprom->group1_drive   =  buf[0x0d]       & DRIVE_16MA;             /* not a bitflag */
+        eeprom->group1_schmitt =  !!(buf[0x0d]       & IS_SCHMITT);
+        eeprom->group1_slew    =  !!(buf[0x0d]       & SLOW_SLEW);
 
         for(i=0; i<5; i++)
         {
@@ -3784,14 +3817,14 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
         {
             eeprom->cbus_function[i] =  buf[0x1a + i] & 0xFF;
         }
-        eeprom->group0_drive   =  buf[0x0c]       & 0x03;
-        eeprom->group0_schmitt =  buf[0x0c]       & IS_SCHMITT;
-        eeprom->group0_slew    =  buf[0x0c]       & SLOW_SLEW;
-        eeprom->group1_drive   = (buf[0x0c] >> 4) & 0x03;
-        eeprom->group1_schmitt = (buf[0x0c] >> 4) & IS_SCHMITT;
-        eeprom->group1_slew    = (buf[0x0c] >> 4) & SLOW_SLEW;
-
-        eeprom->invert = buf[0xb];
+        eeprom->group0_drive   = buf[0x0c]       & DRIVE_16MA;              /* not a bitflag */
+        eeprom->group0_schmitt = !!(buf[0x0c]       & IS_SCHMITT);
+        eeprom->group0_slew    = !!(buf[0x0c]       & SLOW_SLEW);
+        eeprom->group1_drive   = (buf[0x0c] >> 4) & DRIVE_16MA;             /* not a bitflag */
+        eeprom->group1_schmitt = !!((buf[0x0c] >> 4) & IS_SCHMITT);
+        eeprom->group1_slew    = !!((buf[0x0c] >> 4) & SLOW_SLEW);
+
+        eeprom->invert = buf[0xb];                                          /* not a bitflag */
     }
 
     if (verbose)