diff mbox series

[v23,32/32] ASoC: doc: Add documentation for SOC USB

Message ID 20240610235808.22173-33-quic_wcheng@quicinc.com (mailing list archive)
State New
Headers show
Series Introduce QC USB SND audio offloading support | expand

Commit Message

Wesley Cheng June 10, 2024, 11:58 p.m. UTC
With the introduction of the soc-usb driver, add documentation highlighting
details on how to utilize the new driver and how it interacts with
different components in USB SND and ASoC.  It provides examples on how to
implement the drivers that will need to be introduced in order to enable
USB audio offloading.

Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
---
 Documentation/sound/soc/index.rst |   1 +
 Documentation/sound/soc/usb.rst   | 603 ++++++++++++++++++++++++++++++
 2 files changed, 604 insertions(+)
 create mode 100644 Documentation/sound/soc/usb.rst

Comments

Bagas Sanjaya June 12, 2024, 12:25 p.m. UTC | #1
On Mon, Jun 10, 2024 at 04:58:08PM -0700, Wesley Cheng wrote:
> +Overview
> +========
> +In order to leverage the existing USB sound device support in ALSA, the
> +introduction of the ASoC USB APIs, allow for the entities to communicate
> +with one another.
"... ASoC USB APIs are introduced to allow for ..."

> +USB Audio Device Connection Flow
> +--------------------------------
> +USB devices can be hotplugged into the USB root hub 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.
> +The following callback can be used to notify the BE DAI link of any change:
> +
> +	**connection_status_cb()**
"... connection_status_cb() can be used to ..."

Thanks.
Amadeusz Sławiński June 12, 2024, 2:47 p.m. UTC | #2
On 6/11/2024 1:58 AM, Wesley Cheng wrote:

(...)

> +In the case where the USB offload driver is unbounded, while USB SND is

unbounded -> unbound

(...)

