aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/f_audio.c')
-rw-r--r--drivers/usb/gadget/f_audio.c97
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;
28module_param(audio_buf_size, int, S_IRUGO); 28module_param(audio_buf_size, int, S_IRUGO);
29MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); 29MODULE_PARM_DESC(audio_buf_size, "Audio buffer size");
30 30
31static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value);
32static 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
53DECLARE_USB_AC_HEADER_DESCRIPTOR(2); 56DECLARE_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 */
57static struct usb_ac_header_descriptor_2 ac_header_desc = { 60static 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
71static struct usb_input_terminal_descriptor input_terminal_desc = { 74static 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
81DECLARE_USB_AC_FEATURE_UNIT_DESCRIPTOR(0); 84DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0);
82 85
83#define FEATURE_UNIT_ID 2 86#define FEATURE_UNIT_ID 2
84static struct usb_ac_feature_unit_descriptor_0 feature_unit_desc = { 87static 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
94static struct usb_audio_control mute_control = { 97static 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 = {
103static struct usb_audio_control volume_control = { 106static 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
121static struct usb_output_terminal_descriptor output_terminal_desc = { 124static 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 */
151static struct usb_as_header_descriptor as_header_desc = { 154static 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
160DECLARE_USB_AS_FORMAT_TYPE_I_DISCRETE_DESC(1); 163DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1);
161 164
162static struct usb_as_formate_type_i_discrete_descriptor_1 as_type_i_desc = { 165static 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 */
184static struct usb_as_iso_endpoint_descriptor as_iso_out_desc __initdata = { 187static 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
638static 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
645static 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 */
636int __init control_selector_init(struct f_audio *audio) 651int __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}