ALSA: hdspm - Allow the TCO and SYNC-IN to be used in slave mode
authorAdrian Knoth <adi@drcomp.erfurt.thur.de>
Sat, 9 Mar 2013 23:37:22 +0000 (00:37 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 11 Mar 2013 09:10:53 +0000 (10:10 +0100)
When using the additional Time Code Option module in slave mode or the
SYNC-In wordclock connector, the sample rate needs to be returned by
hdspm_external_sample_rate().

Since this sample rate may contain any value with 1Hz granularity, we
need to round it to a common rate as done by the OSX driver.

[Fixed missing function declarations by tiwai]

Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/rme9652/hdspm.c

index 50cba5c..c56bfe4 100644 (file)
@@ -1076,6 +1076,20 @@ static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm)
        return ret;
 }
 
+/* round arbitary sample rates to commonly known rates */
+static int hdspm_round_frequency(int rate)
+{
+       if (rate < 38050)
+               return 32000;
+       if (rate < 46008)
+               return 44100;
+       else
+               return 48000;
+}
+
+static int hdspm_tco_sync_check(struct hdspm *hdspm);
+static int hdspm_sync_in_sync_check(struct hdspm *hdspm);
+
 /* check for external sample rate */
 static int hdspm_external_sample_rate(struct hdspm *hdspm)
 {
@@ -1217,22 +1231,45 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
                                break;
                        }
 
-                       /* QS and DS rates normally can not be detected
-                        * automatically by the card. Only exception is MADI
-                        * in 96k frame mode.
-                        *
-                        * So if we read SS values (32 .. 48k), check for
-                        * user-provided DS/QS bits in the control register
-                        * and multiply the base frequency accordingly.
-                        */
-                       if (rate <= 48000) {
-                               if (hdspm->control_register & HDSPM_QuadSpeed)
-                                       rate *= 4;
-                               else if (hdspm->control_register &
-                                               HDSPM_DoubleSpeed)
-                                       rate *= 2;
+               } /* endif HDSPM_madiLock */
+
+               /* check sample rate from TCO or SYNC_IN */
+               {
+                       bool is_valid_input = 0;
+                       bool has_sync = 0;
+
+                       syncref = hdspm_autosync_ref(hdspm);
+                       if (HDSPM_AUTOSYNC_FROM_TCO == syncref) {
+                               is_valid_input = 1;
+                               has_sync = (HDSPM_SYNC_CHECK_SYNC ==
+                                       hdspm_tco_sync_check(hdspm));
+                       } else if (HDSPM_AUTOSYNC_FROM_SYNC_IN == syncref) {
+                               is_valid_input = 1;
+                               has_sync = (HDSPM_SYNC_CHECK_SYNC ==
+                                       hdspm_sync_in_sync_check(hdspm));
+                       }
+
+                       if (is_valid_input && has_sync) {
+                               rate = hdspm_round_frequency(
+                                       hdspm_get_pll_freq(hdspm));
                        }
                }
+
+               /* QS and DS rates normally can not be detected
+                * automatically by the card. Only exception is MADI
+                * in 96k frame mode.
+                *
+                * So if we read SS values (32 .. 48k), check for
+                * user-provided DS/QS bits in the control register
+                * and multiply the base frequency accordingly.
+                */
+               if (rate <= 48000) {
+                       if (hdspm->control_register & HDSPM_QuadSpeed)
+                               rate *= 4;
+                       else if (hdspm->control_register &
+                                       HDSPM_DoubleSpeed)
+                               rate *= 2;
+               }
                break;
        }