Linux Sound subsystem development
 help / color / mirror / Atom feed
From: Wesley Cheng <quic_wcheng@quicinc.com>
To: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>,
	<srinivas.kandagatla@linaro.org>, <mathias.nyman@intel.com>,
	<perex@perex.cz>, <conor+dt@kernel.org>,
	<dmitry.torokhov@gmail.com>, <corbet@lwn.net>,
	<broonie@kernel.org>, <lgirdwood@gmail.com>, <tiwai@suse.com>,
	<krzk+dt@kernel.org>, <Thinh.Nguyen@synopsys.com>,
	<bgoswami@quicinc.com>, <robh@kernel.org>,
	<gregkh@linuxfoundation.org>
Cc: <linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-sound@vger.kernel.org>, <linux-input@vger.kernel.org>,
	<linux-usb@vger.kernel.org>, <linux-arm-msm@vger.kernel.org>,
	<linux-doc@vger.kernel.org>, <alsa-devel@alsa-project.org>
Subject: Re: [PATCH v28 18/32] ASoC: doc: Add documentation for SOC USB
Date: Mon, 30 Sep 2024 18:34:38 -0700	[thread overview]
Message-ID: <eec96e68-4fc4-48c5-b526-62166ab96d9e@quicinc.com> (raw)
In-Reply-To: <86c557ca-2b86-4334-bc42-40dfe8203b71@linux.intel.com>

Hi Pierre,

