include/linux/usb/audio.h: add __attribute__((packed))
[safe/jmp/linux-2.6] / include / linux / usb / audio.h
index c3edfcb..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
@@ -32,8 +39,8 @@
 #define UAC_MIXER_UNIT                 0x04
 #define UAC_SELECTOR_UNIT              0x05
 #define UAC_FEATURE_UNIT               0x06
-#define UAC_PROCESSING_UNIT            0x07
-#define UAC_EXTENSION_UNIT             0x08
+#define UAC_PROCESSING_UNIT_V1         0x07
+#define UAC_EXTENSION_UNIT_V1          0x08
 
 /* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
 #define UAC_AS_GENERAL                 0x01
@@ -81,7 +88,7 @@
 
 /* Terminal Control Selectors */
 /* 4.3.2  Class-Specific AC Interface Descriptor */
-struct uac_ac_header_descriptor {
+struct uac_ac_header_descriptor_v1 {
        __u8  bLength;                  /* 8 + n */
        __u8  bDescriptorType;          /* USB_DT_CS_INTERFACE */
        __u8  bDescriptorSubtype;       /* UAC_MS_HEADER */
@@ -95,7 +102,7 @@ struct uac_ac_header_descriptor {
 
 /* As above, but more useful for defining your own descriptors: */
 #define DECLARE_UAC_AC_HEADER_DESCRIPTOR(n)                    \
-struct uac_ac_header_descriptor_##n {                          \
+struct uac_ac_header_descriptor_v1_##n {                       \
        __u8  bLength;                                          \
        __u8  bDescriptorType;                                  \
        __u8  bDescriptorSubtype;                               \
@@ -130,8 +137,12 @@ struct uac_input_terminal_descriptor {
 #define UAC_INPUT_TERMINAL_MICROPHONE_ARRAY            0x205
 #define UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY       0x206
 
+/* Terminals - control selectors */
+
+#define UAC_TERMINAL_CS_COPY_PROTECT_CONTROL           0x01
+
 /* 4.3.2.2 Output Terminal Descriptor */
-struct uac_output_terminal_descriptor {
+struct uac_output_terminal_descriptor_v1 {
        __u8  bLength;                  /* in bytes: 9 */
        __u8  bDescriptorType;          /* CS_INTERFACE descriptor type */
        __u8  bDescriptorSubtype;       /* OUTPUT_TERMINAL descriptor subtype */
@@ -170,8 +181,158 @@ 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 {
+struct uac_as_header_descriptor_v1 {
        __u8  bLength;                  /* in bytes: 7 */
        __u8  bDescriptorType;          /* USB_DT_CS_INTERFACE */
        __u8  bDescriptorSubtype;       /* AS_GENERAL */
@@ -232,11 +393,61 @@ struct uac_format_type_i_discrete_descriptor_##n {                \
 
 #define UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(n)        (8 + (n * 3))
 
+struct uac_format_type_i_ext_descriptor {
+       __u8 bLength;
+       __u8 bDescriptorType;
+       __u8 bDescriptorSubtype;
+       __u8 bFormatType;
+       __u8 bSubslotSize;
+       __u8 bBitResolution;
+       __u8 bHeaderLength;
+       __u8 bControlSize;
+       __u8 bSideBandProtocol;
+} __attribute__((packed));
+
+/* Formats - Audio Data Format Type I Codes */
+
+#define UAC_FORMAT_TYPE_II_MPEG        0x1001
+#define UAC_FORMAT_TYPE_II_AC3 0x1002
+
+struct uac_format_type_ii_discrete_descriptor {
+       __u8 bLength;
+       __u8 bDescriptorType;
+       __u8 bDescriptorSubtype;
+       __u8 bFormatType;
+       __le16 wMaxBitRate;
+       __le16 wSamplesPerFrame;
+       __u8 bSamFreqType;
+       __u8 tSamFreq[][3];
+} __attribute__((packed));
+
+struct uac_format_type_ii_ext_descriptor {
+       __u8 bLength;
+       __u8 bDescriptorType;
+       __u8 bDescriptorSubtype;
+       __u8 bFormatType;
+       __u16 wMaxBitRate;
+       __u16 wSamplesPerFrame;
+       __u8 bHeaderLength;
+       __u8 bSideBandProtocol;
+} __attribute__((packed));
+
+/* type III */
+#define UAC_FORMAT_TYPE_III_IEC1937_AC3        0x2001
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG1_LAYER1       0x2002
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_NOEXT        0x2003
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_EXT  0x2004
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER1_LS    0x2005
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER23_LS   0x2006
+
 /* Formats - A.2 Format Type Codes */
 #define UAC_FORMAT_TYPE_UNDEFINED      0x0
 #define UAC_FORMAT_TYPE_I              0x1
 #define UAC_FORMAT_TYPE_II             0x2
 #define UAC_FORMAT_TYPE_III            0x3
+#define UAC_EXT_FORMAT_TYPE_I          0x81
+#define UAC_EXT_FORMAT_TYPE_II         0x82
+#define UAC_EXT_FORMAT_TYPE_III                0x83
 
 struct uac_iso_endpoint_descriptor {
        __u8  bLength;                  /* in bytes: 7 */
@@ -245,7 +456,7 @@ 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
@@ -253,6 +464,7 @@ struct uac_iso_endpoint_descriptor {
 #define UAC_EP_CS_ATTR_FILL_MAX                0x80
 
 /* A.10.2 Feature Unit Control Selectors */
+
 #define UAC_FU_CONTROL_UNDEFINED       0x00
 #define UAC_MUTE_CONTROL               0x01
 #define UAC_VOLUME_CONTROL             0x02
@@ -276,6 +488,8 @@ struct uac_iso_endpoint_descriptor {
 #define UAC_FU_BASS_BOOST      (1 << (UAC_BASS_BOOST_CONTROL - 1))
 #define UAC_FU_LOUDNESS                (1 << (UAC_LOUDNESS_CONTROL - 1))
 
+#ifdef __KERNEL__
+
 struct usb_audio_control {
        struct list_head list;
        const char *name;
@@ -285,18 +499,6 @@ struct usb_audio_control {
        int (*get)(struct usb_audio_control *con, u8 cmd);
 };
 
-static inline int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value)
-{
-       con->data[cmd] = value;
-
-       return 0;
-}
-
-static inline int generic_get_cmd(struct usb_audio_control *con, u8 cmd)
-{
-       return con->data[cmd];
-}
-
 struct usb_audio_control_selector {
        struct list_head list;
        struct list_head control;
@@ -306,4 +508,6 @@ struct usb_audio_control_selector {
        struct usb_descriptor_header *desc;
 };
 
+#endif /* __KERNEL__ */
+
 #endif /* __LINUX_USB_AUDIO_H */