diff options
author | Daniel Mack <daniel@caiaq.de> | 2010-03-11 15:13:25 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-03-12 06:21:26 -0500 |
commit | 23caaf19b11eda7054348452e1618d4512a86907 (patch) | |
tree | de0f69f74931fb033f3291c27691a3c2ac6367a2 /include | |
parent | 99fc86450c439039d2ef88d06b222fd51a779176 (diff) |
ALSA: usb-mixer: Add support for Audio Class v2.0
USB Audio Class v2.0 compliant devices have different descriptors and a
different way of setting/getting min/max/res/cur properties. This patch
adds support for them.
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/usb/audio-v2.h | 47 | ||||
-rw-r--r-- | include/linux/usb/audio.h | 71 |
2 files changed, 98 insertions, 20 deletions
diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h index 3b8560d233b..0952231e6c3 100644 --- a/include/linux/usb/audio-v2.h +++ b/include/linux/usb/audio-v2.h | |||
@@ -43,6 +43,53 @@ struct uac_clock_selector_descriptor { | |||
43 | __u8 baCSourceID[]; | 43 | __u8 baCSourceID[]; |
44 | } __attribute__((packed)); | 44 | } __attribute__((packed)); |
45 | 45 | ||
46 | /* 4.7.2.4 Input terminal descriptor */ | ||
47 | |||
48 | struct uac2_input_terminal_descriptor { | ||
49 | __u8 bLength; | ||
50 | __u8 bDescriptorType; | ||
51 | __u8 bDescriptorSubtype; | ||
52 | __u8 bTerminalID; | ||
53 | __u16 wTerminalType; | ||
54 | __u8 bAssocTerminal; | ||
55 | __u8 bCSourceID; | ||
56 | __u8 bNrChannels; | ||
57 | __u32 bmChannelConfig; | ||
58 | __u8 iChannelNames; | ||
59 | __u16 bmControls; | ||
60 | __u8 iTerminal; | ||
61 | } __attribute__((packed)); | ||
62 | |||
63 | /* 4.7.2.5 Output terminal descriptor */ | ||
64 | |||
65 | struct uac2_output_terminal_descriptor { | ||
66 | __u8 bLength; | ||
67 | __u8 bDescriptorType; | ||
68 | __u8 bDescriptorSubtype; | ||
69 | __u8 bTerminalID; | ||
70 | __u16 wTerminalType; | ||
71 | __u8 bAssocTerminal; | ||
72 | __u8 bSourceID; | ||
73 | __u8 bCSourceID; | ||
74 | __u16 bmControls; | ||
75 | __u8 iTerminal; | ||
76 | } __attribute__((packed)); | ||
77 | |||
78 | |||
79 | |||
80 | /* 4.7.2.8 Feature Unit Descriptor */ | ||
81 | |||
82 | struct uac2_feature_unit_descriptor { | ||
83 | __u8 bLength; | ||
84 | __u8 bDescriptorType; | ||
85 | __u8 bDescriptorSubtype; | ||
86 | __u8 bUnitID; | ||
87 | __u8 bSourceID; | ||
88 | /* bmaControls is actually u32, | ||
89 | * but u8 is needed for the hybrid parser */ | ||
90 | __u8 bmaControls[0]; /* variable length */ | ||
91 | } __attribute__((packed)); | ||
92 | |||
46 | /* 4.9.2 Class-Specific AS Interface Descriptor */ | 93 | /* 4.9.2 Class-Specific AS Interface Descriptor */ |
47 | 94 | ||
48 | struct uac_as_header_descriptor_v2 { | 95 | struct uac_as_header_descriptor_v2 { |
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index bc78a83d0f4..905a87caf3f 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h | |||
@@ -196,20 +196,33 @@ static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor * | |||
196 | return desc->baSourceID[desc->bNrInPins]; | 196 | return desc->baSourceID[desc->bNrInPins]; |
197 | } | 197 | } |
198 | 198 | ||
199 | static inline __u16 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc) | 199 | static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc, |
200 | int protocol) | ||
200 | { | 201 | { |
201 | return (desc->baSourceID[desc->bNrInPins + 2] << 8) | | 202 | if (protocol == UAC_VERSION_1) |
202 | desc->baSourceID[desc->bNrInPins + 1]; | 203 | return (desc->baSourceID[desc->bNrInPins + 2] << 8) | |
204 | desc->baSourceID[desc->bNrInPins + 1]; | ||
205 | else | ||
206 | return (desc->baSourceID[desc->bNrInPins + 4] << 24) | | ||
207 | (desc->baSourceID[desc->bNrInPins + 3] << 16) | | ||
208 | (desc->baSourceID[desc->bNrInPins + 2] << 8) | | ||
209 | (desc->baSourceID[desc->bNrInPins + 1]); | ||
203 | } | 210 | } |
204 | 211 | ||
205 | static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc) | 212 | static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc, |
213 | int protocol) | ||
206 | { | 214 | { |
207 | return desc->baSourceID[desc->bNrInPins + 3]; | 215 | return (protocol == UAC_VERSION_1) ? |
216 | desc->baSourceID[desc->bNrInPins + 3] : | ||
217 | desc->baSourceID[desc->bNrInPins + 5]; | ||
208 | } | 218 | } |
209 | 219 | ||
210 | static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc) | 220 | static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc, |
221 | int protocol) | ||
211 | { | 222 | { |
212 | return &desc->baSourceID[desc->bNrInPins + 4]; | 223 | return (protocol == UAC_VERSION_1) ? |
224 | &desc->baSourceID[desc->bNrInPins + 4] : | ||
225 | &desc->baSourceID[desc->bNrInPins + 6]; | ||
213 | } | 226 | } |
214 | 227 | ||
215 | static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc) | 228 | static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc) |
@@ -267,36 +280,54 @@ static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_de | |||
267 | return desc->baSourceID[desc->bNrInPins]; | 280 | return desc->baSourceID[desc->bNrInPins]; |
268 | } | 281 | } |
269 | 282 | ||
270 | static inline __u16 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc) | 283 | static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc, |
284 | int protocol) | ||
271 | { | 285 | { |
272 | return (desc->baSourceID[desc->bNrInPins + 2] << 8) | | 286 | if (protocol == UAC_VERSION_1) |
273 | desc->baSourceID[desc->bNrInPins + 1]; | 287 | return (desc->baSourceID[desc->bNrInPins + 2] << 8) | |
288 | desc->baSourceID[desc->bNrInPins + 1]; | ||
289 | else | ||
290 | return (desc->baSourceID[desc->bNrInPins + 4] << 24) | | ||
291 | (desc->baSourceID[desc->bNrInPins + 3] << 16) | | ||
292 | (desc->baSourceID[desc->bNrInPins + 2] << 8) | | ||
293 | (desc->baSourceID[desc->bNrInPins + 1]); | ||
274 | } | 294 | } |
275 | 295 | ||
276 | static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc) | 296 | static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc, |
297 | int protocol) | ||
277 | { | 298 | { |
278 | return desc->baSourceID[desc->bNrInPins + 3]; | 299 | return (protocol == UAC_VERSION_1) ? |
300 | desc->baSourceID[desc->bNrInPins + 3] : | ||
301 | desc->baSourceID[desc->bNrInPins + 5]; | ||
279 | } | 302 | } |
280 | 303 | ||
281 | static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc) | 304 | static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc, |
305 | int protocol) | ||
282 | { | 306 | { |
283 | return desc->baSourceID[desc->bNrInPins + 4]; | 307 | return (protocol == UAC_VERSION_1) ? |
308 | desc->baSourceID[desc->bNrInPins + 4] : | ||
309 | desc->baSourceID[desc->bNrInPins + 6]; | ||
284 | } | 310 | } |
285 | 311 | ||
286 | static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc) | 312 | static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc, |
313 | int protocol) | ||
287 | { | 314 | { |
288 | return &desc->baSourceID[desc->bNrInPins + 5]; | 315 | return (protocol == UAC_VERSION_1) ? |
316 | &desc->baSourceID[desc->bNrInPins + 5] : | ||
317 | &desc->baSourceID[desc->bNrInPins + 7]; | ||
289 | } | 318 | } |
290 | 319 | ||
291 | static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc) | 320 | static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc, |
321 | int protocol) | ||
292 | { | 322 | { |
293 | __u8 control_size = uac_processing_unit_bControlSize(desc); | 323 | __u8 control_size = uac_processing_unit_bControlSize(desc, protocol); |
294 | return desc->baSourceID[desc->bNrInPins + control_size]; | 324 | return desc->baSourceID[desc->bNrInPins + control_size]; |
295 | } | 325 | } |
296 | 326 | ||
297 | static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc) | 327 | static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc, |
328 | int protocol) | ||
298 | { | 329 | { |
299 | __u8 control_size = uac_processing_unit_bControlSize(desc); | 330 | __u8 control_size = uac_processing_unit_bControlSize(desc, protocol); |
300 | return &desc->baSourceID[desc->bNrInPins + control_size + 1]; | 331 | return &desc->baSourceID[desc->bNrInPins + control_size + 1]; |
301 | } | 332 | } |
302 | 333 | ||