@@ -25,10 +25,18 @@
#define SID_MASK 0xF
+struct q6usb_status {
+ unsigned int num_pcm;
+ unsigned int chip_index;
+ unsigned int pcm_index;
+};
+
struct q6usb_port_data {
struct q6afe_usb_cfg usb_cfg;
struct snd_soc_usb *usb;
struct q6usb_offload priv;
+ unsigned long available_card_slot;
+ struct q6usb_status status[SNDRV_CARDS];
int active_idx;
};
@@ -106,10 +114,19 @@ static int q6usb_alsa_connection_cb(struct snd_soc_usb *usb,
data = dev_get_drvdata(usb->component->dev);
- if (connected)
+ if (connected) {
/* We only track the latest USB headset plugged in */
data->active_idx = sdev->card_idx;
+ set_bit(sdev->card_idx, &data->available_card_slot);
+ data->status[sdev->card_idx].num_pcm = sdev->num_playback;
+ data->status[sdev->card_idx].chip_index = sdev->chip_idx;
+ } else {
+ clear_bit(sdev->card_idx, &data->available_card_slot);
+ data->status[sdev->card_idx].num_pcm = 0;
+ data->status[sdev->card_idx].chip_index = 0;
+ }
+
return 0;
}
@@ -175,6 +175,21 @@ enum usb_qmi_audio_format {
USB_QMI_PCM_FORMAT_U32_BE,
};
+static int usb_qmi_get_pcm_num(struct snd_usb_audio *chip, int direction)
+{
+ struct snd_usb_substream *subs = NULL;
+ struct snd_usb_stream *as;
+ int count = 0;
+
+ list_for_each_entry(as, &chip->pcm_list, list) {
+ subs = &as->substream[direction];
+ if (subs->ep_num)
+ count++;
+ }
+
+ return count;
+}
+
static enum usb_qmi_audio_device_speed_enum_v01
get_speed_info(enum usb_device_speed udev_speed)
{
@@ -1574,6 +1589,8 @@ static void qc_usb_audio_offload_probe(struct snd_usb_audio *chip)
sdev->card_idx = chip->card->number;
sdev->chip_idx = chip->index;
+ sdev->num_playback = usb_qmi_get_pcm_num(chip, 0);
+ sdev->num_capture = usb_qmi_get_pcm_num(chip, 1);
uadev[chip->card->number].sdev = sdev;
uaudio_qdev->last_card_num = chip->card->number;
@@ -1674,10 +1691,8 @@ static void qc_usb_audio_offload_disconnect(struct snd_usb_audio *chip)
mutex_unlock(&chip->mutex);
atomic_dec(&uaudio_qdev->qdev_in_use);
- if (!atomic_read(&uaudio_qdev->qdev_in_use)) {
- snd_soc_usb_disconnect(usb_get_usb_backend(udev));
+ if (!atomic_read(&uaudio_qdev->qdev_in_use))
qc_usb_audio_cleanup_qmi_dev();
- }
mutex_unlock(&qdev_mutex);
xhci_sideband_unregister(dev->sb);
Currently, only the index to the USB SND card array is passed to the USB backend. Pass through more information, specifically the USB SND card number and the number of PCM devices available. The USB backend should know about which sound resources are being shared between the ASoC and USB SND paths. This can be utilized to properly select and maintain the offloading devices. Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> --- sound/soc/qcom/qdsp6/q6usb.c | 19 ++++++++++++++++++- sound/usb/qcom/qc_audio_offload.c | 21 ++++++++++++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-)