On 9/25/2024 7:43 AM, Pierre-Louis Bossart wrote:
>> +	int snd_soc_usb_setup_offload_jack(struct snd_soc_component *component,
>> +					struct snd_soc_jack *jack)
>> +..
>> +
>> +  - ``component``: ASoC component to add the jack
>> +  - ``jack``: jack component to populate
>> +
>> +**snd_soc_usb_setup_offload_jack()** is a helper to add a sound jack control to
>> +the platform sound card.  This will allow for consistent naming to be used on
>> +designs that support USB audio offloading.
>> +
>> +Returns 0 on success, negative otherwise.
>> +
>> +.. code-block:: rst
>> +
>> +	int snd_soc_usb_disable_offload_jack(struct snd_soc_component *component)
>> +..
>> +
>> +  - ``component``: ASoC component to disable the jack
>> +
>> +**snd_soc_usb_disable_offload_jack()** is a helper to disable a sound jack control
>> +on the platform sound card.
> is disable_offload_jack() the companion operation to setup_offload_jack()?
>
> it's not clear to me if there's any relationship between the two.
I guess there is a relation in that one creates the jack and the other will disable it when needed.  Might need to have a respective enable API, because I believe there are some situations during PM suspend where a jack may want to be disabled and re-enabled on PM resume.
>> +
>> +Returns 0 on success, negative otherwise.
>> +
>> +.. code-block:: rst
>> +
>> +	int snd_soc_usb_update_offload_route(struct device *dev, int card, int pcm,
>> +					     int direction, long *route)
>> +..
>> +
>> +  - ``dev``: USB device to look up offload path mapping
>> +  - ``card``: USB sound card index
>> +  - ``pcm``: USB sound PCM device index
>> +  - ``direction``: direction to fetch offload routing information
>> +  - ``route``: mapping of sound card and pcm indexes for the offload path.  This is
>> +	       an array of two integers that will carry the card and pcm device indexes
>> +	       in that specific order.  This can be used as the array for the kcontrol
>> +	       output.
>> +
>> +**snd_soc_usb_update_offload_route()** calls a registered callback to the USB BE DAI
>> +link to fetch the information about the mapped ASoC devices for executing USB audio
>> +offload for the device. ``route`` may be a pointer to a kcontrol value output array,
>> +which carries values when the kcontrol is read.
>> +
>> +Returns 0 on success, negative otherwise.
> please clarify what happens if there is no offloaded device for a
> specific USB card. from [2] below it looks like the intended behavior
> for a device without offload capabilities would be to return 0 but the
> mapping would use the -1 magic value to state there is no offload?
>
That is the idea... If we return -1,-1 that is an invalid card/pcm device index, so it would signify that offloading is not available for a USB device.
>> +**snd_soc_usb_free_port()** frees a SOC USB device.
>> +
>> +.. code-block:: rst
>> +
>> +	void snd_soc_usb_add_port(struct snd_soc_usb *usb);
>> +..
>> +
>> +  - ``usb``: SOC USB device to add
>> +
>> +**snd_soc_usb_add_port()** add an allocated SOC USB device to the SOC USB framework.
>> +Once added, this device can be referenced by further operations.
>> +
>> +.. code-block:: rst
>> +
>> +	void snd_soc_usb_remove_port(struct snd_soc_usb *usb);
>> +..
>> +
>> +  - ``usb``: SOC USB device to remove
>> +
>> +**snd_soc_usb_remove_port()** removes a SOC USB device from the SOC USB framework.
>> +After removing a device, any SOC USB operations would not be able to reference the
>> +device removed.
> I don't think the last sentence is correct, below [1] you show an
> example where the free_port() routine is required...
>
The remove will remove it from the available list of SOC USB ports.  The free will just make sure the memory allocated for the SOC USB port is freed.
>> +
>> +	static void q6usb_component_remove(struct snd_soc_component *component)
>> +	{
>> +		...
> [1]
>
>> +		snd_soc_usb_remove_port(data->usb);
>> +		snd_soc_usb_free_port(data->usb);
>> +	}
>> +
>> +	static const struct snd_soc_component_driver q6usb_dai_component = {
>> +		.probe = q6usb_component_probe,
>> +		.remove = q6usb_component_remove,
>> +		.name = "q6usb-dai-component",
>> +		...
>> +	};
>> +..
>> +
>> +BE DAI links can pass along vendor specific information as part of the
>> +call to allocate the SOC USB device.  This will allow any BE DAI link
>> +parameters or settings to be accessed by the USB offload driver that
>> +resides in USB SND.
>> +
>> +USB Audio Device Connection Flow
>> +--------------------------------
>> +USB devices can be hotplugged into the USB ports at any point in time.
>> +The BE DAI link should be aware of the current state of the physical USB
>> +port, i.e. if there are any USB devices with audio interface(s) connected.
>> +connection_status_cb() can be used to notify the BE DAI link of any change.
>> +
>> +This is called whenever there is a USB SND interface bind or remove event,
>> +using snd_soc_usb_connect() or snd_soc_usb_disconnect():
>> +
>> +.. code-block:: rst
>> +
>> +	static void qc_usb_audio_offload_probe(struct snd_usb_audio *chip)
>> +	{
>> +		...
>> +		snd_soc_usb_connect(usb_get_usb_backend(udev), sdev);
>> +		...
>> +	}
>> +
>> +	static void qc_usb_audio_offload_disconnect(struct snd_usb_audio *chip)
>> +	{
>> +		...
>> +		snd_soc_usb_disconnect(usb_get_usb_backend(chip->dev), dev->sdev);
>> +		...
>> +	}
>> +..
>> +
>> +In order to account for conditions where driver or device existence is
>> +not guaranteed, USB SND exposes snd_usb_rediscover_devices() to resend the
>> +connect events for any identified USB audio interfaces.  Consider the
>> +the following situation:
>> +
>> +	**usb_audio_probe()**
>> +	  | --> USB audio streams allocated and saved to usb_chip[]
>> +	  | --> Propagate connect event to USB offload driver in USB SND
>> +	  | --> **snd_soc_usb_connect()** exits as USB BE DAI link is not ready
>> +
>> +	BE DAI link component probe
>> +	  | --> DAI link is probed and SOC USB port is allocated
>> +	  | --> The USB audio device connect event is missed
>> +
>> +To ensure connection events are not missed, **snd_usb_rediscover_devices()**
>> +is executed when the SOC USB device is registered.  Now, when the BE DAI
>> +link component probe occurs, the following highlights the sequence:
>> +
>> +	BE DAI link component probe
>> +	  | --> DAI link is probed and SOC USB port is allocated
>> +	  | --> SOC USB device added, and **snd_usb_rediscover_devices()** runs
>> +
>> +	**snd_usb_rediscover_devices()**
>> +	  | --> Traverses through usb_chip[] and for non-NULL entries issue
>> +	  |     **connection_status_cb()**
>> +
>> +In the case where the USB offload driver is unbound, while USB SND is ready,
>> +the **snd_usb_rediscover_devices()** is called during module init.  This allows
>> +for the offloading path to also be enabled with the following flow:
>> +
>> +	**usb_audio_probe()**
>> +	  | --> USB audio streams allocated and saved to usb_chip[]
>> +	  | --> Propagate connect event to USB offload driver in USB SND
>> +	  | --> USB offload driver **NOT** ready!
>> +
>> +	BE DAI link component probe
>> +	  | --> DAI link is probed and SOC USB port is allocated
>> +	  | --> No USB connect event due to missing USB offload driver
>> +
>> +	USB offload driver probe
>> +	  | --> **qc_usb_audio_offload_init()**
>> +	  | --> Calls **snd_usb_rediscover_devices()** to notify of devices
>> +
>> +USB Offload Related Kcontrols
>> +=============================
>> +Details
>> +-------
>> +A set of kcontrols can be utilized by applications to help select the proper sound
>> +devices to enable USB audio offloading.  SOC USB exposes the get_offload_dev()
>> +callback that designs can use to ensure that the proper indices are returned to the
>> +application.
>> +
>> +Implementation
>> +--------------
>> +
>> +**Example:**
>> +
>> +  **Sound Cards**:
>> +
>> +	::
>> +
>> +	  0 [SM8250MTPWCD938]: sm8250 - SM8250-MTP-WCD9380-WSA8810-VA-D
>> +						SM8250-MTP-WCD9380-WSA8810-VA-DMIC
>> +	  1 [Seri           ]: USB-Audio - Plantronics Blackwire 3225 Seri
>> +						Plantronics Plantronics Blackwire
>> +						3225 Seri at usb-xhci-hcd.1.auto-1.1,
>> +						full sp
>> +	  2 [C320M          ]: USB-Audio - Plantronics C320-M
>> +                      Plantronics Plantronics C320-M at usb-xhci-hcd.1.auto-1.2, full speed
>> +
>> +  **USB Sound Card** - card#1:
>> +
>> +	::
>> +
>> +	  USB Offload Playback Route PCM#0        -1, -1 (range -1->255)
>> +
>> +  **USB Sound Card** - card#2:
>> +
>> +	::
>> +
>> +	  USB Offload Playback Route PCM#0        0, 1 (range -1->255)
>> +
>> +The above example shows a scenario where the system has one ASoC platform card
>> +(card#0) and two USB sound devices connected (card#1 and card#2).  When reading
>> +the available kcontrols for each USB audio device, the following kcontrol lists
>> +the mapped offload path for the specific device:
>> +
>> +	``USB Offload Playback Route#*``
>> +
>> +The kcontrol is indexed, because a USB audio device could potentially have
>> +several PCM devices.  The above kcontrols are defined as:
>> +
>> +  - ``USB Offload Playback Route PCM`` **(R)**: Returns the ASoC platform sound
>> +    card and PCM device index.  The output **"0, 1"** (card index, PCM device index)
>> +    signifies that there is an available offload path for the USB SND device
>> +    through card#0 - PCM device#1.  If **"-1, -1"** is seen, then no offload path is
>> +    available for the USB SND device.
> [2]
>
> maybe I got this wrong but you may want to clarify that the kcontrol is
> always created, but the values indicate if the offload support is real
> or not?
Sure, I will explicitly mention that the kcontrol always exists, and if the path is not available, then this would show -1, -1
>
>> +
>> +USB Offload Playback Route Kcontrol
>> +-----------------------------------
>> +In order to allow for vendor specific implementations on audio offloading device
>> +selection, the SOC USB layer exposes the following:
>> +
>> +.. code-block:: rst
>> +
>> +	int (*update_offload_route_info)(struct snd_soc_component *component,
>> +				int card, int pcm, long *route);
>> +..
>> +
>> +These are specific for the **USB Offload Playback Route PCM#** kcontrol.
>> +
>> +When users issue get calls to the kcontrol, the registered SOC USB callbacks will
>> +execute the registered function calls to the DPCM BE DAI link.
>> +
>> +**Callback Registration:**
>> +
>> +.. code-block:: rst
>> +
>> +	static int q6usb_component_probe(struct snd_soc_component *component)
>> +	{
>> +	...
>> +	usb = snd_soc_usb_allocate_port(component, 1, &data->priv);
>> +	if (IS_ERR(usb))
>> +		return -ENOMEM;
>> +
>> +	usb->connection_status_cb = q6usb_alsa_connection_cb;
>> +	usb->update_offload_route_info = q6usb_get_offload_dev;
>> +
>> +	ret = snd_soc_usb_add_port(usb);
>> +..
>> +
>> +Existing USB Sound Kcontrol
>> +---------------------------
>> +With the introduction of USB offload support, the above USB offload kcontrol
>> +can be added to the pre existing list of kcontrols identified by the USB sound
> is this 'can be added' or 'will be added'? The latter seems more correct
> to me, I don't see anything optional or conditional in the description
> and the example below.

Will be added sounds better.  Will change that.

Thanks

Wesley Cheng

>> +framework.  These kcontrols are still the main controls that are used to
>> +modify characteristics pertaining to the USB audio device.
>> +
>> +	::
>> +
>> +	  Number of controls: 9
>> +	  ctl     type    num     name                                    value
>> +	  0       INT     2       Capture Channel Map                     0, 0 (range 0->36)
>> +	  1       INT     2       Playback Channel Map                    0, 0 (range 0->36)
>> +	  2       BOOL    1       Headset Capture Switch                  On
>> +	  3       INT     1       Headset Capture Volume                  10 (range 0->13)
>> +	  4       BOOL    1       Sidetone Playback Switch                On
>> +	  5       INT     1       Sidetone Playback Volume                4096 (range 0->8192)
>> +	  6       BOOL    1       Headset Playback Switch                 On
>> +	  7       INT     2       Headset Playback Volume                 20, 20 (range 0->24)
>> +	  8       INT     2       USB Offload Playback Route PCM#0        -1, -1 (range -1->255)
>> +
>> +Since USB audio device controls are handled over the USB control endpoint, use the
>> +existing mechanisms present in the USB mixer to set parameters, such as volume.

  reply	other threads:[~2024-10-01  1:35 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-25  0:59 [PATCH v28 00/32] Introduce QC USB SND audio offloading support Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 01/32] xhci: add helper to stop endpoint and wait for completion Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 02/32] usb: host: xhci: Repurpose event handler for skipping interrupter events Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 03/32] xhci: sideband: add initial api to register a sideband entity Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 04/32] usb: xhci: xhci-sideband: Set IMOD for xHCI sideband clients Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 05/32] usb: host: xhci-mem: Cleanup pending secondary event ring events Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 06/32] usb: host: xhci-mem: Allow for interrupter clients to choose specific index Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 07/32] usb: host: xhci-plat: Set XHCI max interrupters if property is present Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 08/32] usb: dwc3: Specify maximum number of XHCI interrupters Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 09/32] ALSA: Add USB audio device jack type Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 10/32] ALSA: usb-audio: Export USB SND APIs for modules Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 11/32] ALSA: usb-audio: Check for support for requested audio format Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 12/32] ALSA: usb-audio: Save UAC sample size information Wesley Cheng
