mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-30 19:06:14 +00:00
[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>
This commit is contained in:
parent
4e55096e27
commit
e3ea4d8961
1 changed files with 53 additions and 9 deletions
|
@ -445,6 +445,7 @@ struct _hdsp {
|
||||||
u32 control2_register; /* cached value */
|
u32 control2_register; /* cached value */
|
||||||
u32 creg_spdif;
|
u32 creg_spdif;
|
||||||
u32 creg_spdif_stream;
|
u32 creg_spdif_stream;
|
||||||
|
int clock_source_locked;
|
||||||
char *card_name; /* digiface/multiface */
|
char *card_name; /* digiface/multiface */
|
||||||
HDSP_IO_Type io_type; /* ditto, but for code use */
|
HDSP_IO_Type io_type; /* ditto, but for code use */
|
||||||
unsigned short firmware_rev;
|
unsigned short firmware_rev;
|
||||||
|
@ -2095,6 +2096,34 @@ static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_val
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int snd_hdsp_info_clock_source_lock(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
|
||||||
|
{
|
||||||
|
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
|
||||||
|
uinfo->count = 1;
|
||||||
|
uinfo->value.integer.min = 0;
|
||||||
|
uinfo->value.integer.max = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int snd_hdsp_get_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
|
||||||
|
{
|
||||||
|
hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
|
||||||
|
|
||||||
|
ucontrol->value.integer.value[0] = hdsp->clock_source_locked;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
|
||||||
|
{
|
||||||
|
hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
|
||||||
|
int change;
|
||||||
|
|
||||||
|
change = (int)ucontrol->value.integer.value[0] != hdsp->clock_source_locked;
|
||||||
|
if (change)
|
||||||
|
hdsp->clock_source_locked = ucontrol->value.integer.value[0];
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
#define HDSP_DA_GAIN(xname, xindex) \
|
#define HDSP_DA_GAIN(xname, xindex) \
|
||||||
{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
|
{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
|
||||||
.name = xname, \
|
.name = xname, \
|
||||||
|
@ -3117,6 +3146,15 @@ HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0),
|
||||||
HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0),
|
HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0),
|
||||||
/* 'Sample Clock Source' complies with the alsa control naming scheme */
|
/* 'Sample Clock Source' complies with the alsa control naming scheme */
|
||||||
HDSP_CLOCK_SOURCE("Sample Clock Source", 0),
|
HDSP_CLOCK_SOURCE("Sample Clock Source", 0),
|
||||||
|
{
|
||||||
|
/* FIXME: should be PCM or MIXER? */
|
||||||
|
/* .iface = SNDRV_CTL_ELEM_IFACE_PCM, */
|
||||||
|
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||||
|
.name = "Sample Clock Source Locking",
|
||||||
|
.info = snd_hdsp_info_clock_source_lock,
|
||||||
|
.get = snd_hdsp_get_clock_source_lock,
|
||||||
|
.put = snd_hdsp_put_clock_source_lock,
|
||||||
|
},
|
||||||
HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
|
HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
|
||||||
HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0),
|
HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0),
|
||||||
HDSP_AUTOSYNC_REF("AutoSync Reference", 0),
|
HDSP_AUTOSYNC_REF("AutoSync Reference", 0),
|
||||||
|
@ -3349,6 +3387,7 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
|
||||||
snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode);
|
snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode);
|
||||||
|
|
||||||
snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate);
|
snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate);
|
||||||
|
snd_iprintf (buffer, "System Clock Locked: %s\n", hdsp->clock_source_locked ? "Yes" : "No");
|
||||||
|
|
||||||
snd_iprintf(buffer, "\n");
|
snd_iprintf(buffer, "\n");
|
||||||
|
|
||||||
|
@ -3853,13 +3892,14 @@ static int snd_hdsp_hw_params(snd_pcm_substream_t *substream,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
spin_lock_irq(&hdsp->lock);
|
spin_lock_irq(&hdsp->lock);
|
||||||
if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) {
|
if (! hdsp->clock_source_locked) {
|
||||||
spin_unlock_irq(&hdsp->lock);
|
if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) {
|
||||||
_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
|
spin_unlock_irq(&hdsp->lock);
|
||||||
return err;
|
_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
|
||||||
} else {
|
return err;
|
||||||
spin_unlock_irq(&hdsp->lock);
|
}
|
||||||
}
|
}
|
||||||
|
spin_unlock_irq(&hdsp->lock);
|
||||||
|
|
||||||
if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) {
|
if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) {
|
||||||
_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
|
_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)
|
||||||
|
|
||||||
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
|
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
|
||||||
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
|
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
|
||||||
if (hdsp->io_type == H9632) {
|
if (hdsp->clock_source_locked) {
|
||||||
runtime->hw.channels_min = hdsp->qs_out_channels;
|
runtime->hw.rate_min = runtime->hw.rate_max = hdsp->system_sample_rate;
|
||||||
runtime->hw.channels_max = hdsp->ss_out_channels;
|
} else if (hdsp->io_type == H9632) {
|
||||||
runtime->hw.rate_max = 192000;
|
runtime->hw.rate_max = 192000;
|
||||||
runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
|
runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
|
||||||
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates);
|
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates);
|
||||||
}
|
}
|
||||||
|
if (hdsp->io_type == H9632) {
|
||||||
|
runtime->hw.channels_min = hdsp->qs_out_channels;
|
||||||
|
runtime->hw.channels_max = hdsp->ss_out_channels;
|
||||||
|
}
|
||||||
|
|
||||||
snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
|
snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
|
||||||
snd_hdsp_hw_rule_out_channels, hdsp,
|
snd_hdsp_hw_rule_out_channels, hdsp,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue