@@ -19,20 +19,21 @@ struct snd_soc_usb {
struct device *dev;
struct snd_soc_component *component;
int (*connection_status_cb)(struct snd_soc_usb *usb, int card_idx,
- int connected);
+ int chip_idx, int num_pcm, int connected);
void *priv_data;
};
int snd_soc_usb_find_format(int card_idx, struct snd_pcm_hw_params *params,
int direction);
-int snd_soc_usb_connect(struct device *usbdev, int card_idx);
-int snd_soc_usb_disconnect(struct device *usbdev);
+int snd_soc_usb_connect(struct device *usbdev, int card_idx, int chip_idx,
+ int num_pcm);
+int snd_soc_usb_disconnect(struct device *usbdev, int card_idx);
void snd_soc_usb_set_priv_data(struct device *dev, void *priv);
void *snd_soc_usb_get_priv_data(struct device *usbdev);
struct snd_soc_usb *snd_soc_usb_add_port(struct device *dev, void *priv,
int (*connection_cb)(struct snd_soc_usb *usb, int card_idx,
- int connected));
+ int chip_idx, int num_pcm, int connected));
int snd_soc_usb_remove_port(struct device *dev);
#endif
@@ -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;
};
@@ -97,7 +105,7 @@ static int q6usb_audio_ports_of_xlate_dai_name(struct snd_soc_component *compone
}
static int q6usb_alsa_connection_cb(struct snd_soc_usb *usb, int card_idx,
- int connected)
+ int chip_idx, int num_pcm, int connected)
{
struct snd_soc_dapm_context *dapm;
struct q6usb_port_data *data;
@@ -109,8 +117,16 @@ static int q6usb_alsa_connection_cb(struct snd_soc_usb *usb, int card_idx,
snd_soc_dapm_enable_pin(dapm, "USB_RX_BE");
/* We only track the latest USB headset plugged in */
data->active_idx = card_idx;
+
+ set_bit(card_idx, &data->available_card_slot);
+ data->status[card_idx].num_pcm = num_pcm;
+ data->status[card_idx].chip_index = chip_idx;
} else {
- snd_soc_dapm_disable_pin(dapm, "USB_RX_BE");
+ 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)
+ snd_soc_dapm_disable_pin(dapm, "USB_RX_BE");
}
snd_soc_dapm_sync(dapm);
@@ -95,7 +95,7 @@ EXPORT_SYMBOL_GPL(snd_soc_usb_find_format);
*/
struct snd_soc_usb *snd_soc_usb_add_port(struct device *dev, void *priv,
int (*connection_cb)(struct snd_soc_usb *usb, int card_idx,
- int connected))
+ int chip_idx, int num_pcm, int connected))
{
struct snd_soc_usb *usb;
@@ -149,7 +149,8 @@ EXPORT_SYMBOL_GPL(snd_soc_usb_remove_port);
* handle how the USB backend selects, which device to enable offloading on.
*
*/
-int snd_soc_usb_connect(struct device *usbdev, int card_idx)
+int snd_soc_usb_connect(struct device *usbdev, int card_idx, int chip_idx,
+ int num_pcm)
{
struct snd_soc_usb *ctx;
@@ -161,7 +162,8 @@ int snd_soc_usb_connect(struct device *usbdev, int card_idx)
return -ENODEV;
if (ctx->connection_status_cb)
- ctx->connection_status_cb(ctx, card_idx, 1);
+ ctx->connection_status_cb(ctx, card_idx, chip_idx,
+ num_pcm, 1);
return 0;
}
@@ -174,7 +176,7 @@ EXPORT_SYMBOL_GPL(snd_soc_usb_connect);
* Notify of a new USB SND device disconnection to the USB backend.
*
*/
-int snd_soc_usb_disconnect(struct device *usbdev)
+int snd_soc_usb_disconnect(struct device *usbdev, int card_idx)
{
struct snd_soc_usb *ctx;
@@ -186,7 +188,7 @@ int snd_soc_usb_disconnect(struct device *usbdev)
return -ENODEV;
if (ctx->connection_status_cb)
- ctx->connection_status_cb(ctx, -1, 0);
+ ctx->connection_status_cb(ctx, card_idx, 0, 0, 0);
return 0;
}
@@ -1562,7 +1562,8 @@ static void qc_usb_audio_offload_probe(struct snd_usb_audio *chip)
uadev[chip->card->number].chip = chip;
uaudio_qdev->last_card_num = chip->card->number;
- snd_soc_usb_connect(usb_get_usb_backend(udev), chip->index);
+ snd_soc_usb_connect(usb_get_usb_backend(udev), chip->card->number,
+ chip->index, chip->pcm_devs);
mutex_unlock(&chip->mutex);
}
@@ -1649,12 +1650,12 @@ static void qc_usb_audio_offload_disconnect(struct snd_usb_audio *chip)
uadev[card_num].chip = NULL;
mutex_unlock(&chip->mutex);
+ snd_soc_usb_disconnect(usb_get_usb_backend(udev), card_num);
+
mutex_lock(&qdev_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);
}