include/linux/usb/audio.h: add __attribute__((packed))
[safe/jmp/linux-2.6] / include / linux / usb / audio.h
index 4d3e450..9fae6bd 100644 (file)
@@ -13,6 +13,9 @@
  * Comments below reference relevant sections of that document:
  *
  * http://www.usb.org/developers/devclass_docs/audio10.pdf
+ *
+ * Types and defines in this file are either specific to version 1.0 of
+ * this standard or common for newer versions.
  */
 
 #ifndef __LINUX_USB_AUDIO_H
 
 #include <linux/types.h>
 
+/* bInterfaceProtocol values to denote the version of the standard used */
+#define UAC_VERSION_1                  0x00
+#define UAC_VERSION_2                  0x20
+
 /* A.2 Audio Interface Subclass Codes */
 #define USB_SUBCLASS_AUDIOCONTROL      0x01
 #define USB_SUBCLASS_AUDIOSTREAMING    0x02
 #define USB_SUBCLASS_MIDISTREAMING     0x03
 
-#define UAC_VERSION_1                  0x00
-#define UAC_VERSION_2                  0x20
-
 /* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
 #define UAC_HEADER                     0x01
 #define UAC_INPUT_TERMINAL             0x02
 #define UAC_PROCESSING_UNIT_V1         0x07
 #define UAC_EXTENSION_UNIT_V1          0x08
 
-/* UAC v2.0 types */
-#define UAC_EFFECT_UNIT                        0x07
-#define UAC_PROCESSING_UNIT_V2         0x08
-#define UAC_EXTENSION_UNIT_V2          0x09
-#define UAC_CLOCK_SOURCE               0x0a
-#define UAC_CLOCK_SELECTOR             0x0b
-#define UAC_CLOCK_MULTIPLIER           0x0c
-#define UAC_SAMPLE_RATE_CONVERTER      0x0d
-
 /* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
 #define UAC_AS_GENERAL                 0x01
 #define UAC_FORMAT_TYPE                        0x02
 
 #define UAC_GET_STAT                   0xff
 
-/* Audio class v2.0 handles all the parameter calls differently */
-#define UAC2_CS_CUR                    0x01
-#define UAC2_CS_RANGE                  0x02
-
 /* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */
 #define UAC_MS_HEADER                  0x01
 #define UAC_MIDI_IN_JACK               0x02
@@ -190,6 +181,156 @@ struct uac_feature_unit_descriptor_##ch {                 \
        __u8  iFeature;                                         \
 } __attribute__ ((packed))
 
