diff options
Diffstat (limited to 'sound')
-rw-r--r-- | 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 index a673cc438b91..0db558a92871 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -445,6 +445,7 @@ struct _hdsp { | |||
445 | u32 control2_register; /* cached value */ | 445 | u32 control2_register; /* cached value */ |
446 | u32 creg_spdif; | 446 | u32 creg_spdif; |
447 | u32 creg_spdif_stream; | 447 | u32 creg_spdif_stream; |
448 | int clock_source_locked; | ||
448 | char *card_name; /* digiface/multiface */ | 449 | char *card_name; /* digiface/multiface */ |
449 | HDSP_IO_Type io_type; /* ditto, but for code use */ | 450 | HDSP_IO_Type io_type; /* ditto, but for code use */ |
450 | unsigned short firmware_rev; | 451 | unsigned short firmware_rev; |
@@ -2095,6 +2096,34 @@ static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_val | |||
2095 | return change; | 2096 | return change; |
2096 | } | 2097 | } |
2097 | 2098 | ||
2099 | static int snd_hdsp_info_clock_source_lock(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) | ||
2100 | { | ||
2101 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
2102 | uinfo->count = 1; | ||
2103 | uinfo->value.integer.min = 0; | ||
2104 | uinfo->value.integer.max = 1; | ||
2105 | return 0; | ||
2106 | } | ||
2107 | |||
2108 | static int snd_hdsp_get_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | ||
2109 | { | ||
2110 | hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); | ||
2111 | |||
2112 | ucontrol->value.integer.value[0] = hdsp->clock_source_locked; | ||
2113 | return 0; | ||
2114 | } | ||
2115 | |||
2116 | static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | ||
2117 | { | ||
2118 | hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); | ||
2119 | int change; | ||
2120 | |||
2121 | change = (int)ucontrol->value.integer.value[0] != hdsp->clock_source_locked; | ||
2122 | if (change) | ||
2123 | hdsp->clock_source_locked = ucontrol->value.integer.value[0]; | ||
2124 | return change; | ||
2125 | } | ||
2126 | |||
2098 | #define HDSP_DA_GAIN(xname, xindex) \ | 2127 | #define HDSP_DA_GAIN(xname, xindex) \ |
2099 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2128 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ |
2100 | .name = xname, \ | 2129 | .name = xname, \ |
@@ -3117,6 +3146,15 @@ HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0), | |||
3117 | HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), | 3146 | HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), |
3118 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ | 3147 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ |
3119 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), | 3148 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), |
3149 | { | ||
3150 | /* FIXME: should be PCM or MIXER? */ | ||
3151 | /* .iface = SNDRV_CTL_ELEM_IFACE_PCM, */ | ||
3152 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3153 | .name = "Sample Clock Source Locking", | ||
3154 | .info = snd_hdsp_info_clock_source_lock, | ||
3155 | .get = snd_hdsp_get_clock_source_lock, | ||
3156 | .put = snd_hdsp_put_clock_source_lock, | ||
3157 | }, | ||
3120 | HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0), | 3158 | HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0), |
3121 | HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0), | 3159 | HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0), |
3122 | HDSP_AUTOSYNC_REF("AutoSync Reference", 0), | 3160 | HDSP_AUTOSYNC_REF("AutoSync Reference", 0), |
@@ -3349,6 +3387,7 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) | |||
3349 | snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode); | 3387 | snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode); |
3350 | 3388 | ||
3351 | snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate); | 3389 | snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate); |
3390 | snd_iprintf (buffer, "System Clock Locked: %s\n", hdsp->clock_source_locked ? "Yes" : "No"); | ||
3352 | 3391 | ||
3353 | snd_iprintf(buffer, "\n"); | 3392 | snd_iprintf(buffer, "\n"); |
3354 | 3393 | ||
@@ -3853,13 +3892,14 @@ static int snd_hdsp_hw_params(snd_pcm_substream_t *substream, | |||
3853 | */ | 3892 | */ |
3854 | 3893 | ||
3855 | spin_lock_irq(&hdsp->lock); | 3894 | spin_lock_irq(&hdsp->lock); |
3856 | if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) { | 3895 | if (! hdsp->clock_source_locked) { |
3857 | spin_unlock_irq(&hdsp->lock); | 3896 | if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) { |
3858 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); | 3897 | spin_unlock_irq(&hdsp->lock); |
3859 | return err; | 3898 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); |
3860 | } else { | 3899 | return err; |
3861 | spin_unlock_irq(&hdsp->lock); | 3900 | } |
3862 | } | 3901 | } |
3902 | spin_unlock_irq(&hdsp->lock); | ||
3863 | 3903 | ||
3864 | if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) { | 3904 | if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) { |
3865 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); | 3905 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); |
@@ -4284,13 +4324,17 @@ static int snd_hdsp_playback_open(snd_pcm_substream_t *substream) | |||
4284 | 4324 | ||
4285 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 4325 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); |
4286 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes); | 4326 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes); |
4287 | if (hdsp->io_type == H9632) { | 4327 | if (hdsp->clock_source_locked) { |
4288 | runtime->hw.channels_min = hdsp->qs_out_channels; | 4328 | runtime->hw.rate_min = runtime->hw.rate_max = hdsp->system_sample_rate; |
4289 | runtime->hw.channels_max = hdsp->ss_out_channels; | 4329 | } else if (hdsp->io_type == H9632) { |
4290 | runtime->hw.rate_max = 192000; | 4330 | runtime->hw.rate_max = 192000; |
4291 | runtime->hw.rates = SNDRV_PCM_RATE_KNOT; | 4331 | runtime->hw.rates = SNDRV_PCM_RATE_KNOT; |
4292 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates); | 4332 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates); |
4293 | } | 4333 | } |
4334 | if (hdsp->io_type == H9632) { | ||
4335 | runtime->hw.channels_min = hdsp->qs_out_channels; | ||
4336 | runtime->hw.channels_max = hdsp->ss_out_channels; | ||
4337 | } | ||
4294 | 4338 | ||
4295 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 4339 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
4296 | snd_hdsp_hw_rule_out_channels, hdsp, | 4340 | snd_hdsp_hw_rule_out_channels, hdsp, |