> +SOC USB and USB Sound Kcontrols
> +===============================
> +Details
> +-------
> +SOC USB and USB sound expose a set of SND kcontrols for applications to select
> +and fetch the current offloading status for the ASoC platform sound card. Kcontrols
> +are split between two layers:
> +
> +	- USB sound - Notifies the sound card number for the ASoC platform sound
> +	  card that it is registered to for supporting audio offload.
> +
> +	- SOC USB - Maintains the current status of the offload path, and device
> +	  (USB sound card and PCM device) information.  This would be the main
> +	  card that applications can read to determine offloading capabilities.
> +
> +Implementation
> +--------------
> +
> +**Example:**
> +
> +  **Sound Cards**:
> +
> +	::
> +
> +	  0 [SM8250MTPWCD938]: sm8250 - SM8250-MTP-WCD9380-WSA8810-VA-D
> +                     SM8250-MTP-WCD9380-WSA8810-VA-DMIC
> +	  1 [C320M          ]: USB-Audio - Plantronics C320-M
> +                     Plantronics Plantronics C320-M at usb-xhci-hcd.1.auto-1, full speed
> +
> +
> +  **Platform Sound Card** - card#0:
> +
> +	::
> +
> +	  USB Offload Playback Route Card Select  1 (range -1->32)
> +	  USB Offload Playback Route PCM Select   0 (range -1->255)
> +	  USB Offload Playback Route Card Status  -1 (range -1->32)
> +	  USB Offload Playback Route PCM Status   -1 (range -1->255)
> +
> +
> +  **USB Sound Card** - card#1:
> +
> +	::
> +
> +	  USB Offload Playback Capable Card         0 (range -1->32)
> +
> +
> +The platform sound card(card#0) kcontrols are created as part of adding the SOC
> +USB device using **snd_soc_usb_add_port()**.  The following kcontrols are defined
> +as:
> +
> +  - ``USB Offload Playback Route Card Status`` **(R)**: USB sound card device index
> +    that defines which USB SND resources are currently offloaded.  If -1 is seen, it
> +    signifies that offload is not active.
> +  - ``USB Offload Playback Route PCM Status`` **(R)**: USB PCM device index
> +    that defines which USB SND resources are currently offloaded.  If -1 is seen, it
> +    signifies that offload is not active.
> +  - ``USB Offload Playback Route Card Select`` **(R/W)**: USB sound card index which
> +    selects the USB device to initiate offloading on.  If no value is written to the
> +    kcontrol, then the last USB device discovered card index will be chosen.

I see only one kcontrol, what if hardware is capable of offloading on 
more cards, is it possible to do offloading on more than one device?

> +  - ``USB Offload Playback Route PCM Select`` **(R/W)**: USB PCM index which selects
> +    the USB device to initiate offloading on.  If no value is written to the
> +    kcontrol, then the last USB device discovered PCM zero index will be chosen.
> +
> +The USB sound card(card#1) kcontrols are created as USB audio devices are plugged
> +into the physical USB port and enumerated.  The kcontrols are defined as:
> +
> +  - ``USB Offload Playback Capable Card`` **(R)**: Provides the sound card
> +    number/index that supports USB offloading.  Further/follow up queries about
> +    the current offload state can be handled by reading the offload status
> +    kcontrol exposed by the platform card.
> +


Why do we need to some magic between cards? I feel like whole kcontrol 
thing is overengineered a bit - I'm not sure I understand the need to do 
linking between cards. It would feel a lot simpler if USB card exposed 
one "USB Offload" kcontrol on USB card if USB controller supports 
offloading and allowed to set it to true/false to allow user to choose 
if they want to do offloading on device.

(...)
> +Mixer Examples
> +--------------
> +
> +	::
> +
> +	  tinymix -D 0 set 'USB Offload Playback Route Card Select' 2
> +	  tinymix -D 0 set 'USB Offload Playback Route PCM Select' 0
> +
> +
> +	::
> +
> +	  tinymix -D 0 get 'USB Offload Playback Route Card Select'
> +	  --> 2 (range -1->32)
> +	  tinymix -D 0 get 'USB Offload Playback Route PCM Select'
> +	  --> 0 (range -1->255)
> +
> +	::
> +
> +	  tinymix -D 0 get 'USB Offload Playback Route Card Status'
> +	  --> 2 (range -1->32)   [OFFLD active]
> +	  --> -1 (range -1->32) [OFFLD idle]
> +	  tinymix -D 0 get 'USB Offload Playback Route PCM Status'
> +	  --> 0 (range -1->255)   [OFFLD active]
> +	  --> -1 (range -1->255) [OFFLD idle]
> +
> +	::
> +
> +	  tinymix -D 1 get 'USB Offload Playback Capable Card'
> +	  --> 0 (range -1->32)
> 

Yes, looking at examples again, I'm still not sure I understand. There 
are two cards and you do linking between them, this feels broken by 
design. From my point of view USB Offload should be property of USB card 
and not involve any other card in a system.
Wesley Cheng June 12, 2024, 7:28 p.m. UTC | #3
Hi Amadeusz,

On 6/12/2024 7:47 AM, Amadeusz Sławiński wrote:
> On 6/11/2024 1:58 AM, Wesley Cheng wrote:
> 
> (...)
> 
>> +In the case where the USB offload driver is unbounded, while USB SND is
> 
> unbounded -> unbound
> 
> (...)
> 
>> +SOC USB and USB Sound Kcontrols
>> +===============================
>> +Details
>> +-------
>> +SOC USB and USB sound expose a set of SND kcontrols for applications 
>> to select
>> +and fetch the current offloading status for the ASoC platform sound 
>> card. Kcontrols
>> +are split between two layers:
>> +
>> +    - USB sound - Notifies the sound card number for the ASoC 
>> platform sound
>> +      card that it is registered to for supporting audio offload.
>> +
>> +    - SOC USB - Maintains the current status of the offload path, and 
>> device
>> +      (USB sound card and PCM device) information.  This would be the 
>> main
>> +      card that applications can read to determine offloading 
>> capabilities.
>> +
>> +Implementation
>> +--------------
>> +
>> +**Example:**
>> +
>> +  **Sound Cards**:
>> +
>> +    ::
>> +
>> +      0 [SM8250MTPWCD938]: sm8250 - SM8250-MTP-WCD9380-WSA8810-VA-D
>> +                     SM8250-MTP-WCD9380-WSA8810-VA-DMIC
>> +      1 [C320M          ]: USB-Audio - Plantronics C320-M
>> +                     Plantronics Plantronics C320-M at 
>> usb-xhci-hcd.1.auto-1, full speed
>> +
>> +
>> +  **Platform Sound Card** - card#0:
>> +
>> +    ::
>> +
>> +      USB Offload Playback Route Card Select  1 (range -1->32)
>> +      USB Offload Playback Route PCM Select   0 (range -1->255)
>> +      USB Offload Playback Route Card Status  -1 (range -1->32)
>> +      USB Offload Playback Route PCM Status   -1 (range -1->255)
>> +
>> +
>> +  **USB Sound Card** - card#1:
>> +
>> +    ::
>> +
>> +      USB Offload Playback Capable Card         0 (range -1->32)
>> +
>> +
>> +The platform sound card(card#0) kcontrols are created as part of 
>> adding the SOC
>> +USB device using **snd_soc_usb_add_port()**.  The following kcontrols 
>> are defined
>> +as:
>> +
>> +  - ``USB Offload Playback Route Card Status`` **(R)**: USB sound 
>> card device index
>> +    that defines which USB SND resources are currently offloaded.  If 
>> -1 is seen, it
>> +    signifies that offload is not active.
>> +  - ``USB Offload Playback Route PCM Status`` **(R)**: USB PCM device 
>> index
>> +    that defines which USB SND resources are currently offloaded.  If 
>> -1 is seen, it
>> +    signifies that offload is not active.
>> +  - ``USB Offload Playback Route Card Select`` **(R/W)**: USB sound 
>> card index which
>> +    selects the USB device to initiate offloading on.  If no value is 
>> written to the
>> +    kcontrol, then the last USB device discovered card index will be 
>> chosen.
> 
> I see only one kcontrol, what if hardware is capable of offloading on 
> more cards, is it possible to do offloading on more than one device?
> 
>> +  - ``USB Offload Playback Route PCM Select`` **(R/W)**: USB PCM 
>> index which selects
>> +    the USB device to initiate offloading on.  If no value is written 
>> to the
>> +    kcontrol, then the last USB device discovered PCM zero index will 
>> be chosen.
>> +
>> +The USB sound card(card#1) kcontrols are created as USB audio devices 
>> are plugged
>> +into the physical USB port and enumerated.  The kcontrols are defined 
>> as:
>> +
>> +  - ``USB Offload Playback Capable Card`` **(R)**: Provides the sound 
>> card
>> +    number/index that supports USB offloading.  Further/follow up 
>> queries about
>> +    the current offload state can be handled by reading the offload 
>> status
>> +    kcontrol exposed by the platform card.
>> +
> 
> 
> Why do we need to some magic between cards? I feel like whole kcontrol 
> thing is overengineered a bit - I'm not sure I understand the need to do 
> linking between cards. It would feel a lot simpler if USB card exposed 
> one "USB Offload" kcontrol on USB card if USB controller supports 
> offloading and allowed to set it to true/false to allow user to choose 
> if they want to do offloading on device.
> 
> (...)

Based on feedback from Pierre, what I understood is that for some 
applications, there won't be an order on which sound card is 
queried/opened first.

So the end use case example given was if an application opened the USB 
sound card first, it can see if there is an offload path available.  If 
there is then it can enable the offload path on the corresponding card 
if desired.

>> +Mixer Examples
>> +--------------
>> +
>> +    ::
>> +
>> +      tinymix -D 0 set 'USB Offload Playback Route Card Select' 2
>> +      tinymix -D 0 set 'USB Offload Playback Route PCM Select' 0
>> +
>> +
>> +    ::
>> +
>> +      tinymix -D 0 get 'USB Offload Playback Route Card Select'
>> +      --> 2 (range -1->32)
>> +      tinymix -D 0 get 'USB Offload Playback Route PCM Select'
>> +      --> 0 (range -1->255)
>> +
>> +    ::
>> +
>> +      tinymix -D 0 get 'USB Offload Playback Route Card Status'
>> +      --> 2 (range -1->32)   [OFFLD active]
>> +      --> -1 (range -1->32) [OFFLD idle]
>> +      tinymix -D 0 get 'USB Offload Playback Route PCM Status'
>> +      --> 0 (range -1->255)   [OFFLD active]
>> +      --> -1 (range -1->255) [OFFLD idle]
>> +
>> +    ::
>> +
>> +      tinymix -D 1 get 'USB Offload Playback Capable Card'
>> +      --> 0 (range -1->32)
>>
> 
> Yes, looking at examples again, I'm still not sure I understand. There 
> are two cards and you do linking between them, this feels broken by 
> design. From my point of view USB Offload should be property of USB card 
> and not involve any other card in a system.
> 

Main benefit to having two cards (keeping one for USB SND and another 
for the ASoC platform sound card) is that current applications won't 
break.  The behavior is the same, in that if something opens the USB 
sound card, it will go through the same non-offloaded path.  During 
initial reviews, I think this was a big point where folks wanted the USB 
PCM path to still be an option.

If applications want to add the offload capabilities to its environment, 
they can enable it as an additional feature.

Thanks
Wesley Cheng
Wesley Cheng June 12, 2024, 7:30 p.m. UTC | #4
Hi Bagas,

On 6/12/2024 5:25 AM, Bagas Sanjaya wrote:
> On Mon, Jun 10, 2024 at 04:58:08PM -0700, Wesley Cheng wrote:
>> +Overview
>> +========
>> +In order to leverage the existing USB sound device support in ALSA, the
>> +introduction of the ASoC USB APIs, allow for the entities to communicate
>> +with one another.
> "... ASoC USB APIs are introduced to allow for ..."
> 
>> +USB Audio Device Connection Flow
>> +--------------------------------
>> +USB devices can be hotplugged into the USB root hub 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.
>> +The following callback can be used to notify the BE DAI link of any change:
>> +
>> +	**connection_status_cb()**
> "... connection_status_cb() can be used to ..."
> 
> Thanks.
> 

Thanks for the review, will update

Thanks
Wesley Cheng
Amadeusz Sławiński June 13, 2024, 7:46 a.m. UTC | #5
On 6/12/2024 9:28 PM, Wesley Cheng wrote:
> Hi Amadeusz,
> 
> On 6/12/2024 7:47 AM, Amadeusz Sławiński wrote:
>> On 6/11/2024 1:58 AM, Wesley Cheng wrote:
>>
>> (...)
>>
>>> +In the case where the USB offload driver is unbounded, while USB SND is
>>
>> unbounded -> unbound
>>
>> (...)
>>
>>> +SOC USB and USB Sound Kcontrols
>>> +===============================
>>> +Details
>>> +-------
>>> +SOC USB and USB sound expose a set of SND kcontrols for applications 
>>> to select
>>> +and fetch the current offloading status for the ASoC platform sound 
>>> card. Kcontrols
>>> +are split between two layers:
>>> +
>>> +    - USB sound - Notifies the sound card number for the ASoC 
>>> platform sound
>>> +      card that it is registered to for supporting audio offload.
>>> +
>>> +    - SOC USB - Maintains the current status of the offload path, 
>>> and device
>>> +      (USB sound card and PCM device) information.  This would be 
>>> the main
>>> +      card that applications can read to determine offloading 
>>> capabilities.
>>> +
>>> +Implementation
>>> +--------------
>>> +
>>> +**Example:**
>>> +
>>> +  **Sound Cards**:
>>> +
>>> +    ::
>>> +
>>> +      0 [SM8250MTPWCD938]: sm8250 - SM8250-MTP-WCD9380-WSA8810-VA-D
>>> +                     SM8250-MTP-WCD9380-WSA8810-VA-DMIC
>>> +      1 [C320M          ]: USB-Audio - Plantronics C320-M
>>> +                     Plantronics Plantronics C320-M at 
>>> usb-xhci-hcd.1.auto-1, full speed
>>> +
>>> +
>>> +  **Platform Sound Card** - card#0:
>>> +
>>> +    ::
>>> +
>>> +      USB Offload Playback Route Card Select  1 (range -1->32)
>>> +      USB Offload Playback Route PCM Select   0 (range -1->255)
>>> +      USB Offload Playback Route Card Status  -1 (range -1->32)
>>> +      USB Offload Playback Route PCM Status   -1 (range -1->255)
>>> +
>>> +
>>> +  **USB Sound Card** - card#1:
>>> +
>>> +    ::
>>> +
>>> +      USB Offload Playback Capable Card         0 (range -1->32)
>>> +
>>> +
>>> +The platform sound card(card#0) kcontrols are created as part of 
>>> adding the SOC
>>> +USB device using **snd_soc_usb_add_port()**.  The following 
>>> kcontrols are defined
>>> +as:
>>> +
>>> +  - ``USB Offload Playback Route Card Status`` **(R)**: USB sound 
>>> card device index
>>> +    that defines which USB SND resources are currently offloaded.  
>>> If -1 is seen, it
>>> +    signifies that offload is not active.
>>> +  - ``USB Offload Playback Route PCM Status`` **(R)**: USB PCM 
>>> device index
>>> +    that defines which USB SND resources are currently offloaded.  
>>> If -1 is seen, it
>>> +    signifies that offload is not active.
>>> +  - ``USB Offload Playback Route Card Select`` **(R/W)**: USB sound 
>>> card index which
>>> +    selects the USB device to initiate offloading on.  If no value 
>>> is written to the
>>> +    kcontrol, then the last USB device discovered card index will be 
>>> chosen.
>>
>> I see only one kcontrol, what if hardware is capable of offloading on 
>> more cards, is it possible to do offloading on more than one device?
>>
>>> +  - ``USB Offload Playback Route PCM Select`` **(R/W)**: USB PCM 
>>> index which selects
>>> +    the USB device to initiate offloading on.  If no value is 
>>> written to the
>>> +    kcontrol, then the last USB device discovered PCM zero index 
>>> will be chosen.
>>> +
>>> +The USB sound card(card#1) kcontrols are created as USB audio 
>>> devices are plugged
>>> +into the physical USB port and enumerated.  The kcontrols are 
>>> defined as:
>>> +
>>> +  - ``USB Offload Playback Capable Card`` **(R)**: Provides the 
>>> sound card
>>> +    number/index that supports USB offloading.  Further/follow up 
>>> queries about
>>> +    the current offload state can be handled by reading the offload 
>>> status
>>> +    kcontrol exposed by the platform card.
>>> +
>>
>>
>> Why do we need to some magic between cards? I feel like whole kcontrol 
>> thing is overengineered a bit - I'm not sure I understand the need to 
>> do linking between cards. It would feel a lot simpler if USB card 
>> exposed one "USB Offload" kcontrol on USB card if USB controller 
>> supports offloading and allowed to set it to true/false to allow user 
>> to choose if they want to do offloading on device.
>>
>> (...)
> 
> Based on feedback from Pierre, what I understood is that for some 
> applications, there won't be an order on which sound card is 
> queried/opened first.
> 

Yes if you have multiple cards, they are probed in random order.

> So the end use case example given was if an application opened the USB 
> sound card first, it can see if there is an offload path available.  If 
> there is then it can enable the offload path on the corresponding card 
> if desired.
> 

This still doesn't explain why you need to link cards using controls. 
What would not work with simple "Enable Offload" with true/false values 
on USB card that works while you do have above routing controls?

>>> +Mixer Examples
>>> +--------------
>>> +
>>> +    ::
>>> +
>>> +      tinymix -D 0 set 'USB Offload Playback Route Card Select' 2
>>> +      tinymix -D 0 set 'USB Offload Playback Route PCM Select' 0
>>> +
>>> +
>>> +    ::
>>> +
>>> +      tinymix -D 0 get 'USB Offload Playback Route Card Select'
>>> +      --> 2 (range -1->32)
>>> +      tinymix -D 0 get 'USB Offload Playback Route PCM Select'
>>> +      --> 0 (range -1->255)
>>> +
>>> +    ::
>>> +
>>> +      tinymix -D 0 get 'USB Offload Playback Route Card Status'
>>> +      --> 2 (range -1->32)   [OFFLD active]
>>> +      --> -1 (range -1->32) [OFFLD idle]
>>> +      tinymix -D 0 get 'USB Offload Playback Route PCM Status'
>>> +      --> 0 (range -1->255)   [OFFLD active]
>>> +      --> -1 (range -1->255) [OFFLD idle]
>>> +
>>> +    ::
>>> +
>>> +      tinymix -D 1 get 'USB Offload Playback Capable Card'
>>> +      --> 0 (range -1->32)
>>>
>>
>> Yes, looking at examples again, I'm still not sure I understand. There 
>> are two cards and you do linking between them, this feels broken by 
>> design. From my point of view USB Offload should be property of USB 
>> card and not involve any other card in a system.
>>
> 
> Main benefit to having two cards (keeping one for USB SND and another 
> for the ASoC platform sound card) is that current applications won't 
> break.  The behavior is the same, in that if something opens the USB 
> sound card, it will go through the same non-offloaded path.  During 
> initial reviews, I think this was a big point where folks wanted the USB 
> PCM path to still be an option.
> 

I'm not against having two cards, in fact I hope that USB card looks and 
behaves the same as before this patch set, with only difference being 
controls for enabling offload.

> If applications want to add the offload capabilities to its environment, 
> they can enable it as an additional feature.

That sounds fine to me.
Wesley Cheng June 17, 2024, 5:02 p.m. UTC | #6
Hi Amadeusz,

On 6/13/2024 12:46 AM, Amadeusz Sławiński wrote:
> On 6/12/2024 9:28 PM, Wesley Cheng wrote:
>> Hi Amadeusz,
>>
>> On 6/12/2024 7:47 AM, Amadeusz Sławiński wrote:
>>> On 6/11/2024 1:58 AM, Wesley Cheng wrote:
>>>
>>> (...)
>>>
>>>> +In the case where the USB offload driver is unbounded, while USB 
>>>> SND is
>>>
>>> unbounded -> unbound
>>>
>>> (...)
>>>
>>>> +SOC USB and USB Sound Kcontrols
>>>> +===============================
>>>> +Details
>>>> +-------
>>>> +SOC USB and USB sound expose a set of SND kcontrols for 
>>>> applications to select
>>>> +and fetch the current offloading status for the ASoC platform sound 
>>>> card. Kcontrols
>>>> +are split between two layers:
>>>> +
>>>> +    - USB sound - Notifies the sound card number for the ASoC 
>>>> platform sound
>>>> +      card that it is registered to for supporting audio offload.
>>>> +
>>>> +    - SOC USB - Maintains the current status of the offload path, 
>>>> and device
>>>> +      (USB sound card and PCM device) information.  This would be 
>>>> the main
>>>> +      card that applications can read to determine offloading 
>>>> capabilities.
>>>> +
>>>> +Implementation
>>>> +--------------
>>>> +
>>>> +**Example:**
>>>> +
>>>> +  **Sound Cards**:
>>>> +
>>>> +    ::
>>>> +
>>>> +      0 [SM8250MTPWCD938]: sm8250 - SM8250-MTP-WCD9380-WSA8810-VA-D
>>>> +                     SM8250-MTP-WCD9380-WSA8810-VA-DMIC
>>>> +      1 [C320M          ]: USB-Audio - Plantronics C320-M
>>>> +                     Plantronics Plantronics C320-M at 
>>>> usb-xhci-hcd.1.auto-1, full speed
>>>> +
>>>> +
>>>> +  **Platform Sound Card** - card#0:
>>>> +
>>>> +    ::
>>>> +
>>>> +      USB Offload Playback Route Card Select  1 (range -1->32)
>>>> +      USB Offload Playback Route PCM Select   0 (range -1->255)
>>>> +      USB Offload Playback Route Card Status  -1 (range -1->32)
>>>> +      USB Offload Playback Route PCM Status   -1 (range -1->255)
>>>> +
>>>> +
>>>> +  **USB Sound Card** - card#1:
>>>> +
>>>> +    ::
>>>> +
>>>> +      USB Offload Playback Capable Card         0 (range -1->32)
>>>> +
>>>> +
>>>> +The platform sound card(card#0) kcontrols are created as part of 
>>>> adding the SOC
>>>> +USB device using **snd_soc_usb_add_port()**.  The following 
>>>> kcontrols are defined
>>>> +as:
>>>> +
>>>> +  - ``USB Offload Playback Route Card Status`` **(R)**: USB sound 
>>>> card device index
>>>> +    that defines which USB SND resources are currently offloaded. 
>>>> If -1 is seen, it
>>>> +    signifies that offload is not active.
>>>> +  - ``USB Offload Playback Route PCM Status`` **(R)**: USB PCM 
>>>> device index
>>>> +    that defines which USB SND resources are currently offloaded. 
>>>> If -1 is seen, it
>>>> +    signifies that offload is not active.
>>>> +  - ``USB Offload Playback Route Card Select`` **(R/W)**: USB sound 
>>>> card index which
>>>> +    selects the USB device to initiate offloading on.  If no value 
>>>> is written to the
>>>> +    kcontrol, then the last USB device discovered card index will 
>>>> be chosen.
>>>
>>> I see only one kcontrol, what if hardware is capable of offloading on 
>>> more cards, is it possible to do offloading on more than one device?
>>>
>>>> +  - ``USB Offload Playback Route PCM Select`` **(R/W)**: USB PCM 
>>>> index which selects
>>>> +    the USB device to initiate offloading on.  If no value is 
>>>> written to the
>>>> +    kcontrol, then the last USB device discovered PCM zero index 
>>>> will be chosen.
>>>> +
>>>> +The USB sound card(card#1) kcontrols are created as USB audio 
>>>> devices are plugged
>>>> +into the physical USB port and enumerated.  The kcontrols are 
>>>> defined as:
>>>> +
>>>> +  - ``USB Offload Playback Capable Card`` **(R)**: Provides the 
>>>> sound card
>>>> +    number/index that supports USB offloading.  Further/follow up 
>>>> queries about
>>>> +    the current offload state can be handled by reading the offload 
>>>> status
>>>> +    kcontrol exposed by the platform card.
>>>> +
>>>
>>>
>>> Why do we need to some magic between cards? I feel like whole 
>>> kcontrol thing is overengineered a bit - I'm not sure I understand 
>>> the need to do linking between cards. It would feel a lot simpler if 
>>> USB card exposed one "USB Offload" kcontrol on USB card if USB 
>>> controller supports offloading and allowed to set it to true/false to 
>>> allow user to choose if they want to do offloading on device.
>>>
>>> (...)
>>
>> Based on feedback from Pierre, what I understood is that for some 
>> applications, there won't be an order on which sound card is 
>> queried/opened first.
>>
> 
> Yes if you have multiple cards, they are probed in random order.
> 
>> So the end use case example given was if an application opened the USB 
>> sound card first, it can see if there is an offload path available.  
>> If there is then it can enable the offload path on the corresponding 
>> card if desired.
>>
> 
> This still doesn't explain why you need to link cards using controls. 
> What would not work with simple "Enable Offload" with true/false values 
> on USB card that works while you do have above routing controls?
> 

Sorry for the late response.

I think either way, even with the "Enable Offload" kcontrol in USB SND, 
we'd need a way to link these cards, because if you have multiple USB 
audio devices connected, and say... your offload mechanism only supports 
one stream.  Then I assume we'd still need to way to determine if that 
stream can be enabled for that USB SND device or not.

Since the USB SND isn't really the entity maintaining the offload path, 
I went with the decision to add that route selection to the ASoC 
platform card. It would have access to all the parameters supported by 
the audio DSP.

Thanks
Wesley Cheng

>>>> +Mixer Examples
>>>> +--------------
>>>> +
>>>> +    ::
>>>> +
>>>> +      tinymix -D 0 set 'USB Offload Playback Route Card Select' 2
>>>> +      tinymix -D 0 set 'USB Offload Playback Route PCM Select' 0
>>>> +
>>>> +
>>>> +    ::
>>>> +
>>>> +      tinymix -D 0 get 'USB Offload Playback Route Card Select'
>>>> +      --> 2 (range -1->32)
>>>> +      tinymix -D 0 get 'USB Offload Playback Route PCM Select'
>>>> +      --> 0 (range -1->255)
>>>> +
>>>> +    ::
>>>> +
>>>> +      tinymix -D 0 get 'USB Offload Playback Route Card Status'
>>>> +      --> 2 (range -1->32)   [OFFLD active]
>>>> +      --> -1 (range -1->32) [OFFLD idle]
>>>> +      tinymix -D 0 get 'USB Offload Playback Route PCM Status'
>>>> +      --> 0 (range -1->255)   [OFFLD active]
>>>> +      --> -1 (range -1->255) [OFFLD idle]
>>>> +
>>>> +    ::
>>>> +
>>>> +      tinymix -D 1 get 'USB Offload Playback Capable Card'
>>>> +      --> 0 (range -1->32)
>>>>
>>>
>>> Yes, looking at examples again, I'm still not sure I understand. 
>>> There are two cards and you do linking between them, this feels 
>>> broken by design. From my point of view USB Offload should be 
>>> property of USB card and not involve any other card in a system.
>>>
>>
>> Main benefit to having two cards (keeping one for USB SND and another 
>> for the ASoC platform sound card) is that current applications won't 
>> break.  The behavior is the same, in that if something opens the USB 
>> sound card, it will go through the same non-offloaded path.  During 
>> initial reviews, I think this was a big point where folks wanted the 
>> USB PCM path to still be an option.
>>
> 
> I'm not against having two cards, in fact I hope that USB card looks and 
> behaves the same as before this patch set, with only difference being 
> controls for enabling offload.
> 
>> If applications want to add the offload capabilities to its 
>> environment, they can enable it as an additional feature.
> 
> That sounds fine to me.
>
Amadeusz Sławiński June 18, 2024, 11:42 a.m. UTC | #7
On 6/17/2024 7:02 PM, Wesley Cheng wrote:
> Hi Amadeusz,
> 
> On 6/13/2024 12:46 AM, Amadeusz Sławiński wrote:
>> On 6/12/2024 9:28 PM, Wesley Cheng wrote:
>>> Hi Amadeusz,
>>>
>>> On 6/12/2024 7:47 AM, Amadeusz Sławiński wrote:
>>>> On 6/11/2024 1:58 AM, Wesley Cheng wrote:
>>>>
>>>> (...)
>>>>
>>>>> +In the case where the USB offload driver is unbounded, while USB 
>>>>> SND is
>>>>
>>>> unbounded -> unbound
>>>>
>>>> (...)
>>>>
>>>>> +SOC USB and USB Sound Kcontrols
>>>>> +===============================
>>>>> +Details
>>>>> +-------
>>>>> +SOC USB and USB sound expose a set of SND kcontrols for 
>>>>> applications to select
>>>>> +and fetch the current offloading status for the ASoC platform 
>>>>> sound card. Kcontrols
>>>>> +are split between two layers:
>>>>> +
>>>>> +    - USB sound - Notifies the sound card number for the ASoC 
>>>>> platform sound
>>>>> +      card that it is registered to for supporting audio offload.
>>>>> +
>>>>> +    - SOC USB - Maintains the current status of the offload path, 
>>>>> and device
>>>>> +      (USB sound card and PCM device) information.  This would be 
>>>>> the main
>>>>> +      card that applications can read to determine offloading 
>>>>> capabilities.
>>>>> +
>>>>> +Implementation
>>>>> +--------------
>>>>> +
>>>>> +**Example:**
>>>>> +
>>>>> +  **Sound Cards**:
>>>>> +
>>>>> +    ::
>>>>> +
>>>>> +      0 [SM8250MTPWCD938]: sm8250 - SM8250-MTP-WCD9380-WSA8810-VA-D
>>>>> +                     SM8250-MTP-WCD9380-WSA8810-VA-DMIC
>>>>> +      1 [C320M          ]: USB-Audio - Plantronics C320-M
>>>>> +                     Plantronics Plantronics C320-M at 
>>>>> usb-xhci-hcd.1.auto-1, full speed
>>>>> +
>>>>> +
>>>>> +  **Platform Sound Card** - card#0:
>>>>> +
>>>>> +    ::
>>>>> +
>>>>> +      USB Offload Playback Route Card Select  1 (range -1->32)
>>>>> +      USB Offload Playback Route PCM Select   0 (range -1->255)
>>>>> +      USB Offload Playback Route Card Status  -1 (range -1->32)
>>>>> +      USB Offload Playback Route PCM Status   -1 (range -1->255)
>>>>> +
>>>>> +
>>>>> +  **USB Sound Card** - card#1:
>>>>> +
>>>>> +    ::
>>>>> +
>>>>> +      USB Offload Playback Capable Card         0 (range -1->32)
>>>>> +
>>>>> +
>>>>> +The platform sound card(card#0) kcontrols are created as part of 
>>>>> adding the SOC
>>>>> +USB device using **snd_soc_usb_add_port()**.  The following 
>>>>> kcontrols are defined
>>>>> +as:
>>>>> +
>>>>> +  - ``USB Offload Playback Route Card Status`` **(R)**: USB sound 
>>>>> card device index
>>>>> +    that defines which USB SND resources are currently offloaded. 
>>>>> If -1 is seen, it
>>>>> +    signifies that offload is not active.
>>>>> +  - ``USB Offload Playback Route PCM Status`` **(R)**: USB PCM 
>>>>> device index
>>>>> +    that defines which USB SND resources are currently offloaded. 
>>>>> If -1 is seen, it
>>>>> +    signifies that offload is not active.
>>>>> +  - ``USB Offload Playback Route Card Select`` **(R/W)**: USB 
>>>>> sound card index which
>>>>> +    selects the USB device to initiate offloading on.  If no value 
>>>>> is written to the
>>>>> +    kcontrol, then the last USB device discovered card index will 
>>>>> be chosen.
>>>>
>>>> I see only one kcontrol, what if hardware is capable of offloading 
>>>> on more cards, is it possible to do offloading on more than one device?
>>>>
>>>>> +  - ``USB Offload Playback Route PCM Select`` **(R/W)**: USB PCM 
>>>>> index which selects
>>>>> +    the USB device to initiate offloading on.  If no value is 
>>>>> written to the
>>>>> +    kcontrol, then the last USB device discovered PCM zero index 
>>>>> will be chosen.
>>>>> +
>>>>> +The USB sound card(card#1) kcontrols are created as USB audio 
>>>>> devices are plugged
>>>>> +into the physical USB port and enumerated.  The kcontrols are 
>>>>> defined as:
>>>>> +
>>>>> +  - ``USB Offload Playback Capable Card`` **(R)**: Provides the 
>>>>> sound card
>>>>> +    number/index that supports USB offloading.  Further/follow up 
>>>>> queries about
>>>>> +    the current offload state can be handled by reading the 
>>>>> offload status
>>>>> +    kcontrol exposed by the platform card.
>>>>> +
>>>>
>>>>
>>>> Why do we need to some magic between cards? I feel like whole 
>>>> kcontrol thing is overengineered a bit - I'm not sure I understand 
>>>> the need to do linking between cards. It would feel a lot simpler if 
>>>> USB card exposed one "USB Offload" kcontrol on USB card if USB 
>>>> controller supports offloading and allowed to set it to true/false 
>>>> to allow user to choose if they want to do offloading on device.
>>>>
>>>> (...)
>>>
>>> Based on feedback from Pierre, what I understood is that for some 
>>> applications, there won't be an order on which sound card is 
>>> queried/opened first.
>>>
>>
>> Yes if you have multiple cards, they are probed in random order.
>>
>>> So the end use case example given was if an application opened the 
>>> USB sound card first, it can see if there is an offload path 
>>> available. If there is then it can enable the offload path on the 
>>> corresponding card if desired.
>>>
>>
>> This still doesn't explain why you need to link cards using controls. 
>> What would not work with simple "Enable Offload" with true/false 
>> values on USB card that works while you do have above routing controls?
>>
> 
> Sorry for the late response.
> 
> I think either way, even with the "Enable Offload" kcontrol in USB SND, 
> we'd need a way to link these cards, because if you have multiple USB 
> audio devices connected, and say... your offload mechanism only supports 
> one stream.  Then I assume we'd still need to way to determine if that 
> stream can be enabled for that USB SND device or not.
> 
> Since the USB SND isn't really the entity maintaining the offload path, 
> I went with the decision to add that route selection to the ASoC 
> platform card. It would have access to all the parameters supported by 
> the audio DSP.
> 

Problem with card selection is that it will most likely work in pretty 
random way during reboots and similar scenarios.

Taking from your example:
	USB Offload Playback Route Card Select  1 (range -1->32)
	USB Offload Playback Route PCM Select   0 (range -1->255)
	USB Offload Playback Route Card Status  -1 (range -1->32)
	USB Offload Playback Route PCM Status   -1 (range -1->255)

This tells that hw:1,0 will be offloaded USB card. What happens if after 
reboot the USB card and offload card change places, the control will be 
pointing at its owner... Another scenario to consider is that user 
attaches two USB cards and only first one does offload. Now what happens 
when they enumerate in different order after reboot (swapping places)? 
Taking into the account that most systems restore previous values of 
controls in some way - this will point at wrong card.

In my opinion Offload capability should be the capability of the 
endpoint - in this case USB card (even if in the background it needs to 
talk to some other device) and it should be exposed as such. Currently 
you are mixing capabilities of your audio card with capabilities of USB 
card.

And adding more controls will not make it easy to use from end user 
perspective. Most users will most likely want for the devices to perform 
offload automatically if possible to save power and just have control to 
disable it in case they want to test if it works better without it in 
case of some problems.

Additional question what happens if you want to offload two usb cards, 
currently the above set of controls allows you to only point at one 
card, will you be adding additional set of above controls dynamically 
for each USB card attached?

Thanks,
Amadeusz
diff mbox series

Patch

diff --git a/Documentation/sound/soc/index.rst b/Documentation/sound/soc/index.rst
index e57df2dab2fd..8bed8f8f48da 100644
--- a/Documentation/sound/soc/index.rst
+++ b/Documentation/sound/soc/index.rst
@@ -18,3 +18,4 @@  The documentation is spilt into the following sections:-
    jack
    dpcm
    codec-to-codec
+   usb
diff --git a/Documentation/sound/soc/usb.rst b/Documentation/sound/soc/usb.rst
new file mode 100644
index 000000000000..c5175af52154
--- /dev/null
+++ b/Documentation/sound/soc/usb.rst
@@ -0,0 +1,603 @@ 
+================
+ASoC USB support
+================
+
+Overview
+========
+In order to leverage the existing USB sound device support in ALSA, the
+introduction of the ASoC USB APIs, allow for the entities to communicate
+with one another.
+
+One potential use case would be to support USB audio offloading, which is
+an implementation that allows for an external DSP on the SoC to handle the
+transfer of audio data over the USB bus.  This would let the main
+processor to stay in lower power modes for longer durations.  The following
+is an example design of how the ASoC and ALSA pieces can be connected
+together to achieve this:
+
+::
+
+               USB                   |            ASoC
+                                     |  _________________________
+                                     | |   ASoC Platform card    |
+                                     | |_________________________|
+                                     |         |           |
+                                     |      ___V____   ____V____
+                                     |     |ASoC BE | |ASoC FE  |
+                                     |     |DAI LNK | |DAI LNK  |
+                                     |     |________| |_________|
+                                     |         ^  ^        ^
+                                     |         |  |________|
+                                     |      ___V____    |
+                                     |     |SOC-USB |   |
+     ________       ________               |        |   |
+    |USB SND |<--->|USBSND  |<------------>|________|   |
+    |(card.c)|     |offld   |<----------                |
+    |________|     |________|___     | |                |
+        ^               ^       |    | |    ____________V_________
+        |               |       |    | |   |IPC                   |
+     __ V_______________V_____  |    | |   |______________________|
+    |USB SND (endpoint.c)     | |    | |              ^
+    |_________________________| |    | |              |
+                ^               |    | |   ___________V___________
+                |               |    | |->|audio DSP              |
+     ___________V_____________  |    |    |_______________________|
+    |XHCI HCD                 |<-    |
+    |_________________________|      |
+
+
+SOC USB driver
+==============
+Structures
+----------
+``struct snd_soc_usb``
+
+  - ``list``: list head for SND SOC struct list
+  - ``dev``: USB backend device reference
+  - ``component``: reference to ASoC component
+  - ``active_list``: active sessions
+  - ``num_supported_streams``: number of supported concurrent sessions
+  - ``connection_status_cb``: callback to notify connection events
+  - ``put_offload_dev``: callback to select USB sound card/PCM device
+  - ``get_offload_dev``: callback to fetch selected USB sound card/PCM device
+  - ``priv_data``: driver data
+
+The snd_soc_usb structure can be referenced using the ASoC platform card
+device, or a USB device (udev->dev).  This is created by the ASoC BE DAI
+link, and the USB sound entity will be able to pass information to the
+ASoC BE DAI link using this structure.
+
+``struct snd_soc_usb_device``
+
+  - ``card_idx``: sound card index associated with USB device
+  - ``chip_idx``: USB sound chip array index
+  - ``num_playback``: number of playback streams
+  - ``num_capture``: number of capture streams
+
+The struct snd_soc_usb_device is created by the USB sound offload driver.
+This will carry basic parameters/limitations that will be used to
+determine the possible offloading paths for this USB audio device.
+
+``struct snd_soc_usb_session``
+
+  - ``active_card_idx``: active offloaded sound card
+  - ``active_pcm_idx``: active offloaded PCM device
+  - ``state``: USB BE DAI link PCM state
+
+The struct snd_soc_usb_session tracks the current offloading state for a
+particular card and PCM combination.  This structure is carried/saved as
+part of the active_list within struct snd_soc_usb.
+
+The number of entities in the active list corresponds to the number of
+snd_soc_usb_session structures that are allocated.  This is controlled
+by the num_supported_streams that is reported as part of the SOC USB
+structure creation.
+
+Functions
+---------
+.. code-block:: rst
+
+	const char *snd_soc_usb_get_components_tag(bool playback);
+..
+
+  - ``playback``: direction of audio stream
+
+**snd_soc_usb_get_components_tag()** returns the tag used for describing if USB
+offloading is supported for appending to the ASoC platform card's components
+string.
+
+Returns a tag based on the direction of the audio stream.
+
+.. code-block:: rst
+
+	int snd_soc_usb_find_format(int card_idx, struct snd_pcm_hw_params *params,
+			int direction)
+..
+
+  - ``card_idx``: the index into the USB sound chip array.
+  - ``params``: Requested PCM parameters from the USB DPCM BE DAI link
+  - ``direction``: capture or playback
+
+**snd_soc_usb_find_format()** ensures that the requested audio profile being
+requested by the external DSP is supported by the USB device.
+
+Returns 0 on success, and -EOPNOTSUPP on failure.
+
+.. code-block:: rst
+
+	int snd_soc_usb_connect(struct device *usbdev, struct snd_soc_usb_device *sdev)
+..
+
+  - ``usbdev``: the usb device that was discovered
+  - ``sdev``: capabilities of the device
+
+**snd_soc_usb_connect()** notifies the ASoC USB DCPM BE DAI link of a USB
+audio device detection.  This can be utilized in the BE DAI
+driver to keep track of available USB audio devices.  This is intended
+to be called by the USB offload driver residing in USB SND.
+
+Returns 0 on success, negative error code on failure.
+
+.. code-block:: rst
+
+	int snd_soc_usb_disconnect(struct device *usbdev, struct snd_soc_usb_device *sdev)
+..
+
+  - ``usbdev``: the usb device that was removed
+  - ``sdev``: capabilities to free
+
+**snd_soc_usb_disconnect()** notifies the ASoC USB DCPM BE DAI link of a USB
+audio device removal.  This is intended to be called by the USB offload
+driver that resides in USB SND.
+
+.. code-block:: rst
+
+	void *snd_soc_usb_find_priv_data(struct device *usbdev)
+..
+
+  - ``usbdev``: the usb device to reference to find private data
+
+**snd_soc_usb_find_priv_data()** fetches the private data saved to the SOC USB
+device.
+
+Returns pointer to priv_data on success, NULL on failure.
+
+.. code-block:: rst
+
+	int snd_soc_usb_device_offload_available(struct device *dev)
+..
+
+  - ``dev``: the device to find in SOC USB
+
+**snd_soc_usb_device_offload_available()** fetch the sound card number associated
+to the USB BE DAI link.
+
+Returns a valid sound card index on success, negative on failure.
+
+.. code-block:: rst
+
+	int snd_soc_usb_prepare_session(struct snd_soc_usb *usb, int card_idx, int pcm_idx);
+..
+
+  - ``usb``: SOC USB device
+  - ``card_idx``: USB sound card index
+  - ``pcm_idx``: USB PCM device index
+
+**snd_soc_usb_prepare_session()** populates active_list with a 'struct
+snd_soc_usb_session.'  This will move the session into the SND_SOC_USB_PREPARED
+state.  State updates will always start here.
+
+Returns index to active_list on success, -EBUSY on failure.
+
+.. code-block:: rst
+
+	int snd_soc_usb_shutdown_session(struct snd_soc_usb *usb, int session_id);
+..
+
+  - ``usb``: SOC USB device
+  - ``session_id``: session id returned by **snd_soc_usb_prepare_session()**
+
+**snd_soc_usb_shutdown_session()** frees up a slot in active_list, which signals
+that there is no longer an active offloading device.  This allows for another
+session to be started.
+
+Returns 0 on success, -EINVAL if session index is invalid.
+
+.. code-block:: rst
+
+	int snd_soc_usb_set_session_state(struct snd_soc_usb *usb, int session_id,
+						enum snd_soc_usb_dai_state state);
+..
+
+  - ``usb``: SOC USB device
+  - ``session_id``: session id returned by **snd_soc_usb_prepare_session()**
+  - ``state``: state to move into
+
+**snd_soc_usb_set_session_state()** moves an offloading session to the desired
+state.
+
+.. code-block:: rst
+
+	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``: ASoC sound jack to add
+
+**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
+
+	struct snd_soc_usb *snd_soc_usb_allocate_port(struct snd_soc_component *component,
+			int num_supported_streams, void *data);
+..
+
+  - ``component``: DPCM BE DAI link component
+  - ``num_supported_streams``: number of active streams supported by external DSP
+  - ``data``: private data
+
+**snd_soc_usb_allocate_port()** allocates a SOC USB device and populates standard
+parameters that is used for further operations.
+
+Returns a pointer to struct soc_usb on success, negative on error.
+
+.. code-block:: rst
+
+	void snd_soc_usb_free_port(struct snd_soc_usb *usb);
+..
+
+  - ``usb``: SOC USB device to free
+
+**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.
+
+How to Register to SOC USB
+--------------------------
+The ASoC DPCM USB BE DAI link is the entity responsible for allocating and
+registering the SOC USB device on the component bind.  Likewise, it will
+also be responsible for freeing the allocated resources.  An example can
+be shown below:
+
+.. code-block:: rst
+
+	static int q6usb_component_probe(struct snd_soc_component *component)
+	{
+		...
+		data->usb = snd_soc_usb_allocate_port(component, 1, &data->priv);
+		if (!data->usb)
+			return -ENOMEM;
+
+		usb->connection_status_cb = q6usb_alsa_connection_cb;
+
+		ret = snd_soc_usb_add_port(usb);
+		if (ret < 0) {
+			dev_err(component->dev, "failed to add usb port\n");
+			goto free_usb;
+		}
+		...
+	}
+
+	static void q6usb_component_remove(struct snd_soc_component *component)
+	{
+		...
+		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 root hub 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.
+The following callback can be used to notify the BE DAI link of any change:
+
+	**connection_status_cb()**
+
+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 situtation:
+
+	**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 unbounded, 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
+
+SOC USB and USB Sound Kcontrols
+===============================
+Details
+-------
+SOC USB and USB sound expose a set of SND kcontrols for applications to select
+and fetch the current offloading status for the ASoC platform sound card. Kcontrols
+are split between two layers:
+
+	- USB sound - Notifies the sound card number for the ASoC platform sound
+	  card that it is registered to for supporting audio offload.
+
+	- SOC USB - Maintains the current status of the offload path, and device
+	  (USB sound card and PCM device) information.  This would be the main
+	  card that applications can read to determine offloading capabilities.
+
+Implementation
+--------------
+
+**Example:**
+
+  **Sound Cards**:
+
+	::
+
+	  0 [SM8250MTPWCD938]: sm8250 - SM8250-MTP-WCD9380-WSA8810-VA-D
+                     SM8250-MTP-WCD9380-WSA8810-VA-DMIC
+	  1 [C320M          ]: USB-Audio - Plantronics C320-M
+                     Plantronics Plantronics C320-M at usb-xhci-hcd.1.auto-1, full speed
+
+
+  **Platform Sound Card** - card#0:
+
+	::
+
+	  USB Offload Playback Route Card Select  1 (range -1->32)
+	  USB Offload Playback Route PCM Select   0 (range -1->255)
+	  USB Offload Playback Route Card Status  -1 (range -1->32)
+	  USB Offload Playback Route PCM Status   -1 (range -1->255)
+
+
+  **USB Sound Card** - card#1:
+
+	::
+
+	  USB Offload Playback Capable Card         0 (range -1->32)
+
+
+The platform sound card(card#0) kcontrols are created as part of adding the SOC
+USB device using **snd_soc_usb_add_port()**.  The following kcontrols are defined
+as:
+
+  - ``USB Offload Playback Route Card Status`` **(R)**: USB sound card device index
+    that defines which USB SND resources are currently offloaded.  If -1 is seen, it
+    signifies that offload is not active.
+  - ``USB Offload Playback Route PCM Status`` **(R)**: USB PCM device index
+    that defines which USB SND resources are currently offloaded.  If -1 is seen, it
+    signifies that offload is not active.
+  - ``USB Offload Playback Route Card Select`` **(R/W)**: USB sound card index which
+    selects the USB device to initiate offloading on.  If no value is written to the
+    kcontrol, then the last USB device discovered card index will be chosen.
+  - ``USB Offload Playback Route PCM Select`` **(R/W)**: USB PCM index which selects
+    the USB device to initiate offloading on.  If no value is written to the
+    kcontrol, then the last USB device discovered PCM zero index will be chosen.
+
+The USB sound card(card#1) kcontrols are created as USB audio devices are plugged
+into the physical USB port and enumerated.  The kcontrols are defined as:
+
+  - ``USB Offload Playback Capable Card`` **(R)**: Provides the sound card
+    number/index that supports USB offloading.  Further/follow up queries about
+    the current offload state can be handled by reading the offload status
+    kcontrol exposed by the platform card.
+
+USB Offload Playback Route Select 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 (*put_offload_dev)(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol);
+	int (*get_offload_dev)(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol);
+..
+
+These are specific for the **USB Offload Playback Route Select** kcontrol.
+
+When users issue get/put 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->put_offload_dev = q6usb_put_offload_dev;
+	usb->get_offload_dev = q6usb_get_offload_dev;
+
+	ret = snd_soc_usb_add_port(usb);
+..
+
+**PUT Callback:**
+
+Can be used to track current device selection, and to issue any external DSP
+commands that might be required for enabling audio offloading.
+
+.. code-block:: rst
+
+	static int q6usb_put_offload_dev(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+	{
+	...
+	if ((cardidx >= 0 && test_bit(cardidx, &data->available_card_slot))) {
+		data->sel_card_idx = cardidx;
+		changed = 1;
+	}
+	...
+	if ((pcmidx >= 0 && pcmidx < data->status[cardidx].sdev->num_playback)) {
+		data->sel_pcm_idx = pcmidx;
+		changed = 1;
+	}
+..
+
+The above is an example of keeping track of what the userspace entity is
+selecting as the playback device.  This can be later used to pass the information
+along to the external DSP.
+
+
+USB Offload Playback Route Status
+---------------------------------
+SOC USB exposes APIs for keeping track of the offloading state, and expects this
+to be maintained by the BE DAI link that created/added the SOC USB device.
+
+**SOC USB State Flow Example**
+
+::
+
+     PCM Core              |      BE USB DAI Link      |     SOC USB
+                           |                           |
+  snd_pcm_hw_params --------> dai_link->ops->hw_params --> snd_soc_usb_prepare_session
+                           |                           |   |--> state = SND_SOC_USB_PREPARED
+  ...                      |                           |   |--> slot[0] now active
+                           |                           |
+                           |                           |
+  snd_pcm_do_prepare--------> dai_link->ops->prepare ---> snd_soc_usb_set_session_state
+                           |                           |   |--> state = SND_SOC_USB_RUNNING
+  ...                      |                           |
+                           |                           |
+  snd_pcm_release_substream-> dai_link->ops->shutdown---> snd_soc_usb_shutdown_session
+                           |                           |   |--> state = SND_SOC_USB_IDLE
+                           |                           |   |--> slot[0] now idle
+
+
+When executing the kcontrol get callback, it will loop across the active_list array
+and report to the application for active USB sound card and USB PCM device indexes.
+
+USB Offload Playback Capable Card
+---------------------------------
+USB sound also creates a kcontrol for applications to help determine which platform
+sound card USB offloading is linked to.  This will allow applications to further
+query the platform sound card for specific information about the current USB offload
+status.
+
+This is added as a separate mixer driver:
+  - mixer_usb_offload.c
+  - kcontrol: snd_usb_offload_available_ctl
+
+**snd_usb_offload_available_get()** fetches the associated sound card by utilizing
+the **snd_soc_usb_device_offload_available()** API.
+
+Mixer Examples
+--------------
+
+	::
+
+	  tinymix -D 0 set 'USB Offload Playback Route Card Select' 2
+	  tinymix -D 0 set 'USB Offload Playback Route PCM Select' 0
+
+
+	::
+
+	  tinymix -D 0 get 'USB Offload Playback Route Card Select'
+	  --> 2 (range -1->32)
+	  tinymix -D 0 get 'USB Offload Playback Route PCM Select'
+	  --> 0 (range -1->255)
+
+	::
+
+	  tinymix -D 0 get 'USB Offload Playback Route Card Status'
+	  --> 2 (range -1->32)   [OFFLD active]
+	  --> -1 (range -1->32) [OFFLD idle]
+	  tinymix -D 0 get 'USB Offload Playback Route PCM Status'
+	  --> 0 (range -1->255)   [OFFLD active]
+	  --> -1 (range -1->255) [OFFLD idle]
+
+	::
+
+	  tinymix -D 1 get 'USB Offload Playback Capable Card'
+	  --> 0 (range -1->32)