From fcdc4ba1d8c69847540cb3152f0ca44e238111ee Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Sun, 10 Mar 2013 00:37:22 +0100 Subject: ALSA: hdspm - Allow the TCO and SYNC-IN to be used in slave mode 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 Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 65 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 14 deletions(-) (limited to 'sound/pci/rme9652') diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 50cba5ce54f..c56bfe40223 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -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; } -- cgit v1.2.3