Re: [PATCH v4 29/32] sound: soc: qcom: q6usb: Add headphone jack for offload connection status

From: Wesley Cheng
Date: Tue Aug 15 2023 - 21:12:56 EST


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@xxxxxxxxxxx>
---
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);