aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/rme9652/hdsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/rme9652/hdsp.c')
-rw-r--r--sound/pci/rme9652/hdsp.c68
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
2098static 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
2107static 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
2115static 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),
3117HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), 3145HDSP_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 */
3119HDSP_CLOCK_SOURCE("Sample Clock Source", 0), 3147HDSP_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},
3120HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0), 3157HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
3121HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0), 3158HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0),
3122HDSP_AUTOSYNC_REF("AutoSync Reference", 0), 3159HDSP_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 }