diff options
Diffstat (limited to 'drivers/usb/gadget/f_audio.c')
| -rw-r--r-- | drivers/usb/gadget/f_audio.c | 97 |
1 files changed, 56 insertions, 41 deletions
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index 66527ba2d2ea..98e9bb977291 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c | |||
| @@ -28,6 +28,9 @@ static int audio_buf_size = 48000; | |||
| 28 | module_param(audio_buf_size, int, S_IRUGO); | 28 | module_param(audio_buf_size, int, S_IRUGO); |
| 29 | MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); | 29 | MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); |
| 30 | 30 | ||
| 31 | static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value); | ||
| 32 | static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); | ||
| 33 | |||
| 31 | /* | 34 | /* |
| 32 | * DESCRIPTORS ... most are static, but strings and full | 35 | * DESCRIPTORS ... most are static, but strings and full |
| 33 | * configuration descriptors are built on demand. | 36 | * configuration descriptors are built on demand. |
| @@ -50,16 +53,16 @@ static struct usb_interface_descriptor ac_interface_desc __initdata = { | |||
| 50 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, | 53 | .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, |
| 51 | }; | 54 | }; |
| 52 | 55 | ||
| 53 | DECLARE_USB_AC_HEADER_DESCRIPTOR(2); | 56 | DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); |
| 54 | 57 | ||
| 55 | #define USB_DT_AC_HEADER_LENGH USB_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) | 58 | #define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) |
| 56 | /* B.3.2 Class-Specific AC Interface Descriptor */ | 59 | /* B.3.2 Class-Specific AC Interface Descriptor */ |
| 57 | static struct usb_ac_header_descriptor_2 ac_header_desc = { | 60 | static struct uac_ac_header_descriptor_2 ac_header_desc = { |
| 58 | .bLength = USB_DT_AC_HEADER_LENGH, | 61 | .bLength = UAC_DT_AC_HEADER_LENGTH, |
| 59 | .bDescriptorType = USB_DT_CS_INTERFACE, | 62 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 60 | .bDescriptorSubtype = HEADER, | 63 | .bDescriptorSubtype = UAC_HEADER, |
| 61 | .bcdADC = __constant_cpu_to_le16(0x0100), | 64 | .bcdADC = __constant_cpu_to_le16(0x0100), |
| 62 | .wTotalLength = __constant_cpu_to_le16(USB_DT_AC_HEADER_LENGH), | 65 | .wTotalLength = __constant_cpu_to_le16(UAC_DT_AC_HEADER_LENGTH), |
| 63 | .bInCollection = F_AUDIO_NUM_INTERFACES, | 66 | .bInCollection = F_AUDIO_NUM_INTERFACES, |
| 64 | .baInterfaceNr = { | 67 | .baInterfaceNr = { |
| 65 | [0] = F_AUDIO_AC_INTERFACE, | 68 | [0] = F_AUDIO_AC_INTERFACE, |
| @@ -68,33 +71,33 @@ static struct usb_ac_header_descriptor_2 ac_header_desc = { | |||
| 68 | }; | 71 | }; |
| 69 | 72 | ||
| 70 | #define INPUT_TERMINAL_ID 1 | 73 | #define INPUT_TERMINAL_ID 1 |
| 71 | static struct usb_input_terminal_descriptor input_terminal_desc = { | 74 | static struct uac_input_terminal_descriptor input_terminal_desc = { |
| 72 | .bLength = USB_DT_AC_INPUT_TERMINAL_SIZE, | 75 | .bLength = UAC_DT_INPUT_TERMINAL_SIZE, |
| 73 | .bDescriptorType = USB_DT_CS_INTERFACE, | 76 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 74 | .bDescriptorSubtype = INPUT_TERMINAL, | 77 | .bDescriptorSubtype = UAC_INPUT_TERMINAL, |
| 75 | .bTerminalID = INPUT_TERMINAL_ID, | 78 | .bTerminalID = INPUT_TERMINAL_ID, |
| 76 | .wTerminalType = USB_AC_TERMINAL_STREAMING, | 79 | .wTerminalType = UAC_TERMINAL_STREAMING, |
| 77 | .bAssocTerminal = 0, | 80 | .bAssocTerminal = 0, |
| 78 | .wChannelConfig = 0x3, | 81 | .wChannelConfig = 0x3, |
| 79 | }; | 82 | }; |
| 80 | 83 | ||
| 81 | DECLARE_USB_AC_FEATURE_UNIT_DESCRIPTOR(0); | 84 | DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); |
| 82 | 85 | ||
| 83 | #define FEATURE_UNIT_ID 2 | 86 | #define FEATURE_UNIT_ID 2 |
| 84 | static struct usb_ac_feature_unit_descriptor_0 feature_unit_desc = { | 87 | static struct uac_feature_unit_descriptor_0 feature_unit_desc = { |
| 85 | .bLength = USB_DT_AC_FEATURE_UNIT_SIZE(0), | 88 | .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), |
| 86 | .bDescriptorType = USB_DT_CS_INTERFACE, | 89 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 87 | .bDescriptorSubtype = FEATURE_UNIT, | 90 | .bDescriptorSubtype = UAC_FEATURE_UNIT, |
| 88 | .bUnitID = FEATURE_UNIT_ID, | 91 | .bUnitID = FEATURE_UNIT_ID, |
| 89 | .bSourceID = INPUT_TERMINAL_ID, | 92 | .bSourceID = INPUT_TERMINAL_ID, |
| 90 | .bControlSize = 2, | 93 | .bControlSize = 2, |
| 91 | .bmaControls[0] = (FU_MUTE | FU_VOLUME), | 94 | .bmaControls[0] = (UAC_FU_MUTE | UAC_FU_VOLUME), |
| 92 | }; | 95 | }; |
| 93 | 96 | ||
| 94 | static struct usb_audio_control mute_control = { | 97 | static struct usb_audio_control mute_control = { |
| 95 | .list = LIST_HEAD_INIT(mute_control.list), | 98 | .list = LIST_HEAD_INIT(mute_control.list), |
| 96 | .name = "Mute Control", | 99 | .name = "Mute Control", |
| 97 | .type = MUTE_CONTROL, | 100 | .type = UAC_MUTE_CONTROL, |
| 98 | /* Todo: add real Mute control code */ | 101 | /* Todo: add real Mute control code */ |
| 99 | .set = generic_set_cmd, | 102 | .set = generic_set_cmd, |
| 100 | .get = generic_get_cmd, | 103 | .get = generic_get_cmd, |
| @@ -103,7 +106,7 @@ static struct usb_audio_control mute_control = { | |||
| 103 | static struct usb_audio_control volume_control = { | 106 | static struct usb_audio_control volume_control = { |
| 104 | .list = LIST_HEAD_INIT(volume_control.list), | 107 | .list = LIST_HEAD_INIT(volume_control.list), |
| 105 | .name = "Volume Control", | 108 | .name = "Volume Control", |
| 106 | .type = VOLUME_CONTROL, | 109 | .type = UAC_VOLUME_CONTROL, |
| 107 | /* Todo: add real Volume control code */ | 110 | /* Todo: add real Volume control code */ |
| 108 | .set = generic_set_cmd, | 111 | .set = generic_set_cmd, |
| 109 | .get = generic_get_cmd, | 112 | .get = generic_get_cmd, |
| @@ -113,17 +116,17 @@ static struct usb_audio_control_selector feature_unit = { | |||
| 113 | .list = LIST_HEAD_INIT(feature_unit.list), | 116 | .list = LIST_HEAD_INIT(feature_unit.list), |
| 114 | .id = FEATURE_UNIT_ID, | 117 | .id = FEATURE_UNIT_ID, |
| 115 | .name = "Mute & Volume Control", | 118 | .name = "Mute & Volume Control", |
| 116 | .type = FEATURE_UNIT, | 119 | .type = UAC_FEATURE_UNIT, |
| 117 | .desc = (struct usb_descriptor_header *)&feature_unit_desc, | 120 | .desc = (struct usb_descriptor_header *)&feature_unit_desc, |
| 118 | }; | 121 | }; |
| 119 | 122 | ||
| 120 | #define OUTPUT_TERMINAL_ID 3 | 123 | #define OUTPUT_TERMINAL_ID 3 |
| 121 | static struct usb_output_terminal_descriptor output_terminal_desc = { | 124 | static struct uac_output_terminal_descriptor output_terminal_desc = { |
| 122 | .bLength = USB_DT_AC_OUTPUT_TERMINAL_SIZE, | 125 | .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, |
| 123 | .bDescriptorType = USB_DT_CS_INTERFACE, | 126 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 124 | .bDescriptorSubtype = OUTPUT_TERMINAL, | 127 | .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, |
| 125 | .bTerminalID = OUTPUT_TERMINAL_ID, | 128 | .bTerminalID = OUTPUT_TERMINAL_ID, |
| 126 | .wTerminalType = USB_AC_OUTPUT_TERMINAL_SPEAKER, | 129 | .wTerminalType = UAC_OUTPUT_TERMINAL_SPEAKER, |
| 127 | .bAssocTerminal = FEATURE_UNIT_ID, | 130 | .bAssocTerminal = FEATURE_UNIT_ID, |
| 128 | .bSourceID = FEATURE_UNIT_ID, | 131 | .bSourceID = FEATURE_UNIT_ID, |
| 129 | }; | 132 | }; |
| @@ -148,22 +151,22 @@ static struct usb_interface_descriptor as_interface_alt_1_desc = { | |||
| 148 | }; | 151 | }; |
| 149 | 152 | ||
| 150 | /* B.4.2 Class-Specific AS Interface Descriptor */ | 153 | /* B.4.2 Class-Specific AS Interface Descriptor */ |
| 151 | static struct usb_as_header_descriptor as_header_desc = { | 154 | static struct uac_as_header_descriptor as_header_desc = { |
| 152 | .bLength = USB_DT_AS_HEADER_SIZE, | 155 | .bLength = UAC_DT_AS_HEADER_SIZE, |
| 153 | .bDescriptorType = USB_DT_CS_INTERFACE, | 156 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 154 | .bDescriptorSubtype = AS_GENERAL, | 157 | .bDescriptorSubtype = UAC_AS_GENERAL, |
| 155 | .bTerminalLink = INPUT_TERMINAL_ID, | 158 | .bTerminalLink = INPUT_TERMINAL_ID, |
| 156 | .bDelay = 1, | 159 | .bDelay = 1, |
| 157 | .wFormatTag = USB_AS_AUDIO_FORMAT_TYPE_I_PCM, | 160 | .wFormatTag = UAC_FORMAT_TYPE_I_PCM, |
| 158 | }; | 161 | }; |
| 159 | 162 | ||
| 160 | DECLARE_USB_AS_FORMAT_TYPE_I_DISCRETE_DESC(1); | 163 | DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); |
| 161 | 164 | ||
| 162 | static struct usb_as_formate_type_i_discrete_descriptor_1 as_type_i_desc = { | 165 | static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { |
| 163 | .bLength = USB_AS_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), | 166 | .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), |
| 164 | .bDescriptorType = USB_DT_CS_INTERFACE, | 167 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 165 | .bDescriptorSubtype = FORMAT_TYPE, | 168 | .bDescriptorSubtype = UAC_FORMAT_TYPE, |
| 166 | .bFormatType = USB_AS_FORMAT_TYPE_I, | 169 | .bFormatType = UAC_FORMAT_TYPE_I, |
| 167 | .bSubframeSize = 2, | 170 | .bSubframeSize = 2, |
| 168 | .bBitResolution = 16, | 171 | .bBitResolution = 16, |
| 169 | .bSamFreqType = 1, | 172 | .bSamFreqType = 1, |
| @@ -174,17 +177,17 @@ static struct usb_endpoint_descriptor as_out_ep_desc __initdata = { | |||
| 174 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, | 177 | .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, |
| 175 | .bDescriptorType = USB_DT_ENDPOINT, | 178 | .bDescriptorType = USB_DT_ENDPOINT, |
| 176 | .bEndpointAddress = USB_DIR_OUT, | 179 | .bEndpointAddress = USB_DIR_OUT, |
| 177 | .bmAttributes = USB_AS_ENDPOINT_ADAPTIVE | 180 | .bmAttributes = USB_ENDPOINT_SYNC_ADAPTIVE |
| 178 | | USB_ENDPOINT_XFER_ISOC, | 181 | | USB_ENDPOINT_XFER_ISOC, |
| 179 | .wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE), | 182 | .wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE), |
| 180 | .bInterval = 4, | 183 | .bInterval = 4, |
| 181 | }; | 184 | }; |
| 182 | 185 | ||
| 183 | /* Class-specific AS ISO OUT Endpoint Descriptor */ | 186 | /* Class-specific AS ISO OUT Endpoint Descriptor */ |
| 184 | static struct usb_as_iso_endpoint_descriptor as_iso_out_desc __initdata = { | 187 | static struct uac_iso_endpoint_descriptor as_iso_out_desc __initdata = { |
| 185 | .bLength = USB_AS_ISO_ENDPOINT_DESC_SIZE, | 188 | .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, |
| 186 | .bDescriptorType = USB_DT_CS_ENDPOINT, | 189 | .bDescriptorType = USB_DT_CS_ENDPOINT, |
| 187 | .bDescriptorSubtype = EP_GENERAL, | 190 | .bDescriptorSubtype = UAC_EP_GENERAL, |
| 188 | .bmAttributes = 1, | 191 | .bmAttributes = 1, |
| 189 | .bLockDelayUnits = 1, | 192 | .bLockDelayUnits = 1, |
| 190 | .wLockDelay = __constant_cpu_to_le16(1), | 193 | .wLockDelay = __constant_cpu_to_le16(1), |
| @@ -456,11 +459,11 @@ f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | |||
| 456 | * Audio class messages; interface activation uses set_alt(). | 459 | * Audio class messages; interface activation uses set_alt(). |
| 457 | */ | 460 | */ |
| 458 | switch (ctrl->bRequestType) { | 461 | switch (ctrl->bRequestType) { |
| 459 | case USB_AUDIO_SET_INTF: | 462 | case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE: |
| 460 | value = audio_set_intf_req(f, ctrl); | 463 | value = audio_set_intf_req(f, ctrl); |
| 461 | break; | 464 | break; |
| 462 | 465 | ||
| 463 | case USB_AUDIO_GET_INTF: | 466 | case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE: |
| 464 | value = audio_get_intf_req(f, ctrl); | 467 | value = audio_get_intf_req(f, ctrl); |
| 465 | break; | 468 | break; |
| 466 | 469 | ||
| @@ -632,6 +635,18 @@ f_audio_unbind(struct usb_configuration *c, struct usb_function *f) | |||
| 632 | 635 | ||
| 633 | /*-------------------------------------------------------------------------*/ | 636 | /*-------------------------------------------------------------------------*/ |
| 634 | 637 | ||
| 638 | static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value) | ||
| 639 | { | ||
| 640 | con->data[cmd] = value; | ||
| 641 | |||
| 642 | return 0; | ||
| 643 | } | ||
| 644 | |||
| 645 | static int generic_get_cmd(struct usb_audio_control *con, u8 cmd) | ||
| 646 | { | ||
| 647 | return con->data[cmd]; | ||
| 648 | } | ||
| 649 | |||
| 635 | /* Todo: add more control selecotor dynamically */ | 650 | /* Todo: add more control selecotor dynamically */ |
| 636 | int __init control_selector_init(struct f_audio *audio) | 651 | int __init control_selector_init(struct f_audio *audio) |
| 637 | { | 652 | { |
| @@ -642,10 +657,10 @@ int __init control_selector_init(struct f_audio *audio) | |||
| 642 | list_add(&mute_control.list, &feature_unit.control); | 657 | list_add(&mute_control.list, &feature_unit.control); |
| 643 | list_add(&volume_control.list, &feature_unit.control); | 658 | list_add(&volume_control.list, &feature_unit.control); |
| 644 | 659 | ||
| 645 | volume_control.data[_CUR] = 0xffc0; | 660 | volume_control.data[UAC__CUR] = 0xffc0; |
| 646 | volume_control.data[_MIN] = 0xe3a0; | 661 | volume_control.data[UAC__MIN] = 0xe3a0; |
| 647 | volume_control.data[_MAX] = 0xfff0; | 662 | volume_control.data[UAC__MAX] = 0xfff0; |
| 648 | volume_control.data[_RES] = 0x0030; | 663 | volume_control.data[UAC__RES] = 0x0030; |
| 649 | 664 | ||
| 650 | return 0; | 665 | return 0; |
| 651 | } | 666 | } |
