[PATCHv2 0/3] USB Audio Gadget: Support multiple sampling rates
Sending v2 of this patch series, including fixes for build regressions introduced with the original series. I missed the usage of f_uac* in the legacy modules and did not test that. Fixed now, see patches changelog for details. This patch series adds support for exposing multiple supported sampling rates from UAC1 and UAC2 USB gadgets to the connected host. It is currently limited to up to ten discrete sampling frequencies. The USB specification does not actually limit this, but to avoid complex list handling I am using a static array for now. As the configfs bindings for f_uac1 and f_uac2 have been identical already, I decided to move the shared code for this out of the functions first. This avoids code duplication and simplifies the addition of the list parsing for sampling rates. The host can configure active sampling rate and the function adapts it's internal active rate automatically. On playback/capture start the rate is checked, so that the user recognizes rate mismatches. Furthermore the active rate is exposed as an amixer control with change notifications, so that users can check current rate upfront and get notified about updates. Julian Scheel (3): usb: gadget: f_uac1: Fix endpoint reading usb: gadget: f_uac*: Reduce code duplication usb: gadget: f_uac*: Support multiple sampling rates Documentation/ABI/testing/configfs-usb-gadget-uac1 | 4 +- Documentation/usb/gadget-testing.txt | 8 +- drivers/usb/gadget/function/f_uac1.c | 258 +- drivers/usb/gadget/function/f_uac2.c | 297 ++--- drivers/usb/gadget/function/u_audio.c | 118 +++- drivers/usb/gadget/function/u_audio.h | 9 +- drivers/usb/gadget/function/u_uac.h| 180 + drivers/usb/gadget/function/u_uac1.h | 41 --- drivers/usb/gadget/function/u_uac2.h | 44 --- drivers/usb/gadget/legacy/audio.c | 91 ++- 10 files changed, 608 insertions(+), 442 deletions(-) create mode 100644 drivers/usb/gadget/function/u_uac.h delete mode 100644 drivers/usb/gadget/function/u_uac1.h delete mode 100644 drivers/usb/gadget/function/u_uac2.h -- 2.13.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 3/3] usb: gadget: f_uac*: Support multiple sampling rates
Implement support for multiple sampling rates in the USB Audio gadgets. A list of sampling rates can be specified via configfs. All enabled sampling rates are sent to the USB host on request. When the host selects a sampling rate the internal active rate is updated. The currently configured rates are exposed through amixer controls. Also on pcm open from userspace the requested rated is checked against the currently configured rate of the host. Signed-off-by: Julian Scheel <jul...@jusst.de> --- Documentation/ABI/testing/configfs-usb-gadget-uac1 | 4 +- Documentation/usb/gadget-testing.txt | 8 +- drivers/usb/gadget/function/f_uac1.c | 120 + drivers/usb/gadget/function/f_uac2.c | 146 +++-- drivers/usb/gadget/function/u_audio.c | 119 - drivers/usb/gadget/function/u_audio.h | 9 +- drivers/usb/gadget/function/u_uac.h| 68 +- 7 files changed, 396 insertions(+), 78 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1 index abfe447c848f..ad2fa4a00918 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac1 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1 @@ -5,10 +5,10 @@ Description: The attributes: c_chmask - capture channel mask - c_srate - capture sampling rate + c_srate - list of capture sampling rates (comma-separataed) c_ssize - capture sample size (bytes) p_chmask - playback channel mask - p_srate - playback sampling rate + p_srate - list of playback sampling rates (comma-separated) p_ssize - playback sample size (bytes) req_number - the number of pre-allocated request for both capture and playback diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index fbc397d17e98..85878880 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -629,10 +629,10 @@ The function name to use when creating the function directory is "uac2". The uac2 function provides these attributes in its function directory: c_chmask - capture channel mask - c_srate - capture sampling rate + c_srate - list of capture sampling rates (comma-separated) c_ssize - capture sample size (bytes) p_chmask - playback channel mask - p_srate - playback sampling rate + p_srate - list of playback sampling rates (comma-separated) p_ssize - playback sample size (bytes) req_number - the number of pre-allocated request for both capture and playback @@ -790,10 +790,10 @@ The function name to use when creating the function directory is "uac1". The uac1 function provides these attributes in its function directory: c_chmask - capture channel mask - c_srate - capture sampling rate + c_srate - list of capture sampling rates (comma-separated) c_ssize - capture sample size (bytes) p_chmask - playback channel mask - p_srate - playback sampling rate + p_srate - list of playback sampling rates (comma-separated) p_ssize - playback sample size (bytes) req_number - the number of pre-allocated request for both capture and playback diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 6e86e4f704e1..d14777973b9f 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -2,6 +2,7 @@ * f_uac1.c -- USB Audio Class 1.0 Function (using u_audio API) * * Copyright (C) 2016 Ruslan Bilovol <ruslan.bilo...@gmail.com> + * Copyright (C) 2017 Julian Scheel <jul...@jusst.de> * * This driver doesn't expect any real Audio codec to be present * on the device - the audio streams are simply sinked to and @@ -175,16 +176,18 @@ static struct uac1_as_header_descriptor as_in_header_desc = { .wFormatTag = UAC_FORMAT_TYPE_I_PCM, }; -DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); +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 -static struct uac_format_type_i_discrete_descriptor_1 as_out_type_i_desc = { - .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), +static struct uac_format_type_i_discrete_descriptor as_out_type_i_desc = { + .bLength = 0, /* filled on rate setup */ .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_FORMAT_TYPE, .bFormatType = UAC_FORMAT_TYPE_I, .bSubframeSize =2, .bBitResolution = 16, - .bSamFreqType =
[PATCHv2 2/3] usb: gadget: f_uac*: Reduce code duplication
This replaces the dedicated headers for uac1 and uac2 functions with a shared header for both of them. Apart from unifying the struct names, further duplicated code for configfs setup is moved out of the function files into the shared header. Signed-off-by: Julian Scheel <jul...@jusst.de> --- Changes in v2: - Fix build as module - Fix build of legacy/audio module in f_uac1/f_uac2 mode drivers/usb/gadget/function/f_uac1.c | 142 -- drivers/usb/gadget/function/f_uac2.c | 161 ++ drivers/usb/gadget/function/u_audio.c | 1 - drivers/usb/gadget/function/u_uac.h | 116 drivers/usb/gadget/function/u_uac1.h | 41 - drivers/usb/gadget/function/u_uac2.h | 44 -- drivers/usb/gadget/legacy/audio.c | 91 +-- 7 files changed, 222 insertions(+), 374 deletions(-) create mode 100644 drivers/usb/gadget/function/u_uac.h delete mode 100644 drivers/usb/gadget/function/u_uac1.h delete mode 100644 drivers/usb/gadget/function/u_uac2.h diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index b955913bd7ea..6e86e4f704e1 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -21,18 +21,7 @@ #include #include "u_audio.h" -#include "u_uac1.h" - -struct f_uac1 { - 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() */ -}; - -static inline struct f_uac1 *func_to_uac1(struct usb_function *f) -{ - return container_of(f, struct f_uac1, g_audio.func); -} +#include "u_uac.h" /* * DESCRIPTORS ... most are static, but strings and full @@ -435,7 +424,7 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_composite_dev *cdev = f->config->cdev; struct usb_gadget *gadget = cdev->gadget; struct device *dev = >dev; - struct f_uac1 *uac1 = func_to_uac1(f); + struct f_uac *uac1 = func_to_uac(f); int ret = 0; /* No i/f has more than 2 alt settings */ @@ -480,7 +469,7 @@ static int f_audio_get_alt(struct usb_function *f, unsigned intf) struct usb_composite_dev *cdev = f->config->cdev; struct usb_gadget *gadget = cdev->gadget; struct device *dev = >dev; - struct f_uac1 *uac1 = func_to_uac1(f); + struct f_uac *uac1 = func_to_uac(f); if (intf == uac1->ac_intf) return uac1->ac_alt; @@ -498,7 +487,7 @@ static int f_audio_get_alt(struct usb_function *f, unsigned intf) static void f_audio_disable(struct usb_function *f) { - struct f_uac1 *uac1 = func_to_uac1(f); + struct f_uac *uac1 = func_to_uac(f); uac1->as_out_alt = 0; uac1->as_in_alt = 0; @@ -513,16 +502,16 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev*cdev = c->cdev; struct usb_gadget *gadget = cdev->gadget; - struct f_uac1 *uac1 = func_to_uac1(f); + struct f_uac*uac1 = func_to_uac(f); struct g_audio *audio = func_to_g_audio(f); - struct f_uac1_opts *audio_opts; + struct f_uac_opts *audio_opts; struct usb_ep *ep = NULL; struct usb_string *us; u8 *sam_freq; int rate; int status; - audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); + audio_opts = container_of(f->fi, struct f_uac_opts, func_inst); us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); if (IS_ERR(us)) @@ -630,82 +619,27 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) /*-*/ -static inline struct f_uac1_opts *to_f_uac1_opts(struct config_item *item) -{ - return container_of(to_config_group(item), struct f_uac1_opts, - func_inst.group); -} - -static void f_uac1_attr_release(struct config_item *item) -{ - struct f_uac1_opts *opts = to_f_uac1_opts(item); - - usb_put_function_instance(>func_inst); -} - static struct configfs_item_operations f_uac1_item_ops = { - .release= f_uac1_attr_release, + .release= f_uac_attr_release, }; -#define UAC1_ATTRIBUTE(name) \ -static ssize_t f_uac1_opts_##name##_show( \ - struct config_item *item, \ - char *page) \ -{
[PATCHv2 1/3] usb: gadget: f_uac1: Fix endpoint reading
The endpoint is stored in the lower byte of wIndex, according to USB Audio 1.0 specification, section 5.2.1.1. Signed-off-by: Julian Scheel <jul...@jusst.de> --- drivers/usb/gadget/function/f_uac1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 8656f84e17d9..b955913bd7ea 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -327,7 +327,7 @@ static int audio_set_endpoint_req(struct usb_function *f, { struct usb_composite_dev *cdev = f->config->cdev; int value = -EOPNOTSUPP; - u16 ep = le16_to_cpu(ctrl->wIndex); + u8 ep = le16_to_cpu(ctrl->wIndex) & 0xff; u16 len = le16_to_cpu(ctrl->wLength); u16 w_value = le16_to_cpu(ctrl->wValue); @@ -363,7 +363,7 @@ static int audio_get_endpoint_req(struct usb_function *f, { struct usb_composite_dev *cdev = f->config->cdev; int value = -EOPNOTSUPP; - u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); + u8 ep = le16_to_cpu(ctrl->wIndex) & 0xff; u16 len = le16_to_cpu(ctrl->wLength); u16 w_value = le16_to_cpu(ctrl->wValue); -- 2.13.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/3] USB Audio Gadget: Support multiple sampling rates
This patch series adds support for exposing multiple supported sampling rates from UAC1 and UAC2 USB gadgets to the connected host. It is currently limited to up to ten discrete sampling frequencies. The USB specification does not actually limit this, but to avoid complex list handling I am using a static array for now. As the configfs bindings for f_uac1 and f_uac2 have been identical already, I decided to move the shared code for this out of the functions first. This avoids code duplication and simplifies the addition of the list parsing for sampling rates. The host can configure active sampling rate and the function adapts it's internal active rate automatically. On playback/capture start the rate is checked, so that the user recognizes rate mismatches. Furthermore the active rate is exposed as an amixer control with change notifications, so that users can check current rate upfront and get notified about updates. Julian Scheel (3): usb: gadget: f_uac1: Fix endpoint reading usb: gadget: f_uac*: Reduce code duplication usb: gadget: f_uac*: Support multiple sampling rates Documentation/ABI/testing/configfs-usb-gadget-uac1 | 4 +- Documentation/usb/gadget-testing.txt | 8 +- drivers/usb/gadget/function/f_uac1.c | 258 +- drivers/usb/gadget/function/f_uac2.c | 297 ++--- drivers/usb/gadget/function/u_audio.c | 116 +++- drivers/usb/gadget/function/u_audio.h | 9 +- drivers/usb/gadget/function/u_uac.h| 178 drivers/usb/gadget/function/u_uac1.h | 41 --- drivers/usb/gadget/function/u_uac2.h | 44 --- 9 files changed, 582 insertions(+), 373 deletions(-) create mode 100644 drivers/usb/gadget/function/u_uac.h delete mode 100644 drivers/usb/gadget/function/u_uac1.h delete mode 100644 drivers/usb/gadget/function/u_uac2.h -- 2.13.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] usb: gadget: f_uac1: Fix endpoint reading
The endpoint is stored in the lower byte of wIndex, according to USB Audio 1.0 specification, section 5.2.1.1. Signed-off-by: Julian Scheel <jul...@jusst.de> --- drivers/usb/gadget/function/f_uac1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 8656f84e17d9..b955913bd7ea 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -327,7 +327,7 @@ static int audio_set_endpoint_req(struct usb_function *f, { struct usb_composite_dev *cdev = f->config->cdev; int value = -EOPNOTSUPP; - u16 ep = le16_to_cpu(ctrl->wIndex); + u8 ep = le16_to_cpu(ctrl->wIndex) & 0xff; u16 len = le16_to_cpu(ctrl->wLength); u16 w_value = le16_to_cpu(ctrl->wValue); @@ -363,7 +363,7 @@ static int audio_get_endpoint_req(struct usb_function *f, { struct usb_composite_dev *cdev = f->config->cdev; int value = -EOPNOTSUPP; - u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); + u8 ep = le16_to_cpu(ctrl->wIndex) & 0xff; u16 len = le16_to_cpu(ctrl->wLength); u16 w_value = le16_to_cpu(ctrl->wValue); -- 2.13.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] usb: gadget: f_uac*: Support multiple sampling rates
Implement support for multiple sampling rates in the USB Audio gadgets. A list of sampling rates can be specified via configfs. All enabled sampling rates are sent to the USB host on request. When the host selects a sampling rate the internal active rate is updated. The currently configured rates are exposed through amixer controls. Also on pcm open from userspace the requested rated is checked against the currently configured rate of the host. Signed-off-by: Julian Scheel <jul...@jusst.de> --- Documentation/ABI/testing/configfs-usb-gadget-uac1 | 4 +- Documentation/usb/gadget-testing.txt | 8 +- drivers/usb/gadget/function/f_uac1.c | 120 + drivers/usb/gadget/function/f_uac2.c | 146 +++-- drivers/usb/gadget/function/u_audio.c | 116 +++- drivers/usb/gadget/function/u_audio.h | 9 +- drivers/usb/gadget/function/u_uac.h| 69 +- 7 files changed, 393 insertions(+), 79 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1 index abfe447c848f..ad2fa4a00918 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac1 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1 @@ -5,10 +5,10 @@ Description: The attributes: c_chmask - capture channel mask - c_srate - capture sampling rate + c_srate - list of capture sampling rates (comma-separataed) c_ssize - capture sample size (bytes) p_chmask - playback channel mask - p_srate - playback sampling rate + p_srate - list of playback sampling rates (comma-separated) p_ssize - playback sample size (bytes) req_number - the number of pre-allocated request for both capture and playback diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index fbc397d17e98..85878880 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -629,10 +629,10 @@ The function name to use when creating the function directory is "uac2". The uac2 function provides these attributes in its function directory: c_chmask - capture channel mask - c_srate - capture sampling rate + c_srate - list of capture sampling rates (comma-separated) c_ssize - capture sample size (bytes) p_chmask - playback channel mask - p_srate - playback sampling rate + p_srate - list of playback sampling rates (comma-separated) p_ssize - playback sample size (bytes) req_number - the number of pre-allocated request for both capture and playback @@ -790,10 +790,10 @@ The function name to use when creating the function directory is "uac1". The uac1 function provides these attributes in its function directory: c_chmask - capture channel mask - c_srate - capture sampling rate + c_srate - list of capture sampling rates (comma-separated) c_ssize - capture sample size (bytes) p_chmask - playback channel mask - p_srate - playback sampling rate + p_srate - list of playback sampling rates (comma-separated) p_ssize - playback sample size (bytes) req_number - the number of pre-allocated request for both capture and playback diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 7e5a9bd46bcf..6ae210a9ddfc 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -2,6 +2,7 @@ * f_uac1.c -- USB Audio Class 1.0 Function (using u_audio API) * * Copyright (C) 2016 Ruslan Bilovol <ruslan.bilo...@gmail.com> + * Copyright (C) 2017 Julian Scheel <jul...@jusst.de> * * This driver doesn't expect any real Audio codec to be present * on the device - the audio streams are simply sinked to and @@ -177,16 +178,18 @@ static struct uac1_as_header_descriptor as_in_header_desc = { .wFormatTag = UAC_FORMAT_TYPE_I_PCM, }; -DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); +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 -static struct uac_format_type_i_discrete_descriptor_1 as_out_type_i_desc = { - .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), +static struct uac_format_type_i_discrete_descriptor as_out_type_i_desc = { + .bLength = 0, /* filled on rate setup */ .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_FORMAT_TYPE, .bFormatType = UAC_FORMAT_TYPE_I, .bSubframeSize =2, .bBitResolution = 16, - .bSamFreqType =
[PATCH 2/3] usb: gadget: f_uac*: Reduce code duplication
This replaces the dedicated headers for uac1 and uac2 functions with a shared header for both of them. Apart from unifying the struct names, further duplicated code for configfs setup is moved out of the function files into the shared header. Signed-off-by: Julian Scheel <jul...@jusst.de> --- drivers/usb/gadget/function/f_uac1.c | 142 +- drivers/usb/gadget/function/f_uac2.c | 161 ++- drivers/usb/gadget/function/u_uac.h | 115 + drivers/usb/gadget/function/u_uac1.h | 41 - drivers/usb/gadget/function/u_uac2.h | 44 -- 5 files changed, 199 insertions(+), 304 deletions(-) create mode 100644 drivers/usb/gadget/function/u_uac.h delete mode 100644 drivers/usb/gadget/function/u_uac1.h delete mode 100644 drivers/usb/gadget/function/u_uac2.h diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index b955913bd7ea..7e5a9bd46bcf 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -21,18 +21,9 @@ #include #include "u_audio.h" -#include "u_uac1.h" +#include "u_uac.h" -struct f_uac1 { - 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() */ -}; - -static inline struct f_uac1 *func_to_uac1(struct usb_function *f) -{ - return container_of(f, struct f_uac1, g_audio.func); -} +#define UAC1_OUT_EP_MAX_PACKET_SIZE 200 /* * DESCRIPTORS ... most are static, but strings and full @@ -435,7 +426,7 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_composite_dev *cdev = f->config->cdev; struct usb_gadget *gadget = cdev->gadget; struct device *dev = >dev; - struct f_uac1 *uac1 = func_to_uac1(f); + struct f_uac *uac1 = func_to_uac(f); int ret = 0; /* No i/f has more than 2 alt settings */ @@ -480,7 +471,7 @@ static int f_audio_get_alt(struct usb_function *f, unsigned intf) struct usb_composite_dev *cdev = f->config->cdev; struct usb_gadget *gadget = cdev->gadget; struct device *dev = >dev; - struct f_uac1 *uac1 = func_to_uac1(f); + struct f_uac *uac1 = func_to_uac(f); if (intf == uac1->ac_intf) return uac1->ac_alt; @@ -498,7 +489,7 @@ static int f_audio_get_alt(struct usb_function *f, unsigned intf) static void f_audio_disable(struct usb_function *f) { - struct f_uac1 *uac1 = func_to_uac1(f); + struct f_uac *uac1 = func_to_uac(f); uac1->as_out_alt = 0; uac1->as_in_alt = 0; @@ -513,16 +504,16 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev*cdev = c->cdev; struct usb_gadget *gadget = cdev->gadget; - struct f_uac1 *uac1 = func_to_uac1(f); + struct f_uac*uac1 = func_to_uac(f); struct g_audio *audio = func_to_g_audio(f); - struct f_uac1_opts *audio_opts; + struct f_uac_opts *audio_opts; struct usb_ep *ep = NULL; struct usb_string *us; u8 *sam_freq; int rate; int status; - audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); + audio_opts = container_of(f->fi, struct f_uac_opts, func_inst); us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); if (IS_ERR(us)) @@ -630,82 +621,27 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) /*-*/ -static inline struct f_uac1_opts *to_f_uac1_opts(struct config_item *item) -{ - return container_of(to_config_group(item), struct f_uac1_opts, - func_inst.group); -} - -static void f_uac1_attr_release(struct config_item *item) -{ - struct f_uac1_opts *opts = to_f_uac1_opts(item); - - usb_put_function_instance(>func_inst); -} - static struct configfs_item_operations f_uac1_item_ops = { - .release= f_uac1_attr_release, + .release= f_uac_attr_release, }; -#define UAC1_ATTRIBUTE(name) \ -static ssize_t f_uac1_opts_##name##_show( \ - struct config_item *item, \ - char *page) \ -{ \ -
Re: [PATCH v4 3/3] usb: gadget: add f_uac1 variant based on a new u_audio api
On 18.05.2017 00:37, Ruslan Bilovol wrote: This patch adds a new function 'f_uac1_acard' (f_uac1 with virtual "ALSA card") that uses recently created u_audio API. Comparing to legacy f_uac1 function implementation it doesn't require any real Audio codec to be present on the device. In f_uac1_acard audio streams are simply sinked to and sourced from a virtual ALSA sound card created using u_audio API. Legacy f_uac1 approach is to write audio samples directly to existing ALSA sound card f_uac1_acard approach is more generic/flexible one - create an ALSA sound card that represents USB Audio function and allows to be used by userspace application that may choose to do whatever it wants with the data received from the USB Host and choose to provide whatever it wants as audio data to the USB Host. f_uac1_acard also has capture support (gadget->host) thanks to easy implementation via u_audio. By default, capture interface has 48000kHz/2ch configuration, same as playback channel has. f_uac1_acard descriptors naming convention uses f_uac2 driver naming convention that makes it more common and meaningful. Comparing to f_uac1, the f_uac1_acard doesn't have volume/mute functionality. This is because the f_uac1 volume/mute feature unit was dummy implementation since that driver creation (2009) and never had any real volume control or mute functionality, so there is no any difference here. Since f_uac1_acard functionality, exposed interface to userspace (virtual ALSA card), input parameters are so different comparing to legace f_uac1, that there is no any reason to keep them in the same file/module, and separate function was created. g_audio can be built using one of existing UAC functions (f_uac1, f_uac1_acard or f_uac2) Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- .../ABI/testing/configfs-usb-gadget-uac1_acard | 14 + Documentation/usb/gadget-testing.txt | 45 ++ drivers/usb/gadget/Kconfig | 21 + drivers/usb/gadget/function/Makefile | 2 + drivers/usb/gadget/function/f_uac1_acard.c | 803 + drivers/usb/gadget/function/u_uac1_acard.h | 41 ++ drivers/usb/gadget/legacy/Kconfig | 15 +- drivers/usb/gadget/legacy/audio.c | 53 ++ 8 files changed, 992 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_acard create mode 100644 drivers/usb/gadget/function/f_uac1_acard.c create mode 100644 drivers/usb/gadget/function/u_uac1_acard.h Tested on iMX7D using chipidea usb gadget controller. Tested Windows 10 and Linux 4.11 as host. Both work fine. Tested-by: Julian Scheel <jul...@jusst.de> -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html