diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-04-02 13:50:41 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-04-02 13:50:59 -0400 |
commit | bc334cb61b9ee6e85b9bb01519989a3ae8fe03f6 (patch) | |
tree | 34424a812537fe11beeee727b30b19c67193fe36 | |
parent | 5607dddbfca774fb38bffadcb077fe03aa4ac5c6 (diff) | |
parent | b44d419b98fae759b4f746186b1d1c8d01d962f2 (diff) |
Merge branch 'for-next' into for-linus
Preparation for 4.17 merge.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
35 files changed, 1853 insertions, 473 deletions
diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h index 3119d0ace7aa..aaafecf073ff 100644 --- a/include/linux/usb/audio-v2.h +++ b/include/linux/usb/audio-v2.h | |||
@@ -34,14 +34,14 @@ | |||
34 | * | 34 | * |
35 | */ | 35 | */ |
36 | 36 | ||
37 | static inline bool uac2_control_is_readable(u32 bmControls, u8 control) | 37 | static inline bool uac_v2v3_control_is_readable(u32 bmControls, u8 control) |
38 | { | 38 | { |
39 | return (bmControls >> (control * 2)) & 0x1; | 39 | return (bmControls >> ((control - 1) * 2)) & 0x1; |
40 | } | 40 | } |
41 | 41 | ||
42 | static inline bool uac2_control_is_writeable(u32 bmControls, u8 control) | 42 | static inline bool uac_v2v3_control_is_writeable(u32 bmControls, u8 control) |
43 | { | 43 | { |
44 | return (bmControls >> (control * 2)) & 0x2; | 44 | return (bmControls >> ((control - 1) * 2)) & 0x2; |
45 | } | 45 | } |
46 | 46 | ||
47 | /* 4.7.2 Class-Specific AC Interface Descriptor */ | 47 | /* 4.7.2 Class-Specific AC Interface Descriptor */ |
diff --git a/include/linux/usb/audio-v3.h b/include/linux/usb/audio-v3.h new file mode 100644 index 000000000000..a8959aaba0ae --- /dev/null +++ b/include/linux/usb/audio-v3.h | |||
@@ -0,0 +1,395 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* | ||
3 | * Copyright (c) 2017 Ruslan Bilovol <ruslan.bilovol@gmail.com> | ||
4 | * | ||
5 | * This file holds USB constants and structures defined | ||
6 | * by the USB DEVICE CLASS DEFINITION FOR AUDIO DEVICES Release 3.0. | ||
7 | */ | ||
8 | |||
9 | #ifndef __LINUX_USB_AUDIO_V3_H | ||
10 | #define __LINUX_USB_AUDIO_V3_H | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | |||
14 | /* | ||
15 | * v1.0, v2.0 and v3.0 of this standard have many things in common. For the rest | ||
16 | * of the definitions, please refer to audio.h and audio-v2.h | ||
17 | */ | ||
18 | |||
19 | /* All High Capability descriptors have these 2 fields at the beginning */ | ||
20 | struct uac3_hc_descriptor_header { | ||
21 | __le16 wLength; | ||
22 | __u8 bDescriptorType; | ||
23 | __u8 bDescriptorSubtype; | ||
24 | __le16 wDescriptorID; | ||
25 | } __attribute__ ((packed)); | ||
26 | |||
27 | /* 4.3.1 CLUSTER DESCRIPTOR HEADER */ | ||
28 | struct uac3_cluster_header_descriptor { | ||
29 | __le16 wLength; | ||
30 | __u8 bDescriptorType; | ||
31 | __u8 bDescriptorSubtype; | ||
32 | __le16 wDescriptorID; | ||
33 | __u8 bNrChannels; | ||
34 | } __attribute__ ((packed)); | ||
35 | |||
36 | /* 4.3.2.1 SEGMENTS */ | ||
37 | struct uac3_cluster_segment_descriptor { | ||
38 | __le16 wLength; | ||
39 | __u8 bSegmentType; | ||
40 | /* __u8[0]; segment-specific data */ | ||
41 | } __attribute__ ((packed)); | ||
42 | |||
43 | /* 4.3.2.1.1 END SEGMENT */ | ||
44 | struct uac3_cluster_end_segment_descriptor { | ||
45 | __le16 wLength; | ||
46 | __u8 bSegmentType; /* Constant END_SEGMENT */ | ||
47 | } __attribute__ ((packed)); | ||
48 | |||
49 | /* 4.3.2.1.3.1 INFORMATION SEGMENT */ | ||
50 | struct uac3_cluster_information_segment_descriptor { | ||
51 | __le16 wLength; | ||
52 | __u8 bSegmentType; | ||
53 | __u8 bChPurpose; | ||
54 | __u8 bChRelationship; | ||
55 | __u8 bChGroupID; | ||
56 | } __attribute__ ((packed)); | ||
57 | |||
58 | /* 4.5.2 CLASS-SPECIFIC AC INTERFACE DESCRIPTOR */ | ||
59 | struct uac3_ac_header_descriptor { | ||
60 | __u8 bLength; /* 10 */ | ||
61 | __u8 bDescriptorType; /* CS_INTERFACE descriptor type */ | ||
62 | __u8 bDescriptorSubtype; /* HEADER descriptor subtype */ | ||
63 | __u8 bCategory; | ||
64 | |||
65 | /* includes Clock Source, Unit, Terminal, and Power Domain desc. */ | ||
66 | __le16 wTotalLength; | ||
67 | |||
68 | __le32 bmControls; | ||
69 | } __attribute__ ((packed)); | ||
70 | |||
71 | /* 4.5.2.1 INPUT TERMINAL DESCRIPTOR */ | ||
72 | struct uac3_input_terminal_descriptor { | ||
73 | __u8 bLength; | ||
74 | __u8 bDescriptorType; | ||
75 | __u8 bDescriptorSubtype; | ||
76 | __u8 bTerminalID; | ||
77 | __le16 wTerminalType; | ||
78 | __u8 bAssocTerminal; | ||
79 | __u8 bCSourceID; | ||
80 | __le32 bmControls; | ||
81 | __le16 wClusterDescrID; | ||
82 | __le16 wExTerminalDescrID; | ||
83 | __le16 wConnectorsDescrID; | ||
84 | __le16 wTerminalDescrStr; | ||
85 | } __attribute__((packed)); | ||
86 | |||
87 | /* 4.5.2.2 OUTPUT TERMINAL DESCRIPTOR */ | ||
88 | struct uac3_output_terminal_descriptor { | ||
89 | __u8 bLength; | ||
90 | __u8 bDescriptorType; | ||
91 | __u8 bDescriptorSubtype; | ||
92 | __u8 bTerminalID; | ||
93 | __le16 wTerminalType; | ||
94 | __u8 bAssocTerminal; | ||
95 | __u8 bSourceID; | ||
96 | __u8 bCSourceID; | ||
97 | __le32 bmControls; | ||
98 | __le16 wExTerminalDescrID; | ||
99 | __le16 wConnectorsDescrID; | ||
100 | __le16 wTerminalDescrStr; | ||
101 | } __attribute__((packed)); | ||
102 | |||
103 | /* 4.5.2.7 FEATURE UNIT DESCRIPTOR */ | ||
104 | struct uac3_feature_unit_descriptor { | ||
105 | __u8 bLength; | ||
106 | __u8 bDescriptorType; | ||
107 | __u8 bDescriptorSubtype; | ||
108 | __u8 bUnitID; | ||
109 | __u8 bSourceID; | ||
110 | /* bmaControls is actually u32, | ||
111 | * but u8 is needed for the hybrid parser */ | ||
112 | __u8 bmaControls[0]; /* variable length */ | ||
113 | /* wFeatureDescrStr omitted */ | ||
114 | } __attribute__((packed)); | ||
115 | |||
116 | #define UAC3_DT_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 4) | ||
117 | |||
118 | /* As above, but more useful for defining your own descriptors */ | ||
119 | #define DECLARE_UAC3_FEATURE_UNIT_DESCRIPTOR(ch) \ | ||
120 | struct uac3_feature_unit_descriptor_##ch { \ | ||
121 | __u8 bLength; \ | ||
122 | __u8 bDescriptorType; \ | ||
123 | __u8 bDescriptorSubtype; \ | ||
124 | __u8 bUnitID; \ | ||
125 | __u8 bSourceID; \ | ||
126 | __le32 bmaControls[ch + 1]; \ | ||
127 | __le16 wFeatureDescrStr; \ | ||
128 | } __attribute__ ((packed)) | ||
129 | |||
130 | /* 4.5.2.12 CLOCK SOURCE DESCRIPTOR */ | ||
131 | struct uac3_clock_source_descriptor { | ||
132 | __u8 bLength; | ||
133 | __u8 bDescriptorType; | ||
134 | __u8 bDescriptorSubtype; | ||
135 | __u8 bClockID; | ||
136 | __u8 bmAttributes; | ||
137 | __le32 bmControls; | ||
138 | __u8 bReferenceTerminal; | ||
139 | __le16 wClockSourceStr; | ||
140 | } __attribute__((packed)); | ||
141 | |||
142 | /* bmAttribute fields */ | ||
143 | #define UAC3_CLOCK_SOURCE_TYPE_EXT 0x0 | ||
144 | #define UAC3_CLOCK_SOURCE_TYPE_INT 0x1 | ||
145 | #define UAC3_CLOCK_SOURCE_ASYNC (0 << 2) | ||
146 | #define UAC3_CLOCK_SOURCE_SYNCED_TO_SOF (1 << 1) | ||
147 | |||
148 | /* 4.5.2.13 CLOCK SELECTOR DESCRIPTOR */ | ||
149 | struct uac3_clock_selector_descriptor { | ||
150 | __u8 bLength; | ||
151 | __u8 bDescriptorType; | ||
152 | __u8 bDescriptorSubtype; | ||
153 | __u8 bClockID; | ||
154 | __u8 bNrInPins; | ||
155 | __u8 baCSourceID[]; | ||
156 | /* bmControls and wCSelectorDescrStr omitted */ | ||
157 | } __attribute__((packed)); | ||
158 | |||
159 | /* 4.5.2.14 CLOCK MULTIPLIER DESCRIPTOR */ | ||
160 | struct uac3_clock_multiplier_descriptor { | ||
161 | __u8 bLength; | ||
162 | __u8 bDescriptorType; | ||
163 | __u8 bDescriptorSubtype; | ||
164 | __u8 bClockID; | ||
165 | __u8 bCSourceID; | ||
166 | __le32 bmControls; | ||
167 | __le16 wCMultiplierDescrStr; | ||
168 | } __attribute__((packed)); | ||
169 | |||
170 | /* 4.5.2.15 POWER DOMAIN DESCRIPTOR */ | ||
171 | struct uac3_power_domain_descriptor { | ||
172 | __u8 bLength; | ||
173 | __u8 bDescriptorType; | ||
174 | __u8 bDescriptorSubtype; | ||
175 | __u8 bPowerDomainID; | ||
176 | __le16 waRecoveryTime1; | ||
177 | __le16 waRecoveryTime2; | ||
178 | __u8 bNrEntities; | ||
179 | __u8 baEntityID[]; | ||
180 | /* wPDomainDescrStr omitted */ | ||
181 | } __attribute__((packed)); | ||
182 | |||
183 | /* As above, but more useful for defining your own descriptors */ | ||
184 | #define DECLARE_UAC3_POWER_DOMAIN_DESCRIPTOR(n) \ | ||
185 | struct uac3_power_domain_descriptor_##n { \ | ||
186 | __u8 bLength; \ | ||
187 | __u8 bDescriptorType; \ | ||
188 | __u8 bDescriptorSubtype; \ | ||
189 | __u8 bPowerDomainID; \ | ||
190 | __le16 waRecoveryTime1; \ | ||
191 | __le16 waRecoveryTime2; \ | ||
192 | __u8 bNrEntities; \ | ||
193 | __u8 baEntityID[n]; \ | ||
194 | __le16 wPDomainDescrStr; \ | ||
195 | } __attribute__ ((packed)) | ||
196 | |||
197 | /* 4.7.2 CLASS-SPECIFIC AS INTERFACE DESCRIPTOR */ | ||
198 | struct uac3_as_header_descriptor { | ||
199 | __u8 bLength; | ||
200 | __u8 bDescriptorType; | ||
201 | __u8 bDescriptorSubtype; | ||
202 | __u8 bTerminalLink; | ||
203 | __le32 bmControls; | ||
204 | __le16 wClusterDescrID; | ||
205 | __le64 bmFormats; | ||
206 | __u8 bSubslotSize; | ||
207 | __u8 bBitResolution; | ||
208 | __le16 bmAuxProtocols; | ||
209 | __u8 bControlSize; | ||
210 | } __attribute__((packed)); | ||
211 | |||
212 | #define UAC3_FORMAT_TYPE_I_RAW_DATA (1 << 6) | ||
213 | |||
214 | /* 4.8.1.2 CLASS-SPECIFIC AS ISOCHRONOUS AUDIO DATA ENDPOINT DESCRIPTOR */ | ||
215 | struct uac3_iso_endpoint_descriptor { | ||
216 | __u8 bLength; | ||
217 | __u8 bDescriptorType; | ||
218 | __u8 bDescriptorSubtype; | ||
219 | __le32 bmControls; | ||
220 | __u8 bLockDelayUnits; | ||
221 | __le16 wLockDelay; | ||
222 | } __attribute__((packed)); | ||
223 | |||
224 | /* 6.1 INTERRUPT DATA MESSAGE */ | ||
225 | struct uac3_interrupt_data_msg { | ||
226 | __u8 bInfo; | ||
227 | __u8 bSourceType; | ||
228 | __le16 wValue; | ||
229 | __le16 wIndex; | ||
230 | } __attribute__((packed)); | ||
231 | |||
232 | /* A.2 AUDIO AUDIO FUNCTION SUBCLASS CODES */ | ||
233 | #define UAC3_FUNCTION_SUBCLASS_UNDEFINED 0x00 | ||
234 | #define UAC3_FUNCTION_SUBCLASS_FULL_ADC_3_0 0x01 | ||
235 | /* BADD profiles */ | ||
236 | #define UAC3_FUNCTION_SUBCLASS_GENERIC_IO 0x20 | ||
237 | #define UAC3_FUNCTION_SUBCLASS_HEADPHONE 0x21 | ||
238 | #define UAC3_FUNCTION_SUBCLASS_SPEAKER 0x22 | ||
239 | #define UAC3_FUNCTION_SUBCLASS_MICROPHONE 0x23 | ||
240 | #define UAC3_FUNCTION_SUBCLASS_HEADSET 0x24 | ||
241 | #define UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER 0x25 | ||
242 | #define UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE 0x26 | ||
243 | |||
244 | /* A.7 AUDIO FUNCTION CATEGORY CODES */ | ||
245 | #define UAC3_FUNCTION_SUBCLASS_UNDEFINED 0x00 | ||
246 | #define UAC3_FUNCTION_DESKTOP_SPEAKER 0x01 | ||
247 | #define UAC3_FUNCTION_HOME_THEATER 0x02 | ||
248 | #define UAC3_FUNCTION_MICROPHONE 0x03 | ||
249 | #define UAC3_FUNCTION_HEADSET 0x04 | ||
250 | #define UAC3_FUNCTION_TELEPHONE 0x05 | ||
251 | #define UAC3_FUNCTION_CONVERTER 0x06 | ||
252 | #define UAC3_FUNCTION_SOUND_RECORDER 0x07 | ||
253 | #define UAC3_FUNCTION_IO_BOX 0x08 | ||
254 | #define UAC3_FUNCTION_MUSICAL_INSTRUMENT 0x09 | ||
255 | #define UAC3_FUNCTION_PRO_AUDIO 0x0a | ||
256 | #define UAC3_FUNCTION_AUDIO_VIDEO 0x0b | ||
257 | #define UAC3_FUNCTION_CONTROL_PANEL 0x0c | ||
258 | #define UAC3_FUNCTION_HEADPHONE 0x0d | ||
259 | #define UAC3_FUNCTION_GENERIC_SPEAKER 0x0e | ||
260 | #define UAC3_FUNCTION_HEADSET_ADAPTER 0x0f | ||
261 | #define UAC3_FUNCTION_SPEAKERPHONE 0x10 | ||
262 | #define UAC3_FUNCTION_OTHER 0xff | ||
263 | |||
264 | /* A.8 AUDIO CLASS-SPECIFIC DESCRIPTOR TYPES */ | ||
265 | #define UAC3_CS_UNDEFINED 0x20 | ||
266 | #define UAC3_CS_DEVICE 0x21 | ||
267 | #define UAC3_CS_CONFIGURATION 0x22 | ||
268 | #define UAC3_CS_STRING 0x23 | ||
269 | #define UAC3_CS_INTERFACE 0x24 | ||
270 | #define UAC3_CS_ENDPOINT 0x25 | ||
271 | #define UAC3_CS_CLUSTER 0x26 | ||
272 | |||
273 | /* A.10 CLUSTER DESCRIPTOR SEGMENT TYPES */ | ||
274 | #define UAC3_SEGMENT_UNDEFINED 0x00 | ||
275 | #define UAC3_CLUSTER_DESCRIPTION 0x01 | ||
276 | #define UAC3_CLUSTER_VENDOR_DEFINED 0x1F | ||
277 | #define UAC3_CHANNEL_INFORMATION 0x20 | ||
278 | #define UAC3_CHANNEL_AMBISONIC 0x21 | ||
279 | #define UAC3_CHANNEL_DESCRIPTION 0x22 | ||
280 | #define UAC3_CHANNEL_VENDOR_DEFINED 0xFE | ||
281 | #define UAC3_END_SEGMENT 0xFF | ||
282 | |||
283 | /* A.11 CHANNEL PURPOSE DEFINITIONS */ | ||
284 | #define UAC3_PURPOSE_UNDEFINED 0x00 | ||
285 | #define UAC3_PURPOSE_GENERIC_AUDIO 0x01 | ||
286 | #define UAC3_PURPOSE_VOICE 0x02 | ||
287 | #define UAC3_PURPOSE_SPEECH 0x03 | ||
288 | #define UAC3_PURPOSE_AMBIENT 0x04 | ||
289 | #define UAC3_PURPOSE_REFERENCE 0x05 | ||
290 | #define UAC3_PURPOSE_ULTRASONIC 0x06 | ||
291 | #define UAC3_PURPOSE_VIBROKINETIC 0x07 | ||
292 | #define UAC3_PURPOSE_NON_AUDIO 0xFF | ||
293 | |||
294 | /* A.12 CHANNEL RELATIONSHIP DEFINITIONS */ | ||
295 | #define UAC3_CH_RELATIONSHIP_UNDEFINED 0x00 | ||
296 | #define UAC3_CH_MONO 0x01 | ||
297 | #define UAC3_CH_LEFT 0x02 | ||
298 | #define UAC3_CH_RIGHT 0x03 | ||
299 | #define UAC3_CH_ARRAY 0x04 | ||
300 | #define UAC3_CH_PATTERN_X 0x20 | ||
301 | #define UAC3_CH_PATTERN_Y 0x21 | ||
302 | #define UAC3_CH_PATTERN_A 0x22 | ||
303 | #define UAC3_CH_PATTERN_B 0x23 | ||
304 | #define UAC3_CH_PATTERN_M 0x24 | ||
305 | #define UAC3_CH_PATTERN_S 0x25 | ||
306 | #define UAC3_CH_FRONT_LEFT 0x80 | ||
307 | #define UAC3_CH_FRONT_RIGHT 0x81 | ||
308 | #define UAC3_CH_FRONT_CENTER 0x82 | ||
309 | #define UAC3_CH_FRONT_LEFT_OF_CENTER 0x83 | ||
310 | #define UAC3_CH_FRONT_RIGHT_OF_CENTER 0x84 | ||
311 | #define UAC3_CH_FRONT_WIDE_LEFT 0x85 | ||
312 | #define UAC3_CH_FRONT_WIDE_RIGHT 0x86 | ||
313 | #define UAC3_CH_SIDE_LEFT 0x87 | ||
314 | #define UAC3_CH_SIDE_RIGHT 0x88 | ||
315 | #define UAC3_CH_SURROUND_ARRAY_LEFT 0x89 | ||
316 | #define UAC3_CH_SURROUND_ARRAY_RIGHT 0x8A | ||
317 | #define UAC3_CH_BACK_LEFT 0x8B | ||
318 | #define UAC3_CH_BACK_RIGHT 0x8C | ||
319 | #define UAC3_CH_BACK_CENTER 0x8D | ||
320 | #define UAC3_CH_BACK_LEFT_OF_CENTER 0x8E | ||
321 | #define UAC3_CH_BACK_RIGHT_OF_CENTER 0x8F | ||
322 | #define UAC3_CH_BACK_WIDE_LEFT 0x90 | ||
323 | #define UAC3_CH_BACK_WIDE_RIGHT 0x91 | ||
324 | #define UAC3_CH_TOP_CENTER 0x92 | ||
325 | #define UAC3_CH_TOP_FRONT_LEFT 0x93 | ||
326 | #define UAC3_CH_TOP_FRONT_RIGHT 0x94 | ||
327 | #define UAC3_CH_TOP_FRONT_CENTER 0x95 | ||
328 | #define UAC3_CH_TOP_FRONT_LOC 0x96 | ||
329 | #define UAC3_CH_TOP_FRONT_ROC 0x97 | ||
330 | #define UAC3_CH_TOP_FRONT_WIDE_LEFT 0x98 | ||
331 | #define UAC3_CH_TOP_FRONT_WIDE_RIGHT 0x99 | ||
332 | #define UAC3_CH_TOP_SIDE_LEFT 0x9A | ||
333 | #define UAC3_CH_TOP_SIDE_RIGHT 0x9B | ||
334 | #define UAC3_CH_TOP_SURR_ARRAY_LEFT 0x9C | ||
335 | #define UAC3_CH_TOP_SURR_ARRAY_RIGHT 0x9D | ||
336 | #define UAC3_CH_TOP_BACK_LEFT 0x9E | ||
337 | #define UAC3_CH_TOP_BACK_RIGHT 0x9F | ||
338 | #define UAC3_CH_TOP_BACK_CENTER 0xA0 | ||
339 | #define UAC3_CH_TOP_BACK_LOC 0xA1 | ||
340 | #define UAC3_CH_TOP_BACK_ROC 0xA2 | ||
341 | #define UAC3_CH_TOP_BACK_WIDE_LEFT 0xA3 | ||
342 | #define UAC3_CH_TOP_BACK_WIDE_RIGHT 0xA4 | ||
343 | #define UAC3_CH_BOTTOM_CENTER 0xA5 | ||
344 | #define UAC3_CH_BOTTOM_FRONT_LEFT 0xA6 | ||
345 | #define UAC3_CH_BOTTOM_FRONT_RIGHT 0xA7 | ||
346 | #define UAC3_CH_BOTTOM_FRONT_CENTER 0xA8 | ||
347 | #define UAC3_CH_BOTTOM_FRONT_LOC 0xA9 | ||
348 | #define UAC3_CH_BOTTOM_FRONT_ROC 0xAA | ||
349 | #define UAC3_CH_BOTTOM_FRONT_WIDE_LEFT 0xAB | ||
350 | #define UAC3_CH_BOTTOM_FRONT_WIDE_RIGHT 0xAC | ||
351 | #define UAC3_CH_BOTTOM_SIDE_LEFT 0xAD | ||
352 | #define UAC3_CH_BOTTOM_SIDE_RIGHT 0xAE | ||
353 | #define UAC3_CH_BOTTOM_SURR_ARRAY_LEFT 0xAF | ||
354 | #define UAC3_CH_BOTTOM_SURR_ARRAY_RIGHT 0xB0 | ||
355 | #define UAC3_CH_BOTTOM_BACK_LEFT 0xB1 | ||
356 | #define UAC3_CH_BOTTOM_BACK_RIGHT 0xB2 | ||
357 | #define UAC3_CH_BOTTOM_BACK_CENTER 0xB3 | ||
358 | #define UAC3_CH_BOTTOM_BACK_LOC 0xB4 | ||
359 | #define UAC3_CH_BOTTOM_BACK_ROC 0xB5 | ||
360 | #define UAC3_CH_BOTTOM_BACK_WIDE_LEFT 0xB6 | ||
361 | #define UAC3_CH_BOTTOM_BACK_WIDE_RIGHT 0xB7 | ||
362 | #define UAC3_CH_LOW_FREQUENCY_EFFECTS 0xB8 | ||
363 | #define UAC3_CH_LFE_LEFT 0xB9 | ||
364 | #define UAC3_CH_LFE_RIGHT 0xBA | ||
365 | #define UAC3_CH_HEADPHONE_LEFT 0xBB | ||
366 | #define UAC3_CH_HEADPHONE_RIGHT 0xBC | ||
367 | |||
368 | /* A.15 AUDIO CLASS-SPECIFIC AC INTERFACE DESCRIPTOR SUBTYPES */ | ||
369 | /* see audio.h for the rest, which is identical to v1 */ | ||
370 | #define UAC3_EXTENDED_TERMINAL 0x04 | ||
371 | #define UAC3_MIXER_UNIT 0x05 | ||
372 | #define UAC3_SELECTOR_UNIT 0x06 | ||
373 | #define UAC3_FEATURE_UNIT 0x07 | ||
374 | #define UAC3_EFFECT_UNIT 0x08 | ||
375 | #define UAC3_PROCESSING_UNIT 0x09 | ||
376 | #define UAC3_EXTENSION_UNIT 0x0a | ||
377 | #define UAC3_CLOCK_SOURCE 0x0b | ||
378 | #define UAC3_CLOCK_SELECTOR 0x0c | ||
379 | #define UAC3_CLOCK_MULTIPLIER 0x0d | ||
380 | #define UAC3_SAMPLE_RATE_CONVERTER 0x0e | ||
381 | #define UAC3_CONNECTORS 0x0f | ||
382 | #define UAC3_POWER_DOMAIN 0x10 | ||
383 | |||
384 | /* A.22 AUDIO CLASS-SPECIFIC REQUEST CODES */ | ||
385 | /* see audio-v2.h for the rest, which is identical to v2 */ | ||
386 | #define UAC3_CS_REQ_INTEN 0x04 | ||
387 | #define UAC3_CS_REQ_STRING 0x05 | ||
388 | #define UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR 0x06 | ||
389 | |||
390 | /* A.23.1 AUDIOCONTROL INTERFACE CONTROL SELECTORS */ | ||
391 | #define UAC3_AC_CONTROL_UNDEFINED 0x00 | ||
392 | #define UAC3_AC_ACTIVE_INTERFACE_CONTROL 0x01 | ||
393 | #define UAC3_AC_POWER_DOMAIN_CONTROL 0x02 | ||
394 | |||
395 | #endif /* __LINUX_USB_AUDIO_V3_H */ | ||
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 4f42affe777c..5ebcc51c0a6a 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
@@ -1710,6 +1710,7 @@ struct snd_emu10k1 { | |||
1710 | unsigned int ecard_ctrl; /* ecard control bits */ | 1710 | unsigned int ecard_ctrl; /* ecard control bits */ |
1711 | unsigned int address_mode; /* address mode */ | 1711 | unsigned int address_mode; /* address mode */ |
1712 | unsigned long dma_mask; /* PCI DMA mask */ | 1712 | unsigned long dma_mask; /* PCI DMA mask */ |
1713 | bool iommu_workaround; /* IOMMU workaround needed */ | ||
1713 | unsigned int delay_pcm_irq; /* in samples */ | 1714 | unsigned int delay_pcm_irq; /* in samples */ |
1714 | int max_cache_pages; /* max memory size / PAGE_SIZE */ | 1715 | int max_cache_pages; /* max memory size / PAGE_SIZE */ |
1715 | struct snd_dma_buffer silent_page; /* silent page */ | 1716 | struct snd_dma_buffer silent_page; /* silent page */ |
@@ -1718,7 +1719,6 @@ struct snd_emu10k1 { | |||
1718 | struct snd_dma_buffer p16v_buffer; | 1719 | struct snd_dma_buffer p16v_buffer; |
1719 | 1720 | ||
1720 | struct snd_util_memhdr *memhdr; /* page allocation list */ | 1721 | struct snd_util_memhdr *memhdr; /* page allocation list */ |
1721 | struct snd_emu10k1_memblk *reserved_page; /* reserved page */ | ||
1722 | 1722 | ||
1723 | struct list_head mapped_link_head; | 1723 | struct list_head mapped_link_head; |
1724 | struct list_head mapped_order_link_head; | 1724 | struct list_head mapped_order_link_head; |
@@ -1878,6 +1878,8 @@ void snd_p16v_resume(struct snd_emu10k1 *emu); | |||
1878 | /* memory allocation */ | 1878 | /* memory allocation */ |
1879 | struct snd_util_memblk *snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream); | 1879 | struct snd_util_memblk *snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream); |
1880 | int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk); | 1880 | int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk); |
1881 | int snd_emu10k1_alloc_pages_maybe_wider(struct snd_emu10k1 *emu, size_t size, | ||
1882 | struct snd_dma_buffer *dmab); | ||
1881 | struct snd_util_memblk *snd_emu10k1_synth_alloc(struct snd_emu10k1 *emu, unsigned int size); | 1883 | struct snd_util_memblk *snd_emu10k1_synth_alloc(struct snd_emu10k1 *emu, unsigned int size); |
1882 | int snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *blk); | 1884 | int snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *blk); |
1883 | int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk, int offset, int size); | 1885 | int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk, int offset, int size); |
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 68169e3749de..4c93ff5301bd 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h | |||
@@ -146,6 +146,8 @@ int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid, | |||
146 | int flags, unsigned int verb, unsigned int parm); | 146 | int flags, unsigned int verb, unsigned int parm); |
147 | bool snd_hdac_check_power_state(struct hdac_device *hdac, | 147 | bool snd_hdac_check_power_state(struct hdac_device *hdac, |
148 | hda_nid_t nid, unsigned int target_state); | 148 | hda_nid_t nid, unsigned int target_state); |
149 | unsigned int snd_hdac_sync_power_state(struct hdac_device *hdac, | ||
150 | hda_nid_t nid, unsigned int target_state); | ||
149 | /** | 151 | /** |
150 | * snd_hdac_read_parm - read a codec parameter | 152 | * snd_hdac_read_parm - read a codec parameter |
151 | * @codec: the codec object | 153 | * @codec: the codec object |
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h index 760c969d885d..12bbf8c81112 100644 --- a/include/sound/pcm_oss.h +++ b/include/sound/pcm_oss.h | |||
@@ -57,6 +57,7 @@ struct snd_pcm_oss_runtime { | |||
57 | char *buffer; /* vmallocated period */ | 57 | char *buffer; /* vmallocated period */ |
58 | size_t buffer_used; /* used length from period buffer */ | 58 | size_t buffer_used; /* used length from period buffer */ |
59 | struct mutex params_lock; | 59 | struct mutex params_lock; |
60 | atomic_t rw_ref; /* concurrent read/write accesses */ | ||
60 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | 61 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS |
61 | struct snd_pcm_plugin *plugin_first; | 62 | struct snd_pcm_plugin *plugin_first; |
62 | struct snd_pcm_plugin *plugin_last; | 63 | struct snd_pcm_plugin *plugin_last; |
diff --git a/include/uapi/linux/usb/audio.h b/include/uapi/linux/usb/audio.h index da3315ed1bcd..3a78e7145689 100644 --- a/include/uapi/linux/usb/audio.h +++ b/include/uapi/linux/usb/audio.h | |||
@@ -27,6 +27,7 @@ | |||
27 | /* bInterfaceProtocol values to denote the version of the standard used */ | 27 | /* bInterfaceProtocol values to denote the version of the standard used */ |
28 | #define UAC_VERSION_1 0x00 | 28 | #define UAC_VERSION_1 0x00 |
29 | #define UAC_VERSION_2 0x20 | 29 | #define UAC_VERSION_2 0x20 |
30 | #define UAC_VERSION_3 0x30 | ||
30 | 31 | ||
31 | /* A.2 Audio Interface Subclass Codes */ | 32 | /* A.2 Audio Interface Subclass Codes */ |
32 | #define USB_SUBCLASS_AUDIOCONTROL 0x01 | 33 | #define USB_SUBCLASS_AUDIOCONTROL 0x01 |
diff --git a/sound/core/control.c b/sound/core/control.c index 8a77620a3854..69734b0eafd0 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -105,7 +105,7 @@ static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl) | |||
105 | { | 105 | { |
106 | unsigned long flags; | 106 | unsigned long flags; |
107 | struct snd_kctl_event *cread; | 107 | struct snd_kctl_event *cread; |
108 | 108 | ||
109 | spin_lock_irqsave(&ctl->read_lock, flags); | 109 | spin_lock_irqsave(&ctl->read_lock, flags); |
110 | while (!list_empty(&ctl->events)) { | 110 | while (!list_empty(&ctl->events)) { |
111 | cread = snd_kctl_event(ctl->events.next); | 111 | cread = snd_kctl_event(ctl->events.next); |
@@ -159,7 +159,7 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, | |||
159 | unsigned long flags; | 159 | unsigned long flags; |
160 | struct snd_ctl_file *ctl; | 160 | struct snd_ctl_file *ctl; |
161 | struct snd_kctl_event *ev; | 161 | struct snd_kctl_event *ev; |
162 | 162 | ||
163 | if (snd_BUG_ON(!card || !id)) | 163 | if (snd_BUG_ON(!card || !id)) |
164 | return; | 164 | return; |
165 | if (card->shutdown) | 165 | if (card->shutdown) |
@@ -213,7 +213,7 @@ static int snd_ctl_new(struct snd_kcontrol **kctl, unsigned int count, | |||
213 | { | 213 | { |
214 | unsigned int size; | 214 | unsigned int size; |
215 | unsigned int idx; | 215 | unsigned int idx; |
216 | 216 | ||
217 | if (count == 0 || count > MAX_CONTROL_COUNT) | 217 | if (count == 0 || count > MAX_CONTROL_COUNT) |
218 | return -EINVAL; | 218 | return -EINVAL; |
219 | 219 | ||
@@ -238,7 +238,7 @@ static int snd_ctl_new(struct snd_kcontrol **kctl, unsigned int count, | |||
238 | * @ncontrol: the initialization record | 238 | * @ncontrol: the initialization record |
239 | * @private_data: the private data to set | 239 | * @private_data: the private data to set |
240 | * | 240 | * |
241 | * Allocates a new struct snd_kcontrol instance and initialize from the given | 241 | * Allocates a new struct snd_kcontrol instance and initialize from the given |
242 | * template. When the access field of ncontrol is 0, it's assumed as | 242 | * template. When the access field of ncontrol is 0, it's assumed as |
243 | * READWRITE access. When the count field is 0, it's assumes as one. | 243 | * READWRITE access. When the count field is 0, it's assumes as one. |
244 | * | 244 | * |
@@ -251,7 +251,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, | |||
251 | unsigned int count; | 251 | unsigned int count; |
252 | unsigned int access; | 252 | unsigned int access; |
253 | int err; | 253 | int err; |
254 | 254 | ||
255 | if (snd_BUG_ON(!ncontrol || !ncontrol->info)) | 255 | if (snd_BUG_ON(!ncontrol || !ncontrol->info)) |
256 | return NULL; | 256 | return NULL; |
257 | 257 | ||
@@ -753,7 +753,7 @@ static int snd_ctl_elem_list(struct snd_card *card, | |||
753 | struct snd_ctl_elem_id id; | 753 | struct snd_ctl_elem_id id; |
754 | unsigned int offset, space, jidx; | 754 | unsigned int offset, space, jidx; |
755 | int err = 0; | 755 | int err = 0; |
756 | 756 | ||
757 | if (copy_from_user(&list, _list, sizeof(list))) | 757 | if (copy_from_user(&list, _list, sizeof(list))) |
758 | return -EFAULT; | 758 | return -EFAULT; |
759 | offset = list.offset; | 759 | offset = list.offset; |
@@ -827,7 +827,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl, | |||
827 | struct snd_kcontrol_volatile *vd; | 827 | struct snd_kcontrol_volatile *vd; |
828 | unsigned int index_offset; | 828 | unsigned int index_offset; |
829 | int result; | 829 | int result; |
830 | 830 | ||
831 | down_read(&card->controls_rwsem); | 831 | down_read(&card->controls_rwsem); |
832 | kctl = snd_ctl_find_id(card, &info->id); | 832 | kctl = snd_ctl_find_id(card, &info->id); |
833 | if (kctl == NULL) { | 833 | if (kctl == NULL) { |
@@ -992,7 +992,7 @@ static int snd_ctl_elem_lock(struct snd_ctl_file *file, | |||
992 | struct snd_kcontrol *kctl; | 992 | struct snd_kcontrol *kctl; |
993 | struct snd_kcontrol_volatile *vd; | 993 | struct snd_kcontrol_volatile *vd; |
994 | int result; | 994 | int result; |
995 | 995 | ||
996 | if (copy_from_user(&id, _id, sizeof(id))) | 996 | if (copy_from_user(&id, _id, sizeof(id))) |
997 | return -EFAULT; | 997 | return -EFAULT; |
998 | down_write(&card->controls_rwsem); | 998 | down_write(&card->controls_rwsem); |
@@ -1020,7 +1020,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file, | |||
1020 | struct snd_kcontrol *kctl; | 1020 | struct snd_kcontrol *kctl; |
1021 | struct snd_kcontrol_volatile *vd; | 1021 | struct snd_kcontrol_volatile *vd; |
1022 | int result; | 1022 | int result; |
1023 | 1023 | ||
1024 | if (copy_from_user(&id, _id, sizeof(id))) | 1024 | if (copy_from_user(&id, _id, sizeof(id))) |
1025 | return -EFAULT; | 1025 | return -EFAULT; |
1026 | down_write(&card->controls_rwsem); | 1026 | down_write(&card->controls_rwsem); |
diff --git a/sound/core/init.c b/sound/core/init.c index 4fa5dd955740..79b4df1c1dc7 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -670,7 +670,7 @@ card_id_show_attr(struct device *dev, | |||
670 | struct device_attribute *attr, char *buf) | 670 | struct device_attribute *attr, char *buf) |
671 | { | 671 | { |
672 | struct snd_card *card = container_of(dev, struct snd_card, card_dev); | 672 | struct snd_card *card = container_of(dev, struct snd_card, card_dev); |
673 | return snprintf(buf, PAGE_SIZE, "%s\n", card->id); | 673 | return scnprintf(buf, PAGE_SIZE, "%s\n", card->id); |
674 | } | 674 | } |
675 | 675 | ||
676 | static ssize_t | 676 | static ssize_t |
@@ -710,7 +710,7 @@ card_number_show_attr(struct device *dev, | |||
710 | struct device_attribute *attr, char *buf) | 710 | struct device_attribute *attr, char *buf) |
711 | { | 711 | { |
712 | struct snd_card *card = container_of(dev, struct snd_card, card_dev); | 712 | struct snd_card *card = container_of(dev, struct snd_card, card_dev); |
713 | return snprintf(buf, PAGE_SIZE, "%i\n", card->number); | 713 | return scnprintf(buf, PAGE_SIZE, "%i\n", card->number); |
714 | } | 714 | } |
715 | 715 | ||
716 | static DEVICE_ATTR(number, S_IRUGO, card_number_show_attr, NULL); | 716 | static DEVICE_ATTR(number, S_IRUGO, card_number_show_attr, NULL); |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 441405081195..481ab0e94ffa 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -823,8 +823,25 @@ static int choose_rate(struct snd_pcm_substream *substream, | |||
823 | return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); | 823 | return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); |
824 | } | 824 | } |
825 | 825 | ||
826 | static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, | 826 | /* parameter locking: returns immediately if tried during streaming */ |
827 | bool trylock) | 827 | static int lock_params(struct snd_pcm_runtime *runtime) |
828 | { | ||
829 | if (mutex_lock_interruptible(&runtime->oss.params_lock)) | ||
830 | return -ERESTARTSYS; | ||
831 | if (atomic_read(&runtime->oss.rw_ref)) { | ||
832 | mutex_unlock(&runtime->oss.params_lock); | ||
833 | return -EBUSY; | ||
834 | } | ||
835 | return 0; | ||
836 | } | ||
837 | |||
838 | static void unlock_params(struct snd_pcm_runtime *runtime) | ||
839 | { | ||
840 | mutex_unlock(&runtime->oss.params_lock); | ||
841 | } | ||
842 | |||
843 | /* call with params_lock held */ | ||
844 | static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) | ||
828 | { | 845 | { |
829 | struct snd_pcm_runtime *runtime = substream->runtime; | 846 | struct snd_pcm_runtime *runtime = substream->runtime; |
830 | struct snd_pcm_hw_params *params, *sparams; | 847 | struct snd_pcm_hw_params *params, *sparams; |
@@ -838,11 +855,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, | |||
838 | const struct snd_mask *sformat_mask; | 855 | const struct snd_mask *sformat_mask; |
839 | struct snd_mask mask; | 856 | struct snd_mask mask; |
840 | 857 | ||
841 | if (trylock) { | 858 | if (!runtime->oss.params) |
842 | if (!(mutex_trylock(&runtime->oss.params_lock))) | 859 | return 0; |
843 | return -EAGAIN; | ||
844 | } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) | ||
845 | return -ERESTARTSYS; | ||
846 | sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); | 860 | sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); |
847 | params = kmalloc(sizeof(*params), GFP_KERNEL); | 861 | params = kmalloc(sizeof(*params), GFP_KERNEL); |
848 | sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); | 862 | sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); |
@@ -1068,6 +1082,23 @@ failure: | |||
1068 | kfree(sw_params); | 1082 | kfree(sw_params); |
1069 | kfree(params); | 1083 | kfree(params); |
1070 | kfree(sparams); | 1084 | kfree(sparams); |
1085 | return err; | ||
1086 | } | ||
1087 | |||
1088 | /* this one takes the lock by itself */ | ||
1089 | static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, | ||
1090 | bool trylock) | ||
1091 | { | ||
1092 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1093 | int err; | ||
1094 | |||
1095 | if (trylock) { | ||
1096 | if (!(mutex_trylock(&runtime->oss.params_lock))) | ||
1097 | return -EAGAIN; | ||
1098 | } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) | ||
1099 | return -ERESTARTSYS; | ||
1100 | |||
1101 | err = snd_pcm_oss_change_params_locked(substream); | ||
1071 | mutex_unlock(&runtime->oss.params_lock); | 1102 | mutex_unlock(&runtime->oss.params_lock); |
1072 | return err; | 1103 | return err; |
1073 | } | 1104 | } |
@@ -1096,11 +1127,14 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil | |||
1096 | return 0; | 1127 | return 0; |
1097 | } | 1128 | } |
1098 | 1129 | ||
1130 | /* call with params_lock held */ | ||
1099 | static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream) | 1131 | static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream) |
1100 | { | 1132 | { |
1101 | int err; | 1133 | int err; |
1102 | struct snd_pcm_runtime *runtime = substream->runtime; | 1134 | struct snd_pcm_runtime *runtime = substream->runtime; |
1103 | 1135 | ||
1136 | if (!runtime->oss.prepare) | ||
1137 | return 0; | ||
1104 | err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); | 1138 | err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); |
1105 | if (err < 0) { | 1139 | if (err < 0) { |
1106 | pcm_dbg(substream->pcm, | 1140 | pcm_dbg(substream->pcm, |
@@ -1120,8 +1154,6 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream) | |||
1120 | struct snd_pcm_runtime *runtime; | 1154 | struct snd_pcm_runtime *runtime; |
1121 | int err; | 1155 | int err; |
1122 | 1156 | ||
1123 | if (substream == NULL) | ||
1124 | return 0; | ||
1125 | runtime = substream->runtime; | 1157 | runtime = substream->runtime; |
1126 | if (runtime->oss.params) { | 1158 | if (runtime->oss.params) { |
1127 | err = snd_pcm_oss_change_params(substream, false); | 1159 | err = snd_pcm_oss_change_params(substream, false); |
@@ -1129,6 +1161,29 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream) | |||
1129 | return err; | 1161 | return err; |
1130 | } | 1162 | } |
1131 | if (runtime->oss.prepare) { | 1163 | if (runtime->oss.prepare) { |
1164 | if (mutex_lock_interruptible(&runtime->oss.params_lock)) | ||
1165 | return -ERESTARTSYS; | ||
1166 | err = snd_pcm_oss_prepare(substream); | ||
1167 | mutex_unlock(&runtime->oss.params_lock); | ||
1168 | if (err < 0) | ||
1169 | return err; | ||
1170 | } | ||
1171 | return 0; | ||
1172 | } | ||
1173 | |||
1174 | /* call with params_lock held */ | ||
1175 | static int snd_pcm_oss_make_ready_locked(struct snd_pcm_substream *substream) | ||
1176 | { | ||
1177 | struct snd_pcm_runtime *runtime; | ||
1178 | int err; | ||
1179 | |||
1180 | runtime = substream->runtime; | ||
1181 | if (runtime->oss.params) { | ||
1182 | err = snd_pcm_oss_change_params_locked(substream); | ||
1183 | if (err < 0) | ||
1184 | return err; | ||
1185 | } | ||
1186 | if (runtime->oss.prepare) { | ||
1132 | err = snd_pcm_oss_prepare(substream); | 1187 | err = snd_pcm_oss_prepare(substream); |
1133 | if (err < 0) | 1188 | if (err < 0) |
1134 | return err; | 1189 | return err; |
@@ -1332,13 +1387,15 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha | |||
1332 | if (atomic_read(&substream->mmap_count)) | 1387 | if (atomic_read(&substream->mmap_count)) |
1333 | return -ENXIO; | 1388 | return -ENXIO; |
1334 | 1389 | ||
1335 | if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) | 1390 | atomic_inc(&runtime->oss.rw_ref); |
1336 | return tmp; | ||
1337 | while (bytes > 0) { | 1391 | while (bytes > 0) { |
1338 | if (mutex_lock_interruptible(&runtime->oss.params_lock)) { | 1392 | if (mutex_lock_interruptible(&runtime->oss.params_lock)) { |
1339 | tmp = -ERESTARTSYS; | 1393 | tmp = -ERESTARTSYS; |
1340 | break; | 1394 | break; |
1341 | } | 1395 | } |
1396 | tmp = snd_pcm_oss_make_ready_locked(substream); | ||
1397 | if (tmp < 0) | ||
1398 | goto err; | ||
1342 | if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) { | 1399 | if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) { |
1343 | tmp = bytes; | 1400 | tmp = bytes; |
1344 | if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes) | 1401 | if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes) |
@@ -1394,6 +1451,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha | |||
1394 | } | 1451 | } |
1395 | tmp = 0; | 1452 | tmp = 0; |
1396 | } | 1453 | } |
1454 | atomic_dec(&runtime->oss.rw_ref); | ||
1397 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; | 1455 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; |
1398 | } | 1456 | } |
1399 | 1457 | ||
@@ -1439,13 +1497,15 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use | |||
1439 | if (atomic_read(&substream->mmap_count)) | 1497 | if (atomic_read(&substream->mmap_count)) |
1440 | return -ENXIO; | 1498 | return -ENXIO; |
1441 | 1499 | ||
1442 | if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) | 1500 | atomic_inc(&runtime->oss.rw_ref); |
1443 | return tmp; | ||
1444 | while (bytes > 0) { | 1501 | while (bytes > 0) { |
1445 | if (mutex_lock_interruptible(&runtime->oss.params_lock)) { | 1502 | if (mutex_lock_interruptible(&runtime->oss.params_lock)) { |
1446 | tmp = -ERESTARTSYS; | 1503 | tmp = -ERESTARTSYS; |
1447 | break; | 1504 | break; |
1448 | } | 1505 | } |
1506 | tmp = snd_pcm_oss_make_ready_locked(substream); | ||
1507 | if (tmp < 0) | ||
1508 | goto err; | ||
1449 | if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) { | 1509 | if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) { |
1450 | if (runtime->oss.buffer_used == 0) { | 1510 | if (runtime->oss.buffer_used == 0) { |
1451 | tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1); | 1511 | tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1); |
@@ -1486,6 +1546,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use | |||
1486 | } | 1546 | } |
1487 | tmp = 0; | 1547 | tmp = 0; |
1488 | } | 1548 | } |
1549 | atomic_dec(&runtime->oss.rw_ref); | ||
1489 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; | 1550 | return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; |
1490 | } | 1551 | } |
1491 | 1552 | ||
@@ -1501,10 +1562,12 @@ static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file) | |||
1501 | continue; | 1562 | continue; |
1502 | runtime = substream->runtime; | 1563 | runtime = substream->runtime; |
1503 | snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); | 1564 | snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); |
1565 | mutex_lock(&runtime->oss.params_lock); | ||
1504 | runtime->oss.prepare = 1; | 1566 | runtime->oss.prepare = 1; |
1505 | runtime->oss.buffer_used = 0; | 1567 | runtime->oss.buffer_used = 0; |
1506 | runtime->oss.prev_hw_ptr_period = 0; | 1568 | runtime->oss.prev_hw_ptr_period = 0; |
1507 | runtime->oss.period_ptr = 0; | 1569 | runtime->oss.period_ptr = 0; |
1570 | mutex_unlock(&runtime->oss.params_lock); | ||
1508 | } | 1571 | } |
1509 | return 0; | 1572 | return 0; |
1510 | } | 1573 | } |
@@ -1590,9 +1653,13 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) | |||
1590 | goto __direct; | 1653 | goto __direct; |
1591 | if ((err = snd_pcm_oss_make_ready(substream)) < 0) | 1654 | if ((err = snd_pcm_oss_make_ready(substream)) < 0) |
1592 | return err; | 1655 | return err; |
1656 | atomic_inc(&runtime->oss.rw_ref); | ||
1657 | if (mutex_lock_interruptible(&runtime->oss.params_lock)) { | ||
1658 | atomic_dec(&runtime->oss.rw_ref); | ||
1659 | return -ERESTARTSYS; | ||
1660 | } | ||
1593 | format = snd_pcm_oss_format_from(runtime->oss.format); | 1661 | format = snd_pcm_oss_format_from(runtime->oss.format); |
1594 | width = snd_pcm_format_physical_width(format); | 1662 | width = snd_pcm_format_physical_width(format); |
1595 | mutex_lock(&runtime->oss.params_lock); | ||
1596 | if (runtime->oss.buffer_used > 0) { | 1663 | if (runtime->oss.buffer_used > 0) { |
1597 | #ifdef OSS_DEBUG | 1664 | #ifdef OSS_DEBUG |
1598 | pcm_dbg(substream->pcm, "sync: buffer_used\n"); | 1665 | pcm_dbg(substream->pcm, "sync: buffer_used\n"); |
@@ -1602,10 +1669,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) | |||
1602 | runtime->oss.buffer + runtime->oss.buffer_used, | 1669 | runtime->oss.buffer + runtime->oss.buffer_used, |
1603 | size); | 1670 | size); |
1604 | err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes); | 1671 | err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes); |
1605 | if (err < 0) { | 1672 | if (err < 0) |
1606 | mutex_unlock(&runtime->oss.params_lock); | 1673 | goto unlock; |
1607 | return err; | ||
1608 | } | ||
1609 | } else if (runtime->oss.period_ptr > 0) { | 1674 | } else if (runtime->oss.period_ptr > 0) { |
1610 | #ifdef OSS_DEBUG | 1675 | #ifdef OSS_DEBUG |
1611 | pcm_dbg(substream->pcm, "sync: period_ptr\n"); | 1676 | pcm_dbg(substream->pcm, "sync: period_ptr\n"); |
@@ -1615,10 +1680,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) | |||
1615 | runtime->oss.buffer, | 1680 | runtime->oss.buffer, |
1616 | size * 8 / width); | 1681 | size * 8 / width); |
1617 | err = snd_pcm_oss_sync1(substream, size); | 1682 | err = snd_pcm_oss_sync1(substream, size); |
1618 | if (err < 0) { | 1683 | if (err < 0) |
1619 | mutex_unlock(&runtime->oss.params_lock); | 1684 | goto unlock; |
1620 | return err; | ||
1621 | } | ||
1622 | } | 1685 | } |
1623 | /* | 1686 | /* |
1624 | * The ALSA's period might be a bit large than OSS one. | 1687 | * The ALSA's period might be a bit large than OSS one. |
@@ -1632,7 +1695,11 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) | |||
1632 | else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) | 1695 | else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) |
1633 | snd_pcm_lib_writev(substream, NULL, size); | 1696 | snd_pcm_lib_writev(substream, NULL, size); |
1634 | } | 1697 | } |
1698 | unlock: | ||
1635 | mutex_unlock(&runtime->oss.params_lock); | 1699 | mutex_unlock(&runtime->oss.params_lock); |
1700 | atomic_dec(&runtime->oss.rw_ref); | ||
1701 | if (err < 0) | ||
1702 | return err; | ||
1636 | /* | 1703 | /* |
1637 | * finish sync: drain the buffer | 1704 | * finish sync: drain the buffer |
1638 | */ | 1705 | */ |
@@ -1643,7 +1710,9 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) | |||
1643 | substream->f_flags = saved_f_flags; | 1710 | substream->f_flags = saved_f_flags; |
1644 | if (err < 0) | 1711 | if (err < 0) |
1645 | return err; | 1712 | return err; |
1713 | mutex_lock(&runtime->oss.params_lock); | ||
1646 | runtime->oss.prepare = 1; | 1714 | runtime->oss.prepare = 1; |
1715 | mutex_unlock(&runtime->oss.params_lock); | ||
1647 | } | 1716 | } |
1648 | 1717 | ||
1649 | substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; | 1718 | substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; |
@@ -1654,8 +1723,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) | |||
1654 | err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); | 1723 | err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); |
1655 | if (err < 0) | 1724 | if (err < 0) |
1656 | return err; | 1725 | return err; |
1726 | mutex_lock(&runtime->oss.params_lock); | ||
1657 | runtime->oss.buffer_used = 0; | 1727 | runtime->oss.buffer_used = 0; |
1658 | runtime->oss.prepare = 1; | 1728 | runtime->oss.prepare = 1; |
1729 | mutex_unlock(&runtime->oss.params_lock); | ||
1659 | } | 1730 | } |
1660 | return 0; | 1731 | return 0; |
1661 | } | 1732 | } |
@@ -1667,6 +1738,8 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate) | |||
1667 | for (idx = 1; idx >= 0; --idx) { | 1738 | for (idx = 1; idx >= 0; --idx) { |
1668 | struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; | 1739 | struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; |
1669 | struct snd_pcm_runtime *runtime; | 1740 | struct snd_pcm_runtime *runtime; |
1741 | int err; | ||
1742 | |||
1670 | if (substream == NULL) | 1743 | if (substream == NULL) |
1671 | continue; | 1744 | continue; |
1672 | runtime = substream->runtime; | 1745 | runtime = substream->runtime; |
@@ -1674,10 +1747,14 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate) | |||
1674 | rate = 1000; | 1747 | rate = 1000; |
1675 | else if (rate > 192000) | 1748 | else if (rate > 192000) |
1676 | rate = 192000; | 1749 | rate = 192000; |
1750 | err = lock_params(runtime); | ||
1751 | if (err < 0) | ||
1752 | return err; | ||
1677 | if (runtime->oss.rate != rate) { | 1753 | if (runtime->oss.rate != rate) { |
1678 | runtime->oss.params = 1; | 1754 | runtime->oss.params = 1; |
1679 | runtime->oss.rate = rate; | 1755 | runtime->oss.rate = rate; |
1680 | } | 1756 | } |
1757 | unlock_params(runtime); | ||
1681 | } | 1758 | } |
1682 | return snd_pcm_oss_get_rate(pcm_oss_file); | 1759 | return snd_pcm_oss_get_rate(pcm_oss_file); |
1683 | } | 1760 | } |
@@ -1702,13 +1779,19 @@ static int snd_pcm_oss_set_channels(struct snd_pcm_oss_file *pcm_oss_file, unsig | |||
1702 | for (idx = 1; idx >= 0; --idx) { | 1779 | for (idx = 1; idx >= 0; --idx) { |
1703 | struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; | 1780 | struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; |
1704 | struct snd_pcm_runtime *runtime; | 1781 | struct snd_pcm_runtime *runtime; |
1782 | int err; | ||
1783 | |||
1705 | if (substream == NULL) | 1784 | if (substream == NULL) |
1706 | continue; | 1785 | continue; |
1707 | runtime = substream->runtime; | 1786 | runtime = substream->runtime; |
1787 | err = lock_params(runtime); | ||
1788 | if (err < 0) | ||
1789 | return err; | ||
1708 | if (runtime->oss.channels != channels) { | 1790 | if (runtime->oss.channels != channels) { |
1709 | runtime->oss.params = 1; | 1791 | runtime->oss.params = 1; |
1710 | runtime->oss.channels = channels; | 1792 | runtime->oss.channels = channels; |
1711 | } | 1793 | } |
1794 | unlock_params(runtime); | ||
1712 | } | 1795 | } |
1713 | return snd_pcm_oss_get_channels(pcm_oss_file); | 1796 | return snd_pcm_oss_get_channels(pcm_oss_file); |
1714 | } | 1797 | } |
@@ -1781,6 +1864,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) | |||
1781 | static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) | 1864 | static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) |
1782 | { | 1865 | { |
1783 | int formats, idx; | 1866 | int formats, idx; |
1867 | int err; | ||
1784 | 1868 | ||
1785 | if (format != AFMT_QUERY) { | 1869 | if (format != AFMT_QUERY) { |
1786 | formats = snd_pcm_oss_get_formats(pcm_oss_file); | 1870 | formats = snd_pcm_oss_get_formats(pcm_oss_file); |
@@ -1794,10 +1878,14 @@ static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int for | |||
1794 | if (substream == NULL) | 1878 | if (substream == NULL) |
1795 | continue; | 1879 | continue; |
1796 | runtime = substream->runtime; | 1880 | runtime = substream->runtime; |
1881 | err = lock_params(runtime); | ||
1882 | if (err < 0) | ||
1883 | return err; | ||
1797 | if (runtime->oss.format != format) { | 1884 | if (runtime->oss.format != format) { |
1798 | runtime->oss.params = 1; | 1885 | runtime->oss.params = 1; |
1799 | runtime->oss.format = format; | 1886 | runtime->oss.format = format; |
1800 | } | 1887 | } |
1888 | unlock_params(runtime); | ||
1801 | } | 1889 | } |
1802 | } | 1890 | } |
1803 | return snd_pcm_oss_get_format(pcm_oss_file); | 1891 | return snd_pcm_oss_get_format(pcm_oss_file); |
@@ -1817,8 +1905,6 @@ static int snd_pcm_oss_set_subdivide1(struct snd_pcm_substream *substream, int s | |||
1817 | { | 1905 | { |
1818 | struct snd_pcm_runtime *runtime; | 1906 | struct snd_pcm_runtime *runtime; |
1819 | 1907 | ||
1820 | if (substream == NULL) | ||
1821 | return 0; | ||
1822 | runtime = substream->runtime; | 1908 | runtime = substream->runtime; |
1823 | if (subdivide == 0) { | 1909 | if (subdivide == 0) { |
1824 | subdivide = runtime->oss.subdivision; | 1910 | subdivide = runtime->oss.subdivision; |
@@ -1842,9 +1928,17 @@ static int snd_pcm_oss_set_subdivide(struct snd_pcm_oss_file *pcm_oss_file, int | |||
1842 | 1928 | ||
1843 | for (idx = 1; idx >= 0; --idx) { | 1929 | for (idx = 1; idx >= 0; --idx) { |
1844 | struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; | 1930 | struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; |
1931 | struct snd_pcm_runtime *runtime; | ||
1932 | |||
1845 | if (substream == NULL) | 1933 | if (substream == NULL) |
1846 | continue; | 1934 | continue; |
1847 | if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 0) | 1935 | runtime = substream->runtime; |
1936 | err = lock_params(runtime); | ||
1937 | if (err < 0) | ||
1938 | return err; | ||
1939 | err = snd_pcm_oss_set_subdivide1(substream, subdivide); | ||
1940 | unlock_params(runtime); | ||
1941 | if (err < 0) | ||
1848 | return err; | 1942 | return err; |
1849 | } | 1943 | } |
1850 | return err; | 1944 | return err; |
@@ -1854,8 +1948,6 @@ static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsign | |||
1854 | { | 1948 | { |
1855 | struct snd_pcm_runtime *runtime; | 1949 | struct snd_pcm_runtime *runtime; |
1856 | 1950 | ||
1857 | if (substream == NULL) | ||
1858 | return 0; | ||
1859 | runtime = substream->runtime; | 1951 | runtime = substream->runtime; |
1860 | if (runtime->oss.subdivision || runtime->oss.fragshift) | 1952 | if (runtime->oss.subdivision || runtime->oss.fragshift) |
1861 | return -EINVAL; | 1953 | return -EINVAL; |
@@ -1875,9 +1967,17 @@ static int snd_pcm_oss_set_fragment(struct snd_pcm_oss_file *pcm_oss_file, unsig | |||
1875 | 1967 | ||
1876 | for (idx = 1; idx >= 0; --idx) { | 1968 | for (idx = 1; idx >= 0; --idx) { |
1877 | struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; | 1969 | struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; |
1970 | struct snd_pcm_runtime *runtime; | ||
1971 | |||
1878 | if (substream == NULL) | 1972 | if (substream == NULL) |
1879 | continue; | 1973 | continue; |
1880 | if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0) | 1974 | runtime = substream->runtime; |
1975 | err = lock_params(runtime); | ||
1976 | if (err < 0) | ||
1977 | return err; | ||
1978 | err = snd_pcm_oss_set_fragment1(substream, val); | ||
1979 | unlock_params(runtime); | ||
1980 | if (err < 0) | ||
1881 | return err; | 1981 | return err; |
1882 | } | 1982 | } |
1883 | return err; | 1983 | return err; |
@@ -1961,6 +2061,9 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr | |||
1961 | } | 2061 | } |
1962 | if (psubstream) { | 2062 | if (psubstream) { |
1963 | runtime = psubstream->runtime; | 2063 | runtime = psubstream->runtime; |
2064 | cmd = 0; | ||
2065 | if (mutex_lock_interruptible(&runtime->oss.params_lock)) | ||
2066 | return -ERESTARTSYS; | ||
1964 | if (trigger & PCM_ENABLE_OUTPUT) { | 2067 | if (trigger & PCM_ENABLE_OUTPUT) { |
1965 | if (runtime->oss.trigger) | 2068 | if (runtime->oss.trigger) |
1966 | goto _skip1; | 2069 | goto _skip1; |
@@ -1978,13 +2081,19 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr | |||
1978 | cmd = SNDRV_PCM_IOCTL_DROP; | 2081 | cmd = SNDRV_PCM_IOCTL_DROP; |
1979 | runtime->oss.prepare = 1; | 2082 | runtime->oss.prepare = 1; |
1980 | } | 2083 | } |
1981 | err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL); | ||
1982 | if (err < 0) | ||
1983 | return err; | ||
1984 | } | ||
1985 | _skip1: | 2084 | _skip1: |
2085 | mutex_unlock(&runtime->oss.params_lock); | ||
2086 | if (cmd) { | ||
2087 | err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL); | ||
2088 | if (err < 0) | ||
2089 | return err; | ||
2090 | } | ||
2091 | } | ||
1986 | if (csubstream) { | 2092 | if (csubstream) { |
1987 | runtime = csubstream->runtime; | 2093 | runtime = csubstream->runtime; |
2094 | cmd = 0; | ||
2095 | if (mutex_lock_interruptible(&runtime->oss.params_lock)) | ||
2096 | return -ERESTARTSYS; | ||
1988 | if (trigger & PCM_ENABLE_INPUT) { | 2097 | if (trigger & PCM_ENABLE_INPUT) { |
1989 | if (runtime->oss.trigger) | 2098 | if (runtime->oss.trigger) |
1990 | goto _skip2; | 2099 | goto _skip2; |
@@ -1999,11 +2108,14 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr | |||
1999 | cmd = SNDRV_PCM_IOCTL_DROP; | 2108 | cmd = SNDRV_PCM_IOCTL_DROP; |
2000 | runtime->oss.prepare = 1; | 2109 | runtime->oss.prepare = 1; |
2001 | } | 2110 | } |
2002 | err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL); | ||
2003 | if (err < 0) | ||
2004 | return err; | ||
2005 | } | ||
2006 | _skip2: | 2111 | _skip2: |
2112 | mutex_unlock(&runtime->oss.params_lock); | ||
2113 | if (cmd) { | ||
2114 | err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL); | ||
2115 | if (err < 0) | ||
2116 | return err; | ||
2117 | } | ||
2118 | } | ||
2007 | return 0; | 2119 | return 0; |
2008 | } | 2120 | } |
2009 | 2121 | ||
@@ -2255,6 +2367,7 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, | |||
2255 | runtime->oss.maxfrags = 0; | 2367 | runtime->oss.maxfrags = 0; |
2256 | runtime->oss.subdivision = 0; | 2368 | runtime->oss.subdivision = 0; |
2257 | substream->pcm_release = snd_pcm_oss_release_substream; | 2369 | substream->pcm_release = snd_pcm_oss_release_substream; |
2370 | atomic_set(&runtime->oss.rw_ref, 0); | ||
2258 | } | 2371 | } |
2259 | 2372 | ||
2260 | static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) | 2373 | static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index a83152e7d387..f4a19509cccf 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -1129,16 +1129,12 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, | |||
1129 | if (constrs->rules_num >= constrs->rules_all) { | 1129 | if (constrs->rules_num >= constrs->rules_all) { |
1130 | struct snd_pcm_hw_rule *new; | 1130 | struct snd_pcm_hw_rule *new; |
1131 | unsigned int new_rules = constrs->rules_all + 16; | 1131 | unsigned int new_rules = constrs->rules_all + 16; |
1132 | new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL); | 1132 | new = krealloc(constrs->rules, new_rules * sizeof(*c), |
1133 | GFP_KERNEL); | ||
1133 | if (!new) { | 1134 | if (!new) { |
1134 | va_end(args); | 1135 | va_end(args); |
1135 | return -ENOMEM; | 1136 | return -ENOMEM; |
1136 | } | 1137 | } |
1137 | if (constrs->rules) { | ||
1138 | memcpy(new, constrs->rules, | ||
1139 | constrs->rules_num * sizeof(*c)); | ||
1140 | kfree(constrs->rules); | ||
1141 | } | ||
1142 | constrs->rules = new; | 1138 | constrs->rules = new; |
1143 | constrs->rules_all = new_rules; | 1139 | constrs->rules_all = new_rules; |
1144 | } | 1140 | } |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index d18b3982548b..b84554893fab 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -323,7 +323,7 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream, | |||
323 | struct snd_pcm_hw_constraints *constrs = | 323 | struct snd_pcm_hw_constraints *constrs = |
324 | &substream->runtime->hw_constraints; | 324 | &substream->runtime->hw_constraints; |
325 | unsigned int k; | 325 | unsigned int k; |
326 | unsigned int rstamps[constrs->rules_num]; | 326 | unsigned int *rstamps; |
327 | unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1]; | 327 | unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1]; |
328 | unsigned int stamp; | 328 | unsigned int stamp; |
329 | struct snd_pcm_hw_rule *r; | 329 | struct snd_pcm_hw_rule *r; |
@@ -331,7 +331,7 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream, | |||
331 | struct snd_mask old_mask; | 331 | struct snd_mask old_mask; |
332 | struct snd_interval old_interval; | 332 | struct snd_interval old_interval; |
333 | bool again; | 333 | bool again; |
334 | int changed; | 334 | int changed, err = 0; |
335 | 335 | ||
336 | /* | 336 | /* |
337 | * Each application of rule has own sequence number. | 337 | * Each application of rule has own sequence number. |
@@ -339,8 +339,9 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream, | |||
339 | * Each member of 'rstamps' array represents the sequence number of | 339 | * Each member of 'rstamps' array represents the sequence number of |
340 | * recent application of corresponding rule. | 340 | * recent application of corresponding rule. |
341 | */ | 341 | */ |
342 | for (k = 0; k < constrs->rules_num; k++) | 342 | rstamps = kcalloc(constrs->rules_num, sizeof(unsigned int), GFP_KERNEL); |
343 | rstamps[k] = 0; | 343 | if (!rstamps) |
344 | return -ENOMEM; | ||
344 | 345 | ||
345 | /* | 346 | /* |
346 | * Each member of 'vstamps' array represents the sequence number of | 347 | * Each member of 'vstamps' array represents the sequence number of |
@@ -398,8 +399,10 @@ retry: | |||
398 | } | 399 | } |
399 | 400 | ||
400 | changed = r->func(params, r); | 401 | changed = r->func(params, r); |
401 | if (changed < 0) | 402 | if (changed < 0) { |
402 | return changed; | 403 | err = changed; |
404 | goto out; | ||
405 | } | ||
403 | 406 | ||
404 | /* | 407 | /* |
405 | * When the parameter is changed, notify it to the caller | 408 | * When the parameter is changed, notify it to the caller |
@@ -430,7 +433,9 @@ retry: | |||
430 | if (again) | 433 | if (again) |
431 | goto retry; | 434 | goto retry; |
432 | 435 | ||
433 | return 0; | 436 | out: |
437 | kfree(rstamps); | ||
438 | return err; | ||
434 | } | 439 | } |
435 | 440 | ||
436 | static int fixup_unreferenced_params(struct snd_pcm_substream *substream, | 441 | static int fixup_unreferenced_params(struct snd_pcm_substream *substream, |
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 8632301489fa..9e96186742d0 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c | |||
@@ -63,15 +63,18 @@ static int slave_update(struct link_slave *slave) | |||
63 | struct snd_ctl_elem_value *uctl; | 63 | struct snd_ctl_elem_value *uctl; |
64 | int err, ch; | 64 | int err, ch; |
65 | 65 | ||
66 | uctl = kmalloc(sizeof(*uctl), GFP_KERNEL); | 66 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); |
67 | if (!uctl) | 67 | if (!uctl) |
68 | return -ENOMEM; | 68 | return -ENOMEM; |
69 | uctl->id = slave->slave.id; | 69 | uctl->id = slave->slave.id; |
70 | err = slave->slave.get(&slave->slave, uctl); | 70 | err = slave->slave.get(&slave->slave, uctl); |
71 | if (err < 0) | ||
72 | goto error; | ||
71 | for (ch = 0; ch < slave->info.count; ch++) | 73 | for (ch = 0; ch < slave->info.count; ch++) |
72 | slave->vals[ch] = uctl->value.integer.value[ch]; | 74 | slave->vals[ch] = uctl->value.integer.value[ch]; |
75 | error: | ||
73 | kfree(uctl); | 76 | kfree(uctl); |
74 | return 0; | 77 | return err < 0 ? err : 0; |
75 | } | 78 | } |
76 | 79 | ||
77 | /* get the slave ctl info and save the initial values */ | 80 | /* get the slave ctl info and save the initial values */ |
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 1063a4377502..58e349fc893f 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c | |||
@@ -296,6 +296,8 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) | |||
296 | cable->pause |= stream; | 296 | cable->pause |= stream; |
297 | loopback_timer_stop(dpcm); | 297 | loopback_timer_stop(dpcm); |
298 | spin_unlock(&cable->lock); | 298 | spin_unlock(&cable->lock); |
299 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
300 | loopback_active_notify(dpcm); | ||
299 | break; | 301 | break; |
300 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 302 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
301 | case SNDRV_PCM_TRIGGER_RESUME: | 303 | case SNDRV_PCM_TRIGGER_RESUME: |
@@ -304,6 +306,8 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) | |||
304 | cable->pause &= ~stream; | 306 | cable->pause &= ~stream; |
305 | loopback_timer_start(dpcm); | 307 | loopback_timer_start(dpcm); |
306 | spin_unlock(&cable->lock); | 308 | spin_unlock(&cable->lock); |
309 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
310 | loopback_active_notify(dpcm); | ||
307 | break; | 311 | break; |
308 | default: | 312 | default: |
309 | return -EINVAL; | 313 | return -EINVAL; |
@@ -892,9 +896,11 @@ static int loopback_active_get(struct snd_kcontrol *kcontrol, | |||
892 | [kcontrol->id.subdevice][kcontrol->id.device ^ 1]; | 896 | [kcontrol->id.subdevice][kcontrol->id.device ^ 1]; |
893 | unsigned int val = 0; | 897 | unsigned int val = 0; |
894 | 898 | ||
895 | if (cable != NULL) | 899 | if (cable != NULL) { |
896 | val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? | 900 | unsigned int running = cable->running ^ cable->pause; |
897 | 1 : 0; | 901 | |
902 | val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0; | ||
903 | } | ||
898 | ucontrol->value.integer.value[0] = val; | 904 | ucontrol->value.integer.value[0] = val; |
899 | return 0; | 905 | return 0; |
900 | } | 906 | } |
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c index 06f845e293cb..7ba100bb1c3f 100644 --- a/sound/hda/hdac_device.c +++ b/sound/hda/hdac_device.c | |||
@@ -3,6 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
6 | #include <linux/delay.h> | ||
6 | #include <linux/device.h> | 7 | #include <linux/device.h> |
7 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
8 | #include <linux/module.h> | 9 | #include <linux/module.h> |
@@ -1064,3 +1065,37 @@ bool snd_hdac_check_power_state(struct hdac_device *hdac, | |||
1064 | return (state == target_state); | 1065 | return (state == target_state); |
1065 | } | 1066 | } |
1066 | EXPORT_SYMBOL_GPL(snd_hdac_check_power_state); | 1067 | EXPORT_SYMBOL_GPL(snd_hdac_check_power_state); |
1068 | /** | ||
1069 | * snd_hdac_sync_power_state - wait until actual power state matches | ||
1070 | * with the target state | ||
1071 | * | ||
1072 | * @hdac: the HDAC device | ||
1073 | * @nid: NID to send the command | ||
1074 | * @target_state: target state to check for | ||
1075 | * | ||
1076 | * Return power state or PS_ERROR if codec rejects GET verb. | ||
1077 | */ | ||
1078 | unsigned int snd_hdac_sync_power_state(struct hdac_device *codec, | ||
1079 | hda_nid_t nid, unsigned int power_state) | ||
1080 | { | ||
1081 | unsigned long end_time = jiffies + msecs_to_jiffies(500); | ||
1082 | unsigned int state, actual_state, count; | ||
1083 | |||
1084 | for (count = 0; count < 500; count++) { | ||
1085 | state = snd_hdac_codec_read(codec, nid, 0, | ||
1086 | AC_VERB_GET_POWER_STATE, 0); | ||
1087 | if (state & AC_PWRST_ERROR) { | ||
1088 | msleep(20); | ||
1089 | break; | ||
1090 | } | ||
1091 | actual_state = (state >> 4) & 0x0f; | ||
1092 | if (actual_state == power_state) | ||
1093 | break; | ||
1094 | if (time_after_eq(jiffies, end_time)) | ||
1095 | break; | ||
1096 | /* wait until the codec reachs to the target state */ | ||
1097 | msleep(1); | ||
1098 | } | ||
1099 | return state; | ||
1100 | } | ||
1101 | EXPORT_SYMBOL_GPL(snd_hdac_sync_power_state); | ||
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index d68f99e076a8..0935a5c8741f 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -736,8 +736,7 @@ static int pcm_prepare(struct snd_pcm_substream *substream) | |||
736 | static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 736 | static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
737 | { | 737 | { |
738 | struct echoaudio *chip = snd_pcm_substream_chip(substream); | 738 | struct echoaudio *chip = snd_pcm_substream_chip(substream); |
739 | struct snd_pcm_runtime *runtime = substream->runtime; | 739 | struct audiopipe *pipe; |
740 | struct audiopipe *pipe = runtime->private_data; | ||
741 | int i, err; | 740 | int i, err; |
742 | u32 channelmask = 0; | 741 | u32 channelmask = 0; |
743 | struct snd_pcm_substream *s; | 742 | struct snd_pcm_substream *s; |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index ccf4415a1c7b..18267de3a269 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
39 | #include <linux/iommu.h> | ||
39 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
40 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
41 | #include <linux/vmalloc.h> | 42 | #include <linux/vmalloc.h> |
@@ -1272,12 +1273,6 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) | |||
1272 | release_firmware(emu->dock_fw); | 1273 | release_firmware(emu->dock_fw); |
1273 | if (emu->irq >= 0) | 1274 | if (emu->irq >= 0) |
1274 | free_irq(emu->irq, emu); | 1275 | free_irq(emu->irq, emu); |
1275 | /* remove reserved page */ | ||
1276 | if (emu->reserved_page) { | ||
1277 | snd_emu10k1_synth_free(emu, | ||
1278 | (struct snd_util_memblk *)emu->reserved_page); | ||
1279 | emu->reserved_page = NULL; | ||
1280 | } | ||
1281 | snd_util_memhdr_free(emu->memhdr); | 1276 | snd_util_memhdr_free(emu->memhdr); |
1282 | if (emu->silent_page.area) | 1277 | if (emu->silent_page.area) |
1283 | snd_dma_free_pages(&emu->silent_page); | 1278 | snd_dma_free_pages(&emu->silent_page); |
@@ -1764,6 +1759,38 @@ static struct snd_emu_chip_details emu_chip_details[] = { | |||
1764 | { } /* terminator */ | 1759 | { } /* terminator */ |
1765 | }; | 1760 | }; |
1766 | 1761 | ||
1762 | /* | ||
1763 | * The chip (at least the Audigy 2 CA0102 chip, but most likely others, too) | ||
1764 | * has a problem that from time to time it likes to do few DMA reads a bit | ||
1765 | * beyond its normal allocation and gets very confused if these reads get | ||
1766 | * blocked by a IOMMU. | ||
1767 | * | ||
1768 | * This behaviour has been observed for the first (reserved) page | ||
1769 | * (for which it happens multiple times at every playback), often for various | ||
1770 | * synth pages and sometimes for PCM playback buffers and the page table | ||
1771 | * memory itself. | ||
1772 | * | ||
1773 | * As a workaround let's widen these DMA allocations by an extra page if we | ||
1774 | * detect that the device is behind a non-passthrough IOMMU. | ||
1775 | */ | ||
1776 | static void snd_emu10k1_detect_iommu(struct snd_emu10k1 *emu) | ||
1777 | { | ||
1778 | struct iommu_domain *domain; | ||
1779 | |||
1780 | emu->iommu_workaround = false; | ||
1781 | |||
1782 | if (!iommu_present(emu->card->dev->bus)) | ||
1783 | return; | ||
1784 | |||
1785 | domain = iommu_get_domain_for_dev(emu->card->dev); | ||
1786 | if (domain && domain->type == IOMMU_DOMAIN_IDENTITY) | ||
1787 | return; | ||
1788 | |||
1789 | dev_notice(emu->card->dev, | ||
1790 | "non-passthrough IOMMU detected, widening DMA allocations"); | ||
1791 | emu->iommu_workaround = true; | ||
1792 | } | ||
1793 | |||
1767 | int snd_emu10k1_create(struct snd_card *card, | 1794 | int snd_emu10k1_create(struct snd_card *card, |
1768 | struct pci_dev *pci, | 1795 | struct pci_dev *pci, |
1769 | unsigned short extin_mask, | 1796 | unsigned short extin_mask, |
@@ -1776,6 +1803,7 @@ int snd_emu10k1_create(struct snd_card *card, | |||
1776 | struct snd_emu10k1 *emu; | 1803 | struct snd_emu10k1 *emu; |
1777 | int idx, err; | 1804 | int idx, err; |
1778 | int is_audigy; | 1805 | int is_audigy; |
1806 | size_t page_table_size; | ||
1779 | unsigned int silent_page; | 1807 | unsigned int silent_page; |
1780 | const struct snd_emu_chip_details *c; | 1808 | const struct snd_emu_chip_details *c; |
1781 | static struct snd_device_ops ops = { | 1809 | static struct snd_device_ops ops = { |
@@ -1873,12 +1901,13 @@ int snd_emu10k1_create(struct snd_card *card, | |||
1873 | 1901 | ||
1874 | is_audigy = emu->audigy = c->emu10k2_chip; | 1902 | is_audigy = emu->audigy = c->emu10k2_chip; |
1875 | 1903 | ||
1904 | snd_emu10k1_detect_iommu(emu); | ||
1905 | |||
1876 | /* set addressing mode */ | 1906 | /* set addressing mode */ |
1877 | emu->address_mode = is_audigy ? 0 : 1; | 1907 | emu->address_mode = is_audigy ? 0 : 1; |
1878 | /* set the DMA transfer mask */ | 1908 | /* set the DMA transfer mask */ |
1879 | emu->dma_mask = emu->address_mode ? EMU10K1_DMA_MASK : AUDIGY_DMA_MASK; | 1909 | emu->dma_mask = emu->address_mode ? EMU10K1_DMA_MASK : AUDIGY_DMA_MASK; |
1880 | if (dma_set_mask(&pci->dev, emu->dma_mask) < 0 || | 1910 | if (dma_set_mask_and_coherent(&pci->dev, emu->dma_mask) < 0) { |
1881 | dma_set_coherent_mask(&pci->dev, emu->dma_mask) < 0) { | ||
1882 | dev_err(card->dev, | 1911 | dev_err(card->dev, |
1883 | "architecture does not support PCI busmaster DMA with mask 0x%lx\n", | 1912 | "architecture does not support PCI busmaster DMA with mask 0x%lx\n", |
1884 | emu->dma_mask); | 1913 | emu->dma_mask); |
@@ -1900,11 +1929,17 @@ int snd_emu10k1_create(struct snd_card *card, | |||
1900 | emu->port = pci_resource_start(pci, 0); | 1929 | emu->port = pci_resource_start(pci, 0); |
1901 | 1930 | ||
1902 | emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT; | 1931 | emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT; |
1903 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), | 1932 | |
1904 | (emu->address_mode ? 32 : 16) * 1024, &emu->ptb_pages) < 0) { | 1933 | page_table_size = sizeof(u32) * (emu->address_mode ? MAXPAGES1 : |
1934 | MAXPAGES0); | ||
1935 | if (snd_emu10k1_alloc_pages_maybe_wider(emu, page_table_size, | ||
1936 | &emu->ptb_pages) < 0) { | ||
1905 | err = -ENOMEM; | 1937 | err = -ENOMEM; |
1906 | goto error; | 1938 | goto error; |
1907 | } | 1939 | } |
1940 | dev_dbg(card->dev, "page table address range is %.8lx:%.8lx\n", | ||
1941 | (unsigned long)emu->ptb_pages.addr, | ||
1942 | (unsigned long)(emu->ptb_pages.addr + emu->ptb_pages.bytes)); | ||
1908 | 1943 | ||
1909 | emu->page_ptr_table = vmalloc(emu->max_cache_pages * sizeof(void *)); | 1944 | emu->page_ptr_table = vmalloc(emu->max_cache_pages * sizeof(void *)); |
1910 | emu->page_addr_table = vmalloc(emu->max_cache_pages * | 1945 | emu->page_addr_table = vmalloc(emu->max_cache_pages * |
@@ -1914,11 +1949,16 @@ int snd_emu10k1_create(struct snd_card *card, | |||
1914 | goto error; | 1949 | goto error; |
1915 | } | 1950 | } |
1916 | 1951 | ||
1917 | if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), | 1952 | if (snd_emu10k1_alloc_pages_maybe_wider(emu, EMUPAGESIZE, |
1918 | EMUPAGESIZE, &emu->silent_page) < 0) { | 1953 | &emu->silent_page) < 0) { |
1919 | err = -ENOMEM; | 1954 | err = -ENOMEM; |
1920 | goto error; | 1955 | goto error; |
1921 | } | 1956 | } |
1957 | dev_dbg(card->dev, "silent page range is %.8lx:%.8lx\n", | ||
1958 | (unsigned long)emu->silent_page.addr, | ||
1959 | (unsigned long)(emu->silent_page.addr + | ||
1960 | emu->silent_page.bytes)); | ||
1961 | |||
1922 | emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE); | 1962 | emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE); |
1923 | if (emu->memhdr == NULL) { | 1963 | if (emu->memhdr == NULL) { |
1924 | err = -ENOMEM; | 1964 | err = -ENOMEM; |
@@ -1993,13 +2033,8 @@ int snd_emu10k1_create(struct snd_card *card, | |||
1993 | SPCS_GENERATIONSTATUS | 0x00001200 | | 2033 | SPCS_GENERATIONSTATUS | 0x00001200 | |
1994 | 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT; | 2034 | 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT; |
1995 | 2035 | ||
1996 | emu->reserved_page = (struct snd_emu10k1_memblk *) | ||
1997 | snd_emu10k1_synth_alloc(emu, 4096); | ||
1998 | if (emu->reserved_page) | ||
1999 | emu->reserved_page->map_locked = 1; | ||
2000 | |||
2001 | /* Clear silent pages and set up pointers */ | 2036 | /* Clear silent pages and set up pointers */ |
2002 | memset(emu->silent_page.area, 0, PAGE_SIZE); | 2037 | memset(emu->silent_page.area, 0, emu->silent_page.bytes); |
2003 | silent_page = emu->silent_page.addr << emu->address_mode; | 2038 | silent_page = emu->silent_page.addr << emu->address_mode; |
2004 | for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++) | 2039 | for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++) |
2005 | ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx); | 2040 | ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx); |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 2683b9717215..cefe613ef7b7 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
@@ -411,12 +411,20 @@ static int snd_emu10k1_playback_hw_params(struct snd_pcm_substream *substream, | |||
411 | struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); | 411 | struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); |
412 | struct snd_pcm_runtime *runtime = substream->runtime; | 412 | struct snd_pcm_runtime *runtime = substream->runtime; |
413 | struct snd_emu10k1_pcm *epcm = runtime->private_data; | 413 | struct snd_emu10k1_pcm *epcm = runtime->private_data; |
414 | size_t alloc_size; | ||
414 | int err; | 415 | int err; |
415 | 416 | ||
416 | if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0) | 417 | if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0) |
417 | return err; | 418 | return err; |
418 | if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) | 419 | |
420 | alloc_size = params_buffer_bytes(hw_params); | ||
421 | if (emu->iommu_workaround) | ||
422 | alloc_size += EMUPAGESIZE; | ||
423 | err = snd_pcm_lib_malloc_pages(substream, alloc_size); | ||
424 | if (err < 0) | ||
419 | return err; | 425 | return err; |
426 | if (emu->iommu_workaround && runtime->dma_bytes >= EMUPAGESIZE) | ||
427 | runtime->dma_bytes -= EMUPAGESIZE; | ||
420 | if (err > 0) { /* change */ | 428 | if (err > 0) { /* change */ |
421 | int mapped; | 429 | int mapped; |
422 | if (epcm->memblk != NULL) | 430 | if (epcm->memblk != NULL) |
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 4f1f69be1865..5865f3b90b34 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c | |||
@@ -34,7 +34,10 @@ | |||
34 | * aligned pages in others | 34 | * aligned pages in others |
35 | */ | 35 | */ |
36 | #define __set_ptb_entry(emu,page,addr) \ | 36 | #define __set_ptb_entry(emu,page,addr) \ |
37 | (((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << (emu->address_mode)) | (page))) | 37 | (((__le32 *)(emu)->ptb_pages.area)[page] = \ |
38 | cpu_to_le32(((addr) << (emu->address_mode)) | (page))) | ||
39 | #define __get_ptb_entry(emu, page) \ | ||
40 | (le32_to_cpu(((__le32 *)(emu)->ptb_pages.area)[page])) | ||
38 | 41 | ||
39 | #define UNIT_PAGES (PAGE_SIZE / EMUPAGESIZE) | 42 | #define UNIT_PAGES (PAGE_SIZE / EMUPAGESIZE) |
40 | #define MAX_ALIGN_PAGES0 (MAXPAGES0 / UNIT_PAGES) | 43 | #define MAX_ALIGN_PAGES0 (MAXPAGES0 / UNIT_PAGES) |
@@ -44,8 +47,7 @@ | |||
44 | /* get offset address from aligned page */ | 47 | /* get offset address from aligned page */ |
45 | #define aligned_page_offset(page) ((page) << PAGE_SHIFT) | 48 | #define aligned_page_offset(page) ((page) << PAGE_SHIFT) |
46 | 49 | ||
47 | #if PAGE_SIZE == 4096 | 50 | #if PAGE_SIZE == EMUPAGESIZE && !IS_ENABLED(CONFIG_DYNAMIC_DEBUG) |
48 | /* page size == EMUPAGESIZE */ | ||
49 | /* fill PTB entrie(s) corresponding to page with addr */ | 51 | /* fill PTB entrie(s) corresponding to page with addr */ |
50 | #define set_ptb_entry(emu,page,addr) __set_ptb_entry(emu,page,addr) | 52 | #define set_ptb_entry(emu,page,addr) __set_ptb_entry(emu,page,addr) |
51 | /* fill PTB entrie(s) corresponding to page with silence pointer */ | 53 | /* fill PTB entrie(s) corresponding to page with silence pointer */ |
@@ -58,6 +60,8 @@ static inline void set_ptb_entry(struct snd_emu10k1 *emu, int page, dma_addr_t a | |||
58 | page *= UNIT_PAGES; | 60 | page *= UNIT_PAGES; |
59 | for (i = 0; i < UNIT_PAGES; i++, page++) { | 61 | for (i = 0; i < UNIT_PAGES; i++, page++) { |
60 | __set_ptb_entry(emu, page, addr); | 62 | __set_ptb_entry(emu, page, addr); |
63 | dev_dbg(emu->card->dev, "mapped page %d to entry %.8x\n", page, | ||
64 | (unsigned int)__get_ptb_entry(emu, page)); | ||
61 | addr += EMUPAGESIZE; | 65 | addr += EMUPAGESIZE; |
62 | } | 66 | } |
63 | } | 67 | } |
@@ -65,9 +69,12 @@ static inline void set_silent_ptb(struct snd_emu10k1 *emu, int page) | |||
65 | { | 69 | { |
66 | int i; | 70 | int i; |
67 | page *= UNIT_PAGES; | 71 | page *= UNIT_PAGES; |
68 | for (i = 0; i < UNIT_PAGES; i++, page++) | 72 | for (i = 0; i < UNIT_PAGES; i++, page++) { |
69 | /* do not increment ptr */ | 73 | /* do not increment ptr */ |
70 | __set_ptb_entry(emu, page, emu->silent_page.addr); | 74 | __set_ptb_entry(emu, page, emu->silent_page.addr); |
75 | dev_dbg(emu->card->dev, "mapped silent page %d to entry %.8x\n", | ||
76 | page, (unsigned int)__get_ptb_entry(emu, page)); | ||
77 | } | ||
71 | } | 78 | } |
72 | #endif /* PAGE_SIZE */ | 79 | #endif /* PAGE_SIZE */ |
73 | 80 | ||
@@ -102,7 +109,7 @@ static void emu10k1_memblk_init(struct snd_emu10k1_memblk *blk) | |||
102 | */ | 109 | */ |
103 | static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct list_head **nextp) | 110 | static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct list_head **nextp) |
104 | { | 111 | { |
105 | int page = 0, found_page = -ENOMEM; | 112 | int page = 1, found_page = -ENOMEM; |
106 | int max_size = npages; | 113 | int max_size = npages; |
107 | int size; | 114 | int size; |
108 | struct list_head *candidate = &emu->mapped_link_head; | 115 | struct list_head *candidate = &emu->mapped_link_head; |
@@ -147,6 +154,10 @@ static int map_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) | |||
147 | page = search_empty_map_area(emu, blk->pages, &next); | 154 | page = search_empty_map_area(emu, blk->pages, &next); |
148 | if (page < 0) /* not found */ | 155 | if (page < 0) /* not found */ |
149 | return page; | 156 | return page; |
157 | if (page == 0) { | ||
158 | dev_err(emu->card->dev, "trying to map zero (reserved) page\n"); | ||
159 | return -EINVAL; | ||
160 | } | ||
150 | /* insert this block in the proper position of mapped list */ | 161 | /* insert this block in the proper position of mapped list */ |
151 | list_add_tail(&blk->mapped_link, next); | 162 | list_add_tail(&blk->mapped_link, next); |
152 | /* append this as a newest block in order list */ | 163 | /* append this as a newest block in order list */ |
@@ -177,7 +188,7 @@ static int unmap_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) | |||
177 | q = get_emu10k1_memblk(p, mapped_link); | 188 | q = get_emu10k1_memblk(p, mapped_link); |
178 | start_page = q->mapped_page + q->pages; | 189 | start_page = q->mapped_page + q->pages; |
179 | } else | 190 | } else |
180 | start_page = 0; | 191 | start_page = 1; |
181 | if ((p = blk->mapped_link.next) != &emu->mapped_link_head) { | 192 | if ((p = blk->mapped_link.next) != &emu->mapped_link_head) { |
182 | q = get_emu10k1_memblk(p, mapped_link); | 193 | q = get_emu10k1_memblk(p, mapped_link); |
183 | end_page = q->mapped_page; | 194 | end_page = q->mapped_page; |
@@ -366,6 +377,33 @@ int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk) | |||
366 | return snd_emu10k1_synth_free(emu, blk); | 377 | return snd_emu10k1_synth_free(emu, blk); |
367 | } | 378 | } |
368 | 379 | ||
380 | /* | ||
381 | * allocate DMA pages, widening the allocation if necessary | ||
382 | * | ||
383 | * See the comment above snd_emu10k1_detect_iommu() in emu10k1_main.c why | ||
384 | * this might be needed. | ||
385 | * | ||
386 | * If you modify this function check whether __synth_free_pages() also needs | ||
387 | * changes. | ||
388 | */ | ||
389 | int snd_emu10k1_alloc_pages_maybe_wider(struct snd_emu10k1 *emu, size_t size, | ||
390 | struct snd_dma_buffer *dmab) | ||
391 | { | ||
392 | if (emu->iommu_workaround) { | ||
393 | size_t npages = (size + PAGE_SIZE - 1) / PAGE_SIZE; | ||
394 | size_t size_real = npages * PAGE_SIZE; | ||
395 | |||
396 | /* | ||
397 | * The device has been observed to accesses up to 256 extra | ||
398 | * bytes, but use 1k to be safe. | ||
399 | */ | ||
400 | if (size_real < size + 1024) | ||
401 | size += PAGE_SIZE; | ||
402 | } | ||
403 | |||
404 | return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, | ||
405 | snd_dma_pci_data(emu->pci), size, dmab); | ||
406 | } | ||
369 | 407 | ||
370 | /* | 408 | /* |
371 | * memory allocation using multiple pages (for synth) | 409 | * memory allocation using multiple pages (for synth) |
@@ -450,10 +488,27 @@ static void get_single_page_range(struct snd_util_memhdr *hdr, | |||
450 | static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page, | 488 | static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page, |
451 | int last_page) | 489 | int last_page) |
452 | { | 490 | { |
491 | struct snd_dma_buffer dmab; | ||
453 | int page; | 492 | int page; |
454 | 493 | ||
494 | dmab.dev.type = SNDRV_DMA_TYPE_DEV; | ||
495 | dmab.dev.dev = snd_dma_pci_data(emu->pci); | ||
496 | |||
455 | for (page = first_page; page <= last_page; page++) { | 497 | for (page = first_page; page <= last_page; page++) { |
456 | free_page((unsigned long)emu->page_ptr_table[page]); | 498 | if (emu->page_ptr_table[page] == NULL) |
499 | continue; | ||
500 | dmab.area = emu->page_ptr_table[page]; | ||
501 | dmab.addr = emu->page_addr_table[page]; | ||
502 | |||
503 | /* | ||
504 | * please keep me in sync with logic in | ||
505 | * snd_emu10k1_alloc_pages_maybe_wider() | ||
506 | */ | ||
507 | dmab.bytes = PAGE_SIZE; | ||
508 | if (emu->iommu_workaround) | ||
509 | dmab.bytes *= 2; | ||
510 | |||
511 | snd_dma_free_pages(&dmab); | ||
457 | emu->page_addr_table[page] = 0; | 512 | emu->page_addr_table[page] = 0; |
458 | emu->page_ptr_table[page] = NULL; | 513 | emu->page_ptr_table[page] = NULL; |
459 | } | 514 | } |
@@ -465,30 +520,30 @@ static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page, | |||
465 | static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) | 520 | static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) |
466 | { | 521 | { |
467 | int page, first_page, last_page; | 522 | int page, first_page, last_page; |
523 | struct snd_dma_buffer dmab; | ||
468 | 524 | ||
469 | emu10k1_memblk_init(blk); | 525 | emu10k1_memblk_init(blk); |
470 | get_single_page_range(emu->memhdr, blk, &first_page, &last_page); | 526 | get_single_page_range(emu->memhdr, blk, &first_page, &last_page); |
471 | /* allocate kernel pages */ | 527 | /* allocate kernel pages */ |
472 | for (page = first_page; page <= last_page; page++) { | 528 | for (page = first_page; page <= last_page; page++) { |
473 | /* first try to allocate from <4GB zone */ | 529 | if (snd_emu10k1_alloc_pages_maybe_wider(emu, PAGE_SIZE, |
474 | struct page *p = alloc_page(GFP_KERNEL | GFP_DMA32 | | 530 | &dmab) < 0) |
475 | __GFP_NOWARN); | 531 | goto __fail; |
476 | if (!p || (page_to_pfn(p) & ~(emu->dma_mask >> PAGE_SHIFT))) { | 532 | if (!is_valid_page(emu, dmab.addr)) { |
477 | if (p) | 533 | snd_dma_free_pages(&dmab); |
478 | __free_page(p); | 534 | goto __fail; |
479 | /* try to allocate from <16MB zone */ | ||
480 | p = alloc_page(GFP_ATOMIC | GFP_DMA | | ||
481 | __GFP_NORETRY | /* no OOM-killer */ | ||
482 | __GFP_NOWARN); | ||
483 | } | 535 | } |
484 | if (!p) { | 536 | emu->page_addr_table[page] = dmab.addr; |
485 | __synth_free_pages(emu, first_page, page - 1); | 537 | emu->page_ptr_table[page] = dmab.area; |
486 | return -ENOMEM; | ||
487 | } | ||
488 | emu->page_addr_table[page] = page_to_phys(p); | ||
489 | emu->page_ptr_table[page] = page_address(p); | ||
490 | } | 538 | } |
491 | return 0; | 539 | return 0; |
540 | |||
541 | __fail: | ||
542 | /* release allocated pages */ | ||
543 | last_page = page - 1; | ||
544 | __synth_free_pages(emu, first_page, last_page); | ||
545 | |||
546 | return -ENOMEM; | ||
492 | } | 547 | } |
493 | 548 | ||
494 | /* | 549 | /* |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index c397e7da0eac..066b5b59c4d7 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -1,22 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
1 | /* | 2 | /* |
2 | * Digital Beep Input Interface for HD-audio codec | 3 | * Digital Beep Input Interface for HD-audio codec |
3 | * | 4 | * |
4 | * Author: Matt Ranostay <mranostay@gmail.com> | 5 | * Author: Matt Ranostay <matt.ranostay@konsulko.com> |
5 | * Copyright (c) 2008 Embedded Alley Solutions Inc | 6 | * Copyright (c) 2008 Embedded Alley Solutions Inc |
6 | * | ||
7 | * This driver is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This driver is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | 7 | */ |
21 | 8 | ||
22 | #include <linux/input.h> | 9 | #include <linux/input.h> |
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index 1052ad380e97..d1a6a9c1329a 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h | |||
@@ -1,22 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
1 | /* | 2 | /* |
2 | * Digital Beep Input Interface for HD-audio codec | 3 | * Digital Beep Input Interface for HD-audio codec |
3 | * | 4 | * |
4 | * Author: Matt Ranostay <mranostay@gmail.com> | 5 | * Author: Matt Ranostay <matt.ranostay@konsulko.com> |
5 | * Copyright (c) 2008 Embedded Alley Solutions Inc | 6 | * Copyright (c) 2008 Embedded Alley Solutions Inc |
6 | * | ||
7 | * This driver is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This driver is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | 7 | */ |
21 | 8 | ||
22 | #ifndef __SOUND_HDA_BEEP_H | 9 | #ifndef __SOUND_HDA_BEEP_H |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e018ecbf78a8..5bc3a7468e17 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -2702,32 +2702,6 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, | |||
2702 | } | 2702 | } |
2703 | EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all); | 2703 | EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all); |
2704 | 2704 | ||
2705 | /* | ||
2706 | * wait until the state is reached, returns the current state | ||
2707 | */ | ||
2708 | static unsigned int hda_sync_power_state(struct hda_codec *codec, | ||
2709 | hda_nid_t fg, | ||
2710 | unsigned int power_state) | ||
2711 | { | ||
2712 | unsigned long end_time = jiffies + msecs_to_jiffies(500); | ||
2713 | unsigned int state, actual_state; | ||
2714 | |||
2715 | for (;;) { | ||
2716 | state = snd_hda_codec_read(codec, fg, 0, | ||
2717 | AC_VERB_GET_POWER_STATE, 0); | ||
2718 | if (state & AC_PWRST_ERROR) | ||
2719 | break; | ||
2720 | actual_state = (state >> 4) & 0x0f; | ||
2721 | if (actual_state == power_state) | ||
2722 | break; | ||
2723 | if (time_after_eq(jiffies, end_time)) | ||
2724 | break; | ||
2725 | /* wait until the codec reachs to the target state */ | ||
2726 | msleep(1); | ||
2727 | } | ||
2728 | return state; | ||
2729 | } | ||
2730 | |||
2731 | /** | 2705 | /** |
2732 | * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD | 2706 | * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD |
2733 | * @codec: the HDA codec | 2707 | * @codec: the HDA codec |
@@ -2790,7 +2764,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, | |||
2790 | state); | 2764 | state); |
2791 | snd_hda_codec_set_power_to_all(codec, fg, power_state); | 2765 | snd_hda_codec_set_power_to_all(codec, fg, power_state); |
2792 | } | 2766 | } |
2793 | state = hda_sync_power_state(codec, fg, power_state); | 2767 | state = snd_hda_sync_power_state(codec, fg, power_state); |
2794 | if (!(state & AC_PWRST_ERROR)) | 2768 | if (!(state & AC_PWRST_ERROR)) |
2795 | break; | 2769 | break; |
2796 | } | 2770 | } |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c507c69029e3..ccffce068634 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2434,6 +2434,9 @@ static const struct pci_device_id azx_ids[] = { | |||
2434 | /* Cannonlake */ | 2434 | /* Cannonlake */ |
2435 | { PCI_DEVICE(0x8086, 0x9dc8), | 2435 | { PCI_DEVICE(0x8086, 0x9dc8), |
2436 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | 2436 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, |
2437 | /* Icelake */ | ||
2438 | { PCI_DEVICE(0x8086, 0x34c8), | ||
2439 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, | ||
2437 | /* Broxton-P(Apollolake) */ | 2440 | /* Broxton-P(Apollolake) */ |
2438 | { PCI_DEVICE(0x8086, 0x5a98), | 2441 | { PCI_DEVICE(0x8086, 0x5a98), |
2439 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON }, | 2442 | .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON }, |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 5b5c324c99b9..321e78baa63c 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -622,7 +622,11 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid, | |||
622 | { | 622 | { |
623 | return snd_hdac_check_power_state(&codec->core, nid, target_state); | 623 | return snd_hdac_check_power_state(&codec->core, nid, target_state); |
624 | } | 624 | } |
625 | 625 | static inline bool snd_hda_sync_power_state(struct hda_codec *codec, | |
626 | hda_nid_t nid, unsigned int target_state) | ||
627 | { | ||
628 | return snd_hdac_sync_power_state(&codec->core, nid, target_state); | ||
629 | } | ||
626 | unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, | 630 | unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, |
627 | hda_nid_t nid, | 631 | hda_nid_t nid, |
628 | unsigned int power_state); | 632 | unsigned int power_state); |
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 0dbaccf61f33..21806bab4757 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/string.h> | ||
30 | #include <sound/core.h> | 31 | #include <sound/core.h> |
31 | #include <sound/tlv.h> | 32 | #include <sound/tlv.h> |
32 | 33 | ||
@@ -425,10 +426,9 @@ DECLARE_TLV_DB_SCALE(juli_master_db_scale, -6350, 50, 1); | |||
425 | static struct snd_kcontrol *ctl_find(struct snd_card *card, | 426 | static struct snd_kcontrol *ctl_find(struct snd_card *card, |
426 | const char *name) | 427 | const char *name) |
427 | { | 428 | { |
428 | struct snd_ctl_elem_id sid; | 429 | struct snd_ctl_elem_id sid = {0}; |
429 | memset(&sid, 0, sizeof(sid)); | 430 | |
430 | /* FIXME: strcpy is bad. */ | 431 | strlcpy(sid.name, name, sizeof(sid.name)); |
431 | strcpy(sid.name, name); | ||
432 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 432 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
433 | return snd_ctl_find_id(card, &sid); | 433 | return snd_ctl_find_id(card, &sid); |
434 | } | 434 | } |
diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c index d145b5eb7ff8..5bc836241c97 100644 --- a/sound/pci/ice1712/quartet.c +++ b/sound/pci/ice1712/quartet.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/string.h> | ||
29 | #include <sound/core.h> | 30 | #include <sound/core.h> |
30 | #include <sound/tlv.h> | 31 | #include <sound/tlv.h> |
31 | #include <sound/info.h> | 32 | #include <sound/info.h> |
@@ -785,10 +786,9 @@ DECLARE_TLV_DB_SCALE(qtet_master_db_scale, -6350, 50, 1); | |||
785 | static struct snd_kcontrol *ctl_find(struct snd_card *card, | 786 | static struct snd_kcontrol *ctl_find(struct snd_card *card, |
786 | const char *name) | 787 | const char *name) |
787 | { | 788 | { |
788 | struct snd_ctl_elem_id sid; | 789 | struct snd_ctl_elem_id sid = {0}; |
789 | memset(&sid, 0, sizeof(sid)); | 790 | |
790 | /* FIXME: strcpy is bad. */ | 791 | strlcpy(sid.name, name, sizeof(sid.name)); |
791 | strcpy(sid.name, name); | ||
792 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 792 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
793 | return snd_ctl_find_id(card, &sid); | 793 | return snd_ctl_find_id(card, &sid); |
794 | } | 794 | } |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 8018d56cfecc..4a1c6bb3dfa0 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Alan Cox (alan@lxorguk.ukuu.org.uk) | 7 | * Alan Cox (alan@lxorguk.ukuu.org.uk) |
8 | * Thomas Sailer (sailer@ife.ee.ethz.ch) | 8 | * Thomas Sailer (sailer@ife.ee.ethz.ch) |
9 | * | 9 | * |
10 | * Audio Class 3.0 support by Ruslan Bilovol <ruslan.bilovol@gmail.com> | ||
10 | * | 11 | * |
11 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
@@ -44,6 +45,7 @@ | |||
44 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
45 | #include <linux/usb/audio.h> | 46 | #include <linux/usb/audio.h> |
46 | #include <linux/usb/audio-v2.h> | 47 | #include <linux/usb/audio-v2.h> |
48 | #include <linux/usb/audio-v3.h> | ||
47 | #include <linux/module.h> | 49 | #include <linux/module.h> |
48 | 50 | ||
49 | #include <sound/control.h> | 51 | #include <sound/control.h> |
@@ -281,7 +283,8 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
281 | break; | 283 | break; |
282 | } | 284 | } |
283 | 285 | ||
284 | case UAC_VERSION_2: { | 286 | case UAC_VERSION_2: |
287 | case UAC_VERSION_3: { | ||
285 | struct usb_interface_assoc_descriptor *assoc = | 288 | struct usb_interface_assoc_descriptor *assoc = |
286 | usb_ifnum_to_if(dev, ctrlif)->intf_assoc; | 289 | usb_ifnum_to_if(dev, ctrlif)->intf_assoc; |
287 | 290 | ||
@@ -301,7 +304,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
301 | } | 304 | } |
302 | 305 | ||
303 | if (!assoc) { | 306 | if (!assoc) { |
304 | dev_err(&dev->dev, "Audio class v2 interfaces need an interface association\n"); | 307 | dev_err(&dev->dev, "Audio class v2/v3 interfaces need an interface association\n"); |
305 | return -EINVAL; | 308 | return -EINVAL; |
306 | } | 309 | } |
307 | 310 | ||
diff --git a/sound/usb/card.h b/sound/usb/card.h index ed87cc83eb47..1406292d50ec 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -22,7 +22,7 @@ struct audioformat { | |||
22 | unsigned char endpoint; /* endpoint */ | 22 | unsigned char endpoint; /* endpoint */ |
23 | unsigned char ep_attr; /* endpoint attributes */ | 23 | unsigned char ep_attr; /* endpoint attributes */ |
24 | unsigned char datainterval; /* log_2 of data packet interval */ | 24 | unsigned char datainterval; /* log_2 of data packet interval */ |
25 | unsigned char protocol; /* UAC_VERSION_1/2 */ | 25 | unsigned char protocol; /* UAC_VERSION_1/2/3 */ |
26 | unsigned int maxpacksize; /* max. packet size */ | 26 | unsigned int maxpacksize; /* max. packet size */ |
27 | unsigned int rates; /* rate bitmasks */ | 27 | unsigned int rates; /* rate bitmasks */ |
28 | unsigned int rate_min, rate_max; /* min/max rates */ | 28 | unsigned int rate_min, rate_max; /* min/max rates */ |
diff --git a/sound/usb/clock.c b/sound/usb/clock.c index eb3396ffba4c..ab39ccb974c6 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/usb.h> | 23 | #include <linux/usb.h> |
24 | #include <linux/usb/audio.h> | 24 | #include <linux/usb/audio.h> |
25 | #include <linux/usb/audio-v2.h> | 25 | #include <linux/usb/audio-v2.h> |
26 | #include <linux/usb/audio-v3.h> | ||
26 | 27 | ||
27 | #include <sound/core.h> | 28 | #include <sound/core.h> |
28 | #include <sound/info.h> | 29 | #include <sound/info.h> |
@@ -50,6 +51,22 @@ static struct uac_clock_source_descriptor * | |||
50 | return NULL; | 51 | return NULL; |
51 | } | 52 | } |
52 | 53 | ||
54 | static struct uac3_clock_source_descriptor * | ||
55 | snd_usb_find_clock_source_v3(struct usb_host_interface *ctrl_iface, | ||
56 | int clock_id) | ||
57 | { | ||
58 | struct uac3_clock_source_descriptor *cs = NULL; | ||
59 | |||
60 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
61 | ctrl_iface->extralen, | ||
62 | cs, UAC3_CLOCK_SOURCE))) { | ||
63 | if (cs->bClockID == clock_id) | ||
64 | return cs; | ||
65 | } | ||
66 | |||
67 | return NULL; | ||
68 | } | ||
69 | |||
53 | static struct uac_clock_selector_descriptor * | 70 | static struct uac_clock_selector_descriptor * |
54 | snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface, | 71 | snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface, |
55 | int clock_id) | 72 | int clock_id) |
@@ -69,6 +86,22 @@ static struct uac_clock_selector_descriptor * | |||
69 | return NULL; | 86 | return NULL; |
70 | } | 87 | } |
71 | 88 | ||
89 | static struct uac3_clock_selector_descriptor * | ||
90 | snd_usb_find_clock_selector_v3(struct usb_host_interface *ctrl_iface, | ||
91 | int clock_id) | ||
92 | { | ||
93 | struct uac3_clock_selector_descriptor *cs = NULL; | ||
94 | |||
95 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
96 | ctrl_iface->extralen, | ||
97 | cs, UAC3_CLOCK_SELECTOR))) { | ||
98 | if (cs->bClockID == clock_id) | ||
99 | return cs; | ||
100 | } | ||
101 | |||
102 | return NULL; | ||
103 | } | ||
104 | |||
72 | static struct uac_clock_multiplier_descriptor * | 105 | static struct uac_clock_multiplier_descriptor * |
73 | snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface, | 106 | snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface, |
74 | int clock_id) | 107 | int clock_id) |
@@ -85,6 +118,22 @@ static struct uac_clock_multiplier_descriptor * | |||
85 | return NULL; | 118 | return NULL; |
86 | } | 119 | } |
87 | 120 | ||
121 | static struct uac3_clock_multiplier_descriptor * | ||
122 | snd_usb_find_clock_multiplier_v3(struct usb_host_interface *ctrl_iface, | ||
123 | int clock_id) | ||
124 | { | ||
125 | struct uac3_clock_multiplier_descriptor *cs = NULL; | ||
126 | |||
127 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
128 | ctrl_iface->extralen, | ||
129 | cs, UAC3_CLOCK_MULTIPLIER))) { | ||
130 | if (cs->bClockID == clock_id) | ||
131 | return cs; | ||
132 | } | ||
133 | |||
134 | return NULL; | ||
135 | } | ||
136 | |||
88 | static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id) | 137 | static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id) |
89 | { | 138 | { |
90 | unsigned char buf; | 139 | unsigned char buf; |
@@ -138,20 +187,34 @@ static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_i | |||
138 | return ret; | 187 | return ret; |
139 | } | 188 | } |
140 | 189 | ||
141 | static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) | 190 | static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, |
191 | int protocol, | ||
192 | int source_id) | ||
142 | { | 193 | { |
143 | int err; | 194 | int err; |
144 | unsigned char data; | 195 | unsigned char data; |
145 | struct usb_device *dev = chip->dev; | 196 | struct usb_device *dev = chip->dev; |
146 | struct uac_clock_source_descriptor *cs_desc = | 197 | u32 bmControls; |
147 | snd_usb_find_clock_source(chip->ctrl_intf, source_id); | 198 | |
148 | 199 | if (protocol == UAC_VERSION_3) { | |
149 | if (!cs_desc) | 200 | struct uac3_clock_source_descriptor *cs_desc = |
150 | return 0; | 201 | snd_usb_find_clock_source_v3(chip->ctrl_intf, source_id); |
202 | |||
203 | if (!cs_desc) | ||
204 | return 0; | ||
205 | bmControls = le32_to_cpu(cs_desc->bmControls); | ||
206 | } else { /* UAC_VERSION_1/2 */ | ||
207 | struct uac_clock_source_descriptor *cs_desc = | ||
208 | snd_usb_find_clock_source(chip->ctrl_intf, source_id); | ||
209 | |||
210 | if (!cs_desc) | ||
211 | return 0; | ||
212 | bmControls = cs_desc->bmControls; | ||
213 | } | ||
151 | 214 | ||
152 | /* If a clock source can't tell us whether it's valid, we assume it is */ | 215 | /* If a clock source can't tell us whether it's valid, we assume it is */ |
153 | if (!uac2_control_is_readable(cs_desc->bmControls, | 216 | if (!uac_v2v3_control_is_readable(bmControls, |
154 | UAC2_CS_CONTROL_CLOCK_VALID - 1)) | 217 | UAC2_CS_CONTROL_CLOCK_VALID)) |
155 | return 1; | 218 | return 1; |
156 | 219 | ||
157 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | 220 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, |
@@ -170,9 +233,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) | |||
170 | return !!data; | 233 | return !!data; |
171 | } | 234 | } |
172 | 235 | ||
173 | static int __uac_clock_find_source(struct snd_usb_audio *chip, | 236 | static int __uac_clock_find_source(struct snd_usb_audio *chip, int entity_id, |
174 | int entity_id, unsigned long *visited, | 237 | unsigned long *visited, bool validate) |
175 | bool validate) | ||
176 | { | 238 | { |
177 | struct uac_clock_source_descriptor *source; | 239 | struct uac_clock_source_descriptor *source; |
178 | struct uac_clock_selector_descriptor *selector; | 240 | struct uac_clock_selector_descriptor *selector; |
@@ -191,7 +253,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, | |||
191 | source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id); | 253 | source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id); |
192 | if (source) { | 254 | if (source) { |
193 | entity_id = source->bClockID; | 255 | entity_id = source->bClockID; |
194 | if (validate && !uac_clock_source_is_valid(chip, entity_id)) { | 256 | if (validate && !uac_clock_source_is_valid(chip, UAC_VERSION_2, |
257 | entity_id)) { | ||
195 | usb_audio_err(chip, | 258 | usb_audio_err(chip, |
196 | "clock source %d is not valid, cannot use\n", | 259 | "clock source %d is not valid, cannot use\n", |
197 | entity_id); | 260 | entity_id); |
@@ -260,6 +323,97 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, | |||
260 | return -EINVAL; | 323 | return -EINVAL; |
261 | } | 324 | } |
262 | 325 | ||
326 | static int __uac3_clock_find_source(struct snd_usb_audio *chip, int entity_id, | ||
327 | unsigned long *visited, bool validate) | ||
328 | { | ||
329 | struct uac3_clock_source_descriptor *source; | ||
330 | struct uac3_clock_selector_descriptor *selector; | ||
331 | struct uac3_clock_multiplier_descriptor *multiplier; | ||
332 | |||
333 | entity_id &= 0xff; | ||
334 | |||
335 | if (test_and_set_bit(entity_id, visited)) { | ||
336 | usb_audio_warn(chip, | ||
337 | "%s(): recursive clock topology detected, id %d.\n", | ||
338 | __func__, entity_id); | ||
339 | return -EINVAL; | ||
340 | } | ||
341 | |||
342 | /* first, see if the ID we're looking for is a clock source already */ | ||
343 | source = snd_usb_find_clock_source_v3(chip->ctrl_intf, entity_id); | ||
344 | if (source) { | ||
345 | entity_id = source->bClockID; | ||
346 | if (validate && !uac_clock_source_is_valid(chip, UAC_VERSION_3, | ||
347 | entity_id)) { | ||
348 | usb_audio_err(chip, | ||
349 | "clock source %d is not valid, cannot use\n", | ||
350 | entity_id); | ||
351 | return -ENXIO; | ||
352 | } | ||
353 | return entity_id; | ||
354 | } | ||
355 | |||
356 | selector = snd_usb_find_clock_selector_v3(chip->ctrl_intf, entity_id); | ||
357 | if (selector) { | ||
358 | int ret, i, cur; | ||
359 | |||
360 | /* the entity ID we are looking for is a selector. | ||
361 | * find out what it currently selects */ | ||
362 | ret = uac_clock_selector_get_val(chip, selector->bClockID); | ||
363 | if (ret < 0) | ||
364 | return ret; | ||
365 | |||
366 | /* Selector values are one-based */ | ||
367 | |||
368 | if (ret > selector->bNrInPins || ret < 1) { | ||
369 | usb_audio_err(chip, | ||
370 | "%s(): selector reported illegal value, id %d, ret %d\n", | ||
371 | __func__, selector->bClockID, ret); | ||
372 | |||
373 | return -EINVAL; | ||
374 | } | ||
375 | |||
376 | cur = ret; | ||
377 | ret = __uac3_clock_find_source(chip, selector->baCSourceID[ret - 1], | ||
378 | visited, validate); | ||
379 | if (!validate || ret > 0 || !chip->autoclock) | ||
380 | return ret; | ||
381 | |||
382 | /* The current clock source is invalid, try others. */ | ||
383 | for (i = 1; i <= selector->bNrInPins; i++) { | ||
384 | int err; | ||
385 | |||
386 | if (i == cur) | ||
387 | continue; | ||
388 | |||
389 | ret = __uac3_clock_find_source(chip, selector->baCSourceID[i - 1], | ||
390 | visited, true); | ||
391 | if (ret < 0) | ||
392 | continue; | ||
393 | |||
394 | err = uac_clock_selector_set_val(chip, entity_id, i); | ||
395 | if (err < 0) | ||
396 | continue; | ||
397 | |||
398 | usb_audio_info(chip, | ||
399 | "found and selected valid clock source %d\n", | ||
400 | ret); | ||
401 | return ret; | ||
402 | } | ||
403 | |||
404 | return -ENXIO; | ||
405 | } | ||
406 | |||
407 | /* FIXME: multipliers only act as pass-thru element for now */ | ||
408 | multiplier = snd_usb_find_clock_multiplier_v3(chip->ctrl_intf, | ||
409 | entity_id); | ||
410 | if (multiplier) | ||
411 | return __uac3_clock_find_source(chip, multiplier->bCSourceID, | ||
412 | visited, validate); | ||
413 | |||
414 | return -EINVAL; | ||
415 | } | ||
416 | |||
263 | /* | 417 | /* |
264 | * For all kinds of sample rate settings and other device queries, | 418 | * For all kinds of sample rate settings and other device queries, |
265 | * the clock source (end-leaf) must be used. However, clock selectors, | 419 | * the clock source (end-leaf) must be used. However, clock selectors, |
@@ -271,12 +425,22 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, | |||
271 | * | 425 | * |
272 | * Returns the clock source UnitID (>=0) on success, or an error. | 426 | * Returns the clock source UnitID (>=0) on success, or an error. |
273 | */ | 427 | */ |
274 | int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id, | 428 | int snd_usb_clock_find_source(struct snd_usb_audio *chip, int protocol, |
275 | bool validate) | 429 | int entity_id, bool validate) |
276 | { | 430 | { |
277 | DECLARE_BITMAP(visited, 256); | 431 | DECLARE_BITMAP(visited, 256); |
278 | memset(visited, 0, sizeof(visited)); | 432 | memset(visited, 0, sizeof(visited)); |
279 | return __uac_clock_find_source(chip, entity_id, visited, validate); | 433 | |
434 | switch (protocol) { | ||
435 | case UAC_VERSION_2: | ||
436 | return __uac_clock_find_source(chip, entity_id, visited, | ||
437 | validate); | ||
438 | case UAC_VERSION_3: | ||
439 | return __uac3_clock_find_source(chip, entity_id, visited, | ||
440 | validate); | ||
441 | default: | ||
442 | return -EINVAL; | ||
443 | } | ||
280 | } | 444 | } |
281 | 445 | ||
282 | static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | 446 | static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, |
@@ -335,7 +499,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | |||
335 | return 0; | 499 | return 0; |
336 | } | 500 | } |
337 | 501 | ||
338 | static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface, | 502 | static int get_sample_rate_v2v3(struct snd_usb_audio *chip, int iface, |
339 | int altsetting, int clock) | 503 | int altsetting, int clock) |
340 | { | 504 | { |
341 | struct usb_device *dev = chip->dev; | 505 | struct usb_device *dev = chip->dev; |
@@ -348,7 +512,7 @@ static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
348 | snd_usb_ctrl_intf(chip) | (clock << 8), | 512 | snd_usb_ctrl_intf(chip) | (clock << 8), |
349 | &data, sizeof(data)); | 513 | &data, sizeof(data)); |
350 | if (err < 0) { | 514 | if (err < 0) { |
351 | dev_warn(&dev->dev, "%d:%d: cannot get freq (v2): err %d\n", | 515 | dev_warn(&dev->dev, "%d:%d: cannot get freq (v2/v3): err %d\n", |
352 | iface, altsetting, err); | 516 | iface, altsetting, err); |
353 | return 0; | 517 | return 0; |
354 | } | 518 | } |
@@ -356,7 +520,7 @@ static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
356 | return le32_to_cpu(data); | 520 | return le32_to_cpu(data); |
357 | } | 521 | } |
358 | 522 | ||
359 | static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | 523 | static int set_sample_rate_v2v3(struct snd_usb_audio *chip, int iface, |
360 | struct usb_host_interface *alts, | 524 | struct usb_host_interface *alts, |
361 | struct audioformat *fmt, int rate) | 525 | struct audioformat *fmt, int rate) |
362 | { | 526 | { |
@@ -365,18 +529,31 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
365 | int err, cur_rate, prev_rate; | 529 | int err, cur_rate, prev_rate; |
366 | int clock; | 530 | int clock; |
367 | bool writeable; | 531 | bool writeable; |
368 | struct uac_clock_source_descriptor *cs_desc; | 532 | u32 bmControls; |
369 | 533 | ||
370 | clock = snd_usb_clock_find_source(chip, fmt->clock, true); | 534 | clock = snd_usb_clock_find_source(chip, fmt->protocol, |
535 | fmt->clock, true); | ||
371 | if (clock < 0) | 536 | if (clock < 0) |
372 | return clock; | 537 | return clock; |
373 | 538 | ||
374 | prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); | 539 | prev_rate = get_sample_rate_v2v3(chip, iface, fmt->altsetting, clock); |
375 | if (prev_rate == rate) | 540 | if (prev_rate == rate) |
376 | return 0; | 541 | return 0; |
377 | 542 | ||
378 | cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock); | 543 | if (fmt->protocol == UAC_VERSION_3) { |
379 | writeable = uac2_control_is_writeable(cs_desc->bmControls, UAC2_CS_CONTROL_SAM_FREQ - 1); | 544 | struct uac3_clock_source_descriptor *cs_desc; |
545 | |||
546 | cs_desc = snd_usb_find_clock_source_v3(chip->ctrl_intf, clock); | ||
547 | bmControls = le32_to_cpu(cs_desc->bmControls); | ||
548 | } else { | ||
549 | struct uac_clock_source_descriptor *cs_desc; | ||
550 | |||
551 | cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock); | ||
552 | bmControls = cs_desc->bmControls; | ||
553 | } | ||
554 | |||
555 | writeable = uac_v2v3_control_is_writeable(bmControls, | ||
556 | UAC2_CS_CONTROL_SAM_FREQ); | ||
380 | if (writeable) { | 557 | if (writeable) { |
381 | data = cpu_to_le32(rate); | 558 | data = cpu_to_le32(rate); |
382 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, | 559 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, |
@@ -386,12 +563,13 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
386 | &data, sizeof(data)); | 563 | &data, sizeof(data)); |
387 | if (err < 0) { | 564 | if (err < 0) { |
388 | usb_audio_err(chip, | 565 | usb_audio_err(chip, |
389 | "%d:%d: cannot set freq %d (v2): err %d\n", | 566 | "%d:%d: cannot set freq %d (v2/v3): err %d\n", |
390 | iface, fmt->altsetting, rate, err); | 567 | iface, fmt->altsetting, rate, err); |
391 | return err; | 568 | return err; |
392 | } | 569 | } |
393 | 570 | ||
394 | cur_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); | 571 | cur_rate = get_sample_rate_v2v3(chip, iface, |
572 | fmt->altsetting, clock); | ||
395 | } else { | 573 | } else { |
396 | cur_rate = prev_rate; | 574 | cur_rate = prev_rate; |
397 | } | 575 | } |
@@ -430,7 +608,8 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface, | |||
430 | return set_sample_rate_v1(chip, iface, alts, fmt, rate); | 608 | return set_sample_rate_v1(chip, iface, alts, fmt, rate); |
431 | 609 | ||
432 | case UAC_VERSION_2: | 610 | case UAC_VERSION_2: |
433 | return set_sample_rate_v2(chip, iface, alts, fmt, rate); | 611 | case UAC_VERSION_3: |
612 | return set_sample_rate_v2v3(chip, iface, alts, fmt, rate); | ||
434 | } | 613 | } |
435 | } | 614 | } |
436 | 615 | ||
diff --git a/sound/usb/clock.h b/sound/usb/clock.h index 87557cae1a0b..076e31b79ee0 100644 --- a/sound/usb/clock.h +++ b/sound/usb/clock.h | |||
@@ -6,7 +6,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface, | |||
6 | struct usb_host_interface *alts, | 6 | struct usb_host_interface *alts, |
7 | struct audioformat *fmt, int rate); | 7 | struct audioformat *fmt, int rate); |
8 | 8 | ||
9 | int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id, | 9 | int snd_usb_clock_find_source(struct snd_usb_audio *chip, int protocol, |
10 | bool validate); | 10 | int entity_id, bool validate); |
11 | 11 | ||
12 | #endif /* __USBAUDIO_CLOCK_H */ | 12 | #endif /* __USBAUDIO_CLOCK_H */ |
diff --git a/sound/usb/format.c b/sound/usb/format.c index 2c44386e5569..49e7ec6d2399 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
21 | #include <linux/usb/audio.h> | 21 | #include <linux/usb/audio.h> |
22 | #include <linux/usb/audio-v2.h> | 22 | #include <linux/usb/audio-v2.h> |
23 | #include <linux/usb/audio-v3.h> | ||
23 | 24 | ||
24 | #include <sound/core.h> | 25 | #include <sound/core.h> |
25 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
@@ -39,11 +40,11 @@ | |||
39 | * @dev: usb device | 40 | * @dev: usb device |
40 | * @fp: audioformat record | 41 | * @fp: audioformat record |
41 | * @format: the format tag (wFormatTag) | 42 | * @format: the format tag (wFormatTag) |
42 | * @fmt: the format type descriptor | 43 | * @fmt: the format type descriptor (v1/v2) or AudioStreaming descriptor (v3) |
43 | */ | 44 | */ |
44 | static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, | 45 | static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, |
45 | struct audioformat *fp, | 46 | struct audioformat *fp, |
46 | unsigned int format, void *_fmt) | 47 | u64 format, void *_fmt) |
47 | { | 48 | { |
48 | int sample_width, sample_bytes; | 49 | int sample_width, sample_bytes; |
49 | u64 pcm_formats = 0; | 50 | u64 pcm_formats = 0; |
@@ -54,7 +55,7 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, | |||
54 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; | 55 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; |
55 | sample_width = fmt->bBitResolution; | 56 | sample_width = fmt->bBitResolution; |
56 | sample_bytes = fmt->bSubframeSize; | 57 | sample_bytes = fmt->bSubframeSize; |
57 | format = 1 << format; | 58 | format = 1ULL << format; |
58 | break; | 59 | break; |
59 | } | 60 | } |
60 | 61 | ||
@@ -69,6 +70,18 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, | |||
69 | format <<= 1; | 70 | format <<= 1; |
70 | break; | 71 | break; |
71 | } | 72 | } |
73 | case UAC_VERSION_3: { | ||
74 | struct uac3_as_header_descriptor *as = _fmt; | ||
75 | |||
76 | sample_width = as->bBitResolution; | ||
77 | sample_bytes = as->bSubslotSize; | ||
78 | |||
79 | if (format & UAC3_FORMAT_TYPE_I_RAW_DATA) | ||
80 | pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL; | ||
81 | |||
82 | format <<= 1; | ||
83 | break; | ||
84 | } | ||
72 | } | 85 | } |
73 | 86 | ||
74 | if ((pcm_formats == 0) && | 87 | if ((pcm_formats == 0) && |
@@ -137,7 +150,7 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, | |||
137 | } | 150 | } |
138 | if (format & ~0x3f) { | 151 | if (format & ~0x3f) { |
139 | usb_audio_info(chip, | 152 | usb_audio_info(chip, |
140 | "%u:%d : unsupported format bits %#x\n", | 153 | "%u:%d : unsupported format bits %#llx\n", |
141 | fp->iface, fp->altsetting, format); | 154 | fp->iface, fp->altsetting, format); |
142 | } | 155 | } |
143 | 156 | ||
@@ -281,15 +294,16 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip, | |||
281 | 294 | ||
282 | /* | 295 | /* |
283 | * parse the format descriptor and stores the possible sample rates | 296 | * parse the format descriptor and stores the possible sample rates |
284 | * on the audioformat table (audio class v2). | 297 | * on the audioformat table (audio class v2 and v3). |
285 | */ | 298 | */ |
286 | static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, | 299 | static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip, |
287 | struct audioformat *fp) | 300 | struct audioformat *fp) |
288 | { | 301 | { |
289 | struct usb_device *dev = chip->dev; | 302 | struct usb_device *dev = chip->dev; |
290 | unsigned char tmp[2], *data; | 303 | unsigned char tmp[2], *data; |
291 | int nr_triplets, data_size, ret = 0; | 304 | int nr_triplets, data_size, ret = 0; |
292 | int clock = snd_usb_clock_find_source(chip, fp->clock, false); | 305 | int clock = snd_usb_clock_find_source(chip, fp->protocol, |
306 | fp->clock, false); | ||
293 | 307 | ||
294 | if (clock < 0) { | 308 | if (clock < 0) { |
295 | dev_err(&dev->dev, | 309 | dev_err(&dev->dev, |
@@ -368,13 +382,30 @@ err: | |||
368 | * parse the format type I and III descriptors | 382 | * parse the format type I and III descriptors |
369 | */ | 383 | */ |
370 | static int parse_audio_format_i(struct snd_usb_audio *chip, | 384 | static int parse_audio_format_i(struct snd_usb_audio *chip, |
371 | struct audioformat *fp, unsigned int format, | 385 | struct audioformat *fp, u64 format, |
372 | struct uac_format_type_i_continuous_descriptor *fmt) | 386 | void *_fmt) |
373 | { | 387 | { |
374 | snd_pcm_format_t pcm_format; | 388 | snd_pcm_format_t pcm_format; |
389 | unsigned int fmt_type; | ||
375 | int ret; | 390 | int ret; |
376 | 391 | ||
377 | if (fmt->bFormatType == UAC_FORMAT_TYPE_III) { | 392 | switch (fp->protocol) { |
393 | default: | ||
394 | case UAC_VERSION_1: | ||
395 | case UAC_VERSION_2: { | ||
396 | struct uac_format_type_i_continuous_descriptor *fmt = _fmt; | ||
397 | |||
398 | fmt_type = fmt->bFormatType; | ||
399 | break; | ||
400 | } | ||
401 | case UAC_VERSION_3: { | ||
402 | /* fp->fmt_type is already set in this case */ | ||
403 | fmt_type = fp->fmt_type; | ||
404 | break; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | if (fmt_type == UAC_FORMAT_TYPE_III) { | ||
378 | /* FIXME: the format type is really IECxxx | 409 | /* FIXME: the format type is really IECxxx |
379 | * but we give normal PCM format to get the existing | 410 | * but we give normal PCM format to get the existing |
380 | * apps working... | 411 | * apps working... |
@@ -393,7 +424,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
393 | } | 424 | } |
394 | fp->formats = pcm_format_to_bits(pcm_format); | 425 | fp->formats = pcm_format_to_bits(pcm_format); |
395 | } else { | 426 | } else { |
396 | fp->formats = parse_audio_format_i_type(chip, fp, format, fmt); | 427 | fp->formats = parse_audio_format_i_type(chip, fp, format, _fmt); |
397 | if (!fp->formats) | 428 | if (!fp->formats) |
398 | return -EINVAL; | 429 | return -EINVAL; |
399 | } | 430 | } |
@@ -405,15 +436,20 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
405 | */ | 436 | */ |
406 | switch (fp->protocol) { | 437 | switch (fp->protocol) { |
407 | default: | 438 | default: |
408 | case UAC_VERSION_1: | 439 | case UAC_VERSION_1: { |
440 | struct uac_format_type_i_continuous_descriptor *fmt = _fmt; | ||
441 | |||
409 | fp->channels = fmt->bNrChannels; | 442 | fp->channels = fmt->bNrChannels; |
410 | ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); | 443 | ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); |
411 | break; | 444 | break; |
445 | } | ||
412 | case UAC_VERSION_2: | 446 | case UAC_VERSION_2: |
447 | case UAC_VERSION_3: { | ||
413 | /* fp->channels is already set in this case */ | 448 | /* fp->channels is already set in this case */ |
414 | ret = parse_audio_format_rates_v2(chip, fp); | 449 | ret = parse_audio_format_rates_v2v3(chip, fp); |
415 | break; | 450 | break; |
416 | } | 451 | } |
452 | } | ||
417 | 453 | ||
418 | if (fp->channels < 1) { | 454 | if (fp->channels < 1) { |
419 | usb_audio_err(chip, | 455 | usb_audio_err(chip, |
@@ -430,7 +466,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
430 | */ | 466 | */ |
431 | static int parse_audio_format_ii(struct snd_usb_audio *chip, | 467 | static int parse_audio_format_ii(struct snd_usb_audio *chip, |
432 | struct audioformat *fp, | 468 | struct audioformat *fp, |
433 | int format, void *_fmt) | 469 | u64 format, void *_fmt) |
434 | { | 470 | { |
435 | int brate, framesize, ret; | 471 | int brate, framesize, ret; |
436 | 472 | ||
@@ -445,7 +481,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
445 | break; | 481 | break; |
446 | default: | 482 | default: |
447 | usb_audio_info(chip, | 483 | usb_audio_info(chip, |
448 | "%u:%d : unknown format tag %#x is detected. processed as MPEG.\n", | 484 | "%u:%d : unknown format tag %#llx is detected. processed as MPEG.\n", |
449 | fp->iface, fp->altsetting, format); | 485 | fp->iface, fp->altsetting, format); |
450 | fp->formats = SNDRV_PCM_FMTBIT_MPEG; | 486 | fp->formats = SNDRV_PCM_FMTBIT_MPEG; |
451 | break; | 487 | break; |
@@ -470,7 +506,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
470 | framesize = le16_to_cpu(fmt->wSamplesPerFrame); | 506 | framesize = le16_to_cpu(fmt->wSamplesPerFrame); |
471 | usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); | 507 | usb_audio_info(chip, "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); |
472 | fp->frame_size = framesize; | 508 | fp->frame_size = framesize; |
473 | ret = parse_audio_format_rates_v2(chip, fp); | 509 | ret = parse_audio_format_rates_v2v3(chip, fp); |
474 | break; | 510 | break; |
475 | } | 511 | } |
476 | } | 512 | } |
@@ -479,7 +515,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
479 | } | 515 | } |
480 | 516 | ||
481 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, | 517 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, |
482 | struct audioformat *fp, unsigned int format, | 518 | struct audioformat *fp, u64 format, |
483 | struct uac_format_type_i_continuous_descriptor *fmt, | 519 | struct uac_format_type_i_continuous_descriptor *fmt, |
484 | int stream) | 520 | int stream) |
485 | { | 521 | { |
@@ -520,3 +556,26 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, | |||
520 | return 0; | 556 | return 0; |
521 | } | 557 | } |
522 | 558 | ||
559 | int snd_usb_parse_audio_format_v3(struct snd_usb_audio *chip, | ||
560 | struct audioformat *fp, | ||
561 | struct uac3_as_header_descriptor *as, | ||
562 | int stream) | ||
563 | { | ||
564 | u64 format = le64_to_cpu(as->bmFormats); | ||
565 | int err; | ||
566 | |||
567 | /* | ||
568 | * Type I format bits are D0..D6 | ||
569 | * This test works because type IV is not supported | ||
570 | */ | ||
571 | if (format & 0x7f) | ||
572 | fp->fmt_type = UAC_FORMAT_TYPE_I; | ||
573 | else | ||
574 | fp->fmt_type = UAC_FORMAT_TYPE_III; | ||
575 | |||
576 | err = parse_audio_format_i(chip, fp, format, as); | ||
577 | if (err < 0) | ||
578 | return err; | ||
579 | |||
580 | return 0; | ||
581 | } | ||
diff --git a/sound/usb/format.h b/sound/usb/format.h index 8c3ff9ce0824..e70171892f32 100644 --- a/sound/usb/format.h +++ b/sound/usb/format.h | |||
@@ -3,8 +3,12 @@ | |||
3 | #define __USBAUDIO_FORMAT_H | 3 | #define __USBAUDIO_FORMAT_H |
4 | 4 | ||
5 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, | 5 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, |
6 | struct audioformat *fp, unsigned int format, | 6 | struct audioformat *fp, u64 format, |
7 | struct uac_format_type_i_continuous_descriptor *fmt, | 7 | struct uac_format_type_i_continuous_descriptor *fmt, |
8 | int stream); | 8 | int stream); |
9 | 9 | ||
10 | int snd_usb_parse_audio_format_v3(struct snd_usb_audio *chip, | ||
11 | struct audioformat *fp, | ||
12 | struct uac3_as_header_descriptor *as, | ||
13 | int stream); | ||
10 | #endif /* __USBAUDIO_FORMAT_H */ | 14 | #endif /* __USBAUDIO_FORMAT_H */ |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 06b22624ab7a..301ad61ed426 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/usb.h> | 51 | #include <linux/usb.h> |
52 | #include <linux/usb/audio.h> | 52 | #include <linux/usb/audio.h> |
53 | #include <linux/usb/audio-v2.h> | 53 | #include <linux/usb/audio-v2.h> |
54 | #include <linux/usb/audio-v3.h> | ||
54 | 55 | ||
55 | #include <sound/core.h> | 56 | #include <sound/core.h> |
56 | #include <sound/control.h> | 57 | #include <sound/control.h> |
@@ -189,7 +190,7 @@ static void *find_audio_control_unit(struct mixer_build *state, | |||
189 | USB_DT_CS_INTERFACE)) != NULL) { | 190 | USB_DT_CS_INTERFACE)) != NULL) { |
190 | if (hdr->bLength >= 4 && | 191 | if (hdr->bLength >= 4 && |
191 | hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL && | 192 | hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL && |
192 | hdr->bDescriptorSubtype <= UAC2_SAMPLE_RATE_CONVERTER && | 193 | hdr->bDescriptorSubtype <= UAC3_SAMPLE_RATE_CONVERTER && |
193 | hdr->bUnitID == unit) | 194 | hdr->bUnitID == unit) |
194 | return hdr; | 195 | return hdr; |
195 | } | 196 | } |
@@ -468,9 +469,10 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | |||
468 | 469 | ||
469 | validx += cval->idx_off; | 470 | validx += cval->idx_off; |
470 | 471 | ||
472 | |||
471 | if (cval->head.mixer->protocol == UAC_VERSION_1) { | 473 | if (cval->head.mixer->protocol == UAC_VERSION_1) { |
472 | val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; | 474 | val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; |
473 | } else { /* UAC_VERSION_2 */ | 475 | } else { /* UAC_VERSION_2/3 */ |
474 | val_len = uac2_ctl_value_size(cval->val_type); | 476 | val_len = uac2_ctl_value_size(cval->val_type); |
475 | 477 | ||
476 | /* FIXME */ | 478 | /* FIXME */ |
@@ -723,6 +725,7 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
723 | static int check_input_term(struct mixer_build *state, int id, | 725 | static int check_input_term(struct mixer_build *state, int id, |
724 | struct usb_audio_term *term) | 726 | struct usb_audio_term *term) |
725 | { | 727 | { |
728 | int protocol = state->mixer->protocol; | ||
726 | int err; | 729 | int err; |
727 | void *p1; | 730 | void *p1; |
728 | 731 | ||
@@ -730,16 +733,104 @@ static int check_input_term(struct mixer_build *state, int id, | |||
730 | while ((p1 = find_audio_control_unit(state, id)) != NULL) { | 733 | while ((p1 = find_audio_control_unit(state, id)) != NULL) { |
731 | unsigned char *hdr = p1; | 734 | unsigned char *hdr = p1; |
732 | term->id = id; | 735 | term->id = id; |
733 | switch (hdr[2]) { | 736 | |
734 | case UAC_INPUT_TERMINAL: | 737 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { |
735 | if (state->mixer->protocol == UAC_VERSION_1) { | 738 | switch (hdr[2]) { |
736 | struct uac_input_terminal_descriptor *d = p1; | 739 | case UAC_INPUT_TERMINAL: |
737 | term->type = le16_to_cpu(d->wTerminalType); | 740 | if (protocol == UAC_VERSION_1) { |
738 | term->channels = d->bNrChannels; | 741 | struct uac_input_terminal_descriptor *d = p1; |
739 | term->chconfig = le16_to_cpu(d->wChannelConfig); | 742 | |
740 | term->name = d->iTerminal; | 743 | term->type = le16_to_cpu(d->wTerminalType); |
741 | } else { /* UAC_VERSION_2 */ | 744 | term->channels = d->bNrChannels; |
742 | struct uac2_input_terminal_descriptor *d = p1; | 745 | term->chconfig = le16_to_cpu(d->wChannelConfig); |
746 | term->name = d->iTerminal; | ||
747 | } else { /* UAC_VERSION_2 */ | ||
748 | struct uac2_input_terminal_descriptor *d = p1; | ||
749 | |||
750 | /* call recursively to verify that the | ||
751 | * referenced clock entity is valid */ | ||
752 | err = check_input_term(state, d->bCSourceID, term); | ||
753 | if (err < 0) | ||
754 | return err; | ||
755 | |||
756 | /* save input term properties after recursion, | ||
757 | * to ensure they are not overriden by the | ||
758 | * recursion calls */ | ||
759 | term->id = id; | ||
760 | term->type = le16_to_cpu(d->wTerminalType); | ||
761 | term->channels = d->bNrChannels; | ||
762 | term->chconfig = le32_to_cpu(d->bmChannelConfig); | ||
763 | term->name = d->iTerminal; | ||
764 | } | ||
765 | return 0; | ||
766 | case UAC_FEATURE_UNIT: { | ||
767 | /* the header is the same for v1 and v2 */ | ||
768 | struct uac_feature_unit_descriptor *d = p1; | ||
769 | |||
770 | id = d->bSourceID; | ||
771 | break; /* continue to parse */ | ||
772 | } | ||
773 | case UAC_MIXER_UNIT: { | ||
774 | struct uac_mixer_unit_descriptor *d = p1; | ||
775 | |||
776 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
777 | term->channels = uac_mixer_unit_bNrChannels(d); | ||
778 | term->chconfig = uac_mixer_unit_wChannelConfig(d, protocol); | ||
779 | term->name = uac_mixer_unit_iMixer(d); | ||
780 | return 0; | ||
781 | } | ||
782 | case UAC_SELECTOR_UNIT: | ||
783 | case UAC2_CLOCK_SELECTOR: { | ||
784 | struct uac_selector_unit_descriptor *d = p1; | ||
785 | /* call recursively to retrieve the channel info */ | ||
786 | err = check_input_term(state, d->baSourceID[0], term); | ||
787 | if (err < 0) | ||
788 | return err; | ||
789 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
790 | term->id = id; | ||
791 | term->name = uac_selector_unit_iSelector(d); | ||
792 | return 0; | ||
793 | } | ||
794 | case UAC1_PROCESSING_UNIT: | ||
795 | case UAC1_EXTENSION_UNIT: | ||
796 | /* UAC2_PROCESSING_UNIT_V2 */ | ||
797 | /* UAC2_EFFECT_UNIT */ | ||
798 | case UAC2_EXTENSION_UNIT_V2: { | ||
799 | struct uac_processing_unit_descriptor *d = p1; | ||
800 | |||
801 | if (protocol == UAC_VERSION_2 && | ||
802 | hdr[2] == UAC2_EFFECT_UNIT) { | ||
803 | /* UAC2/UAC1 unit IDs overlap here in an | ||
804 | * uncompatible way. Ignore this unit for now. | ||
805 | */ | ||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | if (d->bNrInPins) { | ||
810 | id = d->baSourceID[0]; | ||
811 | break; /* continue to parse */ | ||
812 | } | ||
813 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
814 | term->channels = uac_processing_unit_bNrChannels(d); | ||
815 | term->chconfig = uac_processing_unit_wChannelConfig(d, protocol); | ||
816 | term->name = uac_processing_unit_iProcessing(d, protocol); | ||
817 | return 0; | ||
818 | } | ||
819 | case UAC2_CLOCK_SOURCE: { | ||
820 | struct uac_clock_source_descriptor *d = p1; | ||
821 | |||
822 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
823 | term->id = id; | ||
824 | term->name = d->iClockSource; | ||
825 | return 0; | ||
826 | } | ||
827 | default: | ||
828 | return -ENODEV; | ||
829 | } | ||
830 | } else { /* UAC_VERSION_3 */ | ||
831 | switch (hdr[2]) { | ||
832 | case UAC_INPUT_TERMINAL: { | ||
833 | struct uac3_input_terminal_descriptor *d = p1; | ||
743 | 834 | ||
744 | /* call recursively to verify that the | 835 | /* call recursively to verify that the |
745 | * referenced clock entity is valid */ | 836 | * referenced clock entity is valid */ |
@@ -752,71 +843,31 @@ static int check_input_term(struct mixer_build *state, int id, | |||
752 | * recursion calls */ | 843 | * recursion calls */ |
753 | term->id = id; | 844 | term->id = id; |
754 | term->type = le16_to_cpu(d->wTerminalType); | 845 | term->type = le16_to_cpu(d->wTerminalType); |
755 | term->channels = d->bNrChannels; | 846 | |
756 | term->chconfig = le32_to_cpu(d->bmChannelConfig); | 847 | /* REVISIT: UAC3 IT doesn't have channels/cfg */ |
757 | term->name = d->iTerminal; | 848 | term->channels = 0; |
758 | } | 849 | term->chconfig = 0; |
759 | return 0; | 850 | |
760 | case UAC_FEATURE_UNIT: { | 851 | term->name = le16_to_cpu(d->wTerminalDescrStr); |
761 | /* the header is the same for v1 and v2 */ | ||
762 | struct uac_feature_unit_descriptor *d = p1; | ||
763 | id = d->bSourceID; | ||
764 | break; /* continue to parse */ | ||
765 | } | ||
766 | case UAC_MIXER_UNIT: { | ||
767 | struct uac_mixer_unit_descriptor *d = p1; | ||
768 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
769 | term->channels = uac_mixer_unit_bNrChannels(d); | ||
770 | term->chconfig = uac_mixer_unit_wChannelConfig(d, state->mixer->protocol); | ||
771 | term->name = uac_mixer_unit_iMixer(d); | ||
772 | return 0; | ||
773 | } | ||
774 | case UAC_SELECTOR_UNIT: | ||
775 | case UAC2_CLOCK_SELECTOR: { | ||
776 | struct uac_selector_unit_descriptor *d = p1; | ||
777 | /* call recursively to retrieve the channel info */ | ||
778 | err = check_input_term(state, d->baSourceID[0], term); | ||
779 | if (err < 0) | ||
780 | return err; | ||
781 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | ||
782 | term->id = id; | ||
783 | term->name = uac_selector_unit_iSelector(d); | ||
784 | return 0; | ||
785 | } | ||
786 | case UAC1_PROCESSING_UNIT: | ||
787 | case UAC1_EXTENSION_UNIT: | ||
788 | /* UAC2_PROCESSING_UNIT_V2 */ | ||
789 | /* UAC2_EFFECT_UNIT */ | ||
790 | case UAC2_EXTENSION_UNIT_V2: { | ||
791 | struct uac_processing_unit_descriptor *d = p1; | ||
792 | |||
793 | if (state->mixer->protocol == UAC_VERSION_2 && | ||
794 | hdr[2] == UAC2_EFFECT_UNIT) { | ||
795 | /* UAC2/UAC1 unit IDs overlap here in an | ||
796 | * uncompatible way. Ignore this unit for now. | ||
797 | */ | ||
798 | return 0; | 852 | return 0; |
799 | } | 853 | } |
854 | case UAC3_FEATURE_UNIT: { | ||
855 | struct uac3_feature_unit_descriptor *d = p1; | ||
800 | 856 | ||
801 | if (d->bNrInPins) { | 857 | id = d->bSourceID; |
802 | id = d->baSourceID[0]; | ||
803 | break; /* continue to parse */ | 858 | break; /* continue to parse */ |
804 | } | 859 | } |
805 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | 860 | case UAC3_CLOCK_SOURCE: { |
806 | term->channels = uac_processing_unit_bNrChannels(d); | 861 | struct uac3_clock_source_descriptor *d = p1; |
807 | term->chconfig = uac_processing_unit_wChannelConfig(d, state->mixer->protocol); | 862 | |
808 | term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol); | 863 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ |
809 | return 0; | 864 | term->id = id; |
810 | } | 865 | term->name = le16_to_cpu(d->wClockSourceStr); |
811 | case UAC2_CLOCK_SOURCE: { | 866 | return 0; |
812 | struct uac_clock_source_descriptor *d = p1; | 867 | } |
813 | term->type = d->bDescriptorSubtype << 16; /* virtual type */ | 868 | default: |
814 | term->id = id; | 869 | return -ENODEV; |
815 | term->name = d->iClockSource; | 870 | } |
816 | return 0; | ||
817 | } | ||
818 | default: | ||
819 | return -ENODEV; | ||
820 | } | 871 | } |
821 | } | 872 | } |
822 | return -ENODEV; | 873 | return -ENODEV; |
@@ -828,26 +879,27 @@ static int check_input_term(struct mixer_build *state, int id, | |||
828 | 879 | ||
829 | /* feature unit control information */ | 880 | /* feature unit control information */ |
830 | struct usb_feature_control_info { | 881 | struct usb_feature_control_info { |
882 | int control; | ||
831 | const char *name; | 883 | const char *name; |
832 | int type; /* data type for uac1 */ | 884 | int type; /* data type for uac1 */ |
833 | int type_uac2; /* data type for uac2 if different from uac1, else -1 */ | 885 | int type_uac2; /* data type for uac2 if different from uac1, else -1 */ |
834 | }; | 886 | }; |
835 | 887 | ||
836 | static struct usb_feature_control_info audio_feature_info[] = { | 888 | static struct usb_feature_control_info audio_feature_info[] = { |
837 | { "Mute", USB_MIXER_INV_BOOLEAN, -1 }, | 889 | { UAC_FU_MUTE, "Mute", USB_MIXER_INV_BOOLEAN, -1 }, |
838 | { "Volume", USB_MIXER_S16, -1 }, | 890 | { UAC_FU_VOLUME, "Volume", USB_MIXER_S16, -1 }, |
839 | { "Tone Control - Bass", USB_MIXER_S8, -1 }, | 891 | { UAC_FU_BASS, "Tone Control - Bass", USB_MIXER_S8, -1 }, |
840 | { "Tone Control - Mid", USB_MIXER_S8, -1 }, | 892 | { UAC_FU_MID, "Tone Control - Mid", USB_MIXER_S8, -1 }, |
841 | { "Tone Control - Treble", USB_MIXER_S8, -1 }, | 893 | { UAC_FU_TREBLE, "Tone Control - Treble", USB_MIXER_S8, -1 }, |
842 | { "Graphic Equalizer", USB_MIXER_S8, -1 }, /* FIXME: not implemeted yet */ | 894 | { UAC_FU_GRAPHIC_EQUALIZER, "Graphic Equalizer", USB_MIXER_S8, -1 }, /* FIXME: not implemented yet */ |
843 | { "Auto Gain Control", USB_MIXER_BOOLEAN, -1 }, | 895 | { UAC_FU_AUTOMATIC_GAIN, "Auto Gain Control", USB_MIXER_BOOLEAN, -1 }, |
844 | { "Delay Control", USB_MIXER_U16, USB_MIXER_U32 }, | 896 | { UAC_FU_DELAY, "Delay Control", USB_MIXER_U16, USB_MIXER_U32 }, |
845 | { "Bass Boost", USB_MIXER_BOOLEAN, -1 }, | 897 | { UAC_FU_BASS_BOOST, "Bass Boost", USB_MIXER_BOOLEAN, -1 }, |
846 | { "Loudness", USB_MIXER_BOOLEAN, -1 }, | 898 | { UAC_FU_LOUDNESS, "Loudness", USB_MIXER_BOOLEAN, -1 }, |
847 | /* UAC2 specific */ | 899 | /* UAC2 specific */ |
848 | { "Input Gain Control", USB_MIXER_S16, -1 }, | 900 | { UAC2_FU_INPUT_GAIN, "Input Gain Control", USB_MIXER_S16, -1 }, |
849 | { "Input Gain Pad Control", USB_MIXER_S16, -1 }, | 901 | { UAC2_FU_INPUT_GAIN_PAD, "Input Gain Pad Control", USB_MIXER_S16, -1 }, |
850 | { "Phase Inverter Control", USB_MIXER_BOOLEAN, -1 }, | 902 | { UAC2_FU_PHASE_INVERTER, "Phase Inverter Control", USB_MIXER_BOOLEAN, -1 }, |
851 | }; | 903 | }; |
852 | 904 | ||
853 | /* private_free callback */ | 905 | /* private_free callback */ |
@@ -1183,6 +1235,21 @@ static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, | |||
1183 | return changed; | 1235 | return changed; |
1184 | } | 1236 | } |
1185 | 1237 | ||
1238 | /* get the boolean value from the master channel of a UAC control */ | ||
1239 | static int mixer_ctl_master_bool_get(struct snd_kcontrol *kcontrol, | ||
1240 | struct snd_ctl_elem_value *ucontrol) | ||
1241 | { | ||
1242 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | ||
1243 | int val, err; | ||
1244 | |||
1245 | err = snd_usb_get_cur_mix_value(cval, 0, 0, &val); | ||
1246 | if (err < 0) | ||
1247 | return filter_error(cval, err); | ||
1248 | val = (val != 0); | ||
1249 | ucontrol->value.integer.value[0] = val; | ||
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1186 | static struct snd_kcontrol_new usb_feature_unit_ctl = { | 1253 | static struct snd_kcontrol_new usb_feature_unit_ctl = { |
1187 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1254 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1188 | .name = "", /* will be filled later manually */ | 1255 | .name = "", /* will be filled later manually */ |
@@ -1201,6 +1268,19 @@ static const struct snd_kcontrol_new usb_feature_unit_ctl_ro = { | |||
1201 | }; | 1268 | }; |
1202 | 1269 | ||
1203 | /* | 1270 | /* |
1271 | * A control which shows the boolean value from reading a UAC control on | ||
1272 | * the master channel. | ||
1273 | */ | ||
1274 | static struct snd_kcontrol_new usb_bool_master_control_ctl_ro = { | ||
1275 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, | ||
1276 | .name = "", /* will be filled later manually */ | ||
1277 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | ||
1278 | .info = snd_ctl_boolean_mono_info, | ||
1279 | .get = mixer_ctl_master_bool_get, | ||
1280 | .put = NULL, | ||
1281 | }; | ||
1282 | |||
1283 | /* | ||
1204 | * This symbol is exported in order to allow the mixer quirks to | 1284 | * This symbol is exported in order to allow the mixer quirks to |
1205 | * hook up to the standard feature unit control mechanism | 1285 | * hook up to the standard feature unit control mechanism |
1206 | */ | 1286 | */ |
@@ -1242,6 +1322,17 @@ static void check_no_speaker_on_headset(struct snd_kcontrol *kctl, | |||
1242 | strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name)); | 1322 | strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name)); |
1243 | } | 1323 | } |
1244 | 1324 | ||
1325 | static struct usb_feature_control_info *get_feature_control_info(int control) | ||
1326 | { | ||
1327 | int i; | ||
1328 | |||
1329 | for (i = 0; i < ARRAY_SIZE(audio_feature_info); ++i) { | ||
1330 | if (audio_feature_info[i].control == control) | ||
1331 | return &audio_feature_info[i]; | ||
1332 | } | ||
1333 | return NULL; | ||
1334 | } | ||
1335 | |||
1245 | static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | 1336 | static void build_feature_ctl(struct mixer_build *state, void *raw_desc, |
1246 | unsigned int ctl_mask, int control, | 1337 | unsigned int ctl_mask, int control, |
1247 | struct usb_audio_term *iterm, int unitid, | 1338 | struct usb_audio_term *iterm, int unitid, |
@@ -1257,8 +1348,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1257 | const struct usbmix_name_map *map; | 1348 | const struct usbmix_name_map *map; |
1258 | unsigned int range; | 1349 | unsigned int range; |
1259 | 1350 | ||
1260 | control++; /* change from zero-based to 1-based value */ | ||
1261 | |||
1262 | if (control == UAC_FU_GRAPHIC_EQUALIZER) { | 1351 | if (control == UAC_FU_GRAPHIC_EQUALIZER) { |
1263 | /* FIXME: not supported yet */ | 1352 | /* FIXME: not supported yet */ |
1264 | return; | 1353 | return; |
@@ -1274,7 +1363,12 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1274 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); | 1363 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); |
1275 | cval->control = control; | 1364 | cval->control = control; |
1276 | cval->cmask = ctl_mask; | 1365 | cval->cmask = ctl_mask; |
1277 | ctl_info = &audio_feature_info[control-1]; | 1366 | |
1367 | ctl_info = get_feature_control_info(control); | ||
1368 | if (!ctl_info) { | ||
1369 | kfree(cval); | ||
1370 | return; | ||
1371 | } | ||
1278 | if (state->mixer->protocol == UAC_VERSION_1) | 1372 | if (state->mixer->protocol == UAC_VERSION_1) |
1279 | cval->val_type = ctl_info->type; | 1373 | cval->val_type = ctl_info->type; |
1280 | else /* UAC_VERSION_2 */ | 1374 | else /* UAC_VERSION_2 */ |
@@ -1400,6 +1494,60 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1400 | snd_usb_mixer_add_control(&cval->head, kctl); | 1494 | snd_usb_mixer_add_control(&cval->head, kctl); |
1401 | } | 1495 | } |
1402 | 1496 | ||
1497 | static void get_connector_control_name(struct mixer_build *state, | ||
1498 | struct usb_audio_term *term, | ||
1499 | bool is_input, char *name, int name_size) | ||
1500 | { | ||
1501 | int name_len = get_term_name(state, term, name, name_size, 0); | ||
1502 | |||
1503 | if (name_len == 0) | ||
1504 | strlcpy(name, "Unknown", name_size); | ||
1505 | |||
1506 | /* | ||
1507 | * sound/core/ctljack.c has a convention of naming jack controls | ||
1508 | * by ending in " Jack". Make it slightly more useful by | ||
1509 | * indicating Input or Output after the terminal name. | ||
1510 | */ | ||
1511 | if (is_input) | ||
1512 | strlcat(name, " - Input Jack", name_size); | ||
1513 | else | ||
1514 | strlcat(name, " - Output Jack", name_size); | ||
1515 | } | ||
1516 | |||
1517 | /* Build a mixer control for a UAC connector control (jack-detect) */ | ||
1518 | static void build_connector_control(struct mixer_build *state, | ||
1519 | struct usb_audio_term *term, bool is_input) | ||
1520 | { | ||
1521 | struct snd_kcontrol *kctl; | ||
1522 | struct usb_mixer_elem_info *cval; | ||
1523 | |||
1524 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | ||
1525 | if (!cval) | ||
1526 | return; | ||
1527 | snd_usb_mixer_elem_init_std(&cval->head, state->mixer, term->id); | ||
1528 | /* | ||
1529 | * The first byte from reading the UAC2_TE_CONNECTOR control returns the | ||
1530 | * number of channels connected. This boolean ctl will simply report | ||
1531 | * if any channels are connected or not. | ||
1532 | * (Audio20_final.pdf Table 5-10: Connector Control CUR Parameter Block) | ||
1533 | */ | ||
1534 | cval->control = UAC2_TE_CONNECTOR; | ||
1535 | cval->val_type = USB_MIXER_BOOLEAN; | ||
1536 | cval->channels = 1; /* report true if any channel is connected */ | ||
1537 | cval->min = 0; | ||
1538 | cval->max = 1; | ||
1539 | kctl = snd_ctl_new1(&usb_bool_master_control_ctl_ro, cval); | ||
1540 | if (!kctl) { | ||
1541 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); | ||
1542 | kfree(cval); | ||
1543 | return; | ||
1544 | } | ||
1545 | get_connector_control_name(state, term, is_input, kctl->id.name, | ||
1546 | sizeof(kctl->id.name)); | ||
1547 | kctl->private_free = snd_usb_mixer_elem_free; | ||
1548 | snd_usb_mixer_add_control(&cval->head, kctl); | ||
1549 | } | ||
1550 | |||
1403 | static int parse_clock_source_unit(struct mixer_build *state, int unitid, | 1551 | static int parse_clock_source_unit(struct mixer_build *state, int unitid, |
1404 | void *_ftr) | 1552 | void *_ftr) |
1405 | { | 1553 | { |
@@ -1423,8 +1571,8 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid, | |||
1423 | * The only property of this unit we are interested in is the | 1571 | * The only property of this unit we are interested in is the |
1424 | * clock source validity. If that isn't readable, just bail out. | 1572 | * clock source validity. If that isn't readable, just bail out. |
1425 | */ | 1573 | */ |
1426 | if (!uac2_control_is_readable(hdr->bmControls, | 1574 | if (!uac_v2v3_control_is_readable(hdr->bmControls, |
1427 | ilog2(UAC2_CS_CONTROL_CLOCK_VALID))) | 1575 | UAC2_CS_CONTROL_CLOCK_VALID)) |
1428 | return 0; | 1576 | return 0; |
1429 | 1577 | ||
1430 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1578 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
@@ -1439,13 +1587,9 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid, | |||
1439 | cval->val_type = USB_MIXER_BOOLEAN; | 1587 | cval->val_type = USB_MIXER_BOOLEAN; |
1440 | cval->control = UAC2_CS_CONTROL_CLOCK_VALID; | 1588 | cval->control = UAC2_CS_CONTROL_CLOCK_VALID; |
1441 | 1589 | ||
1442 | if (uac2_control_is_writeable(hdr->bmControls, | 1590 | cval->master_readonly = 1; |
1443 | ilog2(UAC2_CS_CONTROL_CLOCK_VALID))) | 1591 | /* From UAC2 5.2.5.1.2 "Only the get request is supported." */ |
1444 | kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); | 1592 | kctl = snd_ctl_new1(&usb_bool_master_control_ctl_ro, cval); |
1445 | else { | ||
1446 | cval->master_readonly = 1; | ||
1447 | kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval); | ||
1448 | } | ||
1449 | 1593 | ||
1450 | if (!kctl) { | 1594 | if (!kctl) { |
1451 | kfree(cval); | 1595 | kfree(cval); |
@@ -1502,7 +1646,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1502 | unitid); | 1646 | unitid); |
1503 | return -EINVAL; | 1647 | return -EINVAL; |
1504 | } | 1648 | } |
1505 | } else { | 1649 | } else if (state->mixer->protocol == UAC_VERSION_2) { |
1506 | struct uac2_feature_unit_descriptor *ftr = _ftr; | 1650 | struct uac2_feature_unit_descriptor *ftr = _ftr; |
1507 | if (hdr->bLength < 6) { | 1651 | if (hdr->bLength < 6) { |
1508 | usb_audio_err(state->chip, | 1652 | usb_audio_err(state->chip, |
@@ -1519,6 +1663,24 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1519 | unitid); | 1663 | unitid); |
1520 | return -EINVAL; | 1664 | return -EINVAL; |
1521 | } | 1665 | } |
1666 | } else { /* UAC_VERSION_3 */ | ||
1667 | struct uac3_feature_unit_descriptor *ftr = _ftr; | ||
1668 | |||
1669 | if (hdr->bLength < 7) { | ||
1670 | usb_audio_err(state->chip, | ||
1671 | "unit %u: invalid UAC3_FEATURE_UNIT descriptor\n", | ||
1672 | unitid); | ||
1673 | return -EINVAL; | ||
1674 | } | ||
1675 | csize = 4; | ||
1676 | channels = (ftr->bLength - 7) / 4 - 1; | ||
1677 | bmaControls = ftr->bmaControls; | ||
1678 | if (hdr->bLength < 7 + csize) { | ||
1679 | usb_audio_err(state->chip, | ||
1680 | "unit %u: invalid UAC3_FEATURE_UNIT descriptor\n", | ||
1681 | unitid); | ||
1682 | return -EINVAL; | ||
1683 | } | ||
1522 | } | 1684 | } |
1523 | 1685 | ||
1524 | /* parse the source unit */ | 1686 | /* parse the source unit */ |
@@ -1556,6 +1718,8 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1556 | /* check all control types */ | 1718 | /* check all control types */ |
1557 | for (i = 0; i < 10; i++) { | 1719 | for (i = 0; i < 10; i++) { |
1558 | unsigned int ch_bits = 0; | 1720 | unsigned int ch_bits = 0; |
1721 | int control = audio_feature_info[i].control; | ||
1722 | |||
1559 | for (j = 0; j < channels; j++) { | 1723 | for (j = 0; j < channels; j++) { |
1560 | unsigned int mask; | 1724 | unsigned int mask; |
1561 | 1725 | ||
@@ -1571,25 +1735,26 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1571 | * (for ease of programming). | 1735 | * (for ease of programming). |
1572 | */ | 1736 | */ |
1573 | if (ch_bits & 1) | 1737 | if (ch_bits & 1) |
1574 | build_feature_ctl(state, _ftr, ch_bits, i, | 1738 | build_feature_ctl(state, _ftr, ch_bits, control, |
1575 | &iterm, unitid, 0); | 1739 | &iterm, unitid, 0); |
1576 | if (master_bits & (1 << i)) | 1740 | if (master_bits & (1 << i)) |
1577 | build_feature_ctl(state, _ftr, 0, i, &iterm, | 1741 | build_feature_ctl(state, _ftr, 0, control, |
1578 | unitid, 0); | 1742 | &iterm, unitid, 0); |
1579 | } | 1743 | } |
1580 | } else { /* UAC_VERSION_2 */ | 1744 | } else { /* UAC_VERSION_2/3 */ |
1581 | for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) { | 1745 | for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) { |
1582 | unsigned int ch_bits = 0; | 1746 | unsigned int ch_bits = 0; |
1583 | unsigned int ch_read_only = 0; | 1747 | unsigned int ch_read_only = 0; |
1748 | int control = audio_feature_info[i].control; | ||
1584 | 1749 | ||
1585 | for (j = 0; j < channels; j++) { | 1750 | for (j = 0; j < channels; j++) { |
1586 | unsigned int mask; | 1751 | unsigned int mask; |
1587 | 1752 | ||
1588 | mask = snd_usb_combine_bytes(bmaControls + | 1753 | mask = snd_usb_combine_bytes(bmaControls + |
1589 | csize * (j+1), csize); | 1754 | csize * (j+1), csize); |
1590 | if (uac2_control_is_readable(mask, i)) { | 1755 | if (uac_v2v3_control_is_readable(mask, control)) { |
1591 | ch_bits |= (1 << j); | 1756 | ch_bits |= (1 << j); |
1592 | if (!uac2_control_is_writeable(mask, i)) | 1757 | if (!uac_v2v3_control_is_writeable(mask, control)) |
1593 | ch_read_only |= (1 << j); | 1758 | ch_read_only |= (1 << j); |
1594 | } | 1759 | } |
1595 | } | 1760 | } |
@@ -1608,11 +1773,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1608 | * (for ease of programming). | 1773 | * (for ease of programming). |
1609 | */ | 1774 | */ |
1610 | if (ch_bits & 1) | 1775 | if (ch_bits & 1) |
1611 | build_feature_ctl(state, _ftr, ch_bits, i, | 1776 | build_feature_ctl(state, _ftr, ch_bits, control, |
1612 | &iterm, unitid, ch_read_only); | 1777 | &iterm, unitid, ch_read_only); |
1613 | if (uac2_control_is_readable(master_bits, i)) | 1778 | if (uac_v2v3_control_is_readable(master_bits, control)) |
1614 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, | 1779 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, |
1615 | !uac2_control_is_writeable(master_bits, i)); | 1780 | !uac_v2v3_control_is_writeable(master_bits, |
1781 | control)); | ||
1616 | } | 1782 | } |
1617 | } | 1783 | } |
1618 | 1784 | ||
@@ -1684,6 +1850,23 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1684 | snd_usb_mixer_add_control(&cval->head, kctl); | 1850 | snd_usb_mixer_add_control(&cval->head, kctl); |
1685 | } | 1851 | } |
1686 | 1852 | ||
1853 | static int parse_audio_input_terminal(struct mixer_build *state, int unitid, | ||
1854 | void *raw_desc) | ||
1855 | { | ||
1856 | struct usb_audio_term iterm; | ||
1857 | struct uac2_input_terminal_descriptor *d = raw_desc; | ||
1858 | |||
1859 | check_input_term(state, d->bTerminalID, &iterm); | ||
1860 | if (state->mixer->protocol == UAC_VERSION_2) { | ||
1861 | /* Check for jack detection. */ | ||
1862 | if (uac_v2v3_control_is_readable(d->bmControls, | ||
1863 | UAC2_TE_CONNECTOR)) { | ||
1864 | build_connector_control(state, &iterm, true); | ||
1865 | } | ||
1866 | } | ||
1867 | return 0; | ||
1868 | } | ||
1869 | |||
1687 | /* | 1870 | /* |
1688 | * parse a mixer unit | 1871 | * parse a mixer unit |
1689 | */ | 1872 | */ |
@@ -2220,6 +2403,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, | |||
2220 | static int parse_audio_unit(struct mixer_build *state, int unitid) | 2403 | static int parse_audio_unit(struct mixer_build *state, int unitid) |
2221 | { | 2404 | { |
2222 | unsigned char *p1; | 2405 | unsigned char *p1; |
2406 | int protocol = state->mixer->protocol; | ||
2223 | 2407 | ||
2224 | if (test_and_set_bit(unitid, state->unitbitmap)) | 2408 | if (test_and_set_bit(unitid, state->unitbitmap)) |
2225 | return 0; /* the unit already visited */ | 2409 | return 0; /* the unit already visited */ |
@@ -2230,36 +2414,61 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) | |||
2230 | return -EINVAL; | 2414 | return -EINVAL; |
2231 | } | 2415 | } |
2232 | 2416 | ||
2233 | switch (p1[2]) { | 2417 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { |
2234 | case UAC_INPUT_TERMINAL: | 2418 | switch (p1[2]) { |
2235 | return 0; /* NOP */ | 2419 | case UAC_INPUT_TERMINAL: |
2236 | case UAC_MIXER_UNIT: | 2420 | return parse_audio_input_terminal(state, unitid, p1); |
2237 | return parse_audio_mixer_unit(state, unitid, p1); | 2421 | case UAC_MIXER_UNIT: |
2238 | case UAC2_CLOCK_SOURCE: | 2422 | return parse_audio_mixer_unit(state, unitid, p1); |
2239 | return parse_clock_source_unit(state, unitid, p1); | 2423 | case UAC2_CLOCK_SOURCE: |
2240 | case UAC_SELECTOR_UNIT: | 2424 | return parse_clock_source_unit(state, unitid, p1); |
2241 | case UAC2_CLOCK_SELECTOR: | 2425 | case UAC_SELECTOR_UNIT: |
2242 | return parse_audio_selector_unit(state, unitid, p1); | 2426 | case UAC2_CLOCK_SELECTOR: |
2243 | case UAC_FEATURE_UNIT: | 2427 | return parse_audio_selector_unit(state, unitid, p1); |
2244 | return parse_audio_feature_unit(state, unitid, p1); | 2428 | case UAC_FEATURE_UNIT: |
2245 | case UAC1_PROCESSING_UNIT: | 2429 | return parse_audio_feature_unit(state, unitid, p1); |
2246 | /* UAC2_EFFECT_UNIT has the same value */ | 2430 | case UAC1_PROCESSING_UNIT: |
2247 | if (state->mixer->protocol == UAC_VERSION_1) | 2431 | /* UAC2_EFFECT_UNIT has the same value */ |
2248 | return parse_audio_processing_unit(state, unitid, p1); | 2432 | if (protocol == UAC_VERSION_1) |
2249 | else | 2433 | return parse_audio_processing_unit(state, unitid, p1); |
2250 | return 0; /* FIXME - effect units not implemented yet */ | 2434 | else |
2251 | case UAC1_EXTENSION_UNIT: | 2435 | return 0; /* FIXME - effect units not implemented yet */ |
2252 | /* UAC2_PROCESSING_UNIT_V2 has the same value */ | 2436 | case UAC1_EXTENSION_UNIT: |
2253 | if (state->mixer->protocol == UAC_VERSION_1) | 2437 | /* UAC2_PROCESSING_UNIT_V2 has the same value */ |
2438 | if (protocol == UAC_VERSION_1) | ||
2439 | return parse_audio_extension_unit(state, unitid, p1); | ||
2440 | else /* UAC_VERSION_2 */ | ||
2441 | return parse_audio_processing_unit(state, unitid, p1); | ||
2442 | case UAC2_EXTENSION_UNIT_V2: | ||
2254 | return parse_audio_extension_unit(state, unitid, p1); | 2443 | return parse_audio_extension_unit(state, unitid, p1); |
2255 | else /* UAC_VERSION_2 */ | 2444 | default: |
2445 | usb_audio_err(state->chip, | ||
2446 | "unit %u: unexpected type 0x%02x\n", unitid, p1[2]); | ||
2447 | return -EINVAL; | ||
2448 | } | ||
2449 | } else { /* UAC_VERSION_3 */ | ||
2450 | switch (p1[2]) { | ||
2451 | case UAC_INPUT_TERMINAL: | ||
2452 | return 0; /* NOP */ | ||
2453 | case UAC3_MIXER_UNIT: | ||
2454 | return parse_audio_mixer_unit(state, unitid, p1); | ||
2455 | case UAC3_CLOCK_SOURCE: | ||
2456 | return parse_clock_source_unit(state, unitid, p1); | ||
2457 | case UAC3_CLOCK_SELECTOR: | ||
2458 | return parse_audio_selector_unit(state, unitid, p1); | ||
2459 | case UAC3_FEATURE_UNIT: | ||
2460 | return parse_audio_feature_unit(state, unitid, p1); | ||
2461 | case UAC3_EFFECT_UNIT: | ||
2462 | return 0; /* FIXME - effect units not implemented yet */ | ||
2463 | case UAC3_PROCESSING_UNIT: | ||
2256 | return parse_audio_processing_unit(state, unitid, p1); | 2464 | return parse_audio_processing_unit(state, unitid, p1); |
2257 | case UAC2_EXTENSION_UNIT_V2: | 2465 | case UAC3_EXTENSION_UNIT: |
2258 | return parse_audio_extension_unit(state, unitid, p1); | 2466 | return parse_audio_extension_unit(state, unitid, p1); |
2259 | default: | 2467 | default: |
2260 | usb_audio_err(state->chip, | 2468 | usb_audio_err(state->chip, |
2261 | "unit %u: unexpected type 0x%02x\n", unitid, p1[2]); | 2469 | "unit %u: unexpected type 0x%02x\n", unitid, p1[2]); |
2262 | return -EINVAL; | 2470 | return -EINVAL; |
2471 | } | ||
2263 | } | 2472 | } |
2264 | } | 2473 | } |
2265 | 2474 | ||
@@ -2330,7 +2539,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
2330 | err = parse_audio_unit(&state, desc->bSourceID); | 2539 | err = parse_audio_unit(&state, desc->bSourceID); |
2331 | if (err < 0 && err != -EINVAL) | 2540 | if (err < 0 && err != -EINVAL) |
2332 | return err; | 2541 | return err; |
2333 | } else { /* UAC_VERSION_2 */ | 2542 | } else if (mixer->protocol == UAC_VERSION_2) { |
2334 | struct uac2_output_terminal_descriptor *desc = p; | 2543 | struct uac2_output_terminal_descriptor *desc = p; |
2335 | 2544 | ||
2336 | if (desc->bLength < sizeof(*desc)) | 2545 | if (desc->bLength < sizeof(*desc)) |
@@ -2351,6 +2560,33 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
2351 | err = parse_audio_unit(&state, desc->bCSourceID); | 2560 | err = parse_audio_unit(&state, desc->bCSourceID); |
2352 | if (err < 0 && err != -EINVAL) | 2561 | if (err < 0 && err != -EINVAL) |
2353 | return err; | 2562 | return err; |
2563 | |||
2564 | if (uac_v2v3_control_is_readable(desc->bmControls, | ||
2565 | UAC2_TE_CONNECTOR)) { | ||
2566 | build_connector_control(&state, &state.oterm, | ||
2567 | false); | ||
2568 | } | ||
2569 | } else { /* UAC_VERSION_3 */ | ||
2570 | struct uac3_output_terminal_descriptor *desc = p; | ||
2571 | |||
2572 | if (desc->bLength < sizeof(*desc)) | ||
2573 | continue; /* invalid descriptor? */ | ||
2574 | /* mark terminal ID as visited */ | ||
2575 | set_bit(desc->bTerminalID, state.unitbitmap); | ||
2576 | state.oterm.id = desc->bTerminalID; | ||
2577 | state.oterm.type = le16_to_cpu(desc->wTerminalType); | ||
2578 | state.oterm.name = le16_to_cpu(desc->wTerminalDescrStr); | ||
2579 | err = parse_audio_unit(&state, desc->bSourceID); | ||
2580 | if (err < 0 && err != -EINVAL) | ||
2581 | return err; | ||
2582 | |||
2583 | /* | ||
2584 | * For UAC3, use the same approach to also add the | ||
2585 | * clock selectors | ||
2586 | */ | ||
2587 | err = parse_audio_unit(&state, desc->bCSourceID); | ||
2588 | if (err < 0 && err != -EINVAL) | ||
2589 | return err; | ||
2354 | } | 2590 | } |
2355 | } | 2591 | } |
2356 | 2592 | ||
@@ -2597,6 +2833,9 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | |||
2597 | case UAC_VERSION_2: | 2833 | case UAC_VERSION_2: |
2598 | mixer->protocol = UAC_VERSION_2; | 2834 | mixer->protocol = UAC_VERSION_2; |
2599 | break; | 2835 | break; |
2836 | case UAC_VERSION_3: | ||
2837 | mixer->protocol = UAC_VERSION_3; | ||
2838 | break; | ||
2600 | } | 2839 | } |
2601 | 2840 | ||
2602 | if ((err = snd_usb_mixer_controls(mixer)) < 0 || | 2841 | if ((err = snd_usb_mixer_controls(mixer)) < 0 || |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 794224e1d6df..acbeb52f6fd6 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -1149,27 +1149,17 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) | |||
1149 | return false; | 1149 | return false; |
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | /* Marantz/Denon USB DACs need a vendor cmd to switch | 1152 | /* ITF-USB DSD based DACs need a vendor cmd to switch |
1153 | * between PCM and native DSD mode | 1153 | * between PCM and native DSD mode |
1154 | */ | 1154 | */ |
1155 | static bool is_marantz_denon_dac(unsigned int id) | 1155 | static bool is_itf_usb_dsd_dac(unsigned int id) |
1156 | { | 1156 | { |
1157 | switch (id) { | 1157 | switch (id) { |
1158 | case USB_ID(0x154e, 0x1003): /* Denon DA-300USB */ | 1158 | case USB_ID(0x154e, 0x1003): /* Denon DA-300USB */ |
1159 | case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ | 1159 | case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ |
1160 | case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ | 1160 | case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ |
1161 | return true; | 1161 | case USB_ID(0x1852, 0x5065): /* Luxman DA-06 */ |
1162 | } | 1162 | case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-501V2/UD-503/NT-503 */ |
1163 | return false; | ||
1164 | } | ||
1165 | |||
1166 | /* TEAC UD-501/UD-503/NT-503 USB DACs need a vendor cmd to switch | ||
1167 | * between PCM/DOP and native DSD mode | ||
1168 | */ | ||
1169 | static bool is_teac_dsd_dac(unsigned int id) | ||
1170 | { | ||
1171 | switch (id) { | ||
1172 | case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */ | ||
1173 | case USB_ID(0x0644, 0x8044): /* Esoteric D-05X */ | 1163 | case USB_ID(0x0644, 0x8044): /* Esoteric D-05X */ |
1174 | case USB_ID(0x0644, 0x804a): /* TEAC UD-301 */ | 1164 | case USB_ID(0x0644, 0x804a): /* TEAC UD-301 */ |
1175 | return true; | 1165 | return true; |
@@ -1183,7 +1173,7 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, | |||
1183 | struct usb_device *dev = subs->dev; | 1173 | struct usb_device *dev = subs->dev; |
1184 | int err; | 1174 | int err; |
1185 | 1175 | ||
1186 | if (is_marantz_denon_dac(subs->stream->chip->usb_id)) { | 1176 | if (is_itf_usb_dsd_dac(subs->stream->chip->usb_id)) { |
1187 | /* First switch to alt set 0, otherwise the mode switch cmd | 1177 | /* First switch to alt set 0, otherwise the mode switch cmd |
1188 | * will not be accepted by the DAC | 1178 | * will not be accepted by the DAC |
1189 | */ | 1179 | */ |
@@ -1193,37 +1183,26 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, | |||
1193 | 1183 | ||
1194 | mdelay(20); /* Delay needed after setting the interface */ | 1184 | mdelay(20); /* Delay needed after setting the interface */ |
1195 | 1185 | ||
1196 | switch (fmt->altsetting) { | ||
1197 | case 2: /* DSD mode requested */ | ||
1198 | case 1: /* PCM mode requested */ | ||
1199 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, | ||
1200 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, | ||
1201 | fmt->altsetting - 1, 1, NULL, 0); | ||
1202 | if (err < 0) | ||
1203 | return err; | ||
1204 | break; | ||
1205 | } | ||
1206 | mdelay(20); | ||
1207 | } else if (is_teac_dsd_dac(subs->stream->chip->usb_id)) { | ||
1208 | /* Vendor mode switch cmd is required. */ | 1186 | /* Vendor mode switch cmd is required. */ |
1209 | switch (fmt->altsetting) { | 1187 | if (fmt->formats & SNDRV_PCM_FMTBIT_DSD_U32_BE) { |
1210 | case 3: /* DSD mode (DSD_U32) requested */ | 1188 | /* DSD mode (DSD_U32) requested */ |
1211 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, | 1189 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, |
1212 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, | 1190 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, |
1213 | 1, 1, NULL, 0); | 1191 | 1, 1, NULL, 0); |
1214 | if (err < 0) | 1192 | if (err < 0) |
1215 | return err; | 1193 | return err; |
1216 | break; | ||
1217 | 1194 | ||
1218 | case 2: /* PCM or DOP mode (S32) requested */ | 1195 | } else { |
1219 | case 1: /* PCM mode (S16) requested */ | 1196 | /* PCM or DOP mode (S32) requested */ |
1197 | /* PCM mode (S16) requested */ | ||
1220 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, | 1198 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, |
1221 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, | 1199 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, |
1222 | 0, 1, NULL, 0); | 1200 | 0, 1, NULL, 0); |
1223 | if (err < 0) | 1201 | if (err < 0) |
1224 | return err; | 1202 | return err; |
1225 | break; | 1203 | |
1226 | } | 1204 | } |
1205 | mdelay(20); | ||
1227 | } | 1206 | } |
1228 | return 0; | 1207 | return 0; |
1229 | } | 1208 | } |
@@ -1300,10 +1279,10 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, | |||
1300 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) | 1279 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) |
1301 | mdelay(20); | 1280 | mdelay(20); |
1302 | 1281 | ||
1303 | /* Marantz/Denon devices with USB DAC functionality need a delay | 1282 | /* ITF-USB DSD based DACs functionality need a delay |
1304 | * after each class compliant request | 1283 | * after each class compliant request |
1305 | */ | 1284 | */ |
1306 | if (is_marantz_denon_dac(chip->usb_id) | 1285 | if (is_itf_usb_dsd_dac(chip->usb_id) |
1307 | && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) | 1286 | && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) |
1308 | mdelay(20); | 1287 | mdelay(20); |
1309 | 1288 | ||
@@ -1329,6 +1308,8 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, | |||
1329 | struct audioformat *fp, | 1308 | struct audioformat *fp, |
1330 | unsigned int sample_bytes) | 1309 | unsigned int sample_bytes) |
1331 | { | 1310 | { |
1311 | struct usb_interface *iface; | ||
1312 | |||
1332 | /* Playback Designs */ | 1313 | /* Playback Designs */ |
1333 | if (USB_ID_VENDOR(chip->usb_id) == 0x23ba) { | 1314 | if (USB_ID_VENDOR(chip->usb_id) == 0x23ba) { |
1334 | switch (fp->altsetting) { | 1315 | switch (fp->altsetting) { |
@@ -1390,17 +1371,52 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, | |||
1390 | break; | 1371 | break; |
1391 | } | 1372 | } |
1392 | 1373 | ||
1393 | /* Denon/Marantz devices with USB DAC functionality */ | 1374 | /* ITF-USB DSD based DACs */ |
1394 | if (is_marantz_denon_dac(chip->usb_id)) { | 1375 | if (is_itf_usb_dsd_dac(chip->usb_id)) { |
1395 | if (fp->altsetting == 2) | 1376 | iface = usb_ifnum_to_if(chip->dev, fp->iface); |
1396 | return SNDRV_PCM_FMTBIT_DSD_U32_BE; | ||
1397 | } | ||
1398 | 1377 | ||
1399 | /* TEAC devices with USB DAC functionality */ | 1378 | /* Altsetting 2 support native DSD if the num of altsets is |
1400 | if (is_teac_dsd_dac(chip->usb_id)) { | 1379 | * three (0-2), |
1401 | if (fp->altsetting == 3) | 1380 | * Altsetting 3 support native DSD if the num of altsets is |
1381 | * four (0-3). | ||
1382 | */ | ||
1383 | if (fp->altsetting == iface->num_altsetting - 1) | ||
1402 | return SNDRV_PCM_FMTBIT_DSD_U32_BE; | 1384 | return SNDRV_PCM_FMTBIT_DSD_U32_BE; |
1403 | } | 1385 | } |
1404 | 1386 | ||
1405 | return 0; | 1387 | return 0; |
1406 | } | 1388 | } |
1389 | |||
1390 | void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip, | ||
1391 | struct audioformat *fp, | ||
1392 | int stream) | ||
1393 | { | ||
1394 | switch (chip->usb_id) { | ||
1395 | case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */ | ||
1396 | /* Optoplay sets the sample rate attribute although | ||
1397 | * it seems not supporting it in fact. | ||
1398 | */ | ||
1399 | fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
1400 | break; | ||
1401 | case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ | ||
1402 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | ||
1403 | /* doesn't set the sample rate attribute, but supports it */ | ||
1404 | fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
1405 | break; | ||
1406 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */ | ||
1407 | case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ | ||
1408 | case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ | ||
1409 | case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is | ||
1410 | an older model 77d:223) */ | ||
1411 | /* | ||
1412 | * plantronics headset and Griffin iMic have set adaptive-in | ||
1413 | * although it's really not... | ||
1414 | */ | ||
1415 | fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE; | ||
1416 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
1417 | fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE; | ||
1418 | else | ||
1419 | fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC; | ||
1420 | break; | ||
1421 | } | ||
1422 | } | ||
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index b90c8b7caab5..a80e0ddd0736 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h | |||
@@ -42,4 +42,8 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, | |||
42 | struct audioformat *fp, | 42 | struct audioformat *fp, |
43 | unsigned int sample_bytes); | 43 | unsigned int sample_bytes); |
44 | 44 | ||
45 | void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip, | ||
46 | struct audioformat *fp, | ||
47 | int stream); | ||
48 | |||
45 | #endif /* __USBAUDIO_QUIRKS_H */ | 49 | #endif /* __USBAUDIO_QUIRKS_H */ |
diff --git a/sound/usb/stream.c b/sound/usb/stream.c index d1776e5517ff..6a8f5843334e 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
21 | #include <linux/usb/audio.h> | 21 | #include <linux/usb/audio.h> |
22 | #include <linux/usb/audio-v2.h> | 22 | #include <linux/usb/audio-v2.h> |
23 | #include <linux/usb/audio-v3.h> | ||
23 | 24 | ||
24 | #include <sound/core.h> | 25 | #include <sound/core.h> |
25 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
@@ -311,6 +312,153 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits, | |||
311 | return chmap; | 312 | return chmap; |
312 | } | 313 | } |
313 | 314 | ||
315 | /* UAC3 device stores channels information in Cluster Descriptors */ | ||
316 | static struct | ||
317 | snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor | ||
318 | *cluster) | ||
319 | { | ||
320 | unsigned int channels = cluster->bNrChannels; | ||
321 | struct snd_pcm_chmap_elem *chmap; | ||
322 | void *p = cluster; | ||
323 | int len, c; | ||
324 | |||
325 | if (channels > ARRAY_SIZE(chmap->map)) | ||
326 | return NULL; | ||
327 | |||
328 | chmap = kzalloc(sizeof(*chmap), GFP_KERNEL); | ||
329 | if (!chmap) | ||
330 | return NULL; | ||
331 | |||
332 | len = le16_to_cpu(cluster->wLength); | ||
333 | c = 0; | ||
334 | p += sizeof(struct uac3_cluster_header_descriptor); | ||
335 | |||
336 | while (((p - (void *)cluster) < len) && (c < channels)) { | ||
337 | struct uac3_cluster_segment_descriptor *cs_desc = p; | ||
338 | u16 cs_len; | ||
339 | u8 cs_type; | ||
340 | |||
341 | cs_len = le16_to_cpu(cs_desc->wLength); | ||
342 | cs_type = cs_desc->bSegmentType; | ||
343 | |||
344 | if (cs_type == UAC3_CHANNEL_INFORMATION) { | ||
345 | struct uac3_cluster_information_segment_descriptor *is = p; | ||
346 | unsigned char map; | ||
347 | |||
348 | /* | ||
349 | * TODO: this conversion is not complete, update it | ||
350 | * after adding UAC3 values to asound.h | ||
351 | */ | ||
352 | switch (is->bChPurpose) { | ||
353 | case UAC3_CH_MONO: | ||
354 | map = SNDRV_CHMAP_MONO; | ||
355 | break; | ||
356 | case UAC3_CH_LEFT: | ||
357 | case UAC3_CH_FRONT_LEFT: | ||
358 | case UAC3_CH_HEADPHONE_LEFT: | ||
359 | map = SNDRV_CHMAP_FL; | ||
360 | break; | ||
361 | case UAC3_CH_RIGHT: | ||
362 | case UAC3_CH_FRONT_RIGHT: | ||
363 | case UAC3_CH_HEADPHONE_RIGHT: | ||
364 | map = SNDRV_CHMAP_FR; | ||
365 | break; | ||
366 | case UAC3_CH_FRONT_CENTER: | ||
367 | map = SNDRV_CHMAP_FC; | ||
368 | break; | ||
369 | case UAC3_CH_FRONT_LEFT_OF_CENTER: | ||
370 | map = SNDRV_CHMAP_FLC; | ||
371 | break; | ||
372 | case UAC3_CH_FRONT_RIGHT_OF_CENTER: | ||
373 | map = SNDRV_CHMAP_FRC; | ||
374 | break; | ||
375 | case UAC3_CH_SIDE_LEFT: | ||
376 | map = SNDRV_CHMAP_SL; | ||
377 | break; | ||
378 | case UAC3_CH_SIDE_RIGHT: | ||
379 | map = SNDRV_CHMAP_SR; | ||
380 | break; | ||
381 | case UAC3_CH_BACK_LEFT: | ||
382 | map = SNDRV_CHMAP_RL; | ||
383 | break; | ||
384 | case UAC3_CH_BACK_RIGHT: | ||
385 | map = SNDRV_CHMAP_RR; | ||
386 | break; | ||
387 | case UAC3_CH_BACK_CENTER: | ||
388 | map = SNDRV_CHMAP_RC; | ||
389 | break; | ||
390 | case UAC3_CH_BACK_LEFT_OF_CENTER: | ||
391 | map = SNDRV_CHMAP_RLC; | ||
392 | break; | ||
393 | case UAC3_CH_BACK_RIGHT_OF_CENTER: | ||
394 | map = SNDRV_CHMAP_RRC; | ||
395 | break; | ||
396 | case UAC3_CH_TOP_CENTER: | ||
397 | map = SNDRV_CHMAP_TC; | ||
398 | break; | ||
399 | case UAC3_CH_TOP_FRONT_LEFT: | ||
400 | map = SNDRV_CHMAP_TFL; | ||
401 | break; | ||
402 | case UAC3_CH_TOP_FRONT_RIGHT: | ||
403 | map = SNDRV_CHMAP_TFR; | ||
404 | break; | ||
405 | case UAC3_CH_TOP_FRONT_CENTER: | ||
406 | map = SNDRV_CHMAP_TFC; | ||
407 | break; | ||
408 | case UAC3_CH_TOP_FRONT_LOC: | ||
409 | map = SNDRV_CHMAP_TFLC; | ||
410 | break; | ||
411 | case UAC3_CH_TOP_FRONT_ROC: | ||
412 | map = SNDRV_CHMAP_TFRC; | ||
413 | break; | ||
414 | case UAC3_CH_TOP_SIDE_LEFT: | ||
415 | map = SNDRV_CHMAP_TSL; | ||
416 | break; | ||
417 | case UAC3_CH_TOP_SIDE_RIGHT: | ||
418 | map = SNDRV_CHMAP_TSR; | ||
419 | break; | ||
420 | case UAC3_CH_TOP_BACK_LEFT: | ||
421 | map = SNDRV_CHMAP_TRL; | ||
422 | break; | ||
423 | case UAC3_CH_TOP_BACK_RIGHT: | ||
424 | map = SNDRV_CHMAP_TRR; | ||
425 | break; | ||
426 | case UAC3_CH_TOP_BACK_CENTER: | ||
427 | map = SNDRV_CHMAP_TRC; | ||
428 | break; | ||
429 | case UAC3_CH_BOTTOM_CENTER: | ||
430 | map = SNDRV_CHMAP_BC; | ||
431 | break; | ||
432 | case UAC3_CH_LOW_FREQUENCY_EFFECTS: | ||
433 | map = SNDRV_CHMAP_LFE; | ||
434 | break; | ||
435 | case UAC3_CH_LFE_LEFT: | ||
436 | map = SNDRV_CHMAP_LLFE; | ||
437 | break; | ||
438 | case UAC3_CH_LFE_RIGHT: | ||
439 | map = SNDRV_CHMAP_RLFE; | ||
440 | break; | ||
441 | case UAC3_CH_RELATIONSHIP_UNDEFINED: | ||
442 | default: | ||
443 | map = SNDRV_CHMAP_UNKNOWN; | ||
444 | break; | ||
445 | } | ||
446 | chmap->map[c++] = map; | ||
447 | } | ||
448 | p += cs_len; | ||
449 | } | ||
450 | |||
451 | if (channels < c) | ||
452 | pr_err("%s: channel number mismatch\n", __func__); | ||
453 | |||
454 | chmap->channels = channels; | ||
455 | |||
456 | for (; c < channels; c++) | ||
457 | chmap->map[c] = SNDRV_CHMAP_UNKNOWN; | ||
458 | |||
459 | return chmap; | ||
460 | } | ||
461 | |||
314 | /* | 462 | /* |
315 | * add this endpoint to the chip instance. | 463 | * add this endpoint to the chip instance. |
316 | * if a stream with the same endpoint already exists, append to it. | 464 | * if a stream with the same endpoint already exists, append to it. |
@@ -461,10 +609,11 @@ snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface, | |||
461 | return NULL; | 609 | return NULL; |
462 | } | 610 | } |
463 | 611 | ||
464 | static struct uac2_output_terminal_descriptor * | 612 | static void * |
465 | snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, | 613 | snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, |
466 | int terminal_id) | 614 | int terminal_id) |
467 | { | 615 | { |
616 | /* OK to use with both UAC2 and UAC3 */ | ||
468 | struct uac2_output_terminal_descriptor *term = NULL; | 617 | struct uac2_output_terminal_descriptor *term = NULL; |
469 | 618 | ||
470 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, | 619 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, |
@@ -484,10 +633,12 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
484 | struct usb_host_interface *alts; | 633 | struct usb_host_interface *alts; |
485 | struct usb_interface_descriptor *altsd; | 634 | struct usb_interface_descriptor *altsd; |
486 | int i, altno, err, stream; | 635 | int i, altno, err, stream; |
487 | unsigned int format = 0, num_channels = 0; | 636 | u64 format = 0; |
637 | unsigned int num_channels = 0; | ||
488 | struct audioformat *fp = NULL; | 638 | struct audioformat *fp = NULL; |
489 | int num, protocol, clock = 0; | 639 | int num, protocol, clock = 0; |
490 | struct uac_format_type_i_continuous_descriptor *fmt; | 640 | struct uac_format_type_i_continuous_descriptor *fmt = NULL; |
641 | struct snd_pcm_chmap_elem *chmap_v3 = NULL; | ||
491 | unsigned int chconfig; | 642 | unsigned int chconfig; |
492 | 643 | ||
493 | dev = chip->dev; | 644 | dev = chip->dev; |
@@ -624,38 +775,158 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
624 | iface_no, altno, as->bTerminalLink); | 775 | iface_no, altno, as->bTerminalLink); |
625 | continue; | 776 | continue; |
626 | } | 777 | } |
627 | } | ||
628 | 778 | ||
629 | /* get format type */ | 779 | case UAC_VERSION_3: { |
630 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE); | 780 | struct uac3_input_terminal_descriptor *input_term; |
631 | if (!fmt) { | 781 | struct uac3_output_terminal_descriptor *output_term; |
782 | struct uac3_as_header_descriptor *as; | ||
783 | struct uac3_cluster_header_descriptor *cluster; | ||
784 | struct uac3_hc_descriptor_header hc_header; | ||
785 | u16 cluster_id, wLength; | ||
786 | |||
787 | as = snd_usb_find_csint_desc(alts->extra, | ||
788 | alts->extralen, | ||
789 | NULL, UAC_AS_GENERAL); | ||
790 | |||
791 | if (!as) { | ||
792 | dev_err(&dev->dev, | ||
793 | "%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
794 | iface_no, altno); | ||
795 | continue; | ||
796 | } | ||
797 | |||
798 | if (as->bLength < sizeof(*as)) { | ||
799 | dev_err(&dev->dev, | ||
800 | "%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
801 | iface_no, altno); | ||
802 | continue; | ||
803 | } | ||
804 | |||
805 | cluster_id = le16_to_cpu(as->wClusterDescrID); | ||
806 | if (!cluster_id) { | ||
807 | dev_err(&dev->dev, | ||
808 | "%u:%d : no cluster descriptor\n", | ||
809 | iface_no, altno); | ||
810 | continue; | ||
811 | } | ||
812 | |||
813 | /* | ||
814 | * Get number of channels and channel map through | ||
815 | * High Capability Cluster Descriptor | ||
816 | * | ||
817 | * First step: get High Capability header and | ||
818 | * read size of Cluster Descriptor | ||
819 | */ | ||
820 | err = snd_usb_ctl_msg(chip->dev, | ||
821 | usb_rcvctrlpipe(chip->dev, 0), | ||
822 | UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, | ||
823 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
824 | cluster_id, | ||
825 | snd_usb_ctrl_intf(chip), | ||
826 | &hc_header, sizeof(hc_header)); | ||
827 | if (err < 0) | ||
828 | return err; | ||
829 | else if (err != sizeof(hc_header)) { | ||
830 | dev_err(&dev->dev, | ||
831 | "%u:%d : can't get High Capability descriptor\n", | ||
832 | iface_no, altno); | ||
833 | return -EIO; | ||
834 | } | ||
835 | |||
836 | /* | ||
837 | * Second step: allocate needed amount of memory | ||
838 | * and request Cluster Descriptor | ||
839 | */ | ||
840 | wLength = le16_to_cpu(hc_header.wLength); | ||
841 | cluster = kzalloc(wLength, GFP_KERNEL); | ||
842 | if (!cluster) | ||
843 | return -ENOMEM; | ||
844 | err = snd_usb_ctl_msg(chip->dev, | ||
845 | usb_rcvctrlpipe(chip->dev, 0), | ||
846 | UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, | ||
847 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
848 | cluster_id, | ||
849 | snd_usb_ctrl_intf(chip), | ||
850 | cluster, wLength); | ||
851 | if (err < 0) { | ||
852 | kfree(cluster); | ||
853 | return err; | ||
854 | } else if (err != wLength) { | ||
855 | dev_err(&dev->dev, | ||
856 | "%u:%d : can't get Cluster Descriptor\n", | ||
857 | iface_no, altno); | ||
858 | kfree(cluster); | ||
859 | return -EIO; | ||
860 | } | ||
861 | |||
862 | num_channels = cluster->bNrChannels; | ||
863 | chmap_v3 = convert_chmap_v3(cluster); | ||
864 | |||
865 | kfree(cluster); | ||
866 | |||
867 | format = le64_to_cpu(as->bmFormats); | ||
868 | |||
869 | /* lookup the terminal associated to this interface | ||
870 | * to extract the clock */ | ||
871 | input_term = snd_usb_find_input_terminal_descriptor( | ||
872 | chip->ctrl_intf, | ||
873 | as->bTerminalLink); | ||
874 | |||
875 | if (input_term) { | ||
876 | clock = input_term->bCSourceID; | ||
877 | break; | ||
878 | } | ||
879 | |||
880 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, | ||
881 | as->bTerminalLink); | ||
882 | if (output_term) { | ||
883 | clock = output_term->bCSourceID; | ||
884 | break; | ||
885 | } | ||
886 | |||
632 | dev_err(&dev->dev, | 887 | dev_err(&dev->dev, |
633 | "%u:%d : no UAC_FORMAT_TYPE desc\n", | 888 | "%u:%d : bogus bTerminalLink %d\n", |
634 | iface_no, altno); | 889 | iface_no, altno, as->bTerminalLink); |
635 | continue; | 890 | continue; |
636 | } | 891 | } |
637 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || | ||
638 | ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { | ||
639 | dev_err(&dev->dev, | ||
640 | "%u:%d : invalid UAC_FORMAT_TYPE desc\n", | ||
641 | iface_no, altno); | ||
642 | continue; | ||
643 | } | 892 | } |
644 | 893 | ||
645 | /* | 894 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { |
646 | * Blue Microphones workaround: The last altsetting is identical | 895 | /* get format type */ |
647 | * with the previous one, except for a larger packet size, but | 896 | fmt = snd_usb_find_csint_desc(alts->extra, |
648 | * is actually a mislabeled two-channel setting; ignore it. | 897 | alts->extralen, |
649 | */ | 898 | NULL, UAC_FORMAT_TYPE); |
650 | if (fmt->bNrChannels == 1 && | 899 | if (!fmt) { |
651 | fmt->bSubframeSize == 2 && | 900 | dev_err(&dev->dev, |
652 | altno == 2 && num == 3 && | 901 | "%u:%d : no UAC_FORMAT_TYPE desc\n", |
653 | fp && fp->altsetting == 1 && fp->channels == 1 && | 902 | iface_no, altno); |
654 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | 903 | continue; |
655 | protocol == UAC_VERSION_1 && | 904 | } |
656 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | 905 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) |
906 | || ((protocol == UAC_VERSION_2) && | ||
907 | (fmt->bLength < 6))) { | ||
908 | dev_err(&dev->dev, | ||
909 | "%u:%d : invalid UAC_FORMAT_TYPE desc\n", | ||
910 | iface_no, altno); | ||
911 | continue; | ||
912 | } | ||
913 | |||
914 | /* | ||
915 | * Blue Microphones workaround: The last altsetting is | ||
916 | * identical with the previous one, except for a larger | ||
917 | * packet size, but is actually a mislabeled two-channel | ||
918 | * setting; ignore it. | ||
919 | */ | ||
920 | if (fmt->bNrChannels == 1 && | ||
921 | fmt->bSubframeSize == 2 && | ||
922 | altno == 2 && num == 3 && | ||
923 | fp && fp->altsetting == 1 && fp->channels == 1 && | ||
924 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | ||
925 | protocol == UAC_VERSION_1 && | ||
926 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | ||
657 | fp->maxpacksize * 2) | 927 | fp->maxpacksize * 2) |
658 | continue; | 928 | continue; |
929 | } | ||
659 | 930 | ||
660 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); | 931 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); |
661 | if (!fp) | 932 | if (!fp) |
@@ -678,48 +949,42 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | |||
678 | INIT_LIST_HEAD(&fp->list); | 949 | INIT_LIST_HEAD(&fp->list); |
679 | 950 | ||
680 | /* some quirks for attributes here */ | 951 | /* some quirks for attributes here */ |
681 | 952 | snd_usb_audioformat_attributes_quirk(chip, fp, stream); | |
682 | switch (chip->usb_id) { | ||
683 | case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */ | ||
684 | /* Optoplay sets the sample rate attribute although | ||
685 | * it seems not supporting it in fact. | ||
686 | */ | ||
687 | fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
688 | break; | ||
689 | case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ | ||
690 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | ||
691 | /* doesn't set the sample rate attribute, but supports it */ | ||
692 | fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
693 | break; | ||
694 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */ | ||
695 | case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ | ||
696 | case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ | ||
697 | case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is | ||
698 | an older model 77d:223) */ | ||
699 | /* | ||
700 | * plantronics headset and Griffin iMic have set adaptive-in | ||
701 | * although it's really not... | ||
702 | */ | ||
703 | fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE; | ||
704 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
705 | fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE; | ||
706 | else | ||
707 | fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC; | ||
708 | break; | ||
709 | } | ||
710 | 953 | ||
711 | /* ok, let's parse further... */ | 954 | /* ok, let's parse further... */ |
712 | if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream) < 0) { | 955 | if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { |
713 | kfree(fp->rate_table); | 956 | if (snd_usb_parse_audio_format(chip, fp, format, |
714 | kfree(fp); | 957 | fmt, stream) < 0) { |
715 | fp = NULL; | 958 | kfree(fp->rate_table); |
716 | continue; | 959 | kfree(fp); |
960 | fp = NULL; | ||
961 | continue; | ||
962 | } | ||
963 | } else { | ||
964 | struct uac3_as_header_descriptor *as; | ||
965 | |||
966 | as = snd_usb_find_csint_desc(alts->extra, | ||
967 | alts->extralen, | ||
968 | NULL, UAC_AS_GENERAL); | ||
969 | |||
970 | if (snd_usb_parse_audio_format_v3(chip, fp, as, | ||
971 | stream) < 0) { | ||
972 | kfree(fp->rate_table); | ||
973 | kfree(fp); | ||
974 | fp = NULL; | ||
975 | continue; | ||
976 | } | ||
717 | } | 977 | } |
718 | 978 | ||
719 | /* Create chmap */ | 979 | /* Create chmap */ |
720 | if (fp->channels != num_channels) | 980 | if (fp->channels != num_channels) |
721 | chconfig = 0; | 981 | chconfig = 0; |
722 | fp->chmap = convert_chmap(fp->channels, chconfig, protocol); | 982 | |
983 | if (protocol == UAC_VERSION_3) | ||
984 | fp->chmap = chmap_v3; | ||
985 | else | ||
986 | fp->chmap = convert_chmap(fp->channels, chconfig, | ||
987 | protocol); | ||
723 | 988 | ||
724 | dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint); | 989 | dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint); |
725 | err = snd_usb_add_audio_stream(chip, stream, fp); | 990 | err = snd_usb_add_audio_stream(chip, stream, fp); |