From 1e50aec53683b29b21f07e4758d84df33ce050db Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Wed, 1 Dec 2021 19:50:18 +0800 Subject: [PATCH] Revert "FROMLIST: usb: gadget: f_uac*: Support multiple sampling rates" This reverts commit 37ed8f46073fa95edb98eeb29627e754423f24fd. Signed-off-by: Tao Huang Change-Id: Id61128a4036dbc8384bc60da8f8a586b9b697800 --- drivers/usb/gadget/function/f_uac1.c | 120 +++++---------------- drivers/usb/gadget/function/f_uac2.c | 144 +++++++------------------- drivers/usb/gadget/function/u_audio.c | 127 ++--------------------- drivers/usb/gadget/function/u_audio.h | 9 +- drivers/usb/gadget/function/u_uac.h | 68 +----------- 5 files changed, 76 insertions(+), 392 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 7b586f57af3f..3af8a1cd172e 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -3,7 +3,6 @@ * f_uac1.c -- USB Audio Class 1.0 Function (using u_audio API) * * Copyright (C) 2016 Ruslan Bilovol - * Copyright (C) 2017 Julian Scheel * * This driver doesn't expect any real Audio codec to be present * on the device - the audio streams are simply sinked to and @@ -183,18 +182,16 @@ static struct uac1_as_header_descriptor as_in_header_desc = { .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM), }; -DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(UAC_MAX_RATES); -#define uac_format_type_i_discrete_descriptor \ - uac_format_type_i_discrete_descriptor_##UAC_MAX_RATES +DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); -static struct uac_format_type_i_discrete_descriptor as_out_type_i_desc = { - .bLength = 0, /* filled on rate setup */ +static struct uac_format_type_i_discrete_descriptor_1 as_out_type_i_desc = { + .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_FORMAT_TYPE, .bFormatType = UAC_FORMAT_TYPE_I, .bSubframeSize = 2, .bBitResolution = 16, - .bSamFreqType = 0, /* filled on rate setup */ + .bSamFreqType = 1, }; /* Standard ISO OUT Endpoint Descriptor */ @@ -218,14 +215,14 @@ static struct uac_iso_endpoint_descriptor as_iso_out_desc = { .wLockDelay = cpu_to_le16(1), }; -static struct uac_format_type_i_discrete_descriptor as_in_type_i_desc = { - .bLength = 0, /* filled on rate setup */ +static struct uac_format_type_i_discrete_descriptor_1 as_in_type_i_desc = { + .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_FORMAT_TYPE, .bFormatType = UAC_FORMAT_TYPE_I, .bSubframeSize = 2, .bBitResolution = 16, - .bSamFreqType = 0, /* filled on rate setup */ + .bSamFreqType = 1, }; /* Standard ISO OUT Endpoint Descriptor */ @@ -324,57 +321,23 @@ static struct usb_gadget_strings *uac1_strings[] = { * This function is an ALSA sound card following USB Audio Class Spec 1.0. */ -static void uac_cs_attr_sample_rate(struct usb_ep *ep, struct usb_request *req) -{ - struct usb_function *fn = ep->driver_data; - struct usb_composite_dev *cdev = fn->config->cdev; - struct g_audio *agdev = func_to_g_audio(fn); - struct f_uac *uac1 = func_to_uac(fn); - struct f_uac_opts *opts = g_audio_to_uac_opts(agdev); - u8 *buf = (u8 *)req->buf; - u32 val = 0; - - if (req->actual != 3) { - WARN(cdev, "Invalid data size for UAC_EP_CS_ATTR_SAMPLE_RATE.\n"); - return; - } - - val = buf[0] | (buf[1] << 8) | (buf[2] << 16); - - if (uac1->ctl_id == agdev->in_ep->address) { - opts->p_srate_active = val; - u_audio_set_playback_srate(agdev, opts->p_srate_active); - } else if (uac1->ctl_id == agdev->out_ep->address) { - opts->c_srate_active = val; - u_audio_set_capture_srate(agdev, opts->c_srate_active); - } -} - static int audio_set_endpoint_req(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { struct usb_composite_dev *cdev = f->config->cdev; - struct usb_request *req = f->config->cdev->req; - struct f_uac *uac1 = func_to_uac(f); int value = -EOPNOTSUPP; u8 ep = le16_to_cpu(ctrl->wIndex) & 0xff; u16 len = le16_to_cpu(ctrl->wLength); u16 w_value = le16_to_cpu(ctrl->wValue); - u8 cs = w_value >> 8; DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", ctrl->bRequest, w_value, len, ep); switch (ctrl->bRequest) { - case UAC_SET_CUR: { - if (cs == UAC_EP_CS_ATTR_SAMPLE_RATE) { - cdev->gadget->ep0->driver_data = f; - uac1->ctl_id = ep; - req->complete = uac_cs_attr_sample_rate; - } + case UAC_SET_CUR: value = len; break; - } + case UAC_SET_MIN: break; @@ -398,34 +361,16 @@ static int audio_get_endpoint_req(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { struct usb_composite_dev *cdev = f->config->cdev; - struct usb_request *req = f->config->cdev->req; - struct g_audio *agdev = func_to_g_audio(f); - struct f_uac_opts *opts = g_audio_to_uac_opts(agdev); - u8 *buf = (u8 *)req->buf; int value = -EOPNOTSUPP; u8 ep = le16_to_cpu(ctrl->wIndex) & 0xff; u16 len = le16_to_cpu(ctrl->wLength); u16 w_value = le16_to_cpu(ctrl->wValue); - u8 cs = w_value >> 8; - u32 val = 0; DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", ctrl->bRequest, w_value, len, ep); switch (ctrl->bRequest) { - case UAC_GET_CUR: { - if (cs == UAC_EP_CS_ATTR_SAMPLE_RATE) { - if (ep == agdev->in_ep->address) - val = opts->p_srate_active; - else if (ep == agdev->out_ep->address) - val = opts->c_srate_active; - buf[2] = (val >> 16) & 0xff; - buf[1] = (val >> 8) & 0xff; - buf[0] = val & 0xff; - } - value = len; - break; - } + case UAC_GET_CUR: case UAC_GET_MIN: case UAC_GET_MAX: case UAC_GET_RES: @@ -573,8 +518,9 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) struct f_uac_opts *audio_opts; struct usb_ep *ep = NULL; struct usb_string *us; + u8 *sam_freq; + int rate; int status; - int idx, i; audio_opts = container_of(f->fi, struct f_uac_opts, func_inst); @@ -608,23 +554,12 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) as_in_type_i_desc.bBitResolution = audio_opts->p_ssize * 8; /* Set sample rates */ - for (i = 0, idx = 0; i < UAC_MAX_RATES; i++) { - if (audio_opts->c_srate[i] == 0) - break; - memcpy(as_out_type_i_desc.tSamFreq[idx++], - &audio_opts->c_srate[i], 3); - } - as_out_type_i_desc.bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(idx); - as_out_type_i_desc.bSamFreqType = idx; - - for (i = 0, idx = 0; i < UAC_MAX_RATES; i++) { - if (audio_opts->p_srate[i] == 0) - break; - memcpy(as_in_type_i_desc.tSamFreq[idx++], - &audio_opts->p_srate[i], 3); - } - as_in_type_i_desc.bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(idx); - as_in_type_i_desc.bSamFreqType = idx; + rate = audio_opts->c_srate; + sam_freq = as_out_type_i_desc.tSamFreq[0]; + memcpy(sam_freq, &rate, 3); + rate = audio_opts->p_srate; + sam_freq = as_in_type_i_desc.tSamFreq[0]; + memcpy(sam_freq, &rate, 3); /* allocate instance-specific interface IDs, and patch descriptors */ status = usb_interface_id(c, f); @@ -679,14 +614,10 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize); audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize); audio->params.c_chmask = audio_opts->c_chmask; - memcpy(audio->params.c_srate, audio_opts->c_srate, - sizeof(audio->params.c_srate)); - audio->params.c_srate_active = audio_opts->c_srate_active; + audio->params.c_srate = audio_opts->c_srate; audio->params.c_ssize = audio_opts->c_ssize; audio->params.p_chmask = audio_opts->p_chmask; - memcpy(audio->params.p_srate, audio_opts->p_srate, - sizeof(audio->params.p_srate)); - audio->params.p_srate_active = audio_opts->p_srate_active; + audio->params.p_srate = audio_opts->p_srate; audio->params.p_ssize = audio_opts->p_ssize; audio->params.req_number = audio_opts->req_number; @@ -709,14 +640,13 @@ static struct configfs_item_operations f_uac1_item_ops = { }; UAC_ATTRIBUTE(c_chmask); +UAC_ATTRIBUTE(c_srate); UAC_ATTRIBUTE(c_ssize); UAC_ATTRIBUTE(p_chmask); +UAC_ATTRIBUTE(p_srate); UAC_ATTRIBUTE(p_ssize); UAC_ATTRIBUTE(req_number); -UAC_RATE_ATTRIBUTE(p_srate); -UAC_RATE_ATTRIBUTE(c_srate); - static struct configfs_attribute *f_uac1_attrs[] = { &f_uac_opts_attr_c_chmask, &f_uac_opts_attr_c_srate, @@ -757,12 +687,10 @@ static struct usb_function_instance *f_audio_alloc_inst(void) &f_uac1_func_type); opts->c_chmask = UAC_DEF_CCHMASK; - opts->c_srate[0] = UAC_DEF_CSRATE; - opts->c_srate_active = UAC_DEF_CSRATE; + opts->c_srate = UAC_DEF_CSRATE; opts->c_ssize = UAC_DEF_CSSIZE; opts->p_chmask = UAC_DEF_PCHMASK; - opts->p_srate[0] = UAC_DEF_PSRATE; - opts->p_srate_active = UAC_DEF_PSRATE; + opts->p_srate = UAC_DEF_PSRATE; opts->p_ssize = UAC_DEF_PSSIZE; opts->req_number = UAC_DEF_REQ_NUM; return &opts->func_inst; diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index b64985c6453d..9a2df37fc87d 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -5,7 +5,6 @@ * Copyright (C) 2011 * Yadwinder Singh (yadi.brar01@gmail.com) * Jaswinder Singh (jaswinder.singh@linaro.org) - * Copyright (C) 2017 Julian Scheel */ #include @@ -60,11 +59,14 @@ enum { STR_AS_IN_ALT1, }; +static char clksrc_in[8]; +static char clksrc_out[8]; + static struct usb_string strings_fn[] = { [STR_ASSOC].s = "Source/Sink", [STR_IF_CTRL].s = "Topology Control", - [STR_CLKSRC_IN].s = "Input clock", - [STR_CLKSRC_OUT].s = "Output clock", + [STR_CLKSRC_IN].s = clksrc_in, + [STR_CLKSRC_OUT].s = clksrc_out, [STR_USB_IT].s = "USBH Out", [STR_IO_IT].s = "USBD Out", [STR_USB_OT].s = "USBH In", @@ -117,7 +119,7 @@ static struct uac_clock_source_descriptor in_clk_src_desc = { .bDescriptorSubtype = UAC2_CLOCK_SOURCE, /* .bClockID = DYNAMIC */ .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED, - .bmControls = (CONTROL_RDWR << CLK_FREQ_CTRL), + .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL), .bAssocTerminal = 0, }; @@ -129,7 +131,7 @@ static struct uac_clock_source_descriptor out_clk_src_desc = { .bDescriptorSubtype = UAC2_CLOCK_SOURCE, /* .bClockID = DYNAMIC */ .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED, - .bmControls = (CONTROL_RDWR << CLK_FREQ_CTRL), + .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL), .bAssocTerminal = 0, }; @@ -422,26 +424,19 @@ struct cntrl_cur_lay3 { }; struct cntrl_range_lay3 { + __le16 wNumSubRanges; __le32 dMIN; __le32 dMAX; __le32 dRES; } __packed; -#define ranges_size(c) (sizeof(c.wNumSubRanges) + c.wNumSubRanges \ - * sizeof(struct cntrl_ranges_lay3)) -struct cntrl_ranges_lay3 { - __u16 wNumSubRanges; - struct cntrl_range_lay3 r[UAC_MAX_RATES]; -} __packed; - static int set_ep_max_packet_size(const struct f_uac_opts *uac2_opts, struct usb_endpoint_descriptor *ep_desc, enum usb_device_speed speed, bool is_playback) { - int chmask, srate = 0, ssize; + int chmask, srate, ssize; u16 max_size_bw, max_size_ep; unsigned int factor; - int i; switch (speed) { case USB_SPEED_FULL: @@ -460,21 +455,11 @@ static int set_ep_max_packet_size(const struct f_uac_opts *uac2_opts, if (is_playback) { chmask = uac2_opts->p_chmask; - for (i = 0; i < UAC_MAX_RATES; i++) { - if (uac2_opts->p_srate[i] == 0) - break; - if (uac2_opts->p_srate[i] > srate) - srate = uac2_opts->p_srate[i]; - } + srate = uac2_opts->p_srate; ssize = uac2_opts->p_ssize; } else { chmask = uac2_opts->c_chmask; - for (i = 0; i < UAC_MAX_RATES; i++) { - if (uac2_opts->c_srate[i] == 0) - break; - if (uac2_opts->c_srate[i] > srate) - srate = uac2_opts->c_srate[i]; - } + srate = uac2_opts->c_srate; ssize = uac2_opts->c_ssize; } @@ -650,6 +635,9 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) as_in_fmt1_desc.bSubslotSize = uac2_opts->p_ssize; as_in_fmt1_desc.bBitResolution = uac2_opts->p_ssize * 8; + snprintf(clksrc_in, sizeof(clksrc_in), "%uHz", uac2_opts->p_srate); + snprintf(clksrc_out, sizeof(clksrc_out), "%uHz", uac2_opts->c_srate); + ret = usb_interface_id(cfg, fn); if (ret < 0) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); @@ -750,14 +738,10 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) agdev->gadget = gadget; agdev->params.p_chmask = uac2_opts->p_chmask; - memcpy(agdev->params.p_srate, uac2_opts->p_srate, - sizeof(agdev->params.p_srate)); - agdev->params.p_srate_active = uac2_opts->p_srate_active; + agdev->params.p_srate = uac2_opts->p_srate; agdev->params.p_ssize = uac2_opts->p_ssize; agdev->params.c_chmask = uac2_opts->c_chmask; - memcpy(agdev->params.c_srate, uac2_opts->c_srate, - sizeof(agdev->params.c_srate)); - agdev->params.c_srate_active = uac2_opts->c_srate_active; + agdev->params.c_srate = uac2_opts->c_srate; agdev->params.c_ssize = uac2_opts->c_ssize; agdev->params.req_number = uac2_opts->req_number; ret = g_audio_setup(agdev, "UAC2 PCM", "UAC2_Gadget"); @@ -863,8 +847,8 @@ in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) int p_srate, c_srate; opts = g_audio_to_uac_opts(agdev); - p_srate = opts->p_srate_active; - c_srate = opts->c_srate_active; + p_srate = opts->p_srate; + c_srate = opts->c_srate; if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { struct cntrl_cur_lay3 c; @@ -875,7 +859,6 @@ in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) else if (entity_id == USB_OUT_CLK_ID) c.dCUR = cpu_to_le32(c_srate); - DBG(fn->config->cdev, "%s(): %d\n", __func__, c.dCUR); value = min_t(unsigned, w_length, sizeof c); memcpy(req->buf, &c, value); } else if (control_selector == UAC2_CS_CONTROL_CLOCK_VALID) { @@ -901,40 +884,28 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) u16 w_value = le16_to_cpu(cr->wValue); u8 entity_id = (w_index >> 8) & 0xff; u8 control_selector = w_value >> 8; - struct cntrl_ranges_lay3 rs; + struct cntrl_range_lay3 r; int value = -EOPNOTSUPP; - int srate = 0; - int i; + int p_srate, c_srate; opts = g_audio_to_uac_opts(agdev); + p_srate = opts->p_srate; + c_srate = opts->c_srate; if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { - rs.wNumSubRanges = 0; - for (i = 0; i < UAC_MAX_RATES; i++) { - if (entity_id == USB_IN_CLK_ID) - srate = opts->p_srate[i]; - else if (entity_id == USB_OUT_CLK_ID) - srate = opts->c_srate[i]; - else - return -EOPNOTSUPP; + if (entity_id == USB_IN_CLK_ID) + r.dMIN = cpu_to_le32(p_srate); + else if (entity_id == USB_OUT_CLK_ID) + r.dMIN = cpu_to_le32(c_srate); + else + return -EOPNOTSUPP; - if (srate == 0) - break; + r.dMAX = r.dMIN; + r.dRES = 0; + r.wNumSubRanges = cpu_to_le16(1); - rs.r[rs.wNumSubRanges].dMIN = srate; - rs.r[rs.wNumSubRanges].dMAX = srate; - rs.r[rs.wNumSubRanges].dRES = 0; - rs.wNumSubRanges++; - DBG(fn->config->cdev, - "%s(): clk %d: report rate %d. %d\n", - __func__, entity_id, rs.wNumSubRanges, - srate); - } - - value = min_t(unsigned int, w_length, ranges_size(rs)); - DBG(fn->config->cdev, "%s(): send %d rates, size %d\n", - __func__, rs.wNumSubRanges, value); - memcpy(req->buf, &rs, value); + value = min_t(unsigned, w_length, sizeof r); + memcpy(req->buf, &r, value); } else { dev_err(&agdev->gadget->dev, "%s:%d control_selector=%d TODO!\n", @@ -947,7 +918,6 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) static int ac_rq_in(struct usb_function *fn, const struct usb_ctrlrequest *cr) { - 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) @@ -956,50 +926,15 @@ ac_rq_in(struct usb_function *fn, const struct usb_ctrlrequest *cr) return -EOPNOTSUPP; } -static void uac2_cs_control_sam_freq(struct usb_ep *ep, struct usb_request *req) -{ - struct usb_function *fn = ep->driver_data; - struct usb_composite_dev *cdev = fn->config->cdev; - struct g_audio *agdev = func_to_g_audio(fn); - struct f_uac *uac2 = func_to_uac(fn); - struct f_uac_opts *opts = g_audio_to_uac_opts(agdev); - u32 val; - - if (req->actual != 4) { - WARN(cdev, "Invalid data size for UAC2_CS_CONTROL_SAM_FREQ.\n"); - return; - } - - val = le32_to_cpu(*((u32 *)req->buf)); - if (uac2->ctl_id == USB_IN_CLK_ID) { - opts->p_srate_active = val; - u_audio_set_playback_srate(agdev, opts->p_srate_active); - } else if (uac2->ctl_id == USB_OUT_CLK_ID) { - opts->c_srate_active = val; - u_audio_set_capture_srate(agdev, opts->c_srate_active); - } -} - static int 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; u16 w_length = le16_to_cpu(cr->wLength); - struct f_uac *uac2 = func_to_uac(fn); u16 w_value = le16_to_cpu(cr->wValue); - u16 w_index = le16_to_cpu(cr->wIndex); u8 control_selector = w_value >> 8; - u8 clock_id = w_index >> 8; - if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { - DBG(cdev, "control_selector UAC2_CS_CONTROL_SAM_FREQ, clock: %d\n", - clock_id); - cdev->gadget->ep0->driver_data = fn; - uac2->ctl_id = clock_id; - req->complete = uac2_cs_control_sam_freq; + if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) return w_length; - } return -EOPNOTSUPP; } @@ -1064,14 +999,13 @@ static struct configfs_item_operations f_uac2_item_ops = { }; UAC_ATTRIBUTE(p_chmask); +UAC_ATTRIBUTE(p_srate); UAC_ATTRIBUTE(p_ssize); UAC_ATTRIBUTE(c_chmask); +UAC_ATTRIBUTE(c_srate); UAC_ATTRIBUTE(c_ssize); UAC_ATTRIBUTE(req_number); -UAC_RATE_ATTRIBUTE(p_srate); -UAC_RATE_ATTRIBUTE(c_srate); - static struct configfs_attribute *f_uac2_attrs[] = { &f_uac_opts_attr_p_chmask, &f_uac_opts_attr_p_srate, @@ -1112,12 +1046,10 @@ static struct usb_function_instance *afunc_alloc_inst(void) &f_uac2_func_type); opts->p_chmask = UAC_DEF_PCHMASK; - opts->p_srate[0] = UAC_DEF_PSRATE; - opts->p_srate_active = UAC_DEF_PSRATE; + opts->p_srate = UAC_DEF_PSRATE; opts->p_ssize = UAC_DEF_PSSIZE; opts->c_chmask = UAC_DEF_CCHMASK; - opts->c_srate[0] = UAC_DEF_CSRATE; - opts->c_srate_active = UAC_DEF_CSRATE; + opts->c_srate = UAC_DEF_CSRATE; opts->c_ssize = UAC_DEF_CSSIZE; opts->req_number = UAC_DEF_REQ_NUM; return &opts->func_inst; diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index eeffbbf9f1b3..828452c74684 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 @@ -249,17 +248,18 @@ static int uac_pcm_open(struct snd_pcm_substream *substream) { struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - struct g_audio *audio_dev = uac->audio_dev; + struct g_audio *audio_dev; struct uac_params *params; int p_ssize, c_ssize; int p_srate, c_srate; int p_chmask, c_chmask; + audio_dev = uac->audio_dev; params = &audio_dev->params; p_ssize = params->p_ssize; c_ssize = params->c_ssize; - p_srate = params->p_srate_active; - c_srate = params->c_srate_active; + p_srate = params->p_srate; + c_srate = params->c_srate; p_chmask = params->p_chmask; c_chmask = params->c_chmask; uac->p_residue = 0; @@ -288,52 +288,6 @@ static int uac_pcm_open(struct snd_pcm_substream *substream) return 0; } -static int uac_pcm_rate_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 324000; - return 0; -} - -static int uac_pcm_rate_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_uac_chip *uac = snd_kcontrol_chip(kcontrol); - struct g_audio *audio_dev = uac->audio_dev; - struct uac_params *params = &audio_dev->params; - - if (kcontrol->private_value == SNDRV_PCM_STREAM_CAPTURE) - ucontrol->value.integer.value[0] = params->c_srate_active; - else if (kcontrol->private_value == SNDRV_PCM_STREAM_PLAYBACK) - ucontrol->value.integer.value[0] = params->p_srate_active; - else - return -EINVAL; - - return 0; -} - -static struct snd_kcontrol_new uac_pcm_controls[] = { -{ - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "Capture Rate", - .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .info = uac_pcm_rate_info, - .get = uac_pcm_rate_get, - .private_value = SNDRV_PCM_STREAM_CAPTURE, -}, -{ - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "Playback Rate", - .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .info = uac_pcm_rate_info, - .get = uac_pcm_rate_get, - .private_value = SNDRV_PCM_STREAM_PLAYBACK, -}, -}; - /* ALSA cries without these function pointers */ static int uac_pcm_null(struct snd_pcm_substream *substream) { @@ -381,59 +335,6 @@ static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep) dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); } -static struct snd_kcontrol *u_audio_get_ctl(struct g_audio *audio_dev, - const char *name) -{ - struct snd_ctl_elem_id elem_id; - - memset(&elem_id, 0, sizeof(elem_id)); - elem_id.iface = SNDRV_CTL_ELEM_IFACE_PCM; - strlcpy(elem_id.name, name, sizeof(elem_id.name)); - return snd_ctl_find_id(audio_dev->uac->card, &elem_id); -} - -int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate) -{ - struct snd_kcontrol *ctl = u_audio_get_ctl(audio_dev, "Capture Rate"); - struct uac_params *params = &audio_dev->params; - int i; - - for (i = 0; i < UAC_MAX_RATES; i++) { - if (params->c_srate[i] == srate) { - params->c_srate_active = srate; - snd_ctl_notify(audio_dev->uac->card, - SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id); - return 0; - } - if (params->c_srate[i] == 0) - break; - } - - return -EINVAL; -} -EXPORT_SYMBOL_GPL(u_audio_set_capture_srate); - -int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate) -{ - struct snd_kcontrol *ctl = u_audio_get_ctl(audio_dev, "Playback Rate"); - struct uac_params *params = &audio_dev->params; - int i; - - for (i = 0; i < UAC_MAX_RATES; i++) { - if (params->p_srate[i] == srate) { - params->p_srate_active = srate; - snd_ctl_notify(audio_dev->uac->card, - SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id); - return 0; - } - if (params->p_srate[i] == 0) - break; - } - - return -EINVAL; -} -EXPORT_SYMBOL_GPL(u_audio_set_playback_srate); - int u_audio_start_capture(struct g_audio *audio_dev) { struct snd_uac_chip *uac = audio_dev->uac; @@ -493,11 +394,10 @@ int u_audio_start_playback(struct g_audio *audio_dev) struct usb_ep *ep; struct uac_rtd_params *prm; struct uac_params *params = &audio_dev->params; - unsigned int factor, rate; + unsigned int factor; const struct usb_endpoint_descriptor *ep_desc; int req_len, i; - dev_dbg(dev, "start playback with rate %d\n", params->p_srate_active); ep = audio_dev->in_ep; prm = &uac->p_prm; config_ep_by_speed(gadget, &audio_dev->func, ep); @@ -513,13 +413,15 @@ int u_audio_start_playback(struct g_audio *audio_dev) /* pre-compute some values for iso_complete() */ uac->p_framesize = params->p_ssize * num_channels(params->p_chmask); - rate = params->p_srate_active * uac->p_framesize; uac->p_interval = factor / (1 << (ep_desc->bInterval - 1)); - uac->p_pktsize = min_t(unsigned int, rate / uac->p_interval, + uac->p_pktsize = min_t(unsigned int, + uac->p_framesize * + (params->p_srate / uac->p_interval), ep->maxpacket); if (uac->p_pktsize < ep->maxpacket) - uac->p_pktsize_residue = rate % uac->p_interval; + uac->p_pktsize_residue = uac->p_framesize * + (params->p_srate % uac->p_interval); else uac->p_pktsize_residue = 0; @@ -569,7 +471,6 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, struct uac_params *params; int p_chmask, c_chmask; int err; - int i; if (!g_audio) return -EINVAL; @@ -661,14 +562,6 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, NULL, 0, BUFF_SIZE_MAX); - /* Add controls */ - for (i = 0; i < ARRAY_SIZE(uac_pcm_controls); i++) { - err = snd_ctl_add(card, - snd_ctl_new1(&uac_pcm_controls[i], uac)); - if (err < 0) - goto snd_fail; - } - err = snd_card_register(card); if (!err) diff --git a/drivers/usb/gadget/function/u_audio.h b/drivers/usb/gadget/function/u_audio.h index cd31dd292e50..5ea6b86f1fda 100644 --- a/drivers/usb/gadget/function/u_audio.h +++ b/drivers/usb/gadget/function/u_audio.h @@ -11,18 +11,15 @@ #include -#define UAC_MAX_RATES 10 struct uac_params { /* playback */ int p_chmask; /* channel mask */ - int p_srate[UAC_MAX_RATES]; /* rate in Hz */ - int p_srate_active; /* selected rate in Hz */ + int p_srate; /* rate in Hz */ int p_ssize; /* sample size */ /* capture */ int c_chmask; /* channel mask */ - int c_srate[UAC_MAX_RATES]; /* rate in Hz */ - int c_srate_active; /* selected rate in Hz */ + int c_srate; /* rate in Hz */ int c_ssize; /* sample size */ int req_number; /* number of preallocated requests */ @@ -84,7 +81,5 @@ int u_audio_start_capture(struct g_audio *g_audio); void u_audio_stop_capture(struct g_audio *g_audio); 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); #endif /* __U_AUDIO_H */ diff --git a/drivers/usb/gadget/function/u_uac.h b/drivers/usb/gadget/function/u_uac.h index ae64a3b373cf..c473c8e58c26 100644 --- a/drivers/usb/gadget/function/u_uac.h +++ b/drivers/usb/gadget/function/u_uac.h @@ -13,7 +13,6 @@ #define __U_UAC_H #include -#include "u_audio.h" #define UAC_DEF_CCHMASK 0x3 #define UAC_DEF_CSRATE 48000 @@ -28,12 +27,10 @@ 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_srate; int c_ssize; int p_chmask; - int p_srate[UAC_MAX_RATES]; - int p_srate_active; + int p_srate; int p_ssize; int req_number; unsigned bound:1; @@ -85,71 +82,10 @@ end: \ \ CONFIGFS_ATTR(f_uac_opts_, name) -#define UAC_RATE_ATTRIBUTE(name) \ -static ssize_t f_uac_opts_##name##_show(struct config_item *item, \ - char *page) \ -{ \ - struct f_uac_opts *opts = to_f_uac_opts(item); \ - int result = 0; \ - int i; \ - \ - mutex_lock(&opts->lock); \ - page[0] = '\0'; \ - for (i = 0; i < UAC_MAX_RATES; i++) { \ - if (opts->name[i] == 0) \ - continue; \ - result += sprintf(page + strlen(page), "%u,", \ - opts->name[i]); \ - } \ - if (strlen(page) > 0) \ - page[strlen(page) - 1] = '\n'; \ - mutex_unlock(&opts->lock); \ - \ - return result; \ -} \ - \ -static ssize_t f_uac_opts_##name##_store(struct config_item *item, \ - const char *page, size_t len) \ -{ \ - struct f_uac_opts *opts = to_f_uac_opts(item); \ - char *split_page = NULL; \ - int ret = -EINVAL; \ - char *token; \ - u32 num; \ - int i; \ - \ - mutex_lock(&opts->lock); \ - if (opts->refcnt) { \ - ret = -EBUSY; \ - goto end; \ - } \ - \ - i = 0; \ - memset(opts->name, 0x00, sizeof(opts->name)); \ - split_page = kstrdup(page, GFP_KERNEL); \ - while ((token = strsep(&split_page, ",")) != NULL) { \ - ret = kstrtou32(token, 0, &num); \ - if (ret) \ - goto end; \ - \ - opts->name[i++] = num; \ - opts->name##_active = num; \ - ret = len; \ - }; \ - \ -end: \ - kfree(split_page); \ - mutex_unlock(&opts->lock); \ - return ret; \ -} \ - \ -CONFIGFS_ATTR(f_uac_opts_, name) - struct f_uac { struct g_audio g_audio; 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; }; static inline struct f_uac *func_to_uac(struct usb_function *f)