[alsa-devel] [PATCH 6/6] bebob: Arrangement for a control element to which two settings relate
Takashi Sakamoto
o-takashi at sakamocchi.jp
Mon Jul 21 04:10:05 CEST 2014
A control element for digital input interface includes two settings; one
is for digital format (S/PDIF or ADAT), another is for interface (optical or
coaxial).
The setting for interface is meaningful just for S/PDIF, therefore to consider
recovery at failure of a operation for the second setting, a operation for
the first setting should be for interface, not digital format.
Additionally, this commit changes special_dig_in_iface_ctl_get() to reduce
needless processing for the interface when the digital format is ADAT.
Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
---
sound/firewire/bebob/bebob_maudio.c | 70 +++++++++++++++++++++----------------
1 file changed, 40 insertions(+), 30 deletions(-)
diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c
index acfe94a..7899b56 100644
--- a/sound/firewire/bebob/bebob_maudio.c
+++ b/sound/firewire/bebob/bebob_maudio.c
@@ -471,21 +471,24 @@ static int special_dig_in_iface_ctl_get(struct snd_kcontrol *kctl,
mutex_lock(&bebob->mutex);
- err = avc_audio_get_selector(bebob->unit, 0x00, 0x04,
- &dig_in_iface);
- if (err < 0) {
- dev_err(&bebob->unit->device,
- "fail to get digital input interface: %d\n", err);
- goto end;
+ /* For ADAT, optical interface is only available. */
+ if (params->dig_in_fmt > 0) {
+ err = 0;
+ dig_in_iface = 0;
+ } else {
+ err = avc_audio_get_selector(bebob->unit, 0x00, 0x04,
+ &dig_in_iface);
+ if (err < 0) {
+ dev_err(&bebob->unit->device,
+ "fail to get digital input interface: %d\n",
+ err);
+ goto end;
+ }
}
/* encoded id for user value */
val = (params->dig_in_fmt << 1) | (dig_in_iface & 0x01);
- /* for ADAT Optical */
- if (val > 2)
- val = 2;
-
uval->value.enumerated.item[0] = val;
end:
mutex_unlock(&bebob->mutex);
@@ -497,7 +500,7 @@ static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl,
struct snd_bebob *bebob = snd_kcontrol_chip(kctl);
struct special_params *params = bebob->maudio_special_quirk;
unsigned int id, dig_in_fmt, dig_in_iface;
- int err;
+ int err = 0;
id = uval->value.enumerated.item[0];
if (id >= ARRAY_SIZE(special_dig_in_iface_labels))
@@ -509,29 +512,36 @@ static int special_dig_in_iface_ctl_set(struct snd_kcontrol *kctl,
mutex_lock(&bebob->mutex);
- err = avc_maudio_set_special_clk(bebob,
- params->clk_src,
- dig_in_fmt,
- params->dig_out_fmt,
- params->clk_lock);
- if (err < 0) {
- dev_err(&bebob->unit->device,
- "fail to change clock source: %d\n", err);
- goto end;
- }
-
- /* For ADAT, optical interface is only available. */
- if (params->dig_in_fmt > 0) {
+ /* For S/PDIF, optical/coaxial interfaces are selectable. */
+ if (dig_in_fmt == 0) {
+ if (amdtp_stream_running(&bebob->rx_stream))
+ goto end;
+
+ err = avc_audio_set_selector(bebob->unit, 0x00, 0x04,
+ dig_in_iface);
+ if (err < 0) {
+ dev_err(&bebob->unit->device,
+ "fail to change digital input interface: %d\n",
+ err);
+ goto end;
+ }
err = 1;
- goto end;
}
- err = avc_audio_set_selector(bebob->unit, 0x00, 0x04, dig_in_iface);
- if (err < 0)
- dev_err(&bebob->unit->device,
- "fail to set digital input interface: %d\n", err);
- else
+ if (params->dig_in_fmt != dig_in_fmt) {
+ err = avc_maudio_set_special_clk(bebob,
+ params->clk_src,
+ dig_in_fmt,
+ params->dig_out_fmt,
+ params->clk_lock);
+ if (err < 0) {
+ dev_err(&bebob->unit->device,
+ "fail to change digital input format: %d\n",
+ err);
+ goto end;
+ }
err = 1;
+ }
end:
mutex_unlock(&bebob->mutex);
return err;
--
1.9.1
More information about the Alsa-devel
mailing list