On 1/25/23 21:14, Wesley Cheng wrote:
Some platforms may want to register its USB port to be handled by the ASoC
framework. Audio playback/capture support is also handled entirely by the
vendor ASoC drivers.
Can you clarify what you mean by 'port'?
+/**
+ * snd_soc_usb_add_port() - Add a USB backend port
+ * @dev: USB backend device
+ * @connection_cb: connection status callback
+ *
+ * Register a USB backend device to the SND USB SOC framework. Memory is
+ * allocated as part of the USB backend device.
+ *
+ */
+struct snd_soc_usb *snd_soc_usb_add_port(struct device *dev,
+ int (*connection_cb)(struct snd_soc_usb *usb, int card_idx,
+ int connected))
+{
+ struct snd_soc_usb *usb;
+
+ usb = devm_kzalloc(dev, sizeof(*usb), GFP_KERNEL);
+ if (!usb)
+ return ERR_PTR(-ENOMEM);
+
+ usb->connection_status_cb = connection_cb;
+ usb->dev = dev;
+
+ mutex_lock(&ctx_mutex);
+ list_add_tail(&usb->list, &usb_ctx_list);
+ mutex_unlock(&ctx_mutex);
+
+ return usb;
+}
+EXPORT_SYMBOL_GPL(snd_soc_usb_add_port);
Can a backend have more than one ports?
Is there any relationship between port and USB endpoint, and if yes
where is this determined?
+
+/**
+ * snd_soc_usb_remove_port() - Remove a USB backend port
+ * @dev: USB backend device
+ *
+ * Remove a USB backend device from USB SND SOC. Memory is freed when USB
+ * backend is removed.
+ *
+ */
+int snd_soc_usb_remove_port(struct device *dev)
+{
+ struct snd_soc_usb *ctx, *tmp;
+
+ mutex_lock(&ctx_mutex);
+ list_for_each_entry_safe(ctx, tmp, &usb_ctx_list, list) {
+ if (ctx->dev == dev) {
+ list_del(&ctx->list);
+ break;
+ }
+ }
+ mutex_unlock(&ctx_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_usb_remove_port);
What happens if the ASoC driver probes/initialize AFTER the USB device
is plugged?
Likewise, can the ASoC driver be removed 'safely' with a fallback to
normal non-offloaded operation happening on remove?
+
+/**
+ * snd_soc_usb_connect() - Notification of USB device connection
+ * @usbdev: USB bus device
+ * @card_idx: USB SND card instance
+ *
+ * Notify of a new USB SND device connection. The card_idx can be used to
+ * handle how the USB backend selects, which device to enable offloading on.
+ *
+ */
+int snd_soc_usb_connect(struct device *usbdev, int card_idx)
+{
+ struct snd_soc_usb *ctx;
+
+ if (!usbdev)
+ return -ENODEV;
+
+ ctx = snd_soc_find_usb_ctx(usbdev);
+ if (!ctx)
+ return -ENODEV;
+
+ if (ctx->connection_status_cb)
+ ctx->connection_status_cb(ctx, card_idx, 1);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_usb_connect);
+
+/**
+ * snd_soc_usb_connect() - Notification of USB device connection
+ * @usbdev: USB bus device
+ *
+ * Notify of a new USB SND device disconnection to the USB backend.
+ *
+ */
+int snd_soc_usb_disconnect(struct device *usbdev)
+{
+ struct snd_soc_usb *ctx;
+
+ if (!usbdev)
+ return -ENODEV;
+
+ ctx = snd_soc_find_usb_ctx(usbdev);
+ if (!ctx)
+ return -ENODEV;
+
+ if (ctx->connection_status_cb)
+ ctx->connection_status_cb(ctx, -1, 0);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_usb_disconnect);
Similar concern on connect/disconnect, does this assume any specific
order for the driver probe?