On Thu, 22 Mar 2018 22:39:56 +0100, Andrew Chant wrote:
This implements UAC2 jack detection support, presenting jack status as a boolean read-only mono mixer.
The presence of any channel in the UAC2_TE_CONNECTOR control for a terminal will result in the mixer saying the jack is connected.
Mixer naming follows the convention in sound/core/ctljack.c, terminating the mixer with " Jack". For additional clues as to which jack is being presented, the name is prefixed with " - Input Jack" or " - Output Jack" depending on if it's an input or output terminal.
This is required because terminal names are ambiguous between inputs and outputs and often duplicated - Bidirectional terminal types (0x400 -> 0x4FF) "... may be used separately for input only or output only. These types require two Terminal descriptors. Both have the same type." (quote from "USB Device Class Definition for Terminal Types")
Since bidirectional terminal types are common for headphone adapters, this distinguishes between two otherwise identically-named jack controls.
Tested with a UAC2 audio device with connector control capability.
Signed-off-by: Andrew Chant achant@google.com
sound/usb/mixer.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 3075ac50a391..6cb61307aefe 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1235,6 +1235,21 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, return changed; }
+/* get the current value from a mixer element */ +static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
+{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int val, err;
- err = snd_usb_get_cur_mix_value(cval, 0, 0, &val);
- if (err < 0)
return filter_error(cval, err);
- val = (val != 0);
- ucontrol->value.integer.value[0] = val;
- return 0;
+}
static struct snd_kcontrol_new usb_feature_unit_ctl = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "", /* will be filled later manually */ @@ -1252,6 +1267,16 @@ static const struct snd_kcontrol_new usb_feature_unit_ctl_ro = { .put = NULL, };
+/* A UAC connector mixer control */ +static struct snd_kcontrol_new usb_connector_ctl_ro = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
Let's follow the other usages, and here iface is set to SNDRV_CTL_ELEM_IFACE_CARD. This was for avoiding such volatile controls appearing the mixer application.
- .name = "", /* will be filled later manually */
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
Actually we should have set SNDRV_CTL_ELEM_ACCESS_VOLATILE, too. We forgot it in ctljack.c, too.
The rest looks good. But one thing to confirm: the value change notification is done in snd_usb_mixer_interrupt()?
Also, is the jack re-detected after suspend/resume? That is, plug off the jack while sleeping, and after the resume, is the jack status change recognized and notified?
thanks,
Takashi