aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/rme9652
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2005-07-04 12:12:39 -0400
committerJaroslav Kysela <perex@suse.cz>2005-07-28 06:21:53 -0400
commite3ea4d896109edd64dc549ecaeeff8d89025fb57 (patch)
tree935c4ee468195cad1b436b4395716488c032037b /sound/pci/rme9652
parent4e55096e27d745908e44c6abd2cc0c5b615854a4 (diff)
[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>
Diffstat (limited to 'sound/pci/rme9652')
-rw-r--r--sound/pci/rme9652/hdsp.c62
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
2099static 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
2108static 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
2116static 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),
3117HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), 3146HDSP_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 */
3119HDSP_CLOCK_SOURCE("Sample Clock Source", 0), 3148HDSP_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},
3120HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0), 3158HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
3121HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0), 3159HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0),
3122HDSP_AUTOSYNC_REF("AutoSync Reference", 0), 3160HDSP_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,