diff options
Diffstat (limited to 'sound/pci/rme9652/hdsp.c')
-rw-r--r-- | sound/pci/rme9652/hdsp.c | 68 |
1 files changed, 55 insertions, 13 deletions
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index a673cc438b91..796621de5009 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; |
@@ -678,8 +679,7 @@ static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) { | |||
678 | } | 679 | } |
679 | 680 | ||
680 | if ((1000 / HZ) < 3000) { | 681 | if ((1000 / HZ) < 3000) { |
681 | set_current_state(TASK_UNINTERRUPTIBLE); | 682 | ssleep(3); |
682 | schedule_timeout((3000 * HZ + 999) / 1000); | ||
683 | } else { | 683 | } else { |
684 | mdelay(3000); | 684 | mdelay(3000); |
685 | } | 685 | } |
@@ -2095,6 +2095,34 @@ static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_val | |||
2095 | return change; | 2095 | return change; |
2096 | } | 2096 | } |
2097 | 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 | |||
2098 | #define HDSP_DA_GAIN(xname, xindex) \ | 2126 | #define HDSP_DA_GAIN(xname, xindex) \ |
2099 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2127 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ |
2100 | .name = xname, \ | 2128 | .name = xname, \ |
@@ -3117,6 +3145,15 @@ HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0), | |||
3117 | HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), | 3145 | HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), |
3118 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ | 3146 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ |
3119 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), | 3147 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), |
3148 | { | ||
3149 | /* FIXME: should be PCM or MIXER? */ | ||
3150 | /* .iface = SNDRV_CTL_ELEM_IFACE_PCM, */ | ||
3151 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3152 | .name = "Sample Clock Source Locking", | ||
3153 | .info = snd_hdsp_info_clock_source_lock, | ||
3154 | .get = snd_hdsp_get_clock_source_lock, | ||
3155 | .put = snd_hdsp_put_clock_source_lock, | ||
3156 | }, | ||
3120 | HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0), | 3157 | HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0), |
3121 | HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0), | 3158 | HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0), |
3122 | HDSP_AUTOSYNC_REF("AutoSync Reference", 0), | 3159 | HDSP_AUTOSYNC_REF("AutoSync Reference", 0), |
@@ -3349,6 +3386,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); | 3386 | snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode); |
3350 | 3387 | ||
3351 | snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate); | 3388 | snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate); |
3389 | snd_iprintf (buffer, "System Clock Locked: %s\n", hdsp->clock_source_locked ? "Yes" : "No"); | ||
3352 | 3390 | ||
3353 | snd_iprintf(buffer, "\n"); | 3391 | snd_iprintf(buffer, "\n"); |
3354 | 3392 | ||
@@ -3853,13 +3891,14 @@ static int snd_hdsp_hw_params(snd_pcm_substream_t *substream, | |||
3853 | */ | 3891 | */ |
3854 | 3892 | ||
3855 | spin_lock_irq(&hdsp->lock); | 3893 | spin_lock_irq(&hdsp->lock); |
3856 | if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) { | 3894 | if (! hdsp->clock_source_locked) { |
3857 | spin_unlock_irq(&hdsp->lock); | 3895 | if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) { |
3858 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); | 3896 | spin_unlock_irq(&hdsp->lock); |
3859 | return err; | 3897 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); |
3860 | } else { | 3898 | return err; |
3861 | spin_unlock_irq(&hdsp->lock); | 3899 | } |
3862 | } | 3900 | } |
3901 | spin_unlock_irq(&hdsp->lock); | ||
3863 | 3902 | ||
3864 | if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) { | 3903 | 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); | 3904 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); |
@@ -4284,13 +4323,17 @@ static int snd_hdsp_playback_open(snd_pcm_substream_t *substream) | |||
4284 | 4323 | ||
4285 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 4324 | 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); | 4325 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes); |
4287 | if (hdsp->io_type == H9632) { | 4326 | if (hdsp->clock_source_locked) { |
4288 | runtime->hw.channels_min = hdsp->qs_out_channels; | 4327 | runtime->hw.rate_min = runtime->hw.rate_max = hdsp->system_sample_rate; |
4289 | runtime->hw.channels_max = hdsp->ss_out_channels; | 4328 | } else if (hdsp->io_type == H9632) { |
4290 | runtime->hw.rate_max = 192000; | 4329 | runtime->hw.rate_max = 192000; |
4291 | runtime->hw.rates = SNDRV_PCM_RATE_KNOT; | 4330 | 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); | 4331 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates); |
4293 | } | 4332 | } |
4333 | if (hdsp->io_type == H9632) { | ||
4334 | runtime->hw.channels_min = hdsp->qs_out_channels; | ||
4335 | runtime->hw.channels_max = hdsp->ss_out_channels; | ||
4336 | } | ||
4294 | 4337 | ||
4295 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 4338 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
4296 | snd_hdsp_hw_rule_out_channels, hdsp, | 4339 | snd_hdsp_hw_rule_out_channels, hdsp, |
@@ -5036,8 +5079,7 @@ static int __devinit snd_hdsp_create(snd_card_t *card, | |||
5036 | if (!is_9652 && !is_9632) { | 5079 | if (!is_9652 && !is_9632) { |
5037 | /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */ | 5080 | /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */ |
5038 | if ((1000 / HZ) < 2000) { | 5081 | if ((1000 / HZ) < 2000) { |
5039 | set_current_state(TASK_UNINTERRUPTIBLE); | 5082 | ssleep(2); |
5040 | schedule_timeout((2000 * HZ + 999) / 1000); | ||
5041 | } else { | 5083 | } else { |
5042 | mdelay(2000); | 5084 | mdelay(2000); |
5043 | } | 5085 | } |