+/* 4.3.2.3 Mixer Unit Descriptor */
+struct uac_mixer_unit_descriptor {
+       __u8 bLength;
+       __u8 bDescriptorType;
+       __u8 bDescriptorSubtype;
+       __u8 bUnitID;
+       __u8 bNrInPins;
+       __u8 baSourceID[];
+} __attribute__ ((packed));
+
+static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *desc)
+{
+       return desc->baSourceID[desc->bNrInPins];
+}
+
+static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc,
+                                                 int protocol)
+{
+       if (protocol == UAC_VERSION_1)
+               return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
+                       desc->baSourceID[desc->bNrInPins + 1];
+       else
+               return  (desc->baSourceID[desc->bNrInPins + 4] << 24) |
+                       (desc->baSourceID[desc->bNrInPins + 3] << 16) |
+                       (desc->baSourceID[desc->bNrInPins + 2] << 8)  |
+                       (desc->baSourceID[desc->bNrInPins + 1]);
+}
+
+static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc,
+                                               int protocol)
+{
+       return (protocol == UAC_VERSION_1) ?
+               desc->baSourceID[desc->bNrInPins + 3] :
+               desc->baSourceID[desc->bNrInPins + 5];
+}
+
+static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
+                                             int protocol)
+{
+       return (protocol == UAC_VERSION_1) ?
+               &desc->baSourceID[desc->bNrInPins + 4] :
+               &desc->baSourceID[desc->bNrInPins + 6];
+}
+
+static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
+{
+       __u8 *raw = (__u8 *) desc;
+       return raw[desc->bLength - 1];
+}
+
+/* 4.3.2.4 Selector Unit Descriptor */
+struct uac_selector_unit_descriptor {
+       __u8 bLength;
+       __u8 bDescriptorType;
+       __u8 bDescriptorSubtype;
+       __u8 bUintID;
+       __u8 bNrInPins;
+       __u8 baSourceID[];
+} __attribute__ ((packed));
+
+static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc)
+{
+       __u8 *raw = (__u8 *) desc;
+       return raw[9 + desc->bLength - 1];
+}
+
+/* 4.3.2.5 Feature Unit Descriptor */
+struct uac_feature_unit_descriptor {
+       __u8 bLength;
+       __u8 bDescriptorType;
+       __u8 bDescriptorSubtype;
+       __u8 bUnitID;
+       __u8 bSourceID;
+       __u8 bControlSize;
+       __u8 bmaControls[0]; /* variable length */
+} __attribute__((packed));
+
+static inline __u8 uac_feature_unit_iFeature(struct uac_feature_unit_descriptor *desc)
+{
+       __u8 *raw = (__u8 *) desc;
+       return raw[desc->bLength - 1];
+}
+
+/* 4.3.2.6 Processing Unit Descriptors */
+struct uac_processing_unit_descriptor {
+       __u8 bLength;
+       __u8 bDescriptorType;
+       __u8 bDescriptorSubtype;
+       __u8 bUnitID;
+       __u16 wProcessType;
+       __u8 bNrInPins;
+       __u8 baSourceID[];
+} __attribute__ ((packed));
+
+static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_descriptor *desc)
+{
+       return desc->baSourceID[desc->bNrInPins];
+}
+
+static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc,
+                                                      int protocol)
+{
+       if (protocol == UAC_VERSION_1)
+               return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
+                       desc->baSourceID[desc->bNrInPins + 1];
+       else
+               return  (desc->baSourceID[desc->bNrInPins + 4] << 24) |
+                       (desc->baSourceID[desc->bNrInPins + 3] << 16) |
+                       (desc->baSourceID[desc->bNrInPins + 2] << 8)  |
+                       (desc->baSourceID[desc->bNrInPins + 1]);
+}
+
+static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc,
+                                                    int protocol)
+{
+       return (protocol == UAC_VERSION_1) ?
+               desc->baSourceID[desc->bNrInPins + 3] :
+               desc->baSourceID[desc->bNrInPins + 5];
+}
+
+static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
+                                                   int protocol)
+{
+       return (protocol == UAC_VERSION_1) ?
+               desc->baSourceID[desc->bNrInPins + 4] :
+               desc->baSourceID[desc->bNrInPins + 6];
+}
+
+static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
+                                                  int protocol)
+{
+       return (protocol == UAC_VERSION_1) ?
+               &desc->baSourceID[desc->bNrInPins + 5] :
+               &desc->baSourceID[desc->bNrInPins + 7];
+}
+
+static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
+                                                  int protocol)
+{
+       __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
+       return desc->baSourceID[desc->bNrInPins + control_size];
+}
+
+static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
+                                                int protocol)
+{
+       __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
+       return &desc->baSourceID[desc->bNrInPins + control_size + 1];
+}
+
 /* 4.5.2 Class-Specific AS Interface Descriptor */
 struct uac_as_header_descriptor_v1 {
        __u8  bLength;                  /* in bytes: 7 */
@@ -200,19 +341,6 @@ struct uac_as_header_descriptor_v1 {
        __le16 wFormatTag;              /* The Audio Data Format */
 } __attribute__ ((packed));
 
-struct uac_as_header_descriptor_v2 {
-       __u8 bLength;
-       __u8 bDescriptorType;
-       __u8 bDescriptorSubtype;
-       __u8 bTerminalLink;
-       __u8 bmControls;
-       __u8 bFormatType;
-       __u32 bmFormats;
-       __u8 bNrChannels;
-       __u32 bmChannelConfig;
-       __u8 iChannelNames;
-} __attribute__((packed));
-
 #define UAC_DT_AS_HEADER_SIZE          7
 
 /* Formats - A.1.1 Audio Data Format Type I Codes */
@@ -277,7 +405,6 @@ struct uac_format_type_i_ext_descriptor {
        __u8 bSideBandProtocol;
 } __attribute__((packed));
 
-
 /* Formats - Audio Data Format Type I Codes */
 
 #define UAC_FORMAT_TYPE_II_MPEG        0x1001
@@ -329,38 +456,15 @@ struct uac_iso_endpoint_descriptor {
        __u8  bmAttributes;
        __u8  bLockDelayUnits;
        __le16 wLockDelay;
-};
+} __attribute__((packed));
 #define UAC_ISO_ENDPOINT_DESC_SIZE     7
 
 #define UAC_EP_CS_ATTR_SAMPLE_RATE     0x01
 #define UAC_EP_CS_ATTR_PITCH_CONTROL   0x02
 #define UAC_EP_CS_ATTR_FILL_MAX                0x80
 
-/* Audio class v2.0: CLOCK_SOURCE descriptor */
-
-struct uac_clock_source_descriptor {
-       __u8 bLength;
-       __u8 bDescriptorType;
-       __u8 bDescriptorSubtype;
-       __u8 bClockID;
-       __u8 bmAttributes;
-       __u8 bmControls;
-       __u8 bAssocTerminal;
-       __u8 iClockSource;
-} __attribute__((packed));
-
 /* A.10.2 Feature Unit Control Selectors */
 
-struct uac_feature_unit_descriptor {
-       __u8 bLength;
-       __u8 bDescriptorType;
-       __u8 bDescriptorSubtype;
-       __u8 bUnitID;
-       __u8 bSourceID;
-       __u8 bControlSize;
-       __u8 controls[0]; /* variable length */
-} __attribute__((packed));
-
 #define UAC_FU_CONTROL_UNDEFINED       0x00
 #define UAC_MUTE_CONTROL               0x01
 #define UAC_VOLUME_CONTROL             0x02