1*6640c9bcSWesley Cheng================ 2*6640c9bcSWesley ChengASoC USB support 3*6640c9bcSWesley Cheng================ 4*6640c9bcSWesley Cheng 5*6640c9bcSWesley ChengOverview 6*6640c9bcSWesley Cheng======== 7*6640c9bcSWesley ChengIn order to leverage the existing USB sound device support in ALSA, the 8*6640c9bcSWesley ChengASoC USB APIs are introduced to allow the subsystems to exchange 9*6640c9bcSWesley Chengconfiguration information. 10*6640c9bcSWesley Cheng 11*6640c9bcSWesley ChengOne potential use case would be to support USB audio offloading, which is 12*6640c9bcSWesley Chengan implementation that allows for an alternate power-optimized path in the audio 13*6640c9bcSWesley Chengsubsystem to handle the transfer of audio data over the USB bus. This would 14*6640c9bcSWesley Chenglet the main processor to stay in lower power modes for longer duration. The 15*6640c9bcSWesley Chengfollowing is an example design of how the ASoC and ALSA pieces can be connected 16*6640c9bcSWesley Chengtogether to achieve this: 17*6640c9bcSWesley Cheng 18*6640c9bcSWesley Cheng:: 19*6640c9bcSWesley Cheng 20*6640c9bcSWesley Cheng USB | ASoC 21*6640c9bcSWesley Cheng | _________________________ 22*6640c9bcSWesley Cheng | | ASoC Platform card | 23*6640c9bcSWesley Cheng | |_________________________| 24*6640c9bcSWesley Cheng | | | 25*6640c9bcSWesley Cheng | ___V____ ____V____ 26*6640c9bcSWesley Cheng | |ASoC BE | |ASoC FE | 27*6640c9bcSWesley Cheng | |DAI LNK | |DAI LNK | 28*6640c9bcSWesley Cheng | |________| |_________| 29*6640c9bcSWesley Cheng | ^ ^ ^ 30*6640c9bcSWesley Cheng | | |________| 31*6640c9bcSWesley Cheng | ___V____ | 32*6640c9bcSWesley Cheng | |SoC-USB | | 33*6640c9bcSWesley Cheng ________ ________ | | | 34*6640c9bcSWesley Cheng |USB SND |<--->|USBSND |<------------>|________| | 35*6640c9bcSWesley Cheng |(card.c)| |offld |<---------- | 36*6640c9bcSWesley Cheng |________| |________|___ | | | 37*6640c9bcSWesley Cheng ^ ^ | | | ____________V_________ 38*6640c9bcSWesley Cheng | | | | | |IPC | 39*6640c9bcSWesley Cheng __ V_______________V_____ | | | |______________________| 40*6640c9bcSWesley Cheng |USB SND (endpoint.c) | | | | ^ 41*6640c9bcSWesley Cheng |_________________________| | | | | 42*6640c9bcSWesley Cheng ^ | | | ___________V___________ 43*6640c9bcSWesley Cheng | | | |->|audio DSP | 44*6640c9bcSWesley Cheng ___________V_____________ | | |_______________________| 45*6640c9bcSWesley Cheng |XHCI HCD |<- | 46*6640c9bcSWesley Cheng |_________________________| | 47*6640c9bcSWesley Cheng 48*6640c9bcSWesley Cheng 49*6640c9bcSWesley ChengSoC USB driver 50*6640c9bcSWesley Cheng============== 51*6640c9bcSWesley ChengStructures 52*6640c9bcSWesley Cheng---------- 53*6640c9bcSWesley Cheng``struct snd_soc_usb`` 54*6640c9bcSWesley Cheng 55*6640c9bcSWesley Cheng - ``list``: list head for SND SoC struct list 56*6640c9bcSWesley Cheng - ``component``: reference to ASoC component 57*6640c9bcSWesley Cheng - ``connection_status_cb``: callback to notify connection events 58*6640c9bcSWesley Cheng - ``update_offload_route_info``: callback to fetch selected USB sound card/PCM 59*6640c9bcSWesley Cheng device 60*6640c9bcSWesley Cheng - ``priv_data``: driver data 61*6640c9bcSWesley Cheng 62*6640c9bcSWesley ChengThe snd_soc_usb structure can be referenced using the ASoC platform card 63*6640c9bcSWesley Chengdevice, or a USB device (udev->dev). This is created by the ASoC BE DAI 64*6640c9bcSWesley Chenglink, and the USB sound entity will be able to pass information to the 65*6640c9bcSWesley ChengASoC BE DAI link using this structure. 66*6640c9bcSWesley Cheng 67*6640c9bcSWesley Cheng``struct snd_soc_usb_device`` 68*6640c9bcSWesley Cheng 69*6640c9bcSWesley Cheng - ``card_idx``: sound card index associated with USB sound device 70*6640c9bcSWesley Cheng - ``chip_idx``: USB sound chip array index 71*6640c9bcSWesley Cheng - ``cpcm_idx``: capture pcm device indexes associated with the USB sound device 72*6640c9bcSWesley Cheng - ``ppcm_idx``: playback pcm device indexes associated with the USB sound device 73*6640c9bcSWesley Cheng - ``num_playback``: number of playback streams 74*6640c9bcSWesley Cheng - ``num_capture``: number of capture streams 75*6640c9bcSWesley Cheng - ``list``: list head for the USB sound device list 76*6640c9bcSWesley Cheng 77*6640c9bcSWesley ChengThe struct snd_soc_usb_device is created by the USB sound offload driver. 78*6640c9bcSWesley ChengThis will carry basic parameters/limitations that will be used to 79*6640c9bcSWesley Chengdetermine the possible offloading paths for this USB audio device. 80*6640c9bcSWesley Cheng 81*6640c9bcSWesley ChengFunctions 82*6640c9bcSWesley Cheng--------- 83*6640c9bcSWesley Cheng.. code-block:: rst 84*6640c9bcSWesley Cheng 85*6640c9bcSWesley Cheng int snd_soc_usb_find_supported_format(int card_idx, 86*6640c9bcSWesley Cheng struct snd_pcm_hw_params *params, int direction) 87*6640c9bcSWesley Cheng.. 88*6640c9bcSWesley Cheng 89*6640c9bcSWesley Cheng - ``card_idx``: the index into the USB sound chip array. 90*6640c9bcSWesley Cheng - ``params``: Requested PCM parameters from the USB DPCM BE DAI link 91*6640c9bcSWesley Cheng - ``direction``: capture or playback 92*6640c9bcSWesley Cheng 93*6640c9bcSWesley Cheng**snd_soc_usb_find_supported_format()** ensures that the requested audio profile 94*6640c9bcSWesley Chengbeing requested by the external DSP is supported by the USB device. 95*6640c9bcSWesley Cheng 96*6640c9bcSWesley ChengReturns 0 on success, and -EOPNOTSUPP on failure. 97*6640c9bcSWesley Cheng 98*6640c9bcSWesley Cheng.. code-block:: rst 99*6640c9bcSWesley Cheng 100*6640c9bcSWesley Cheng int snd_soc_usb_connect(struct device *usbdev, struct snd_soc_usb_device *sdev) 101*6640c9bcSWesley Cheng.. 102*6640c9bcSWesley Cheng 103*6640c9bcSWesley Cheng - ``usbdev``: the usb device that was discovered 104*6640c9bcSWesley Cheng - ``sdev``: capabilities of the device 105*6640c9bcSWesley Cheng 106*6640c9bcSWesley Cheng**snd_soc_usb_connect()** notifies the ASoC USB DCPM BE DAI link of a USB 107*6640c9bcSWesley Chengaudio device detection. This can be utilized in the BE DAI 108*6640c9bcSWesley Chengdriver to keep track of available USB audio devices. This is intended 109*6640c9bcSWesley Chengto be called by the USB offload driver residing in USB SND. 110*6640c9bcSWesley Cheng 111*6640c9bcSWesley ChengReturns 0 on success, negative error code on failure. 112*6640c9bcSWesley Cheng 113*6640c9bcSWesley Cheng.. code-block:: rst 114*6640c9bcSWesley Cheng 115*6640c9bcSWesley Cheng int snd_soc_usb_disconnect(struct device *usbdev, struct snd_soc_usb_device *sdev) 116*6640c9bcSWesley Cheng.. 117*6640c9bcSWesley Cheng 118*6640c9bcSWesley Cheng - ``usbdev``: the usb device that was removed 119*6640c9bcSWesley Cheng - ``sdev``: capabilities to free 120*6640c9bcSWesley Cheng 121*6640c9bcSWesley Cheng**snd_soc_usb_disconnect()** notifies the ASoC USB DCPM BE DAI link of a USB 122*6640c9bcSWesley Chengaudio device removal. This is intended to be called by the USB offload 123*6640c9bcSWesley Chengdriver that resides in USB SND. 124*6640c9bcSWesley Cheng 125*6640c9bcSWesley Cheng.. code-block:: rst 126*6640c9bcSWesley Cheng 127*6640c9bcSWesley Cheng void *snd_soc_usb_find_priv_data(struct device *usbdev) 128*6640c9bcSWesley Cheng.. 129*6640c9bcSWesley Cheng 130*6640c9bcSWesley Cheng - ``usbdev``: the usb device to reference to find private data 131*6640c9bcSWesley Cheng 132*6640c9bcSWesley Cheng**snd_soc_usb_find_priv_data()** fetches the private data saved to the SoC USB 133*6640c9bcSWesley Chengdevice. 134*6640c9bcSWesley Cheng 135*6640c9bcSWesley ChengReturns pointer to priv_data on success, NULL on failure. 136*6640c9bcSWesley Cheng 137*6640c9bcSWesley Cheng.. code-block:: rst 138*6640c9bcSWesley Cheng 139*6640c9bcSWesley Cheng int snd_soc_usb_setup_offload_jack(struct snd_soc_component *component, 140*6640c9bcSWesley Cheng struct snd_soc_jack *jack) 141*6640c9bcSWesley Cheng.. 142*6640c9bcSWesley Cheng 143*6640c9bcSWesley Cheng - ``component``: ASoC component to add the jack 144*6640c9bcSWesley Cheng - ``jack``: jack component to populate 145*6640c9bcSWesley Cheng 146*6640c9bcSWesley Cheng**snd_soc_usb_setup_offload_jack()** is a helper to add a sound jack control to 147*6640c9bcSWesley Chengthe platform sound card. This will allow for consistent naming to be used on 148*6640c9bcSWesley Chengdesigns that support USB audio offloading. Additionally, this will enable the 149*6640c9bcSWesley Chengjack to notify of changes. 150*6640c9bcSWesley Cheng 151*6640c9bcSWesley ChengReturns 0 on success, negative otherwise. 152*6640c9bcSWesley Cheng 153*6640c9bcSWesley Cheng.. code-block:: rst 154*6640c9bcSWesley Cheng 155*6640c9bcSWesley Cheng int snd_soc_usb_update_offload_route(struct device *dev, int card, int pcm, 156*6640c9bcSWesley Cheng int direction, enum snd_soc_usb_kctl path, 157*6640c9bcSWesley Cheng long *route) 158*6640c9bcSWesley Cheng.. 159*6640c9bcSWesley Cheng 160*6640c9bcSWesley Cheng - ``dev``: USB device to look up offload path mapping 161*6640c9bcSWesley Cheng - ``card``: USB sound card index 162*6640c9bcSWesley Cheng - ``pcm``: USB sound PCM device index 163*6640c9bcSWesley Cheng - ``direction``: direction to fetch offload routing information 164*6640c9bcSWesley Cheng - ``path``: kcontrol selector - pcm device or card index 165*6640c9bcSWesley Cheng - ``route``: mapping of sound card and pcm indexes for the offload path. This is 166*6640c9bcSWesley Cheng an array of two integers that will carry the card and pcm device indexes 167*6640c9bcSWesley Cheng in that specific order. This can be used as the array for the kcontrol 168*6640c9bcSWesley Cheng output. 169*6640c9bcSWesley Cheng 170*6640c9bcSWesley Cheng**snd_soc_usb_update_offload_route()** calls a registered callback to the USB BE DAI 171*6640c9bcSWesley Chenglink to fetch the information about the mapped ASoC devices for executing USB audio 172*6640c9bcSWesley Chengoffload for the device. ``route`` may be a pointer to a kcontrol value output array, 173*6640c9bcSWesley Chengwhich carries values when the kcontrol is read. 174*6640c9bcSWesley Cheng 175*6640c9bcSWesley ChengReturns 0 on success, negative otherwise. 176*6640c9bcSWesley Cheng 177*6640c9bcSWesley Cheng.. code-block:: rst 178*6640c9bcSWesley Cheng 179*6640c9bcSWesley Cheng struct snd_soc_usb *snd_soc_usb_allocate_port(struct snd_soc_component *component, 180*6640c9bcSWesley Cheng void *data); 181*6640c9bcSWesley Cheng.. 182*6640c9bcSWesley Cheng 183*6640c9bcSWesley Cheng - ``component``: DPCM BE DAI link component 184*6640c9bcSWesley Cheng - ``data``: private data 185*6640c9bcSWesley Cheng 186*6640c9bcSWesley Cheng**snd_soc_usb_allocate_port()** allocates a SoC USB device and populates standard 187*6640c9bcSWesley Chengparameters that is used for further operations. 188*6640c9bcSWesley Cheng 189*6640c9bcSWesley ChengReturns a pointer to struct soc_usb on success, negative on error. 190*6640c9bcSWesley Cheng 191*6640c9bcSWesley Cheng.. code-block:: rst 192*6640c9bcSWesley Cheng 193*6640c9bcSWesley Cheng void snd_soc_usb_free_port(struct snd_soc_usb *usb); 194*6640c9bcSWesley Cheng.. 195*6640c9bcSWesley Cheng 196*6640c9bcSWesley Cheng - ``usb``: SoC USB device to free 197*6640c9bcSWesley Cheng 198*6640c9bcSWesley Cheng**snd_soc_usb_free_port()** frees a SoC USB device. 199*6640c9bcSWesley Cheng 200*6640c9bcSWesley Cheng.. code-block:: rst 201*6640c9bcSWesley Cheng 202*6640c9bcSWesley Cheng void snd_soc_usb_add_port(struct snd_soc_usb *usb); 203*6640c9bcSWesley Cheng.. 204*6640c9bcSWesley Cheng 205*6640c9bcSWesley Cheng - ``usb``: SoC USB device to add 206*6640c9bcSWesley Cheng 207*6640c9bcSWesley Cheng**snd_soc_usb_add_port()** add an allocated SoC USB device to the SOC USB framework. 208*6640c9bcSWesley ChengOnce added, this device can be referenced by further operations. 209*6640c9bcSWesley Cheng 210*6640c9bcSWesley Cheng.. code-block:: rst 211*6640c9bcSWesley Cheng 212*6640c9bcSWesley Cheng void snd_soc_usb_remove_port(struct snd_soc_usb *usb); 213*6640c9bcSWesley Cheng.. 214*6640c9bcSWesley Cheng 215*6640c9bcSWesley Cheng - ``usb``: SoC USB device to remove 216*6640c9bcSWesley Cheng 217*6640c9bcSWesley Cheng**snd_soc_usb_remove_port()** removes a SoC USB device from the SoC USB framework. 218*6640c9bcSWesley ChengAfter removing a device, any SOC USB operations would not be able to reference the 219*6640c9bcSWesley Chengdevice removed. 220*6640c9bcSWesley Cheng 221*6640c9bcSWesley ChengHow to Register to SoC USB 222*6640c9bcSWesley Cheng-------------------------- 223*6640c9bcSWesley ChengThe ASoC DPCM USB BE DAI link is the entity responsible for allocating and 224*6640c9bcSWesley Chengregistering the SoC USB device on the component bind. Likewise, it will 225*6640c9bcSWesley Chengalso be responsible for freeing the allocated resources. An example can 226*6640c9bcSWesley Chengbe shown below: 227*6640c9bcSWesley Cheng 228*6640c9bcSWesley Cheng.. code-block:: rst 229*6640c9bcSWesley Cheng 230*6640c9bcSWesley Cheng static int q6usb_component_probe(struct snd_soc_component *component) 231*6640c9bcSWesley Cheng { 232*6640c9bcSWesley Cheng ... 233*6640c9bcSWesley Cheng data->usb = snd_soc_usb_allocate_port(component, 1, &data->priv); 234*6640c9bcSWesley Cheng if (!data->usb) 235*6640c9bcSWesley Cheng return -ENOMEM; 236*6640c9bcSWesley Cheng 237*6640c9bcSWesley Cheng usb->connection_status_cb = q6usb_alsa_connection_cb; 238*6640c9bcSWesley Cheng 239*6640c9bcSWesley Cheng ret = snd_soc_usb_add_port(usb); 240*6640c9bcSWesley Cheng if (ret < 0) { 241*6640c9bcSWesley Cheng dev_err(component->dev, "failed to add usb port\n"); 242*6640c9bcSWesley Cheng goto free_usb; 243*6640c9bcSWesley Cheng } 244*6640c9bcSWesley Cheng ... 245*6640c9bcSWesley Cheng } 246*6640c9bcSWesley Cheng 247*6640c9bcSWesley Cheng static void q6usb_component_remove(struct snd_soc_component *component) 248*6640c9bcSWesley Cheng { 249*6640c9bcSWesley Cheng ... 250*6640c9bcSWesley Cheng snd_soc_usb_remove_port(data->usb); 251*6640c9bcSWesley Cheng snd_soc_usb_free_port(data->usb); 252*6640c9bcSWesley Cheng } 253*6640c9bcSWesley Cheng 254*6640c9bcSWesley Cheng static const struct snd_soc_component_driver q6usb_dai_component = { 255*6640c9bcSWesley Cheng .probe = q6usb_component_probe, 256*6640c9bcSWesley Cheng .remove = q6usb_component_remove, 257*6640c9bcSWesley Cheng .name = "q6usb-dai-component", 258*6640c9bcSWesley Cheng ... 259*6640c9bcSWesley Cheng }; 260*6640c9bcSWesley Cheng.. 261*6640c9bcSWesley Cheng 262*6640c9bcSWesley ChengBE DAI links can pass along vendor specific information as part of the 263*6640c9bcSWesley Chengcall to allocate the SoC USB device. This will allow any BE DAI link 264*6640c9bcSWesley Chengparameters or settings to be accessed by the USB offload driver that 265*6640c9bcSWesley Chengresides in USB SND. 266*6640c9bcSWesley Cheng 267*6640c9bcSWesley ChengUSB Audio Device Connection Flow 268*6640c9bcSWesley Cheng-------------------------------- 269*6640c9bcSWesley ChengUSB devices can be hotplugged into the USB ports at any point in time. 270*6640c9bcSWesley ChengThe BE DAI link should be aware of the current state of the physical USB 271*6640c9bcSWesley Chengport, i.e. if there are any USB devices with audio interface(s) connected. 272*6640c9bcSWesley Chengconnection_status_cb() can be used to notify the BE DAI link of any change. 273*6640c9bcSWesley Cheng 274*6640c9bcSWesley ChengThis is called whenever there is a USB SND interface bind or remove event, 275*6640c9bcSWesley Chengusing snd_soc_usb_connect() or snd_soc_usb_disconnect(): 276*6640c9bcSWesley Cheng 277*6640c9bcSWesley Cheng.. code-block:: rst 278*6640c9bcSWesley Cheng 279*6640c9bcSWesley Cheng static void qc_usb_audio_offload_probe(struct snd_usb_audio *chip) 280*6640c9bcSWesley Cheng { 281*6640c9bcSWesley Cheng ... 282*6640c9bcSWesley Cheng snd_soc_usb_connect(usb_get_usb_backend(udev), sdev); 283*6640c9bcSWesley Cheng ... 284*6640c9bcSWesley Cheng } 285*6640c9bcSWesley Cheng 286*6640c9bcSWesley Cheng static void qc_usb_audio_offload_disconnect(struct snd_usb_audio *chip) 287*6640c9bcSWesley Cheng { 288*6640c9bcSWesley Cheng ... 289*6640c9bcSWesley Cheng snd_soc_usb_disconnect(usb_get_usb_backend(chip->dev), dev->sdev); 290*6640c9bcSWesley Cheng ... 291*6640c9bcSWesley Cheng } 292*6640c9bcSWesley Cheng.. 293*6640c9bcSWesley Cheng 294*6640c9bcSWesley ChengIn order to account for conditions where driver or device existence is 295*6640c9bcSWesley Chengnot guaranteed, USB SND exposes snd_usb_rediscover_devices() to resend the 296*6640c9bcSWesley Chengconnect events for any identified USB audio interfaces. Consider the 297*6640c9bcSWesley Chengthe following situation: 298*6640c9bcSWesley Cheng 299*6640c9bcSWesley Cheng **usb_audio_probe()** 300*6640c9bcSWesley Cheng | --> USB audio streams allocated and saved to usb_chip[] 301*6640c9bcSWesley Cheng | --> Propagate connect event to USB offload driver in USB SND 302*6640c9bcSWesley Cheng | --> **snd_soc_usb_connect()** exits as USB BE DAI link is not ready 303*6640c9bcSWesley Cheng 304*6640c9bcSWesley Cheng BE DAI link component probe 305*6640c9bcSWesley Cheng | --> DAI link is probed and SoC USB port is allocated 306*6640c9bcSWesley Cheng | --> The USB audio device connect event is missed 307*6640c9bcSWesley Cheng 308*6640c9bcSWesley ChengTo ensure connection events are not missed, **snd_usb_rediscover_devices()** 309*6640c9bcSWesley Chengis executed when the SoC USB device is registered. Now, when the BE DAI 310*6640c9bcSWesley Chenglink component probe occurs, the following highlights the sequence: 311*6640c9bcSWesley Cheng 312*6640c9bcSWesley Cheng BE DAI link component probe 313*6640c9bcSWesley Cheng | --> DAI link is probed and SoC USB port is allocated 314*6640c9bcSWesley Cheng | --> SoC USB device added, and **snd_usb_rediscover_devices()** runs 315*6640c9bcSWesley Cheng 316*6640c9bcSWesley Cheng **snd_usb_rediscover_devices()** 317*6640c9bcSWesley Cheng | --> Traverses through usb_chip[] and for non-NULL entries issue 318*6640c9bcSWesley Cheng | **connection_status_cb()** 319*6640c9bcSWesley Cheng 320*6640c9bcSWesley ChengIn the case where the USB offload driver is unbound, while USB SND is ready, 321*6640c9bcSWesley Chengthe **snd_usb_rediscover_devices()** is called during module init. This allows 322*6640c9bcSWesley Chengfor the offloading path to also be enabled with the following flow: 323*6640c9bcSWesley Cheng 324*6640c9bcSWesley Cheng **usb_audio_probe()** 325*6640c9bcSWesley Cheng | --> USB audio streams allocated and saved to usb_chip[] 326*6640c9bcSWesley Cheng | --> Propagate connect event to USB offload driver in USB SND 327*6640c9bcSWesley Cheng | --> USB offload driver **NOT** ready! 328*6640c9bcSWesley Cheng 329*6640c9bcSWesley Cheng BE DAI link component probe 330*6640c9bcSWesley Cheng | --> DAI link is probed and SoC USB port is allocated 331*6640c9bcSWesley Cheng | --> No USB connect event due to missing USB offload driver 332*6640c9bcSWesley Cheng 333*6640c9bcSWesley Cheng USB offload driver probe 334*6640c9bcSWesley Cheng | --> **qc_usb_audio_offload_init()** 335*6640c9bcSWesley Cheng | --> Calls **snd_usb_rediscover_devices()** to notify of devices 336*6640c9bcSWesley Cheng 337*6640c9bcSWesley ChengUSB Offload Related Kcontrols 338*6640c9bcSWesley Cheng============================= 339*6640c9bcSWesley ChengDetails 340*6640c9bcSWesley Cheng------- 341*6640c9bcSWesley ChengA set of kcontrols can be utilized by applications to help select the proper sound 342*6640c9bcSWesley Chengdevices to enable USB audio offloading. SoC USB exposes the get_offload_dev() 343*6640c9bcSWesley Chengcallback that designs can use to ensure that the proper indices are returned to the 344*6640c9bcSWesley Chengapplication. 345*6640c9bcSWesley Cheng 346*6640c9bcSWesley ChengImplementation 347*6640c9bcSWesley Cheng-------------- 348*6640c9bcSWesley Cheng 349*6640c9bcSWesley Cheng**Example:** 350*6640c9bcSWesley Cheng 351*6640c9bcSWesley Cheng **Sound Cards**: 352*6640c9bcSWesley Cheng 353*6640c9bcSWesley Cheng :: 354*6640c9bcSWesley Cheng 355*6640c9bcSWesley Cheng 0 [SM8250MTPWCD938]: sm8250 - SM8250-MTP-WCD9380-WSA8810-VA-D 356*6640c9bcSWesley Cheng SM8250-MTP-WCD9380-WSA8810-VA-DMIC 357*6640c9bcSWesley Cheng 1 [Seri ]: USB-Audio - Plantronics Blackwire 3225 Seri 358*6640c9bcSWesley Cheng Plantronics Plantronics Blackwire 359*6640c9bcSWesley Cheng 3225 Seri at usb-xhci-hcd.1.auto-1.1, 360*6640c9bcSWesley Cheng full sp 361*6640c9bcSWesley Cheng 2 [C320M ]: USB-Audio - Plantronics C320-M 362*6640c9bcSWesley Cheng Plantronics Plantronics C320-M at usb-xhci-hcd.1.auto-1.2, full speed 363*6640c9bcSWesley Cheng 364*6640c9bcSWesley Cheng **PCM Devices**: 365*6640c9bcSWesley Cheng 366*6640c9bcSWesley Cheng :: 367*6640c9bcSWesley Cheng 368*6640c9bcSWesley Cheng card 0: SM8250MTPWCD938 [SM8250-MTP-WCD9380-WSA8810-VA-D], device 0: MultiMedia1 (*) [] 369*6640c9bcSWesley Cheng Subdevices: 1/1 370*6640c9bcSWesley Cheng Subdevice #0: subdevice #0 371*6640c9bcSWesley Cheng card 0: SM8250MTPWCD938 [SM8250-MTP-WCD9380-WSA8810-VA-D], device 1: MultiMedia2 (*) [] 372*6640c9bcSWesley Cheng Subdevices: 1/1 373*6640c9bcSWesley Cheng Subdevice #0: subdevice #0 374*6640c9bcSWesley Cheng card 1: Seri [Plantronics Blackwire 3225 Seri], device 0: USB Audio [USB Audio] 375*6640c9bcSWesley Cheng Subdevices: 1/1 376*6640c9bcSWesley Cheng Subdevice #0: subdevice #0 377*6640c9bcSWesley Cheng card 2: C320M [Plantronics C320-M], device 0: USB Audio [USB Audio] 378*6640c9bcSWesley Cheng Subdevices: 1/1 379*6640c9bcSWesley Cheng Subdevice #0: subdevice #0 380*6640c9bcSWesley Cheng 381*6640c9bcSWesley Cheng **USB Sound Card** - card#1: 382*6640c9bcSWesley Cheng 383*6640c9bcSWesley Cheng :: 384*6640c9bcSWesley Cheng 385*6640c9bcSWesley Cheng USB Offload Playback Card Route PCM#0 -1 (range -1->32) 386*6640c9bcSWesley Cheng USB Offload Playback PCM Route PCM#0 -1 (range -1->255) 387*6640c9bcSWesley Cheng 388*6640c9bcSWesley Cheng **USB Sound Card** - card#2: 389*6640c9bcSWesley Cheng 390*6640c9bcSWesley Cheng :: 391*6640c9bcSWesley Cheng 392*6640c9bcSWesley Cheng USB Offload Playback Card Route PCM#0 0 (range -1->32) 393*6640c9bcSWesley Cheng USB Offload Playback PCM Route PCM#0 1 (range -1->255) 394*6640c9bcSWesley Cheng 395*6640c9bcSWesley ChengThe above example shows a scenario where the system has one ASoC platform card 396*6640c9bcSWesley Cheng(card#0) and two USB sound devices connected (card#1 and card#2). When reading 397*6640c9bcSWesley Chengthe available kcontrols for each USB audio device, the following kcontrols lists 398*6640c9bcSWesley Chengthe mapped offload card and pcm device indexes for the specific USB device: 399*6640c9bcSWesley Cheng 400*6640c9bcSWesley Cheng ``USB Offload Playback Card Route PCM#*`` 401*6640c9bcSWesley Cheng 402*6640c9bcSWesley Cheng ``USB Offload Playback PCM Route PCM#*`` 403*6640c9bcSWesley Cheng 404*6640c9bcSWesley ChengThe kcontrol is indexed, because a USB audio device could potentially have 405*6640c9bcSWesley Chengseveral PCM devices. The above kcontrols are defined as: 406*6640c9bcSWesley Cheng 407*6640c9bcSWesley Cheng - ``USB Offload Playback Card Route PCM#`` **(R)**: Returns the ASoC platform sound 408*6640c9bcSWesley Cheng card index for a mapped offload path. The output **"0"** (card index) signifies 409*6640c9bcSWesley Cheng that there is an available offload path for the USB SND device through card#0. 410*6640c9bcSWesley Cheng If **"-1"** is seen, then no offload path is available for the USB SND device. 411*6640c9bcSWesley Cheng This kcontrol exists for each USB audio device that exists in the system, and 412*6640c9bcSWesley Cheng its expected to derive the current status of offload based on the output value 413*6640c9bcSWesley Cheng for the kcontrol along with the PCM route kcontrol. 414*6640c9bcSWesley Cheng 415*6640c9bcSWesley Cheng - ``USB Offload Playback PCM Route PCM#`` **(R)**: Returns the ASoC platform sound 416*6640c9bcSWesley Cheng PCM device index for a mapped offload path. The output **"1"** (PCM device index) 417*6640c9bcSWesley Cheng signifies that there is an available offload path for the USB SND device through 418*6640c9bcSWesley Cheng PCM device#0. If **"-1"** is seen, then no offload path is available for the USB\ 419*6640c9bcSWesley Cheng SND device. This kcontrol exists for each USB audio device that exists in the 420*6640c9bcSWesley Cheng system, and its expected to derive the current status of offload based on the 421*6640c9bcSWesley Cheng output value for this kcontrol, in addition to the card route kcontrol. 422*6640c9bcSWesley Cheng 423*6640c9bcSWesley ChengUSB Offload Playback Route Kcontrol 424*6640c9bcSWesley Cheng----------------------------------- 425*6640c9bcSWesley ChengIn order to allow for vendor specific implementations on audio offloading device 426*6640c9bcSWesley Chengselection, the SoC USB layer exposes the following: 427*6640c9bcSWesley Cheng 428*6640c9bcSWesley Cheng.. code-block:: rst 429*6640c9bcSWesley Cheng 430*6640c9bcSWesley Cheng int (*update_offload_route_info)(struct snd_soc_component *component, 431*6640c9bcSWesley Cheng int card, int pcm, int direction, 432*6640c9bcSWesley Cheng enum snd_soc_usb_kctl path, 433*6640c9bcSWesley Cheng long *route) 434*6640c9bcSWesley Cheng.. 435*6640c9bcSWesley Cheng 436*6640c9bcSWesley ChengThese are specific for the **USB Offload Playback Card Route PCM#** and **USB 437*6640c9bcSWesley ChengOffload PCM Route PCM#** kcontrols. 438*6640c9bcSWesley Cheng 439*6640c9bcSWesley ChengWhen users issue get calls to the kcontrol, the registered SoC USB callbacks will 440*6640c9bcSWesley Chengexecute the registered function calls to the DPCM BE DAI link. 441*6640c9bcSWesley Cheng 442*6640c9bcSWesley Cheng**Callback Registration:** 443*6640c9bcSWesley Cheng 444*6640c9bcSWesley Cheng.. code-block:: rst 445*6640c9bcSWesley Cheng 446*6640c9bcSWesley Cheng static int q6usb_component_probe(struct snd_soc_component *component) 447*6640c9bcSWesley Cheng { 448*6640c9bcSWesley Cheng ... 449*6640c9bcSWesley Cheng usb = snd_soc_usb_allocate_port(component, 1, &data->priv); 450*6640c9bcSWesley Cheng if (IS_ERR(usb)) 451*6640c9bcSWesley Cheng return -ENOMEM; 452*6640c9bcSWesley Cheng 453*6640c9bcSWesley Cheng usb->connection_status_cb = q6usb_alsa_connection_cb; 454*6640c9bcSWesley Cheng usb->update_offload_route_info = q6usb_get_offload_dev; 455*6640c9bcSWesley Cheng 456*6640c9bcSWesley Cheng ret = snd_soc_usb_add_port(usb); 457*6640c9bcSWesley Cheng.. 458*6640c9bcSWesley Cheng 459*6640c9bcSWesley ChengExisting USB Sound Kcontrol 460*6640c9bcSWesley Cheng--------------------------- 461*6640c9bcSWesley ChengWith the introduction of USB offload support, the above USB offload kcontrol 462*6640c9bcSWesley Chengwill be added to the pre existing list of kcontrols identified by the USB sound 463*6640c9bcSWesley Chengframework. These kcontrols are still the main controls that are used to 464*6640c9bcSWesley Chengmodify characteristics pertaining to the USB audio device. 465*6640c9bcSWesley Cheng 466*6640c9bcSWesley Cheng :: 467*6640c9bcSWesley Cheng 468*6640c9bcSWesley Cheng Number of controls: 9 469*6640c9bcSWesley Cheng ctl type num name value 470*6640c9bcSWesley Cheng 0 INT 2 Capture Channel Map 0, 0 (range 0->36) 471*6640c9bcSWesley Cheng 1 INT 2 Playback Channel Map 0, 0 (range 0->36) 472*6640c9bcSWesley Cheng 2 BOOL 1 Headset Capture Switch On 473*6640c9bcSWesley Cheng 3 INT 1 Headset Capture Volume 10 (range 0->13) 474*6640c9bcSWesley Cheng 4 BOOL 1 Sidetone Playback Switch On 475*6640c9bcSWesley Cheng 5 INT 1 Sidetone Playback Volume 4096 (range 0->8192) 476*6640c9bcSWesley Cheng 6 BOOL 1 Headset Playback Switch On 477*6640c9bcSWesley Cheng 7 INT 2 Headset Playback Volume 20, 20 (range 0->24) 478*6640c9bcSWesley Cheng 8 INT 1 USB Offload Playback Card Route PCM#0 0 (range -1->32) 479*6640c9bcSWesley Cheng 9 INT 1 USB Offload Playback PCM Route PCM#0 1 (range -1->255) 480*6640c9bcSWesley Cheng 481*6640c9bcSWesley ChengSince USB audio device controls are handled over the USB control endpoint, use the 482*6640c9bcSWesley Chengexisting mechanisms present in the USB mixer to set parameters, such as volume. 483