xref: /linux/Documentation/sound/soc/usb.rst (revision c0c9379f235df33a12ceae94370ad80c5278324d)
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