Re: [PATCH v28 18/32] ASoC: doc: Add documentation for SOC USB

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



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.




[Index of Archives]     [Pulseaudio]     [Linux Audio Users]     [ALSA Devel]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]

  Powered by Linux