// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/ #include <linux/of.h> #include <linux/usb.h>
/* SOC USB sound kcontrols */ /** * snd_soc_usb_setup_offload_jack() - Create USB offloading jack * @component: USB DPCM backend DAI component * @jack: jack structure to create * * Creates a jack device for notifying userspace of the availability * of an offload capable device. * * Returns 0 on success, negative on error. *
*/ int snd_soc_usb_setup_offload_jack(struct snd_soc_component *component, struct snd_soc_jack *jack)
{ int ret;
ret = snd_soc_card_jack_new(component->card, "USB Offload Jack",
SND_JACK_USB, jack); if (ret < 0) {
dev_err(component->card->dev, "Unable to add USB offload jack: %d\n",
ret); return ret;
}
ret = snd_soc_component_set_jack(component, jack, NULL); if (ret) {
dev_err(component->card->dev, "Failed to set jack: %d\n", ret); return ret;
}
/** * snd_soc_usb_update_offload_route - Find active USB offload path * @dev: USB device to get offload status * @card: USB card index * @pcm: USB PCM device index * @direction: playback or capture direction * @path: pcm or card index * @route: pointer to route output array * * Fetch the current status for the USB SND card and PCM device indexes * specified. The "route" argument should be an array of integers being * used for a kcontrol output. The first element should have the selected * card index, and the second element should have the selected pcm device * index.
*/ int snd_soc_usb_update_offload_route(struct device *dev, int card, int pcm, int direction, enum snd_soc_usb_kctl path, long *route)
{ struct snd_soc_usb *ctx; int ret = -ENODEV;
mutex_lock(&ctx_mutex);
ctx = snd_soc_find_usb_ctx(dev); if (!ctx) gotoexit;
if (ctx->update_offload_route_info)
ret = ctx->update_offload_route_info(ctx->component, card, pcm,
direction, path, route); exit:
mutex_unlock(&ctx_mutex);
/** * snd_soc_usb_find_supported_format() - Check if audio format is supported * @card_idx: USB sound chip array index * @params: PCM parameters * @direction: capture or playback * * Ensure that a requested audio profile from the ASoC side is able to be * supported by the USB device. * * Return 0 on success, negative on error. *
*/ int snd_soc_usb_find_supported_format(int card_idx, struct snd_pcm_hw_params *params, int direction)
{ struct snd_usb_stream *as;
as = snd_usb_find_suppported_substream(card_idx, params, direction); if (!as) return -EOPNOTSUPP;
/** * snd_soc_usb_allocate_port() - allocate a SoC USB port for offloading support * @component: USB DPCM backend DAI component * @data: private data * * Allocate and initialize a SoC USB port. The SoC USB port is used to communicate * different USB audio devices attached, in order to start audio offloading handled * by an ASoC entity. USB device plug in/out events are signaled with a * notification, but don't directly impact the memory allocated for the SoC USB * port. *
*/ struct snd_soc_usb *snd_soc_usb_allocate_port(struct snd_soc_component *component, void *data)
{ struct snd_soc_usb *usb;
usb = kzalloc(sizeof(*usb), GFP_KERNEL); if (!usb) return ERR_PTR(-ENOMEM);
/** * snd_soc_usb_free_port() - free a SoC USB port used for offloading support * @usb: allocated SoC USB port * * Free and remove the SoC USB port from the available list of ports. This will * ensure that the communication between USB SND and ASoC is halted. *
*/ void snd_soc_usb_free_port(struct snd_soc_usb *usb)
{
snd_soc_usb_remove_port(usb);
kfree(usb);
}
EXPORT_SYMBOL_GPL(snd_soc_usb_free_port);
/** * snd_soc_usb_add_port() - Add a USB backend port * @usb: soc usb port to add * * Register a USB backend DAI link to the USB SoC framework. Memory is allocated * as part of the USB backend DAI link. *
*/ void snd_soc_usb_add_port(struct snd_soc_usb *usb)
{
mutex_lock(&ctx_mutex);
list_add_tail(&usb->list, &usb_ctx_list);
mutex_unlock(&ctx_mutex);
/** * snd_soc_usb_remove_port() - Remove a USB backend port * @usb: soc usb port to remove * * Remove a USB backend DAI link from USB SoC. Memory is freed when USB backend * DAI is removed, or when snd_soc_usb_free_port() is called. *
*/ void snd_soc_usb_remove_port(struct snd_soc_usb *usb)
{ struct snd_soc_usb *ctx, *tmp;
/** * snd_soc_usb_connect() - Notification of USB device connection * @usbdev: USB bus device * @sdev: USB SND device to add * * Notify of a new USB SND device connection. The sdev->card_idx can be used to * handle how the DPCM backend selects, which device to enable USB offloading * on. *
*/ int snd_soc_usb_connect(struct device *usbdev, struct snd_soc_usb_device *sdev)
{ struct snd_soc_usb *ctx;
if (!usbdev) return -ENODEV;
mutex_lock(&ctx_mutex);
ctx = snd_soc_find_usb_ctx(usbdev); if (!ctx) gotoexit;
if (ctx->connection_status_cb)
ctx->connection_status_cb(ctx, sdev, true);
/** * snd_soc_usb_disconnect() - Notification of USB device disconnection * @usbdev: USB bus device * @sdev: USB SND device to remove * * Notify of a new USB SND device disconnection to the USB backend. *
*/ int snd_soc_usb_disconnect(struct device *usbdev, struct snd_soc_usb_device *sdev)
{ struct snd_soc_usb *ctx;
if (!usbdev) return -ENODEV;
mutex_lock(&ctx_mutex);
ctx = snd_soc_find_usb_ctx(usbdev); if (!ctx) gotoexit;
if (ctx->connection_status_cb)
ctx->connection_status_cb(ctx, sdev, false);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.