Message ID | 20230725023416.11205-30-quic_wcheng@quicinc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Introduce QC USB SND audio offloading support | expand |
On 7/25/23 04:34, Wesley Cheng wrote: > The headphone jack framework has a well defined intrastructure for infrastructure > notifying userspace entities through input devices. Expose a jack device > that carries information about if an offload capable device is connected. > Applications can further identify specific offloading information through > other SND kcontrols. What if you connect a set of USB speakers? Would they show as a headphone/headset? > Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> > --- > sound/soc/qcom/qdsp6/q6usb.c | 17 +++++++++++++++-- > 1 file changed, 15 insertions(+), 2 deletions(-) > > diff --git a/sound/soc/qcom/qdsp6/q6usb.c b/sound/soc/qcom/qdsp6/q6usb.c > index e4ccb9d912b0..860dff8c1438 100644 > --- a/sound/soc/qcom/qdsp6/q6usb.c > +++ b/sound/soc/qcom/qdsp6/q6usb.c > @@ -20,6 +20,7 @@ > #include <sound/pcm_params.h> > #include <sound/asound.h> > #include <sound/q6usboffload.h> > +#include <sound/jack.h> > > #include "q6dsp-lpass-ports.h" > #include "q6afe.h" > @@ -37,6 +38,7 @@ struct q6usb_status { > struct q6usb_port_data { > struct q6afe_usb_cfg usb_cfg; > struct snd_soc_usb *usb; > + struct snd_soc_jack hs_jack; > struct q6usb_offload priv; > struct mutex mutex; > unsigned long available_card_slot; > @@ -279,6 +281,7 @@ static const struct snd_kcontrol_new q6usb_offload_control = { > /* Build a mixer control for a UAC connector control (jack-detect) */ > static void q6usb_connector_control_init(struct snd_soc_component *component) > { > + struct q6usb_port_data *data = dev_get_drvdata(component->dev); > int ret; > > ret = snd_ctl_add(component->card->snd_card, > @@ -290,6 +293,11 @@ static void q6usb_connector_control_init(struct snd_soc_component *component) > snd_ctl_new1(&q6usb_offload_dev_ctrl, component)); > if (ret < 0) > return; > + > + ret = snd_soc_card_jack_new(component->card, "USB offload", > + SND_JACK_HEADSET, &data->hs_jack); not all USB devices are headsets... > + if (ret) > + return; > } > > static int q6usb_audio_ports_of_xlate_dai_name(struct snd_soc_component *component, > @@ -322,7 +330,10 @@ static int q6usb_alsa_connection_cb(struct snd_soc_usb *usb, int card_idx, > > mutex_lock(&data->mutex); > if (connected) { > - snd_soc_dapm_enable_pin(dapm, "USB_RX_BE"); > + if (!data->available_card_slot) { > + snd_soc_dapm_enable_pin(dapm, "USB_RX_BE"); > + snd_jack_report(data->hs_jack.jack, 1); > + } > /* > * Update the latest USB headset plugged in, if session is > * idle. > @@ -338,8 +349,10 @@ static int q6usb_alsa_connection_cb(struct snd_soc_usb *usb, int card_idx, > clear_bit(card_idx, &data->available_card_slot); > data->status[card_idx].num_pcm = 0; > data->status[card_idx].chip_index = 0; > - if (!data->available_card_slot) > + if (!data->available_card_slot) { > snd_soc_dapm_disable_pin(dapm, "USB_RX_BE"); > + snd_jack_report(data->hs_jack.jack, 0); > + } > } > snd_soc_dapm_sync(dapm); > mutex_unlock(&data->mutex);
Hi Pierre, On 7/25/2023 2:10 AM, Pierre-Louis Bossart wrote: > > > On 7/25/23 04:34, Wesley Cheng wrote: >> The headphone jack framework has a well defined intrastructure for > > infrastructure > >> notifying userspace entities through input devices. Expose a jack device >> that carries information about if an offload capable device is connected. >> Applications can further identify specific offloading information through >> other SND kcontrols. > > What if you connect a set of USB speakers? Would they show as a > headphone/headset? > For now, let me modify the patch to send a HEADPHONE event. We don't support the capture/record path as of now, so it doesn't make sense to generate a HEADSET event (which exposes both MIC and HEADPHONE). When you plug in any USB audio device we'd generate this snd jack event. Main purpose was to notify that the offload path is potentially available. Thanks Wesley Cheng >> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> >> --- >> sound/soc/qcom/qdsp6/q6usb.c | 17 +++++++++++++++-- >> 1 file changed, 15 insertions(+), 2 deletions(-) >> >> diff --git a/sound/soc/qcom/qdsp6/q6usb.c b/sound/soc/qcom/qdsp6/q6usb.c >> index e4ccb9d912b0..860dff8c1438 100644 >> --- a/sound/soc/qcom/qdsp6/q6usb.c >> +++ b/sound/soc/qcom/qdsp6/q6usb.c >> @@ -20,6 +20,7 @@ >> #include <sound/pcm_params.h> >> #include <sound/asound.h> >> #include <sound/q6usboffload.h> >> +#include <sound/jack.h> >> >> #include "q6dsp-lpass-ports.h" >> #include "q6afe.h" >> @@ -37,6 +38,7 @@ struct q6usb_status { >> struct q6usb_port_data { >> struct q6afe_usb_cfg usb_cfg; >> struct snd_soc_usb *usb; >> + struct snd_soc_jack hs_jack; >> struct q6usb_offload priv; >> struct mutex mutex; >> unsigned long available_card_slot; >> @@ -279,6 +281,7 @@ static const struct snd_kcontrol_new q6usb_offload_control = { >> /* Build a mixer control for a UAC connector control (jack-detect) */ >> static void q6usb_connector_control_init(struct snd_soc_component *component) >> { >> + struct q6usb_port_data *data = dev_get_drvdata(component->dev); >> int ret; >> >> ret = snd_ctl_add(component->card->snd_card, >> @@ -290,6 +293,11 @@ static void q6usb_connector_control_init(struct snd_soc_component *component) >> snd_ctl_new1(&q6usb_offload_dev_ctrl, component)); >> if (ret < 0) >> return; >> + >> + ret = snd_soc_card_jack_new(component->card, "USB offload", >> + SND_JACK_HEADSET, &data->hs_jack); > > not all USB devices are headsets... > >> + if (ret) >> + return; >> } >> >> static int q6usb_audio_ports_of_xlate_dai_name(struct snd_soc_component *component, >> @@ -322,7 +330,10 @@ static int q6usb_alsa_connection_cb(struct snd_soc_usb *usb, int card_idx, >> >> mutex_lock(&data->mutex); >> if (connected) { >> - snd_soc_dapm_enable_pin(dapm, "USB_RX_BE"); >> + if (!data->available_card_slot) { >> + snd_soc_dapm_enable_pin(dapm, "USB_RX_BE"); >> + snd_jack_report(data->hs_jack.jack, 1); >> + } >> /* >> * Update the latest USB headset plugged in, if session is >> * idle. >> @@ -338,8 +349,10 @@ static int q6usb_alsa_connection_cb(struct snd_soc_usb *usb, int card_idx, >> clear_bit(card_idx, &data->available_card_slot); >> data->status[card_idx].num_pcm = 0; >> data->status[card_idx].chip_index = 0; >> - if (!data->available_card_slot) >> + if (!data->available_card_slot) { >> snd_soc_dapm_disable_pin(dapm, "USB_RX_BE"); >> + snd_jack_report(data->hs_jack.jack, 0); >> + } >> } >> snd_soc_dapm_sync(dapm); >> mutex_unlock(&data->mutex);
diff --git a/sound/soc/qcom/qdsp6/q6usb.c b/sound/soc/qcom/qdsp6/q6usb.c index e4ccb9d912b0..860dff8c1438 100644 --- a/sound/soc/qcom/qdsp6/q6usb.c +++ b/sound/soc/qcom/qdsp6/q6usb.c @@ -20,6 +20,7 @@ #include <sound/pcm_params.h> #include <sound/asound.h> #include <sound/q6usboffload.h> +#include <sound/jack.h> #include "q6dsp-lpass-ports.h" #include "q6afe.h" @@ -37,6 +38,7 @@ struct q6usb_status { struct q6usb_port_data { struct q6afe_usb_cfg usb_cfg; struct snd_soc_usb *usb; + struct snd_soc_jack hs_jack; struct q6usb_offload priv; struct mutex mutex; unsigned long available_card_slot; @@ -279,6 +281,7 @@ static const struct snd_kcontrol_new q6usb_offload_control = { /* Build a mixer control for a UAC connector control (jack-detect) */ static void q6usb_connector_control_init(struct snd_soc_component *component) { + struct q6usb_port_data *data = dev_get_drvdata(component->dev); int ret; ret = snd_ctl_add(component->card->snd_card, @@ -290,6 +293,11 @@ static void q6usb_connector_control_init(struct snd_soc_component *component) snd_ctl_new1(&q6usb_offload_dev_ctrl, component)); if (ret < 0) return; + + ret = snd_soc_card_jack_new(component->card, "USB offload", + SND_JACK_HEADSET, &data->hs_jack); + if (ret) + return; } static int q6usb_audio_ports_of_xlate_dai_name(struct snd_soc_component *component, @@ -322,7 +330,10 @@ static int q6usb_alsa_connection_cb(struct snd_soc_usb *usb, int card_idx, mutex_lock(&data->mutex); if (connected) { - snd_soc_dapm_enable_pin(dapm, "USB_RX_BE"); + if (!data->available_card_slot) { + snd_soc_dapm_enable_pin(dapm, "USB_RX_BE"); + snd_jack_report(data->hs_jack.jack, 1); + } /* * Update the latest USB headset plugged in, if session is * idle. @@ -338,8 +349,10 @@ static int q6usb_alsa_connection_cb(struct snd_soc_usb *usb, int card_idx, clear_bit(card_idx, &data->available_card_slot); data->status[card_idx].num_pcm = 0; data->status[card_idx].chip_index = 0; - if (!data->available_card_slot) + if (!data->available_card_slot) { snd_soc_dapm_disable_pin(dapm, "USB_RX_BE"); + snd_jack_report(data->hs_jack.jack, 0); + } } snd_soc_dapm_sync(dapm); mutex_unlock(&data->mutex);
The headphone jack framework has a well defined intrastructure for notifying userspace entities through input devices. Expose a jack device that carries information about if an offload capable device is connected. Applications can further identify specific offloading information through other SND kcontrols. Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> --- sound/soc/qcom/qdsp6/q6usb.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)