2024-09-25 14:22   ` Pierre-Louis Bossart
2024-09-25  0:59 ` [PATCH v28 13/32] ALSA: usb-audio: Prevent starting of audio stream if in use Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 14/32] ASoC: Add SOC USB APIs for adding an USB backend Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 15/32] ASoC: usb: Add PCM format check API for " Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 16/32] ASoC: usb: Create SOC USB SND jack kcontrol Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 17/32] ASoC: usb: Fetch ASoC card and pcm device information Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 18/32] ASoC: doc: Add documentation for SOC USB Wesley Cheng
2024-09-25 14:43   ` Pierre-Louis Bossart
2024-10-01  1:34     ` Wesley Cheng [this message]
2024-10-01 13:48   ` Amadeusz Sławiński
2024-09-25  0:59 ` [PATCH v28 19/32] ASoC: dt-bindings: qcom,q6dsp-lpass-ports: Add USB_RX port Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 20/32] ASoC: dt-bindings: Update example for enabling USB offload on SM8250 Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 21/32] ASoC: qcom: qdsp6: Introduce USB AFE port to q6dsp Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 22/32] ASoC: qcom: qdsp6: q6afe: Increase APR timeout Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 23/32] ASoC: qcom: qdsp6: Add USB backend ASoC driver for Q6 Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 24/32] ASoC: qcom: qdsp6: Add headphone jack for offload connection status Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 25/32] ASoC: qcom: qdsp6: Fetch USB offload mapped card and PCM device Wesley Cheng
2024-09-25 14:48   ` Pierre-Louis Bossart
2024-09-25  0:59 ` [PATCH v28 26/32] ALSA: usb-audio: Introduce USB SND platform op callbacks Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 27/32] ALSA: usb-audio: qcom: Add USB QMI definitions Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 28/32] ALSA: usb-audio: qcom: Introduce QC USB SND offloading support Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 29/32] ALSA: usb-audio: qcom: Don't allow USB offload path if PCM device is in use Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 30/32] ALSA: usb-audio: Add USB offload route kcontrol Wesley Cheng
2024-09-25 14:54   ` Pierre-Louis Bossart
2024-09-25 19:37     ` Wesley Cheng
2024-09-25  0:59 ` [PATCH v28 31/32] ALSA: usb-audio: Allow for rediscovery of connected USB SND devices Wesley Cheng
2024-09-25  1:00 ` [PATCH v28 32/32] ASoC: usb: Rediscover USB SND devices on USB port add Wesley Cheng
2024-09-25 15:04 ` [PATCH v28 00/32] Introduce QC USB SND audio offloading support Pierre-Louis Bossart
2024-10-01 13:50 ` Amadeusz Sławiński
  -- strict thread matches above, loose matches on Subject: below --
2024-10-11  0:05 [PATCH v28 00/33] " Wesley Cheng
2024-10-11  0:06 ` [PATCH v28 18/32] ASoC: doc: Add documentation for SOC USB Wesley Cheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=eec96e68-4fc4-48c5-b526-62166ab96d9e@quicinc.com \
    --to=quic_wcheng@quicinc.com \
    --cc=Thinh.Nguyen@synopsys.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=bgoswami@quicinc.com \
    --cc=broonie@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=krzk+dt@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=perex@perex.cz \
    --cc=pierre-louis.bossart@linux.intel.com \
    --cc=robh@kernel.org \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox