diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 3eb028bb017f..7b586f57af3f 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -43,6 +43,7 @@ static struct usb_interface_assoc_descriptor iad_desc = { .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, .bFirstInterface = 0, + .bInterfaceCount = 3, .bFunctionClass = USB_CLASS_AUDIO, .bFunctionSubClass = USB_SUBCLASS_AUDIOSTREAMING, .bFunctionProtocol = UAC_VERSION_1, @@ -63,112 +64,67 @@ static struct usb_interface_descriptor ac_interface_desc = { */ DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); +#define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) +/* 2 input terminals and 2 output terminals */ +#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH \ + + 2*UAC_DT_INPUT_TERMINAL_SIZE + 2*UAC_DT_OUTPUT_TERMINAL_SIZE) /* B.3.2 Class-Specific AC Interface Descriptor */ static struct uac1_ac_header_descriptor_2 ac_header_desc = { + .bLength = UAC_DT_AC_HEADER_LENGTH, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_HEADER, .bcdADC = cpu_to_le16(0x0100), - /* .baInterfaceNr[0] = DYNAMIC */ - /* .baInterfaceNr[1] = DYNAMIC */ + .wTotalLength = cpu_to_le16(UAC_DT_TOTAL_LENGTH), + .bInCollection = F_AUDIO_NUM_INTERFACES, + .baInterfaceNr = { + /* Interface number of the AudioStream interfaces */ + [0] = 1, + [1] = 2, + } }; +#define USB_OUT_IT_ID 1 static struct uac_input_terminal_descriptor usb_out_it_desc = { .bLength = UAC_DT_INPUT_TERMINAL_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_INPUT_TERMINAL, + .bTerminalID = USB_OUT_IT_ID, .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), .bAssocTerminal = 0, .wChannelConfig = cpu_to_le16(0x3), }; -DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); - -static struct uac_feature_unit_descriptor_0 io_out_ot_fu_desc = { - .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_FEATURE_UNIT, - .bControlSize = 2, - .bmaControls[0] = (UAC_CONTROL_BIT(UAC_FU_MUTE) | - UAC_CONTROL_BIT(UAC_FU_VOLUME)), -}; - -static struct usb_audio_control c_mute_control = { - .list = LIST_HEAD_INIT(c_mute_control.list), - .name = "Capture Mute", - .type = UAC_FU_MUTE, - .set = u_audio_fu_set_cmd, - .get = u_audio_fu_get_cmd, -}; - -static struct usb_audio_control c_volume_control = { - .list = LIST_HEAD_INIT(c_volume_control.list), - .name = "Capture Volume", - .type = UAC_FU_VOLUME, - .set = u_audio_fu_set_cmd, - .get = u_audio_fu_get_cmd, -}; - -static struct usb_audio_control_selector c_feature_unit = { - .list = LIST_HEAD_INIT(c_feature_unit.list), - .name = "Capture Mute & Volume Control", - .type = UAC_FEATURE_UNIT, - .desc = (struct usb_descriptor_header *)&io_out_ot_fu_desc, -}; - +#define IO_OUT_OT_ID 2 static struct uac1_output_terminal_descriptor io_out_ot_desc = { .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, + .bTerminalID = IO_OUT_OT_ID, .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER), .bAssocTerminal = 0, + .bSourceID = USB_OUT_IT_ID, }; +#define IO_IN_IT_ID 3 static struct uac_input_terminal_descriptor io_in_it_desc = { .bLength = UAC_DT_INPUT_TERMINAL_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_INPUT_TERMINAL, + .bTerminalID = IO_IN_IT_ID, .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE), .bAssocTerminal = 0, .wChannelConfig = cpu_to_le16(0x3), }; -static struct uac_feature_unit_descriptor_0 usb_in_ot_fu_desc = { - .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_FEATURE_UNIT, - .bControlSize = 2, - .bmaControls[0] = (UAC_FU_MUTE | UAC_FU_VOLUME), -}; - -static struct usb_audio_control p_mute_control = { - .list = LIST_HEAD_INIT(p_mute_control.list), - .name = "Playback Mute", - .type = UAC_FU_MUTE, - .set = u_audio_fu_set_cmd, - .get = u_audio_fu_get_cmd, -}; - -static struct usb_audio_control p_volume_control = { - .list = LIST_HEAD_INIT(p_volume_control.list), - .name = "Playback Volume", - .type = UAC_FU_VOLUME, - .set = u_audio_fu_set_cmd, - .get = u_audio_fu_get_cmd, -}; - -static struct usb_audio_control_selector p_feature_unit = { - .list = LIST_HEAD_INIT(p_feature_unit.list), - .name = "Playback Mute & Volume Control", - .type = UAC_FEATURE_UNIT, - .desc = (struct usb_descriptor_header *)&usb_in_ot_fu_desc, -}; - +#define USB_IN_OT_ID 4 static struct uac1_output_terminal_descriptor usb_in_ot_desc = { .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, + .bTerminalID = USB_IN_OT_ID, .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), .bAssocTerminal = 0, + .bSourceID = IO_IN_IT_ID, }; /* B.4.1 Standard AS Interface Descriptor */ @@ -213,6 +169,7 @@ static struct uac1_as_header_descriptor as_out_header_desc = { .bLength = UAC_DT_AS_HEADER_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_AS_GENERAL, + .bTerminalLink = USB_OUT_IT_ID, .bDelay = 1, .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM), }; @@ -221,6 +178,7 @@ static struct uac1_as_header_descriptor as_in_header_desc = { .bLength = UAC_DT_AS_HEADER_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_AS_GENERAL, + .bTerminalLink = USB_IN_OT_ID, .bDelay = 1, .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM), }; @@ -297,10 +255,8 @@ static struct usb_descriptor_header *f_audio_desc[] = { (struct usb_descriptor_header *)&ac_header_desc, (struct usb_descriptor_header *)&usb_out_it_desc, - (struct usb_descriptor_header *)&io_out_ot_fu_desc, (struct usb_descriptor_header *)&io_out_ot_desc, (struct usb_descriptor_header *)&io_in_it_desc, - (struct usb_descriptor_header *)&usb_in_ot_fu_desc, (struct usb_descriptor_header *)&usb_in_ot_desc, (struct usb_descriptor_header *)&as_out_interface_alt_0_desc, @@ -328,11 +284,9 @@ enum { STR_AC_IF, STR_USB_OUT_IT, STR_USB_OUT_IT_CH_NAMES, - STR_IO_OUT_OT_FU, STR_IO_OUT_OT, STR_IO_IN_IT, STR_IO_IN_IT_CH_NAMES, - STR_USB_IN_OT_FU, STR_USB_IN_OT, STR_AS_OUT_IF_ALT0, STR_AS_OUT_IF_ALT1, @@ -345,11 +299,9 @@ static struct usb_string strings_uac1[] = { [STR_AC_IF].s = "AC Interface", [STR_USB_OUT_IT].s = "Playback Input terminal", [STR_USB_OUT_IT_CH_NAMES].s = "Playback Channels", - [STR_IO_OUT_OT_FU].s = "Playback Feature Unit", [STR_IO_OUT_OT].s = "Playback Output terminal", [STR_IO_IN_IT].s = "Capture Input terminal", [STR_IO_IN_IT_CH_NAMES].s = "Capture Channels", - [STR_USB_IN_OT_FU].s = "Capture Feature Unit", [STR_USB_IN_OT].s = "Capture Output terminal", [STR_AS_OUT_IF_ALT0].s = "Playback Inactive", [STR_AS_OUT_IF_ALT1].s = "Playback Active", @@ -371,25 +323,6 @@ static struct usb_gadget_strings *uac1_strings[] = { /* * This function is an ALSA sound card following USB Audio Class Spec 1.0. */ -static void intf_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct f_uac *uac1 = req->context; - int status = req->status; - u32 data = 0; - - switch (status) { - case 0: /* normal completion? */ - if (uac1->set_con) { - memcpy(&data, req->buf, req->length); - uac1->set_con->set(uac1->set_con, uac1->set_cmd, - le16_to_cpu(data)); - uac1->set_con = NULL; - } - break; - default: - break; - } -} static void uac_cs_attr_sample_rate(struct usb_ep *ep, struct usb_request *req) { @@ -417,80 +350,6 @@ static void uac_cs_attr_sample_rate(struct usb_ep *ep, struct usb_request *req) } } -static int audio_set_intf_req(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - struct f_uac *uac1 = func_to_uac(f); - struct usb_composite_dev *cdev = f->config->cdev; - struct usb_request *req = cdev->req; - u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); - u16 len = le16_to_cpu(ctrl->wLength); - u16 w_value = le16_to_cpu(ctrl->wValue); - u8 con_sel = (w_value >> 8) & 0xFF; - u8 cmd = (ctrl->bRequest & 0x0F); - struct usb_audio_control_selector *cs; - struct usb_audio_control *con; - - DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", - ctrl->bRequest, w_value, len, id); - - list_for_each_entry(cs, &uac1->cs, list) { - if (cs->id == id) { - list_for_each_entry(con, &cs->control, list) { - if (con->type == con_sel) { - uac1->set_con = con; - break; - } - } - break; - } - } - - uac1->set_cmd = cmd; - req->context = uac1; - req->complete = intf_complete; - - return len; -} - -static int audio_get_intf_req(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) -{ - struct f_uac *uac1 = func_to_uac(f); - struct usb_composite_dev *cdev = f->config->cdev; - struct usb_request *req = cdev->req; - int value = -EOPNOTSUPP; - u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); - u16 len = le16_to_cpu(ctrl->wLength); - u16 w_value = le16_to_cpu(ctrl->wValue); - u8 con_sel = (w_value >> 8) & 0xFF; - u8 cmd = (ctrl->bRequest & 0x0F); - struct usb_audio_control_selector *cs; - struct usb_audio_control *con; - - DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", - ctrl->bRequest, w_value, len, id); - - list_for_each_entry(cs, &uac1->cs, list) { - if (cs->id == id) { - list_for_each_entry(con, &cs->control, list) { - if (con->type == con_sel && con->get) { - value = con->get(con, cmd); - break; - } - } - break; - } - } - - req->context = uac1; - req->complete = intf_complete; - len = min_t(size_t, sizeof(value), len); - memcpy(req->buf, &value, len); - - return len; -} - static int audio_set_endpoint_req(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { @@ -595,14 +454,6 @@ f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) * activation uses set_alt(). */ switch (ctrl->bRequestType) { - case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE: - value = audio_set_intf_req(f, ctrl); - break; - - case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE: - value = audio_get_intf_req(f, ctrl); - break; - case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: value = audio_set_endpoint_req(f, ctrl); break; @@ -711,104 +562,6 @@ static void f_audio_disable(struct usb_function *f) } /*-------------------------------------------------------------------------*/ -#define USBDHDR(p) (struct usb_descriptor_header *)(p) - -static void setup_descriptor(struct f_uac_opts *opts) -{ - int i = 1; - u16 len = 0; - - if (EPOUT_EN(opts)) - usb_out_it_desc.bTerminalID = i++; - if (EPIN_EN(opts)) - io_in_it_desc.bTerminalID = i++; - if (EPOUT_EN(opts) && EPOUT_FU(opts)) - io_out_ot_fu_desc.bUnitID = i++; - if (EPIN_EN(opts) && EPIN_FU(opts)) - usb_in_ot_fu_desc.bUnitID = i++; - if (EPOUT_EN(opts)) - io_out_ot_desc.bTerminalID = i++; - if (EPIN_EN(opts)) - usb_in_ot_desc.bTerminalID = i++; - - if (EPIN_FU(opts)) { - usb_in_ot_desc.bSourceID = usb_in_ot_fu_desc.bUnitID; - usb_in_ot_fu_desc.bSourceID = io_in_it_desc.bTerminalID; - p_feature_unit.id = usb_in_ot_fu_desc.bUnitID; - } else { - usb_in_ot_desc.bSourceID = io_in_it_desc.bTerminalID; - } - if (EPOUT_FU(opts)) { - io_out_ot_desc.bSourceID = io_out_ot_fu_desc.bUnitID; - io_out_ot_fu_desc.bSourceID = usb_out_it_desc.bTerminalID; - c_feature_unit.id = io_out_ot_fu_desc.bUnitID; - } else { - io_out_ot_desc.bSourceID = usb_out_it_desc.bTerminalID; - } - as_out_header_desc.bTerminalLink = usb_out_it_desc.bTerminalID; - as_in_header_desc.bTerminalLink = usb_in_ot_desc.bTerminalID; - - iad_desc.bInterfaceCount = 1; - ac_header_desc.bInCollection = 0; - - if (EPIN_EN(opts)) { - len += UAC_DT_INPUT_TERMINAL_SIZE + UAC_DT_OUTPUT_TERMINAL_SIZE; - if (EPIN_FU(opts)) - len += UAC_DT_FEATURE_UNIT_SIZE(0); - iad_desc.bInterfaceCount++; - ac_header_desc.bInCollection++; - } - - if (EPOUT_EN(opts)) { - len += UAC_DT_INPUT_TERMINAL_SIZE + UAC_DT_OUTPUT_TERMINAL_SIZE; - if (EPOUT_FU(opts)) - len += UAC_DT_FEATURE_UNIT_SIZE(0); - iad_desc.bInterfaceCount++; - ac_header_desc.bInCollection++; - } - ac_header_desc.bLength = - UAC_DT_AC_HEADER_SIZE(ac_header_desc.bInCollection); - ac_header_desc.wTotalLength = cpu_to_le16(len + ac_header_desc.bLength); - - i = 0; - f_audio_desc[i++] = USBDHDR(&iad_desc); - f_audio_desc[i++] = USBDHDR(&ac_interface_desc); - f_audio_desc[i++] = USBDHDR(&ac_header_desc); - - if (EPOUT_EN(opts)) { - f_audio_desc[i++] = USBDHDR(&usb_out_it_desc); - if (EPOUT_FU(opts)) - f_audio_desc[i++] = USBDHDR(&io_out_ot_fu_desc); - f_audio_desc[i++] = USBDHDR(&io_out_ot_desc); - } - - if (EPIN_EN(opts)) { - f_audio_desc[i++] = USBDHDR(&io_in_it_desc); - if (EPIN_FU(opts)) - f_audio_desc[i++] = USBDHDR(&usb_in_ot_fu_desc); - f_audio_desc[i++] = USBDHDR(&usb_in_ot_desc); - } - - if (EPOUT_EN(opts)) { - f_audio_desc[i++] = USBDHDR(&as_out_interface_alt_0_desc); - f_audio_desc[i++] = USBDHDR(&as_out_interface_alt_1_desc); - f_audio_desc[i++] = USBDHDR(&as_out_header_desc); - f_audio_desc[i++] = USBDHDR(&as_out_type_i_desc); - f_audio_desc[i++] = USBDHDR(&as_out_ep_desc); - f_audio_desc[i++] = USBDHDR(&as_iso_out_desc); - } - - if (EPIN_EN(opts)) { - f_audio_desc[i++] = USBDHDR(&as_in_interface_alt_0_desc); - f_audio_desc[i++] = USBDHDR(&as_in_interface_alt_1_desc); - f_audio_desc[i++] = USBDHDR(&as_in_header_desc); - f_audio_desc[i++] = USBDHDR(&as_in_type_i_desc); - f_audio_desc[i++] = USBDHDR(&as_in_ep_desc); - f_audio_desc[i++] = USBDHDR(&as_iso_in_desc); - } - f_audio_desc[i++] = NULL; -} - /* audio function driver setup/binding */ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) @@ -833,13 +586,11 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) ac_interface_desc.iInterface = us[STR_AC_IF].id; usb_out_it_desc.iTerminal = us[STR_USB_OUT_IT].id; usb_out_it_desc.iChannelNames = us[STR_USB_OUT_IT_CH_NAMES].id; - io_out_ot_fu_desc.iFeature = us[STR_IO_OUT_OT_FU].id; io_out_ot_desc.iTerminal = us[STR_IO_OUT_OT].id; as_out_interface_alt_0_desc.iInterface = us[STR_AS_OUT_IF_ALT0].id; as_out_interface_alt_1_desc.iInterface = us[STR_AS_OUT_IF_ALT1].id; io_in_it_desc.iTerminal = us[STR_IO_IN_IT].id; io_in_it_desc.iChannelNames = us[STR_IO_IN_IT_CH_NAMES].id; - usb_in_ot_fu_desc.iFeature = us[STR_USB_IN_OT_FU].id; usb_in_ot_desc.iTerminal = us[STR_USB_IN_OT].id; as_in_interface_alt_0_desc.iInterface = us[STR_AS_IN_IF_ALT0].id; as_in_interface_alt_1_desc.iInterface = us[STR_AS_IN_IF_ALT1].id; @@ -883,52 +634,42 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) ac_interface_desc.bInterfaceNumber = status; uac1->ac_intf = status; uac1->ac_alt = 0; - ac_header_desc.baInterfaceNr[0] = ++status; - ac_header_desc.baInterfaceNr[1] = ++status; - if (EPOUT_EN(audio_opts)) { - status = usb_interface_id(c, f); - if (status < 0) - goto fail; - as_out_interface_alt_0_desc.bInterfaceNumber = status; - as_out_interface_alt_1_desc.bInterfaceNumber = status; - uac1->as_out_intf = status; - uac1->as_out_alt = 0; - } + status = usb_interface_id(c, f); + if (status < 0) + goto fail; + as_out_interface_alt_0_desc.bInterfaceNumber = status; + as_out_interface_alt_1_desc.bInterfaceNumber = status; + ac_header_desc.baInterfaceNr[0] = status; + uac1->as_out_intf = status; + uac1->as_out_alt = 0; - if (EPIN_EN(audio_opts)) { - status = usb_interface_id(c, f); - if (status < 0) - goto fail; - as_in_interface_alt_0_desc.bInterfaceNumber = status; - as_in_interface_alt_1_desc.bInterfaceNumber = status; - uac1->as_in_intf = status; - uac1->as_in_alt = 0; - } + status = usb_interface_id(c, f); + if (status < 0) + goto fail; + as_in_interface_alt_0_desc.bInterfaceNumber = status; + as_in_interface_alt_1_desc.bInterfaceNumber = status; + ac_header_desc.baInterfaceNr[1] = status; + uac1->as_in_intf = status; + uac1->as_in_alt = 0; audio->gadget = gadget; status = -ENODEV; /* allocate instance-specific endpoints */ - if (EPOUT_EN(audio_opts)) { - ep = usb_ep_autoconfig(cdev->gadget, &as_out_ep_desc); - if (!ep) - goto fail; - audio->out_ep = ep; - audio->out_ep->desc = &as_out_ep_desc; - } + ep = usb_ep_autoconfig(cdev->gadget, &as_out_ep_desc); + if (!ep) + goto fail; + audio->out_ep = ep; + audio->out_ep->desc = &as_out_ep_desc; - if (EPIN_EN(audio_opts)) { - ep = usb_ep_autoconfig(cdev->gadget, &as_in_ep_desc); - if (!ep) - goto fail; - ep->maxpacket = usb_endpoint_maxp(&as_in_ep_desc); - audio->in_ep = ep; - audio->in_ep->desc = &as_in_ep_desc; - } + ep = usb_ep_autoconfig(cdev->gadget, &as_in_ep_desc); + if (!ep) + goto fail; + audio->in_ep = ep; + audio->in_ep->desc = &as_in_ep_desc; - setup_descriptor(audio_opts); /* copy descriptors, and track endpoint copies */ status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL, NULL); @@ -963,54 +704,14 @@ fail: /*-------------------------------------------------------------------------*/ -/* Todo: add more control selecotor dynamically */ -static int control_selector_init(struct f_uac *uac1) -{ - INIT_LIST_HEAD(&uac1->cs); - - /* playback feature unit */ - list_add(&p_feature_unit.list, &uac1->cs); - - INIT_LIST_HEAD(&p_feature_unit.control); - list_add(&p_mute_control.list, &p_feature_unit.control); - list_add(&p_volume_control.list, &p_feature_unit.control); - - p_volume_control.data[UAC__CUR] = UAC_VOLUME_CUR; - p_volume_control.data[UAC__MIN] = UAC_VOLUME_MIN; - p_volume_control.data[UAC__MAX] = UAC_VOLUME_MAX; - p_volume_control.data[UAC__RES] = UAC_VOLUME_RES; - - p_volume_control.context = &uac1->g_audio; - p_mute_control.context = &uac1->g_audio; - - /* capture feature unit */ - list_add(&c_feature_unit.list, &uac1->cs); - - INIT_LIST_HEAD(&c_feature_unit.control); - list_add(&c_mute_control.list, &c_feature_unit.control); - list_add(&c_volume_control.list, &c_feature_unit.control); - - c_volume_control.data[UAC__CUR] = UAC_VOLUME_CUR; - c_volume_control.data[UAC__MIN] = UAC_VOLUME_MIN; - c_volume_control.data[UAC__MAX] = UAC_VOLUME_MAX; - c_volume_control.data[UAC__RES] = UAC_VOLUME_RES; - - c_volume_control.context = &uac1->g_audio; - c_mute_control.context = &uac1->g_audio; - - return 0; -} - static struct configfs_item_operations f_uac1_item_ops = { .release = f_uac_attr_release, }; UAC_ATTRIBUTE(c_chmask); UAC_ATTRIBUTE(c_ssize); -UAC_ATTRIBUTE(c_feature_unit); UAC_ATTRIBUTE(p_chmask); UAC_ATTRIBUTE(p_ssize); -UAC_ATTRIBUTE(p_feature_unit); UAC_ATTRIBUTE(req_number); UAC_RATE_ATTRIBUTE(p_srate); @@ -1020,11 +721,9 @@ static struct configfs_attribute *f_uac1_attrs[] = { &f_uac_opts_attr_c_chmask, &f_uac_opts_attr_c_srate, &f_uac_opts_attr_c_ssize, - &f_uac_opts_attr_c_feature_unit, &f_uac_opts_attr_p_chmask, &f_uac_opts_attr_p_srate, &f_uac_opts_attr_p_ssize, - &f_uac_opts_attr_p_feature_unit, &f_uac_opts_attr_req_number, NULL, }; @@ -1061,12 +760,10 @@ static struct usb_function_instance *f_audio_alloc_inst(void) opts->c_srate[0] = UAC_DEF_CSRATE; opts->c_srate_active = UAC_DEF_CSRATE; opts->c_ssize = UAC_DEF_CSSIZE; - opts->c_feature_unit = UAC_DEF_CFU; opts->p_chmask = UAC_DEF_PCHMASK; opts->p_srate[0] = UAC_DEF_PSRATE; opts->p_srate_active = UAC_DEF_PSRATE; opts->p_ssize = UAC_DEF_PSSIZE; - opts->p_feature_unit = UAC_DEF_PFU; opts->req_number = UAC_DEF_REQ_NUM; return &opts->func_inst; } @@ -1118,8 +815,6 @@ static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) uac1->g_audio.func.disable = f_audio_disable; uac1->g_audio.func.free_func = f_audio_free; - control_selector_init(uac1); - return &uac1->g_audio.func; } diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 9862aa062b02..b64985c6453d 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -40,6 +40,9 @@ #define UNFLW_CTRL 8 #define OVFLW_CTRL 10 +#define EPIN_EN(_opts) ((_opts)->p_chmask != 0) +#define EPOUT_EN(_opts) ((_opts)->c_chmask != 0) + /* --------- USB Function Interface ------------- */ enum { @@ -49,8 +52,6 @@ enum { STR_CLKSRC_OUT, STR_USB_IT, STR_IO_IT, - STR_USB_OT_FU, - STR_IO_OT_FU, STR_USB_OT, STR_IO_OT, STR_AS_OUT_ALT0, @@ -66,8 +67,6 @@ static struct usb_string strings_fn[] = { [STR_CLKSRC_OUT].s = "Output clock", [STR_USB_IT].s = "USBH Out", [STR_IO_IT].s = "USBD Out", - [STR_USB_OT_FU].s = "USBH In Feature Unit", - [STR_IO_OT_FU].s = "USBD In Feature Unit", [STR_USB_OT].s = "USBH In", [STR_IO_OT].s = "USBD In", [STR_AS_OUT_ALT0].s = "Playback Inactive", @@ -162,81 +161,6 @@ static struct uac2_input_terminal_descriptor io_in_it_desc = { .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL), }; -DECLARE_UAC2_FEATURE_UNIT_DESCRIPTOR(0); - -/* Feature Unit for I/O-out */ -static struct uac2_feature_unit_descriptor_0 io_out_ot_fu_desc = { - - .bLength = UAC2_DT_FEATURE_UNIT_SIZE(0), - .bDescriptorType = USB_DT_CS_INTERFACE, - - .bDescriptorSubtype = UAC_FEATURE_UNIT, - /* .bUnitID = DYNAMIC */ - /* .bSourceID = DYNAMIC */ - .bmaControls[0] = (UAC2_CONTROL_BIT_RW(UAC_FU_MUTE) | - UAC2_CONTROL_BIT_RW(UAC_FU_VOLUME)), -}; - -static struct usb_audio_control c_mute_control = { - .list = LIST_HEAD_INIT(c_mute_control.list), - .name = "Capture Mute", - .type = UAC_FU_MUTE, - .set = u_audio_fu_set_cmd, - .get = u_audio_fu_get_cmd, -}; - -static struct usb_audio_control c_volume_control = { - .list = LIST_HEAD_INIT(c_volume_control.list), - .name = "Capture Volume", - .type = UAC_FU_VOLUME, - .set = u_audio_fu_set_cmd, - .get = u_audio_fu_get_cmd, -}; - -static struct usb_audio_control_selector c_feature_unit = { - .list = LIST_HEAD_INIT(c_feature_unit.list), - /* .id = DYNAMIC */ - .name = "Capture Mute & Volume Control", - .type = UAC_FEATURE_UNIT, - .desc = (struct usb_descriptor_header *)&io_out_ot_fu_desc, -}; - -/* Feature Unit for USB_IN */ -static struct uac2_feature_unit_descriptor_0 usb_in_ot_fu_desc = { - .bLength = UAC2_DT_FEATURE_UNIT_SIZE(0), - .bDescriptorType = USB_DT_CS_INTERFACE, - - .bDescriptorSubtype = UAC_FEATURE_UNIT, - /* .bUnitID = DYNAMIC */ - /* .bSourceID = DYNAMIC */ - .bmaControls[0] = (UAC2_CONTROL_BIT_RW(UAC_FU_MUTE) | - UAC2_CONTROL_BIT_RW(UAC_FU_VOLUME)), -}; - -static struct usb_audio_control p_mute_control = { - .list = LIST_HEAD_INIT(p_mute_control.list), - .name = "Playback Mute", - .type = UAC_FU_MUTE, - .set = u_audio_fu_set_cmd, - .get = u_audio_fu_get_cmd, -}; - -static struct usb_audio_control p_volume_control = { - .list = LIST_HEAD_INIT(p_volume_control.list), - .name = "Playback Volume", - .type = UAC_FU_VOLUME, - .set = u_audio_fu_set_cmd, - .get = u_audio_fu_get_cmd, -}; - -static struct usb_audio_control_selector p_feature_unit = { - .list = LIST_HEAD_INIT(p_feature_unit.list), - /* .id = DYNAMIC */ - .name = "Playback Mute & Volume Control", - .type = UAC_FEATURE_UNIT, - .desc = (struct usb_descriptor_header *)&usb_in_ot_fu_desc, -}; - /* Ouput Terminal for USB_IN */ static struct uac2_output_terminal_descriptor usb_in_ot_desc = { .bLength = sizeof usb_in_ot_desc, @@ -275,8 +199,7 @@ static struct uac2_ac_header_descriptor ac_hdr_desc = { .wTotalLength = cpu_to_le16(sizeof ac_hdr_desc + sizeof in_clk_src_desc + sizeof out_clk_src_desc + sizeof usb_out_it_desc + sizeof io_in_it_desc + sizeof usb_in_ot_desc - + sizeof io_out_ot_desc + sizeof usb_in_ot_fu_desc - + sizeof io_out_ot_fu_desc), + + sizeof io_out_ot_desc), .bmControls = 0, }; @@ -443,8 +366,6 @@ static struct usb_descriptor_header *fs_audio_desc[] = { (struct usb_descriptor_header *)&out_clk_src_desc, (struct usb_descriptor_header *)&usb_out_it_desc, (struct usb_descriptor_header *)&io_in_it_desc, - (struct usb_descriptor_header *)&usb_in_ot_fu_desc, - (struct usb_descriptor_header *)&io_out_ot_fu_desc, (struct usb_descriptor_header *)&usb_in_ot_desc, (struct usb_descriptor_header *)&io_out_ot_desc, @@ -475,8 +396,6 @@ static struct usb_descriptor_header *hs_audio_desc[] = { (struct usb_descriptor_header *)&out_clk_src_desc, (struct usb_descriptor_header *)&usb_out_it_desc, (struct usb_descriptor_header *)&io_in_it_desc, - (struct usb_descriptor_header *)&usb_in_ot_fu_desc, - (struct usb_descriptor_header *)&io_out_ot_fu_desc, (struct usb_descriptor_header *)&usb_in_ot_desc, (struct usb_descriptor_header *)&io_out_ot_desc, @@ -498,17 +417,6 @@ static struct usb_descriptor_header *hs_audio_desc[] = { NULL, }; -struct cntrl_cur_lay2 { - __le16 dCUR; -}; - -struct cntrl_range_lay2 { - __le16 wNumSubRanges; - __le16 dMIN; - __le16 dMAX; - __le16 dRES; -} __packed; - struct cntrl_cur_lay3 { __le32 dCUR; }; @@ -590,10 +498,6 @@ static void setup_descriptor(struct f_uac_opts *opts) usb_out_it_desc.bTerminalID = i++; if (EPIN_EN(opts)) io_in_it_desc.bTerminalID = i++; - if (EPOUT_EN(opts) && EPOUT_FU(opts)) - io_out_ot_fu_desc.bUnitID = i++; - if (EPIN_EN(opts) && EPIN_FU(opts)) - usb_in_ot_fu_desc.bUnitID = i++; if (EPOUT_EN(opts)) io_out_ot_desc.bTerminalID = i++; if (EPIN_EN(opts)) @@ -604,23 +508,11 @@ static void setup_descriptor(struct f_uac_opts *opts) in_clk_src_desc.bClockID = i++; usb_out_it_desc.bCSourceID = out_clk_src_desc.bClockID; - if (EPIN_FU(opts)) { - usb_in_ot_fu_desc.bSourceID = io_in_it_desc.bTerminalID; - usb_in_ot_desc.bSourceID = usb_in_ot_fu_desc.bUnitID; - p_feature_unit.id = usb_in_ot_fu_desc.bUnitID; - } else { - usb_in_ot_desc.bSourceID = io_in_it_desc.bTerminalID; - } + usb_in_ot_desc.bSourceID = io_in_it_desc.bTerminalID; usb_in_ot_desc.bCSourceID = in_clk_src_desc.bClockID; io_in_it_desc.bCSourceID = in_clk_src_desc.bClockID; io_out_ot_desc.bCSourceID = out_clk_src_desc.bClockID; - if (EPOUT_FU(opts)) { - io_out_ot_fu_desc.bSourceID = usb_out_it_desc.bTerminalID; - io_out_ot_desc.bSourceID = io_out_ot_fu_desc.bUnitID; - c_feature_unit.id = io_out_ot_fu_desc.bUnitID; - } else { - io_out_ot_desc.bSourceID = usb_out_it_desc.bTerminalID; - } + io_out_ot_desc.bSourceID = usb_out_it_desc.bTerminalID; as_out_hdr_desc.bTerminalLink = usb_out_it_desc.bTerminalID; as_in_hdr_desc.bTerminalLink = usb_in_ot_desc.bTerminalID; @@ -632,8 +524,6 @@ static void setup_descriptor(struct f_uac_opts *opts) len += sizeof(in_clk_src_desc); len += sizeof(usb_in_ot_desc); - if (EPIN_FU(opts)) - len += sizeof(usb_in_ot_fu_desc); len += sizeof(io_in_it_desc); ac_hdr_desc.wTotalLength = cpu_to_le16(len); iad_desc.bInterfaceCount++; @@ -643,8 +533,6 @@ static void setup_descriptor(struct f_uac_opts *opts) len += sizeof(out_clk_src_desc); len += sizeof(usb_out_it_desc); - if (EPOUT_FU(opts)) - len += sizeof(io_out_ot_fu_desc); len += sizeof(io_out_ot_desc); ac_hdr_desc.wTotalLength = cpu_to_le16(len); iad_desc.bInterfaceCount++; @@ -662,13 +550,9 @@ static void setup_descriptor(struct f_uac_opts *opts) } if (EPIN_EN(opts)) { fs_audio_desc[i++] = USBDHDR(&io_in_it_desc); - if (EPIN_FU(opts)) - fs_audio_desc[i++] = USBDHDR(&usb_in_ot_fu_desc); fs_audio_desc[i++] = USBDHDR(&usb_in_ot_desc); } if (EPOUT_EN(opts)) { - if (EPOUT_FU(opts)) - fs_audio_desc[i++] = USBDHDR(&io_out_ot_fu_desc); fs_audio_desc[i++] = USBDHDR(&io_out_ot_desc); fs_audio_desc[i++] = USBDHDR(&std_as_out_if0_desc); fs_audio_desc[i++] = USBDHDR(&std_as_out_if1_desc); @@ -699,13 +583,9 @@ static void setup_descriptor(struct f_uac_opts *opts) } if (EPIN_EN(opts)) { hs_audio_desc[i++] = USBDHDR(&io_in_it_desc); - if (EPIN_FU(opts)) - hs_audio_desc[i++] = USBDHDR(&usb_in_ot_fu_desc); hs_audio_desc[i++] = USBDHDR(&usb_in_ot_desc); } if (EPOUT_EN(opts)) { - if (EPOUT_FU(opts)) - hs_audio_desc[i++] = USBDHDR(&io_out_ot_fu_desc); hs_audio_desc[i++] = USBDHDR(&io_out_ot_desc); hs_audio_desc[i++] = USBDHDR(&std_as_out_if0_desc); hs_audio_desc[i++] = USBDHDR(&std_as_out_if1_desc); @@ -748,8 +628,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) out_clk_src_desc.iClockSource = us[STR_CLKSRC_OUT].id; usb_out_it_desc.iTerminal = us[STR_USB_IT].id; io_in_it_desc.iTerminal = us[STR_IO_IT].id; - usb_in_ot_fu_desc.iFeature = us[STR_USB_OT_FU].id; - io_out_ot_fu_desc.iFeature = us[STR_IO_OT_FU].id; usb_in_ot_desc.iTerminal = us[STR_USB_OT].id; io_out_ot_desc.iTerminal = us[STR_IO_OT].id; std_as_out_if0_desc.iInterface = us[STR_AS_OUT_ALT0].id; @@ -850,7 +728,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); return -ENODEV; } - agdev->in_ep->maxpacket = usb_endpoint_maxp(&fs_epin_desc); } agdev->in_ep_maxpsize = max_t(u16, @@ -972,7 +849,7 @@ afunc_disable(struct usb_function *fn) } static int -in_rq_cs_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) +in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) { struct usb_request *req = fn->config->cdev->req; struct g_audio *agdev = func_to_g_audio(fn); @@ -1014,7 +891,7 @@ in_rq_cs_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) } static int -in_rq_cs_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) +in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) { struct usb_request *req = fn->config->cdev->req; struct g_audio *agdev = func_to_g_audio(fn); @@ -1067,112 +944,16 @@ in_rq_cs_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) return value; } -static int -in_rq_fu(struct usb_function *fn, const struct usb_ctrlrequest *cr) -{ - struct f_uac *uac2 = func_to_uac(fn); - struct usb_request *req = fn->config->cdev->req; - u16 w_length = le16_to_cpu(cr->wLength); - struct usb_audio_control *con = uac2->get_con; - u8 cmd = uac2->get_cmd; - char c1; - struct cntrl_cur_lay2 c2; - struct cntrl_range_lay2 r; - int value = -EOPNOTSUPP; - - if (cmd == UAC2_CS_CUR && con->type == UAC_FU_MUTE) { - c1 = con->get(con, UAC__CUR); - value = min_t(unsigned int, w_length, 1); - memcpy(req->buf, &c1, value); - } else if (cmd == UAC2_CS_CUR && con->type == UAC_FU_VOLUME) { - c2.dCUR = cpu_to_le16(con->get(con, UAC__CUR)); - value = min_t(unsigned int, w_length, sizeof(c2)); - memcpy(req->buf, &c2, value); - } else if (cmd == UAC2_CS_RANGE) { - r.wNumSubRanges = cpu_to_le16(1); - r.dMIN = cpu_to_le16(con->get(con, UAC__MIN)); - r.dMAX = cpu_to_le16(con->get(con, UAC__MAX)); - r.dRES = cpu_to_le16(con->get(con, UAC__RES)); - value = min_t(unsigned int, w_length, sizeof(r)); - memcpy(req->buf, &r, value); - } - - DBG(fn->config->cdev, "%s(): send size %d\n", __func__, value); - - return value; -} - -static void uac2_fu_control_complt(struct usb_ep *ep, struct usb_request *req) -{ - struct f_uac *uac2 = req->context; - struct usb_audio_control *con = uac2->set_con; - u8 cmd = uac2->set_cmd; - int status = req->status; - char c1; - struct cntrl_cur_lay2 c2; - struct cntrl_range_lay2 r; - - switch (status) { - case 0: /* normal completion? */ - if (!con) - break; - - if (cmd == UAC2_CS_CUR && con->type == UAC_FU_MUTE) { - memcpy(&c1, req->buf, 1); - con->set(con, UAC__CUR, c1); - } else if (cmd == UAC2_CS_CUR && con->type == UAC_FU_VOLUME) { - memcpy(&c2, req->buf, sizeof(c2)); - con->set(con, UAC__CUR, le16_to_cpu(c2.dCUR)); - } else if (cmd == UAC2_CS_RANGE) { - memcpy(&r, req->buf, sizeof(r)); - con->set(con, UAC__MIN, le16_to_cpu(r.dMIN)); - con->set(con, UAC__MAX, le16_to_cpu(r.dMAX)); - con->set(con, UAC__RES, le16_to_cpu(r.dRES)); - } - - uac2->set_con = NULL; - break; - default: - break; - } -} - static int ac_rq_in(struct usb_function *fn, const struct usb_ctrlrequest *cr) { - struct f_uac *uac2 = func_to_uac(fn); - struct usb_composite_dev *cdev = fn->config->cdev; - struct usb_request *req = cdev->req; - u8 id = ((le16_to_cpu(cr->wIndex) >> 8) & 0xFF); - u16 len = le16_to_cpu(cr->wLength); - u16 w_value = le16_to_cpu(cr->wValue); - u8 con_sel = (w_value >> 8) & 0xFF; - u8 cmd = (cr->bRequest & 0x0F); - struct usb_audio_control_selector *cs; - struct usb_audio_control *con; - - DBG(cdev, "bRequest in 0x%x, w_value 0x%04x, len %d, entity %d\n", - cr->bRequest, w_value, len, id); - - if (id == USB_OUT_CLK_ID || id == USB_IN_CLK_ID) { - if (cr->bRequest == UAC2_CS_CUR) - return in_rq_cs_cur(fn, cr); - else if (cr->bRequest == UAC2_CS_RANGE) - return in_rq_cs_range(fn, cr); - } - - list_for_each_entry(cs, &uac2->cs, list) - if (cs->id == id) - list_for_each_entry(con, &cs->control, list) - if (con->type == con_sel) { - req->context = uac2; - uac2->get_con = con; - uac2->get_cmd = cmd; - req->complete = uac2_fu_control_complt; - return in_rq_fu(fn, cr); - } - - return -EOPNOTSUPP; + DBG(fn->config->cdev, "%s(): %d\n", __func__, cr->bRequest); + if (cr->bRequest == UAC2_CS_CUR) + return in_rq_cur(fn, cr); + else if (cr->bRequest == UAC2_CS_RANGE) + return in_rq_range(fn, cr); + else + return -EOPNOTSUPP; } static void uac2_cs_control_sam_freq(struct usb_ep *ep, struct usb_request *req) @@ -1200,7 +981,7 @@ static void uac2_cs_control_sam_freq(struct usb_ep *ep, struct usb_request *req) } static int -out_rq_cs_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) +out_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) { struct usb_composite_dev *cdev = fn->config->cdev; struct usb_request *req = cdev->req; @@ -1223,43 +1004,6 @@ out_rq_cs_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) return -EOPNOTSUPP; } -static int -ac_rq_out(struct usb_function *fn, const struct usb_ctrlrequest *cr) -{ - struct f_uac *uac2 = func_to_uac(fn); - struct usb_composite_dev *cdev = fn->config->cdev; - struct usb_request *req = cdev->req; - u16 w_index = le16_to_cpu(cr->wIndex); - u16 w_value = le16_to_cpu(cr->wValue); - u16 w_length = le16_to_cpu(cr->wLength); - u8 id = (w_index >> 8) & 0xff; - u8 con_sel = (w_value >> 8) & 0xff; - u8 cmd = (cr->bRequest & 0x0f); - struct usb_audio_control_selector *cs; - struct usb_audio_control *con; - - DBG(cdev, "bRequest out 0x%x, w_value 0x%04x, len %d, entity %d\n", - cr->bRequest, w_value, w_length, id); - - if (id == USB_OUT_CLK_ID || id == USB_IN_CLK_ID) { - if (cr->bRequest == UAC2_CS_CUR) - return out_rq_cs_cur(fn, cr); - } - - list_for_each_entry(cs, &uac2->cs, list) - if (cs->id == id) - list_for_each_entry(con, &cs->control, list) - if (con->type == con_sel) { - req->context = uac2; - uac2->set_con = con; - uac2->set_cmd = cmd; - req->complete = uac2_fu_control_complt; - return w_length; - } - - return -EOPNOTSUPP; -} - static int setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr) { @@ -1276,8 +1020,10 @@ setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr) if (cr->bRequestType & USB_DIR_IN) return ac_rq_in(fn, cr); - else - return ac_rq_out(fn, cr); + else if (cr->bRequest == UAC2_CS_CUR) + return out_rq_cur(fn, cr); + + return -EOPNOTSUPP; } static int @@ -1319,10 +1065,8 @@ static struct configfs_item_operations f_uac2_item_ops = { UAC_ATTRIBUTE(p_chmask); UAC_ATTRIBUTE(p_ssize); -UAC_ATTRIBUTE(p_feature_unit); UAC_ATTRIBUTE(c_chmask); UAC_ATTRIBUTE(c_ssize); -UAC_ATTRIBUTE(c_feature_unit); UAC_ATTRIBUTE(req_number); UAC_RATE_ATTRIBUTE(p_srate); @@ -1332,11 +1076,9 @@ static struct configfs_attribute *f_uac2_attrs[] = { &f_uac_opts_attr_p_chmask, &f_uac_opts_attr_p_srate, &f_uac_opts_attr_p_ssize, - &f_uac_opts_attr_p_feature_unit, &f_uac_opts_attr_c_chmask, &f_uac_opts_attr_c_srate, &f_uac_opts_attr_c_ssize, - &f_uac_opts_attr_c_feature_unit, &f_uac_opts_attr_req_number, NULL, }; @@ -1373,12 +1115,10 @@ static struct usb_function_instance *afunc_alloc_inst(void) opts->p_srate[0] = UAC_DEF_PSRATE; opts->p_srate_active = UAC_DEF_PSRATE; opts->p_ssize = UAC_DEF_PSSIZE; - opts->p_feature_unit = UAC_DEF_PFU; opts->c_chmask = UAC_DEF_CCHMASK; opts->c_srate[0] = UAC_DEF_CSRATE; opts->c_srate_active = UAC_DEF_CSRATE; opts->c_ssize = UAC_DEF_CSSIZE; - opts->c_feature_unit = UAC_DEF_CFU; opts->req_number = UAC_DEF_REQ_NUM; return &opts->func_inst; } @@ -1406,45 +1146,6 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f) agdev->gadget = NULL; } -/* Todo: add more control selecotor dynamically */ -static int control_selector_init(struct f_uac *uac2) -{ - INIT_LIST_HEAD(&uac2->cs); - - /* playback feature unit */ - list_add(&p_feature_unit.list, &uac2->cs); - - INIT_LIST_HEAD(&p_feature_unit.control); - list_add(&p_mute_control.list, &p_feature_unit.control); - list_add(&p_volume_control.list, &p_feature_unit.control); - - p_volume_control.data[UAC__CUR] = UAC_VOLUME_CUR; - p_volume_control.data[UAC__MIN] = UAC_VOLUME_MIN; - p_volume_control.data[UAC__MAX] = UAC_VOLUME_MAX; - p_volume_control.data[UAC__RES] = UAC_VOLUME_RES; - - p_volume_control.context = &uac2->g_audio; - p_mute_control.context = &uac2->g_audio; - - /* capture feature unit */ - list_add(&c_feature_unit.list, &uac2->cs); - - INIT_LIST_HEAD(&c_feature_unit.control); - list_add(&c_mute_control.list, &c_feature_unit.control); - list_add(&c_volume_control.list, &c_feature_unit.control); - - c_volume_control.data[UAC__CUR] = UAC_VOLUME_CUR; - c_volume_control.data[UAC__MIN] = UAC_VOLUME_MIN; - c_volume_control.data[UAC__MAX] = UAC_VOLUME_MAX; - c_volume_control.data[UAC__RES] = UAC_VOLUME_RES; - - c_volume_control.context = &uac2->g_audio; - c_mute_control.context = &uac2->g_audio; - - return 0; -} - - static struct usb_function *afunc_alloc(struct usb_function_instance *fi) { struct f_uac *uac2; @@ -1468,8 +1169,6 @@ static struct usb_function *afunc_alloc(struct usb_function_instance *fi) uac2->g_audio.func.setup = afunc_setup; uac2->g_audio.func.free_func = afunc_free; - control_selector_init(uac2); - return &uac2->g_audio.func; } diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index b330ee776b37..85edc72f07c1 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -13,7 +13,6 @@ */ #include -#include #include #include #include @@ -585,46 +584,6 @@ void u_audio_stop_playback(struct g_audio *audio_dev) } EXPORT_SYMBOL_GPL(u_audio_stop_playback); -int u_audio_fu_set_cmd(struct usb_audio_control *con, u8 cmd, int value) -{ - struct g_audio *audio_dev = (struct g_audio *)con->context; - struct uac_params *params = &audio_dev->params; - - switch (cmd) { - case UAC_SET_CUR: - if (!strncmp(con->name, "Capture Mute", 12)) { - params->c_mute = value; - audio_dev->usb_state[SET_MUTE_OUT] = true; - } else if (!strncmp(con->name, "Capture Volume", 14)) { - params->c_volume = value; - audio_dev->usb_state[SET_VOLUME_OUT] = true; - } else if (!strncmp(con->name, "Playback Mute", 13)) { - params->p_mute = value; - audio_dev->usb_state[SET_MUTE_IN] = true; - } else if (!strncmp(con->name, "Playback Volume", 15)) { - params->p_volume = value; - audio_dev->usb_state[SET_VOLUME_IN] = true; - } - break; - case UAC_SET_RES: - fallthrough; - default: - return 0; - } - - con->data[cmd] = value; - schedule_work(&audio_dev->work); - - return 0; -} -EXPORT_SYMBOL_GPL(u_audio_fu_set_cmd); - -int u_audio_fu_get_cmd(struct usb_audio_control *con, u8 cmd) -{ - return con->data[cmd]; -} -EXPORT_SYMBOL_GPL(u_audio_fu_get_cmd); - static void g_audio_work(struct work_struct *data) { struct g_audio *audio = container_of(data, struct g_audio, work); @@ -632,11 +591,10 @@ static void g_audio_work(struct work_struct *data) struct usb_gadget *gadget = audio->gadget; struct device *dev = &gadget->dev; char *uac_event[4] = { NULL, NULL, NULL, NULL }; - char str[19]; - signed short volume; + char srate_str[19]; int i; - for (i = 0; i < SET_USB_STATE_MAX; i++) { + for (i = 0; i < 4; i++) { if (!audio->usb_state[i]) continue; @@ -656,44 +614,16 @@ static void g_audio_work(struct work_struct *data) case SET_SAMPLE_RATE_OUT: uac_event[0] = "USB_STATE=SET_SAMPLE_RATE"; uac_event[1] = "STREAM_DIRECTION=OUT"; - snprintf(str, sizeof(str), "SAMPLE_RATE=%d", + snprintf(srate_str, sizeof(srate_str), "SAMPLE_RATE=%d", params->c_srate_active); - uac_event[2] = str; + uac_event[2] = srate_str; break; case SET_SAMPLE_RATE_IN: uac_event[0] = "USB_STATE=SET_SAMPLE_RATE"; uac_event[1] = "STREAM_DIRECTION=IN"; - snprintf(str, sizeof(str), "SAMPLE_RATE=%d", + snprintf(srate_str, sizeof(srate_str), "SAMPLE_RATE=%d", params->p_srate_active); - uac_event[2] = str; - break; - case SET_MUTE_OUT: - uac_event[0] = "USB_STATE=SET_MUTE"; - uac_event[1] = "STREAM_DIRECTION=OUT"; - snprintf(str, sizeof(str), "MUTE=%d", params->c_mute); - uac_event[2] = str; - break; - case SET_MUTE_IN: - uac_event[0] = "USB_STATE=SET_MUTE"; - uac_event[1] = "STREAM_DIRECTION=IN"; - snprintf(str, sizeof(str), "MUTE=%d", params->p_mute); - uac_event[2] = str; - break; - case SET_VOLUME_OUT: - uac_event[0] = "USB_STATE=SET_VOLUME"; - uac_event[1] = "STREAM_DIRECTION=OUT"; - volume = (signed short)params->c_volume; - volume /= UAC_VOLUME_RES; - snprintf(str, sizeof(str), "VOLUME=%d%%", volume + 50); - uac_event[2] = str; - break; - case SET_VOLUME_IN: - uac_event[0] = "USB_STATE=SET_VOLUME"; - uac_event[1] = "STREAM_DIRECTION=IN"; - volume = (signed short)params->p_volume; - volume /= UAC_VOLUME_RES; - snprintf(str, sizeof(str), "VOLUME=%d%%", volume + 50); - uac_event[2] = str; + uac_event[2] = srate_str; break; default: break; diff --git a/drivers/usb/gadget/function/u_audio.h b/drivers/usb/gadget/function/u_audio.h index 369261e8bdd8..a390a6291c39 100644 --- a/drivers/usb/gadget/function/u_audio.h +++ b/drivers/usb/gadget/function/u_audio.h @@ -11,24 +11,15 @@ #include -#define UAC_VOLUME_CUR 0x0000 -#define UAC_VOLUME_RES 0x0080 /* 0.5 dB */ -#define UAC_VOLUME_MAX 0x1900 /* 25 dB */ -#define UAC_VOLUME_MIN 0xE700 /* -25 dB */ -#define UAC_VOLUME_NEGATIVE_INFINITY 0x8000 #define UAC_MAX_RATES 10 struct uac_params { /* playback */ - int p_volume; - int p_mute; int p_chmask; /* channel mask */ int p_srate[UAC_MAX_RATES]; /* rate in Hz */ int p_srate_active; /* selected rate in Hz */ int p_ssize; /* sample size */ /* capture */ - int c_volume; - int c_mute; int c_chmask; /* channel mask */ int c_srate[UAC_MAX_RATES]; /* rate in Hz */ int c_srate_active; /* selected rate in Hz */ @@ -42,11 +33,6 @@ enum usb_state_index { SET_INTERFACE_IN, SET_SAMPLE_RATE_OUT, SET_SAMPLE_RATE_IN, - SET_VOLUME_OUT, - SET_VOLUME_IN, - SET_MUTE_OUT, - SET_MUTE_IN, - SET_USB_STATE_MAX, }; enum stream_state_index { @@ -56,7 +42,7 @@ enum stream_state_index { struct g_audio { struct device *device; - bool usb_state[SET_USB_STATE_MAX]; + bool usb_state[4]; bool stream_state[2]; struct work_struct work; @@ -117,7 +103,5 @@ int u_audio_start_playback(struct g_audio *g_audio); void u_audio_stop_playback(struct g_audio *g_audio); int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate); int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate); -int u_audio_fu_set_cmd(struct usb_audio_control *con, u8 cmd, int value); -int u_audio_fu_get_cmd(struct usb_audio_control *con, u8 cmd); #endif /* __U_AUDIO_H */ diff --git a/drivers/usb/gadget/function/u_uac.h b/drivers/usb/gadget/function/u_uac.h index 224ddc397c70..ae64a3b373cf 100644 --- a/drivers/usb/gadget/function/u_uac.h +++ b/drivers/usb/gadget/function/u_uac.h @@ -18,32 +18,23 @@ #define UAC_DEF_CCHMASK 0x3 #define UAC_DEF_CSRATE 48000 #define UAC_DEF_CSSIZE 2 -#define UAC_DEF_CFU 0 #define UAC_DEF_PCHMASK 0x3 #define UAC_DEF_PSRATE 48000 #define UAC_DEF_PSSIZE 2 -#define UAC_DEF_PFU 0 #define UAC_DEF_REQ_NUM 2 #define UAC1_OUT_EP_MAX_PACKET_SIZE 200 -#define EPIN_EN(_opts) ((_opts)->p_chmask != 0) -#define EPOUT_EN(_opts) ((_opts)->c_chmask != 0) -#define EPIN_FU(_opts) ((_opts)->p_feature_unit != 0) -#define EPOUT_FU(_opts) ((_opts)->c_feature_unit != 0) - struct f_uac_opts { struct usb_function_instance func_inst; int c_chmask; int c_srate[UAC_MAX_RATES]; int c_srate_active; int c_ssize; - int c_feature_unit; int p_chmask; int p_srate[UAC_MAX_RATES]; int p_srate_active; int p_ssize; - int p_feature_unit; int req_number; unsigned bound:1; @@ -159,12 +150,6 @@ struct f_uac { u8 ac_intf, as_in_intf, as_out_intf; u8 ac_alt, as_in_alt, as_out_alt; /* needed for get_alt() */ int ctl_id; - - struct list_head cs; - u8 set_cmd; - u8 get_cmd; - struct usb_audio_control *set_con; - struct usb_audio_control *get_con; }; static inline struct f_uac *func_to_uac(struct usb_function *f) diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h index 899c84e7c738..ead8c9a47c6a 100644 --- a/include/linux/usb/audio-v2.h +++ b/include/linux/usb/audio-v2.h @@ -168,20 +168,6 @@ struct uac2_effect_unit_descriptor { __u8 bmaControls[]; /* variable length */ } __attribute__((packed)); -#define UAC2_DT_FEATURE_UNIT_SIZE(ch) (6 + ((ch) + 1) * 4) - -/* As above, but more useful for defining your own descriptors: */ -#define DECLARE_UAC2_FEATURE_UNIT_DESCRIPTOR(ch) \ -struct uac2_feature_unit_descriptor_##ch { \ - __u8 bLength; \ - __u8 bDescriptorType; \ - __u8 bDescriptorSubtype; \ - __u8 bUnitID; \ - __u8 bSourceID; \ - __le32 bmaControls[ch + 1]; \ - __u8 iFeature; \ -} __attribute__((packed)) - /* 4.9.2 Class-Specific AS Interface Descriptor */ struct uac2_as_header_descriptor { @@ -345,9 +331,6 @@ struct uac2_interrupt_data_msg { #define UAC2_FU_OVERFLOW 0x0f #define UAC2_FU_LATENCY 0x10 -#define UAC2_CONTROL_BIT_RO(CS) (0x01 << (((CS) - 1) << 1)) -#define UAC2_CONTROL_BIT_RW(CS) (0x03 << (((CS) - 1) << 1)) - /* A.17.8.1 Parametric Equalizer Section Effect Unit Control Selectors */ #define UAC2_PE_UNDEFINED 0x00 #define UAC2_PE_ENABLE 0x01 diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index 646cb0a8dcd6..170acd500ea1 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h @@ -31,7 +31,6 @@ struct usb_audio_control { int data[5]; int (*set)(struct usb_audio_control *con, u8 cmd, int value); int (*get)(struct usb_audio_control *con, u8 cmd); - void *context; }; struct usb_audio_control_selector {