From patchwork Wed Oct 18 04:39:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Charles Yi X-Patchwork-Id: 13426332 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8BDB63E for ; Wed, 18 Oct 2023 04:39:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="j4H81xtV" Received: from m15.mail.163.com (m15.mail.163.com [45.254.50.220]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 5FD783AB1; Tue, 17 Oct 2023 21:39:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-Id:MIME-Version; bh=9+bkJ 6RZ2frbzu8BEZWdCRHTd8pNqz+uHuhFamiuem0=; b=j4H81xtVsI23dfAIUvNIc ZX6FL9CQBvm1EMyQxO8taqRmirnu6Jl8dQ4MTXxv/7lJprO3PdPPqZ5z31BasQIr O0fZLS5EjWhDgW5nw+hH0xrOQ3qEWJefGMQJwFq35isx63dSByAjVPhMpJyiAZNo 93KIpBB6nUbACFULH/cyAo= Received: from ubuntu.. (unknown [171.83.47.247]) by zwqz-smtp-mta-g1-0 (Coremail) with SMTP id _____wC3FetvYS9lkz9qAw--.331S2; Wed, 18 Oct 2023 12:39:11 +0800 (CST) From: Charles Yi To: gregkh@linuxfoundation.org Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Charles Yi Subject: [PATCH v2] usb: gadget: f_uac1: add adaptive sync support for capture Date: Wed, 18 Oct 2023 12:39:07 +0800 Message-Id: <20231018043907.1206817-1-be286@163.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-CM-TRANSID: _____wC3FetvYS9lkz9qAw--.331S2 X-Coremail-Antispam: 1Uf129KBjvJXoWxAr15JF45Xr17KrWDWry7Awb_yoWrCr4Upw 4UC3y0yr45ArZIqr4rAF4rAF43Aa1xG345GrW7W3yYgFsxt3sYva42yryFkF47AFWrCw40 qF4Fgw1a9w4kCrJanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0pRrcT9UUUUU= X-Originating-IP: [171.83.47.247] X-CM-SenderInfo: dehsmli6rwjhhfrp/1tbiWwkM0mI0cUfwVAABsJ X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net UAC1 has it's own freerunning clock and can update Host about real clock frequency through feedback endpoint so Host can align number of samples sent to the UAC1 to prevent overruns/underruns. Change UAC1 driver to make it configurable through additional 'c_sync' configfs file. Default remains 'asynchronous' with possibility to switch it to 'adaptive'. Signed-off-by: Charles Yi --- drivers/usb/gadget/function/f_uac1.c | 30 ++++++++++++++++++++++++++++ drivers/usb/gadget/function/u_uac1.h | 2 ++ 2 files changed, 32 insertions(+) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 6f0e1d803dc2..7a6fcb40bb46 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -33,6 +33,8 @@ #define FUOUT_EN(_opts) ((_opts)->c_mute_present \ || (_opts)->c_volume_present) +#define EPOUT_FBACK_IN_EN(_opts) ((_opts)->c_sync == USB_ENDPOINT_SYNC_ASYNC) + struct f_uac1 { struct g_audio g_audio; u8 ac_intf, as_in_intf, as_out_intf; @@ -227,6 +229,16 @@ static struct uac_iso_endpoint_descriptor as_iso_out_desc = { .wLockDelay = cpu_to_le16(1), }; +static struct usb_endpoint_descriptor as_fback_ep_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_USAGE_FEEDBACK, + .wMaxPacketSize = cpu_to_le16(3), + .bInterval = 1, +}; + static struct uac_format_type_i_discrete_descriptor as_in_type_i_desc = { .bLength = 0, /* filled on rate setup */ .bDescriptorType = USB_DT_CS_INTERFACE, @@ -280,6 +292,7 @@ static struct usb_descriptor_header *f_audio_desc[] = { (struct usb_descriptor_header *)&as_out_ep_desc, (struct usb_descriptor_header *)&as_iso_out_desc, + (struct usb_descriptor_header *)&as_fback_ep_desc, (struct usb_descriptor_header *)&as_in_interface_alt_0_desc, (struct usb_descriptor_header *)&as_in_interface_alt_1_desc, @@ -1107,6 +1120,9 @@ static void setup_descriptor(struct f_uac1_opts *opts) 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 (EPOUT_FBACK_IN_EN(opts)) { + f_audio_desc[i++] = USBDHDR(&as_fback_ep_desc); + } } if (EPIN_EN(opts)) { f_audio_desc[i++] = USBDHDR(&as_in_interface_alt_0_desc); @@ -1317,6 +1333,12 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) ac_header_desc->baInterfaceNr[ba_iface_id++] = status; uac1->as_out_intf = status; uac1->as_out_alt = 0; + + if (EPOUT_FBACK_IN_EN(audio_opts)) { + as_out_ep_desc.bmAttributes = + USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC; + as_out_interface_alt_1_desc.bNumEndpoints++; + } } if (EPIN_EN(audio_opts)) { @@ -1354,6 +1376,12 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) goto err_free_fu; audio->out_ep = ep; audio->out_ep->desc = &as_out_ep_desc; + if (EPOUT_FBACK_IN_EN(audio_opts)) { + audio->in_ep_fback = usb_ep_autoconfig(gadget, &as_fback_ep_desc); + if (!audio->in_ep_fback) { + goto err_free_fu; + } + } } if (EPIN_EN(audio_opts)) { @@ -1685,6 +1713,8 @@ static struct usb_function_instance *f_audio_alloc_inst(void) opts->req_number = UAC1_DEF_REQ_NUM; + opts->c_sync = UAC1_DEF_CSYNC; + snprintf(opts->function_name, sizeof(opts->function_name), "AC Interface"); return &opts->func_inst; diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index f7a616760e31..c6e2271e8cdd 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h @@ -27,6 +27,7 @@ #define UAC1_DEF_MAX_DB 0 /* 0 dB */ #define UAC1_DEF_RES_DB (1*256) /* 1 dB */ +#define UAC1_DEF_CSYNC USB_ENDPOINT_SYNC_ASYNC struct f_uac1_opts { struct usb_function_instance func_inst; @@ -56,6 +57,7 @@ struct f_uac1_opts { struct mutex lock; int refcnt; + int c_sync; }; #endif /* __U_UAC1_H */