[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 <tiwai@suse.de>

authored by Takashi Iwai and committed by Jaroslav Kysela e3ea4d89 4e55096e

+53 -9
+53 -9
sound/pci/rme9652/hdsp.c
··· 445 445 u32 control2_register; /* cached value */ 446 446 u32 creg_spdif; 447 447 u32 creg_spdif_stream; 448 + int clock_source_locked; 448 449 char *card_name; /* digiface/multiface */ 449 450 HDSP_IO_Type io_type; /* ditto, but for code use */ 450 451 unsigned short firmware_rev; ··· 2096 2095 return change; 2097 2096 } 2098 2097 2098 + static int snd_hdsp_info_clock_source_lock(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 2099 + { 2100 + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2101 + uinfo->count = 1; 2102 + uinfo->value.integer.min = 0; 2103 + uinfo->value.integer.max = 1; 2104 + return 0; 2105 + } 2106 + 2107 + static int snd_hdsp_get_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 2108 + { 2109 + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); 2110 + 2111 + ucontrol->value.integer.value[0] = hdsp->clock_source_locked; 2112 + return 0; 2113 + } 2114 + 2115 + static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 2116 + { 2117 + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); 2118 + int change; 2119 + 2120 + change = (int)ucontrol->value.integer.value[0] != hdsp->clock_source_locked; 2121 + if (change) 2122 + hdsp->clock_source_locked = ucontrol->value.integer.value[0]; 2123 + return change; 2124 + } 2125 + 2099 2126 #define HDSP_DA_GAIN(xname, xindex) \ 2100 2127 { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ 2101 2128 .name = xname, \ ··· 3146 3117 HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), 3147 3118 /* 'Sample Clock Source' complies with the alsa control naming scheme */ 3148 3119 HDSP_CLOCK_SOURCE("Sample Clock Source", 0), 3120 + { 3121 + /* FIXME: should be PCM or MIXER? */ 3122 + /* .iface = SNDRV_CTL_ELEM_IFACE_PCM, */ 3123 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3124 + .name = "Sample Clock Source Locking", 3125 + .info = snd_hdsp_info_clock_source_lock, 3126 + .get = snd_hdsp_get_clock_source_lock, 3127 + .put = snd_hdsp_put_clock_source_lock, 3128 + }, 3149 3129 HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0), 3150 3130 HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0), 3151 3131 HDSP_AUTOSYNC_REF("AutoSync Reference", 0), ··· 3387 3349 snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode); 3388 3350 3389 3351 snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate); 3352 + snd_iprintf (buffer, "System Clock Locked: %s\n", hdsp->clock_source_locked ? "Yes" : "No"); 3390 3353 3391 3354 snd_iprintf(buffer, "\n"); 3392 3355 ··· 3892 3853 */ 3893 3854 3894 3855 spin_lock_irq(&hdsp->lock); 3895 - if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) { 3896 - spin_unlock_irq(&hdsp->lock); 3897 - _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); 3898 - return err; 3899 - } else { 3900 - spin_unlock_irq(&hdsp->lock); 3856 + if (! hdsp->clock_source_locked) { 3857 + if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) { 3858 + spin_unlock_irq(&hdsp->lock); 3859 + _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); 3860 + return err; 3861 + } 3901 3862 } 3863 + spin_unlock_irq(&hdsp->lock); 3902 3864 3903 3865 if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) { 3904 3866 _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); ··· 4324 4284 4325 4285 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 4326 4286 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes); 4327 - if (hdsp->io_type == H9632) { 4328 - runtime->hw.channels_min = hdsp->qs_out_channels; 4329 - runtime->hw.channels_max = hdsp->ss_out_channels; 4287 + if (hdsp->clock_source_locked) { 4288 + runtime->hw.rate_min = runtime->hw.rate_max = hdsp->system_sample_rate; 4289 + } else if (hdsp->io_type == H9632) { 4330 4290 runtime->hw.rate_max = 192000; 4331 4291 runtime->hw.rates = SNDRV_PCM_RATE_KNOT; 4332 4292 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates); 4333 4293 } 4294 + if (hdsp->io_type == H9632) { 4295 + runtime->hw.channels_min = hdsp->qs_out_channels; 4296 + runtime->hw.channels_max = hdsp->ss_out_channels; 4297 + } 4334 4298 4335 4299 snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 4336 4300 snd_hdsp_hw_rule_out_channels, hdsp,