tree 935c4ee468195cad1b436b4395716488c032037b
parent 4e55096e27d745908e44c6abd2cc0c5b615854a4
author Takashi Iwai <[EMAIL PROTECTED]> Mon, 04 Jul 2005 18:12:39 +0200
committer Jaroslav Kysela <[EMAIL PROTECTED]> Thu, 28 Jul 2005 12:21:53 +0200

[ALSA] hdsp - Add 'Sample Clock Source Locking' control

RME HDSP driver
Added 'Sample Clock Source Locking' control.  If this switch is on,
the clock source can't be changed via PCM hw_params API (as sample rate).
This will fix the problem of OSS-emulation, for example.

Signed-off-by: Takashi Iwai <[EMAIL PROTECTED]>

 sound/pci/rme9652/hdsp.c |   62 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -445,6 +445,7 @@ struct _hdsp {
        u32                   control2_register;     /* cached value */
        u32                   creg_spdif;
        u32                   creg_spdif_stream;
+       int                   clock_source_locked;
        char                 *card_name;             /* digiface/multiface */
        HDSP_IO_Type          io_type;               /* ditto, but for code use 
*/
         unsigned short        firmware_rev;
@@ -2095,6 +2096,34 @@ static int snd_hdsp_put_clock_source(snd
        return change;
 }
 
+static int snd_hdsp_info_clock_source_lock(snd_kcontrol_t *kcontrol, 
snd_ctl_elem_info_t * uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+       uinfo->count = 1;
+       uinfo->value.integer.min = 0;
+       uinfo->value.integer.max = 1;
+       return 0;
+}
+
+static int snd_hdsp_get_clock_source_lock(snd_kcontrol_t * kcontrol, 
snd_ctl_elem_value_t * ucontrol)
+{
+       hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+       
+       ucontrol->value.integer.value[0] = hdsp->clock_source_locked;
+       return 0;
+}
+
+static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, 
snd_ctl_elem_value_t * ucontrol)
+{
+       hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+       int change;
+
+       change = (int)ucontrol->value.integer.value[0] != 
hdsp->clock_source_locked;
+       if (change)
+               hdsp->clock_source_locked = ucontrol->value.integer.value[0];
+       return change;
+}
+
 #define HDSP_DA_GAIN(xname, xindex) \
 { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
   .name = xname, \
@@ -3117,6 +3146,15 @@ HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit
 HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0),
 /* 'Sample Clock Source' complies with the alsa control naming scheme */ 
 HDSP_CLOCK_SOURCE("Sample Clock Source", 0),
+{
+       /* FIXME: should be PCM or MIXER? */
+       /* .iface = SNDRV_CTL_ELEM_IFACE_PCM, */
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Sample Clock Source Locking",
+       .info = snd_hdsp_info_clock_source_lock,
+       .get = snd_hdsp_get_clock_source_lock,
+       .put = snd_hdsp_put_clock_source_lock,
+},
 HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
 HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0),
 HDSP_AUTOSYNC_REF("AutoSync Reference", 0),
@@ -3349,6 +3387,7 @@ snd_hdsp_proc_read(snd_info_entry_t *ent
        snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode);
 
        snd_iprintf (buffer, "System Clock Frequency: %d\n", 
hdsp->system_sample_rate);
+       snd_iprintf (buffer, "System Clock Locked: %s\n", 
hdsp->clock_source_locked ? "Yes" : "No");
                
        snd_iprintf(buffer, "\n");
 
@@ -3853,13 +3892,14 @@ static int snd_hdsp_hw_params(snd_pcm_su
         */
 
        spin_lock_irq(&hdsp->lock);
-       if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) {
-               spin_unlock_irq(&hdsp->lock);
-               _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
-               return err;
-       } else {
-               spin_unlock_irq(&hdsp->lock);
+       if (! hdsp->clock_source_locked) {
+               if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) {
+                       spin_unlock_irq(&hdsp->lock);
+                       _snd_pcm_hw_param_setempty(params, 
SNDRV_PCM_HW_PARAM_RATE);
+                       return err;
+               }
        }
+       spin_unlock_irq(&hdsp->lock);
 
        if ((err = hdsp_set_interrupt_interval(hdsp, 
params_period_size(params))) < 0) {
                _snd_pcm_hw_param_setempty(params, 
SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
@@ -4284,13 +4324,17 @@ static int snd_hdsp_playback_open(snd_pc
 
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 
&hdsp_hw_constraints_period_sizes);
-       if (hdsp->io_type == H9632) {
-               runtime->hw.channels_min = hdsp->qs_out_channels;
-               runtime->hw.channels_max = hdsp->ss_out_channels;
+       if (hdsp->clock_source_locked) {
+               runtime->hw.rate_min = runtime->hw.rate_max = 
hdsp->system_sample_rate;
+       } else if (hdsp->io_type == H9632) {
                runtime->hw.rate_max = 192000;
                runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
                snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 
&hdsp_hw_constraints_9632_sample_rates);
        }
+       if (hdsp->io_type == H9632) {
+               runtime->hw.channels_min = hdsp->qs_out_channels;
+               runtime->hw.channels_max = hdsp->ss_out_channels;
+       }       
        
        snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
                             snd_hdsp_hw_rule_out_channels, hdsp,
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to