*/
 #define GLOBAL_SAMPLE_RATE             0x05c
 
+/*
+ * Some old firmware versions do not have the following global registers.
+ * Windows drivers produced by TCAT lost backward compatibility in its
+ * early release because they can handle firmware only which supports the
+ * following registers.
+ */
+
 /*
  * The version of the DICE driver specification that this device conforms to;
  * read-only.
  */
 #define GLOBAL_VERSION                 0x060
 
-/* Some old firmware versions do not have the following global registers: */
-
 /*
  * Supported sample rates and clock sources; read-only.
  */
 
                                   >> CLOCK_RATE_SHIFT));
        snd_iprintf(buffer, "  ext status: %08x\n", buf.global.extended_status);
        snd_iprintf(buffer, "  sample rate: %u\n", buf.global.sample_rate);
-       snd_iprintf(buffer, "  version: %u.%u.%u.%u\n",
-                   (buf.global.version >> 24) & 0xff,
-                   (buf.global.version >> 16) & 0xff,
-                   (buf.global.version >>  8) & 0xff,
-                   (buf.global.version >>  0) & 0xff);
        if (quadlets >= 90) {
+               snd_iprintf(buffer, "  version: %u.%u.%u.%u\n",
+                           (buf.global.version >> 24) & 0xff,
+                           (buf.global.version >> 16) & 0xff,
+                           (buf.global.version >>  8) & 0xff,
+                           (buf.global.version >>  0) & 0xff);
                snd_iprintf(buffer, "  clock caps:");
                for (i = 0; i <= 6; ++i)
                        if (buf.global.clock_caps & (1 << i))
 
 static int get_subaddrs(struct snd_dice *dice)
 {
        static const int min_values[10] = {
-               10, 0x64 / 4,
+               10, 0x60 / 4,
                10, 0x18 / 4,
                10, 0x18 / 4,
                0, 0,
                }
        }
 
-       /*
-        * Check that the implemented DICE driver specification major version
-        * number matches.
-        */
-       err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
-                                DICE_PRIVATE_SPACE +
-                                be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION,
-                                &version, sizeof(version), 0);
-       if (err < 0)
-               goto end;
+       if (be32_to_cpu(pointers[1]) > 0x18) {
+               /*
+                * Check that the implemented DICE driver specification major
+                * version number matches.
+                */
+               err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
+                               DICE_PRIVATE_SPACE +
+                               be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION,
+                               &version, sizeof(version), 0);
+               if (err < 0)
+                       goto end;
 
-       if ((version & cpu_to_be32(0xff000000)) != cpu_to_be32(0x01000000)) {
-               dev_err(&dice->unit->device,
-                       "unknown DICE version: 0x%08x\n", be32_to_cpu(version));
-               err = -ENODEV;
-               goto end;
+               if ((version & cpu_to_be32(0xff000000)) !=
+                                               cpu_to_be32(0x01000000)) {
+                       dev_err(&dice->unit->device,
+                               "unknown DICE version: 0x%08x\n",
+                               be32_to_cpu(version));
+                       err = -ENODEV;
+                       goto end;
+               }
+
+               /* Set up later. */
+               dice->clock_caps = 1;
        }
 
        dice->global_offset = be32_to_cpu(pointers[0]) * 4;
        dice->tx_offset = be32_to_cpu(pointers[2]) * 4;
        dice->rx_offset = be32_to_cpu(pointers[4]) * 4;
-       dice->sync_offset = be32_to_cpu(pointers[6]) * 4;
-       dice->rsrv_offset = be32_to_cpu(pointers[8]) * 4;
 
-       /* Set up later. */
-       if (be32_to_cpu(pointers[1]) * 4 >= GLOBAL_CLOCK_CAPABILITIES + 4)
-               dice->clock_caps = 1;
+       /* Old firmware doesn't support these fields. */
+       if (pointers[7])
+               dice->sync_offset = be32_to_cpu(pointers[6]) * 4;
+       if (pointers[9])
+               dice->rsrv_offset = be32_to_cpu(pointers[8]) * 4;
 end:
        kfree(pointers);
        return err;