Re: [PATCH 0/1] USB Audio Device Class 3.0 Gadget support
Hi Felipe, On Mon, Dec 4, 2017 at 1:36 PM, Felipe Balbi <ba...@kernel.org> wrote: > > Hi, > > Ruslan Bilovol <ruslan.bilo...@gmail.com> writes: >> On Tue, Nov 7, 2017 at 3:52 AM, Ruslan Bilovol <ruslan.bilo...@gmail.com> >> wrote: >>> Hi, >>> >>> This patch adds USB Audio Device Class 3.0 [1] function >>> support to gadget subsystem. >>> I didn't add UAC3 support to legacy gadget as it will >>> make preprocessor configuration too complex (UAC3 device >>> must have two configurations for backward compatibility, >>> first is UAC1/2 and second is UAC3), yet also I'm too lazy >>> to do that and verify all possible configurations. >>> >>> For modern ConfigFS interface I'll provide my configuration >>> for testing below; testing was done on a BeagleBone Black >>> board. >>> >>> This patch depends on uac3 header files from include dir >>> which I'll post as part of ALSA host UAC3 patch and will >>> provide the link to it here. >> >> http://www.spinics.net/lists/alsa-devel/msg69071.html > > Once that patch hits upstream, then we can queue this for merge window > otherwise we will just have issues and create unbisectable points in the > tree. Takashi promised to create an immutable branch for that purpose. However, I'm currently reworking configfs part of UAC3 for channels configuration handling, which is now more clear after sharing missing parts of UAC3 spec by Pierre-Louis Bossart during host side patches review; so I will send v2 soon. Thanks, Ruslan -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/1] USB Audio Device Class 3.0 Gadget support
On Tue, Nov 7, 2017 at 3:52 AM, Ruslan Bilovol <ruslan.bilo...@gmail.com> wrote: > Hi, > > This patch adds USB Audio Device Class 3.0 [1] function > support to gadget subsystem. > I didn't add UAC3 support to legacy gadget as it will > make preprocessor configuration too complex (UAC3 device > must have two configurations for backward compatibility, > first is UAC1/2 and second is UAC3), yet also I'm too lazy > to do that and verify all possible configurations. > > For modern ConfigFS interface I'll provide my configuration > for testing below; testing was done on a BeagleBone Black > board. > > This patch depends on uac3 header files from include dir > which I'll post as part of ALSA host UAC3 patch and will > provide the link to it here. http://www.spinics.net/lists/alsa-devel/msg69071.html Thanks, Ruslan -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/1] usb: gadget: add USB Audio Device Class 3.0 gadget support
Recently released USB Audio Class 3.0 specification introduces many significant changes comparing to previous versions, like - new Power Domains, support for LPM/L1 - new Cluster descriptor - changed layout of all class-specific descriptors - new High Capability descriptors - New class-specific String descriptors - new and removed units - additional sources for interrupts - removed Type II Audio Data Formats - ... and many other things (check spec) It also provides backward compatibility through multiple configurations, as well as requires mandatory support for BADD (Basic Audio Device Definition) on each ADC3.0 compliant device This patch adds UAC3 gadget support basing on UAC3 specification, implementing Generic I/O Profile (BAOF + BAIF) from BADD document. There are still few areas for future improvements because not all functionality is completely implemented, for example volume, mute and power management handling has dummy implementation in some places Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- Documentation/ABI/testing/configfs-usb-gadget-uac3 | 14 + Documentation/usb/gadget-testing.txt | 41 + drivers/usb/gadget/Kconfig | 22 + drivers/usb/gadget/function/Makefile |2 + drivers/usb/gadget/function/f_uac3.c | 1497 drivers/usb/gadget/function/u_uac3.h | 38 + drivers/usb/gadget/legacy/Kconfig |3 +- 7 files changed, 1616 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac3 create mode 100644 drivers/usb/gadget/function/f_uac3.c create mode 100644 drivers/usb/gadget/function/u_uac3.h diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac3 b/Documentation/ABI/testing/configfs-usb-gadget-uac3 new file mode 100644 index 000..54bb00e --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac3 @@ -0,0 +1,14 @@ +What: /config/usb-gadget/gadget/functions/uac3.name +Date: Nov 2017 +KernelVersion: 4.16 +Description: + The attributes: + + c_chmask - capture channel mask + c_srate - capture sampling rate + c_ssize - capture sample size (bytes) + p_chmask - playback channel mask + p_srate - playback sampling rate + 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 fbc397d..36d5e2b 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -21,6 +21,7 @@ provided by gadgets. 18. UVC function 19. PRINTER function 20. UAC1 function (new API) +21. UAC3 function 1. ACM function @@ -817,3 +818,43 @@ e.g.: $ arecord -f dat -t wav -D hw:CARD=UAC1Gadget,DEV=0 | \ aplay -D default:CARD=OdroidU3 + +21. UAC3 function += + +The function is provided by usb_f_uac3.ko module. + +Function-specific configfs interface + + +The function name to use when creating the function directory is "uac3". +The uac3 function provides these attributes in its function directory: + + c_chmask - capture channel mask + c_srate - capture sampling rate + c_ssize - capture sample size (bytes) + p_chmask - playback channel mask + p_srate - playback sampling rate + p_ssize - playback sample size (bytes) + req_number - the number of pre-allocated request for both capture +and playback + +The attributes have sane default values. + +Testing the UAC3 function +- + +device: run the gadget +host: aplay -l # should list our USB Audio Gadget + +This function does not require real hardware support, it just +sends a stream of audio data to/from the host. In order to +actually hear something at the device side, a command similar +to this must be used at the device side: + +$ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 & + +e.g.: + +$ arecord -f dat -t wav -D hw:CARD=UAC3Gadget,DEV=0 | \ +aplay -D default:CARD=OdroidU3 diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 31cce78..d53ae7d 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -200,6 +200,9 @@ config USB_F_UAC1_LEGACY config USB_F_UAC2 tristate +config USB_F_UAC3 + tristate + config USB_F_UVC tristate @@ -418,6 +421,25 @@ config USB_CONFIGFS_F_UAC2 received from the USB Host and choose to provide whatever it wants as audio data to the USB Host. +config USB_CONFIGFS_F_UAC3 + bool "Audio Class 3.0" + depends on USB_CONFIGFS + depends on SND + select USB_LIBCOMPOSITE + select SND_PCM + select USB_U_A
[PATCH 0/1] USB Audio Device Class 3.0 Gadget support
Hi, This patch adds USB Audio Device Class 3.0 [1] function support to gadget subsystem. I didn't add UAC3 support to legacy gadget as it will make preprocessor configuration too complex (UAC3 device must have two configurations for backward compatibility, first is UAC1/2 and second is UAC3), yet also I'm too lazy to do that and verify all possible configurations. For modern ConfigFS interface I'll provide my configuration for testing below; testing was done on a BeagleBone Black board. This patch depends on uac3 header files from include dir which I'll post as part of ALSA host UAC3 patch and will provide the link to it here. uac_3 mkdir cfg mount none cfg -t configfs mkdir cfg/usb_gadget/g1 cd cfg/usb_gadget/g1 mkdir configs/c.1 mkdir functions/uac3.0 mkdir strings/0x409 mkdir configs/c.1/strings/0x409 echo 0x0101 > idProduct echo 0x1d6b > idVendor echo my-serial-num > strings/0x409/serialnumber echo my-manufacturer > strings/0x409/manufacturer echo "Test gadget" > strings/0x409/product echo "Conf 1" > configs/c.1/strings/0x409/configuration echo 120 > configs/c.1/MaxPower ln -s functions/uac3.0 configs/c.1 echo musb-hdrc.0 > UDC uac_3 + uac2 mkdir cfg mount none cfg -t configfs mkdir cfg/usb_gadget/g1 cd cfg/usb_gadget/g1 mkdir configs/c.1 mkdir functions/uac2.0 mkdir strings/0x409 mkdir configs/c.1/strings/0x409 echo "Test gadget" > strings/0x409/product echo "Conf 1" > configs/c.1/strings/0x409/configuration echo 120 > configs/c.1/MaxPower ln -s functions/uac2.0 configs/c.1 mkdir configs/c.2 mkdir functions/uac3.0 mkdir strings/0x409 mkdir configs/c.2/strings/0x409 echo "Conf 2" > configs/c.2/strings/0x409/configuration echo 120 > configs/c.2/MaxPower ln -s functions/uac3.0 configs/c.2 echo 0x0101 > idProduct echo 0x1d6b > idVendor echo my-serial-num > strings/0x409/serialnumber echo my-manufacturer > strings/0x409/manufacturer echo musb-hdrc.0 > UDC [1] http://www.usb.org/developers/docs/devclass_docs/USB_Audio_v3.0.zip Ruslan Bilovol (1): usb: gadget: add USB Audio Device Class 3.0 gadget support Documentation/ABI/testing/configfs-usb-gadget-uac3 | 14 + Documentation/usb/gadget-testing.txt | 41 + drivers/usb/gadget/Kconfig | 22 + drivers/usb/gadget/function/Makefile |2 + drivers/usb/gadget/function/f_uac3.c | 1497 drivers/usb/gadget/function/u_uac3.h | 38 + drivers/usb/gadget/legacy/Kconfig |3 +- 7 files changed, 1616 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac3 create mode 100644 drivers/usb/gadget/function/f_uac3.c create mode 100644 drivers/usb/gadget/function/u_uac3.h -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 1/4] usb: gadget: f_uac2: remove platform driver/device creation
Simplify f_uac2 by removing platform driver/device creation; use composite's usb_gadget device as parent for sound card and for debug prints. This removes extra layer of code without any functional change. Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- drivers/usb/gadget/function/f_uac2.c | 107 +-- 1 file changed, 28 insertions(+), 79 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 5a7ba05..f674bae 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -51,8 +50,6 @@ #define UNFLW_CTRL 8 #define OVFLW_CTRL 10 -static const char *uac2_name = "snd_uac2"; - struct uac2_req { struct uac2_rtd_params *pp; /* parent param */ struct usb_request *req; @@ -81,9 +78,6 @@ struct uac2_rtd_params { }; struct snd_uac2_chip { - struct platform_device pdev; - struct platform_driver pdrv; - struct uac2_rtd_params p_prm; struct uac2_rtd_params c_prm; @@ -122,6 +116,7 @@ struct audio_dev { struct usb_ep *in_ep, *out_ep; struct usb_function func; + struct usb_gadget *gadget; /* The ALSA Sound Card it represents on the USB-Client side */ struct snd_uac2_chip uac2; @@ -140,12 +135,6 @@ struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u) } static inline -struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p) -{ - return container_of(p, struct snd_uac2_chip, pdev); -} - -static inline struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev) { return container_of(agdev->func.fi, struct f_uac2_opts, func_inst); @@ -254,7 +243,7 @@ uint num_channels(uint chanmask) exit: if (usb_ep_queue(ep, req, GFP_ATOMIC)) - dev_err(>pdev.dev, "%d Error!\n", __LINE__); + dev_err(uac2->card->dev, "%d Error!\n", __LINE__); if (update_alsa) snd_pcm_period_elapsed(substream); @@ -440,23 +429,22 @@ static int uac2_pcm_null(struct snd_pcm_substream *substream) .prepare = uac2_pcm_null, }; -static int snd_uac2_probe(struct platform_device *pdev) +static int snd_uac2_probe(struct audio_dev *audio_dev) { - struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); + struct snd_uac2_chip *uac2 = _dev->uac2; struct snd_card *card; struct snd_pcm *pcm; - struct audio_dev *audio_dev; struct f_uac2_opts *opts; int err; int p_chmask, c_chmask; - audio_dev = uac2_to_agdev(uac2); opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst); p_chmask = opts->p_chmask; c_chmask = opts->c_chmask; /* Choose any slot, with no id */ - err = snd_card_new(>dev, -1, NULL, THIS_MODULE, 0, ); + err = snd_card_new(_dev->gadget->dev, + -1, NULL, THIS_MODULE, 0, ); if (err < 0) return err; @@ -481,16 +469,15 @@ static int snd_uac2_probe(struct platform_device *pdev) strcpy(card->driver, "UAC2_Gadget"); strcpy(card->shortname, "UAC2_Gadget"); - sprintf(card->longname, "UAC2_Gadget %i", pdev->id); + sprintf(card->longname, "UAC2_Gadget %i", card->dev->id); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX); err = snd_card_register(card); - if (!err) { - platform_set_drvdata(pdev, card); + + if (!err) return 0; - } snd_fail: snd_card_free(card); @@ -501,9 +488,9 @@ static int snd_uac2_probe(struct platform_device *pdev) return err; } -static int snd_uac2_remove(struct platform_device *pdev) +static int snd_uac2_remove(struct audio_dev *audio_dev) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = audio_dev->uac2.card; if (card) return snd_card_free(card); @@ -511,45 +498,6 @@ static int snd_uac2_remove(struct platform_device *pdev) return 0; } -static void snd_uac2_release(struct device *dev) -{ - dev_dbg(dev, "releasing '%s'\n", dev_name(dev)); -} - -static int alsa_uac2_init(struct audio_dev *agdev) -{ - struct snd_uac2_chip *uac2 = >uac2; - int err; - - uac2->pdrv.probe = snd_uac2_probe; - uac2->pdrv.remove = snd_uac2_remove; - uac2->pdrv.driver.name = uac2_name; - - uac2->pdev.id = 0; - uac2->pdev.name = uac2_name; - uac2->pdev.dev.release = snd_uac2_release; - - /* Register snd_uac2 driver */ - err = platform_driver_register(>pdrv); - if (err) -
[PATCH v5 4/4] usb: gadget: add f_uac1 variant based on a new u_audio api
This patch adds a new function 'f_uac1' (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 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 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 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 descriptors naming convention uses f_uac2 driver naming convention that makes it more common and meaningful. Comparing to f_uac1_legacy, the f_uac1 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 functionality, exposed interface to userspace (virtual ALSA card), input parameters are so different comparing to f_uac1_legacy, 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_legacy or f_uac2) Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- Documentation/ABI/testing/configfs-usb-gadget-uac1 | 14 + Documentation/usb/gadget-testing.txt | 44 ++ drivers/usb/gadget/Kconfig | 25 +- drivers/usb/gadget/function/Makefile | 2 + drivers/usb/gadget/function/f_uac1.c | 802 + drivers/usb/gadget/function/u_uac1.h | 41 ++ drivers/usb/gadget/legacy/Kconfig | 18 +- drivers/usb/gadget/legacy/audio.c | 69 +- 8 files changed, 1000 insertions(+), 15 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1 create mode 100644 drivers/usb/gadget/function/f_uac1.c create mode 100644 drivers/usb/gadget/function/u_uac1.h diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1 new file mode 100644 index 000..abfe447 --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1 @@ -0,0 +1,14 @@ +What: /config/usb-gadget/gadget/functions/uac1.name +Date: June 2017 +KernelVersion: 4.14 +Description: + The attributes: + + c_chmask - capture channel mask + c_srate - capture sampling rate + c_ssize - capture sample size (bytes) + p_chmask - playback channel mask + p_srate - playback sampling rate + 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 ce51d6e..fbc397d 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -20,6 +20,7 @@ provided by gadgets. 17. UAC2 function 18. UVC function 19. PRINTER function +20. UAC1 function (new API) 1. ACM function @@ -773,3 +774,46 @@ host: More advanced testing can be done with the prn_example described in Documentation/usb/gadget-printer.txt. + + +20. UAC1 function (virtual ALSA card, using u_audio API) += + +The function is provided by usb_f_uac1.ko module. +It will create a virtual ALSA card and the audio streams are simply +sinked to and sourced from it. + +Function-specific configfs interface + + +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_ssize - capture sample size (bytes) + p_chmask - playback channel mask + p_srate - playback sampling rate + p_ssize - playback sample size (bytes) + req_number - the number of pre-allocated request for both capture +and playback + +The attributes have sane default values. + +Testing the UAC1 function +- + +device: run the gadget +host: aplay -l # should list our USB Audio Gadget + +This function does not require real hardware support, it just +sends a stream of audio data to/from the host. In order to +actually hear something at the d
[PATCH v5 3/4] usb: gadget: function: make current f_uac1 implementation legacy
Before introducing new f_uac1 function (with virtual ALSA card) make current implementation legacy. This includes renaming of existing files, some variables, config options and documentation Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- ...gadget-uac1 => configfs-usb-gadget-uac1_legacy} | 2 +- Documentation/usb/gadget-testing.txt | 9 +++-- drivers/usb/gadget/Kconfig | 8 ++-- drivers/usb/gadget/function/Makefile | 4 +- .../gadget/function/{f_uac1.c => f_uac1_legacy.c} | 45 +++--- .../gadget/function/{u_uac1.c => u_uac1_legacy.c} | 7 ++-- .../gadget/function/{u_uac1.h => u_uac1_legacy.h} | 8 ++-- drivers/usb/gadget/legacy/Kconfig | 6 +-- drivers/usb/gadget/legacy/audio.c | 26 ++--- 9 files changed, 59 insertions(+), 56 deletions(-) rename Documentation/ABI/testing/{configfs-usb-gadget-uac1 => configfs-usb-gadget-uac1_legacy} (84%) rename drivers/usb/gadget/function/{f_uac1.c => f_uac1_legacy.c} (95%) rename drivers/usb/gadget/function/{u_uac1.c => u_uac1_legacy.c} (98%) rename drivers/usb/gadget/function/{u_uac1.h => u_uac1_legacy.h} (94%) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy similarity index 84% rename from Documentation/ABI/testing/configfs-usb-gadget-uac1 rename to Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy index 8ba9a12..b2eaefd 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac1 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy @@ -1,4 +1,4 @@ -What: /config/usb-gadget/gadget/functions/uac1.name +What: /config/usb-gadget/gadget/functions/uac1_legacy.name Date: Sep 2014 KernelVersion: 3.18 Description: diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index fb0cc4d..ce51d6e 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -16,7 +16,7 @@ provided by gadgets. 13. RNDIS function 14. SERIAL function 15. SOURCESINK function -16. UAC1 function +16. UAC1 function (legacy implementation) 17. UAC2 function 18. UVC function 19. PRINTER function @@ -589,15 +589,16 @@ device: run the gadget host: test-usb (tools/usb/testusb.c) -16. UAC1 function +16. UAC1 function (legacy implementation) = -The function is provided by usb_f_uac1.ko module. +The function is provided by usb_f_uac1_legacy.ko module. Function-specific configfs interface -The function name to use when creating the function directory is "uac1". +The function name to use when creating the function directory +is "uac1_legacy". The uac1 function provides these attributes in its function directory: audio_buf_size - audio buffer size diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 3b0ffd6..01c2e2b 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -191,7 +191,7 @@ config USB_F_MASS_STORAGE config USB_F_FS tristate -config USB_F_UAC1 +config USB_F_UAC1_LEGACY tristate config USB_F_UAC2 @@ -365,13 +365,13 @@ config USB_CONFIGFS_F_FS implemented in kernel space (for instance Ethernet, serial or mass storage) and other are implemented in user space. -config USB_CONFIGFS_F_UAC1 - bool "Audio Class 1.0" +config USB_CONFIGFS_F_UAC1_LEGACY + bool "Audio Class 1.0 (legacy implementation)" depends on USB_CONFIGFS depends on SND select USB_LIBCOMPOSITE select SND_PCM - select USB_F_UAC1 + select USB_F_UAC1_LEGACY help This Audio function implements 1 AudioControl interface, 1 AudioStreaming Interface each for USB-OUT and USB-IN. diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index b29f2ae..50ee517 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -33,8 +33,8 @@ obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o usb_f_fs-y := f_fs.o obj-$(CONFIG_USB_F_FS) += usb_f_fs.o obj-$(CONFIG_USB_U_AUDIO) += u_audio.o -usb_f_uac1-y := f_uac1.o u_uac1.o -obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o +usb_f_uac1_legacy-y:= f_uac1_legacy.o u_uac1_legacy.o +obj-$(CONFIG_USB_F_UAC1_LEGACY)+= usb_f_uac1_legacy.o usb_f_uac2-y := f_uac2.o obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o usb_f_uvc-y:= f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_configfs.o diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1_legacy.c similarity index 95% rename from drivers/usb/gadget/function/f_uac1.c rename to drivers/usb/gadget/function/
[PATCH v5 0/4] USB Audio Gadget refactoring
Hi Felipe, This is v5 of audio gadget refactoring. Note, that legacy f_uac1 function is broken since v4.10 by commit 7e4da3fcf7c9 ("usb: gadget: composite: Test get_alt() presence instead of set_alt()"). The fact that at v4.12-rc5 time nobody cares about may be a good sign that number of users is small if any. Thus making it legacy makes sence. This series depends on legacy f_uac1 fix I posted before: http://www.spinics.net/lists/linux-usb/msg158373.html Without this fix it's not possible to check that refactoring didn't break legacy f_uac1 functionality I came to this patch series when wanted to do two things: - use UAC1 as virtual ALSA sound card on gadget side, just like UAC2 is used so it's possible to do rate resampling - have both playback/capture support in UAC1 Since I wanted to have same behavior for both UAC1/UAC2, obviously I've got an utility part (u_audio.c) for virtual ALSA sound card handling like we have for ethernet(u_ether) or serial(u_serial) functions. Function-specific parts (f_uac1/f_uac2) became almost as storage for class-specific USB descriptors, some boilerplate for configfs, binding and few USB config request handling. Originally in RFC [1] I've posted before, there was major change to f_uac1 after that it couldn't do direct play to existing ALSA sound card anymore, representing audio on gadget side as virtual ALSA sound card where audio streams are simply sinked to and sourced from it, so it may break current usecase for some people (and that's why it was RFC). During RFC discussion, it was agreed to not touch existing f_uac1 implementation and create new one instead. At v4 patchet discussion another approach was agreed - current f_uac1.c gets renamed to f_uac1_legacy.c and introduced a *new* f_uac1.c instead that is done in current patchset (v5) Now, it's possible to use existing user-space applications for audio routing between Audio Gadget and real sound card. I personally use alsaloop tool from alsautils and have ability to create PCM loopback between two different ALSA cards using rate resampling, which was not possible with previous "direct play to ALSA card" approach in f_uac1. While here, also dropped redundant platform driver/device creation in f_uac2 driver (as well as didn't add "never implemented" volume/mute functionality in f_uac1_legacy to f_uac1) that made this work even easier to do. This series is tested with both legacy g_audio.ko and modern configfs approaches under Ubuntu 14.04 (UAC1 and UAC2) and under Windows7 x64 (UAC1 only) having perfect results in all cases. Comments, testing are welcome. v5 changes: - after discussion with Felipe, switched to another approach with making current f_uac1 legacy and introducing a new f_uac1.c instead - addressed Jassi's copyright comments v4 changes: - renamed f_uac1_newapi to f_uac1_acard that is more meaningful - rebased on top of balbi/next v3 changes: - renamed u_audio exported symbols so they don't conflict with old f_uac1 if both are built-in. v2 changes: - do not touch f_uac1, instead created f_uac1_newapi - added documentation for f_uac1_newapi - rebased on top of v4.8-rc1 [1] https://lkml.org/lkml/2016/5/23/649 Ruslan Bilovol (4): usb: gadget: f_uac2: remove platform driver/device creation usb: gadget: f_uac2: split out audio core usb: gadget: function: make current f_uac1 implementation legacy usb: gadget: add f_uac1 variant based on a new u_audio api Documentation/ABI/testing/configfs-usb-gadget-uac1 | 18 +- .../ABI/testing/configfs-usb-gadget-uac1_legacy| 12 + Documentation/usb/gadget-testing.txt | 53 +- drivers/usb/gadget/Kconfig | 29 +- drivers/usb/gadget/function/Makefile |5 +- drivers/usb/gadget/function/f_uac1.c | 906 +++-- drivers/usb/gadget/function/f_uac1_legacy.c| 1021 drivers/usb/gadget/function/f_uac2.c | 795 ++- drivers/usb/gadget/function/u_audio.c | 662 + drivers/usb/gadget/function/u_audio.h | 95 ++ drivers/usb/gadget/function/u_uac1.h | 87 +- .../gadget/function/{u_uac1.c => u_uac1_legacy.c} |7 +- drivers/usb/gadget/function/u_uac1_legacy.h| 82 ++ drivers/usb/gadget/legacy/Kconfig | 15 +- drivers/usb/gadget/legacy/audio.c | 55 +- 15 files changed, 2494 insertions(+), 1348 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy create mode 100644 drivers/usb/gadget/function/f_uac1_legacy.c create mode 100644 drivers/usb/gadget/function/u_audio.c create mode 100644 drivers/usb/gadget/function/u_audio.h rename drivers/usb/gadget/function/{u_uac1.c => u_uac1_legacy.c} (98%) create mode 100644 drivers/usb/gadget/function/u_uac1_legacy.h -- 1.9.1 --
[PATCH v5 2/4] usb: gadget: f_uac2: split out audio core
Abstract the peripheral side ALSA sound card code from the f_uac2 function into a component that can be called by various functions, so the various flavors can be split apart and selectively reused. Visible changes: - add uac_params structure to pass audio paramteres for g_audio_setup - make ALSA sound card's name configurable - add [in/out]_ep_maxpsize - allocate snd_uac_chip structure during g_audio_setup - add u_audio_[start/stop]_[capture/playback] functions Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- drivers/usb/gadget/Kconfig| 4 + drivers/usb/gadget/function/Makefile | 1 + drivers/usb/gadget/function/f_uac2.c | 718 -- drivers/usb/gadget/function/u_audio.c | 662 +++ drivers/usb/gadget/function/u_audio.h | 95 + drivers/usb/gadget/legacy/Kconfig | 1 + 6 files changed, 845 insertions(+), 636 deletions(-) create mode 100644 drivers/usb/gadget/function/u_audio.c create mode 100644 drivers/usb/gadget/function/u_audio.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index b3c879b..3b0ffd6 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -158,6 +158,9 @@ config USB_U_SERIAL config USB_U_ETHER tristate +config USB_U_AUDIO + tristate + config USB_F_SERIAL tristate @@ -381,6 +384,7 @@ config USB_CONFIGFS_F_UAC2 depends on SND select USB_LIBCOMPOSITE select SND_PCM + select USB_U_AUDIO select USB_F_UAC2 help This Audio function is compatible with USB Audio Class diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index cb8c225..b29f2ae 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -32,6 +32,7 @@ usb_f_mass_storage-y := f_mass_storage.o storage_common.o obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o usb_f_fs-y := f_fs.o obj-$(CONFIG_USB_F_FS) += usb_f_fs.o +obj-$(CONFIG_USB_U_AUDIO) += u_audio.o usb_f_uac1-y := f_uac1.o u_uac1.o obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o usb_f_uac2-y := f_uac2.o diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index f674bae..9082ce2 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -15,10 +15,7 @@ #include #include -#include -#include -#include - +#include "u_audio.h" #include "u_uac2.h" /* @@ -50,455 +47,23 @@ #define UNFLW_CTRL 8 #define OVFLW_CTRL 10 -struct uac2_req { - struct uac2_rtd_params *pp; /* parent param */ - struct usb_request *req; +struct f_uac2 { + 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() */ }; -struct uac2_rtd_params { - struct snd_uac2_chip *uac2; /* parent chip */ - bool ep_enabled; /* if the ep is enabled */ - /* Size of the ring buffer */ - size_t dma_bytes; - unsigned char *dma_area; - - struct snd_pcm_substream *ss; - - /* Ring buffer */ - ssize_t hw_ptr; - - void *rbuf; - - size_t period_size; - - unsigned max_psize; - struct uac2_req *ureq; - - spinlock_t lock; -}; - -struct snd_uac2_chip { - struct uac2_rtd_params p_prm; - struct uac2_rtd_params c_prm; - - struct snd_card *card; - struct snd_pcm *pcm; - - /* timekeeping for the playback endpoint */ - unsigned int p_interval; - unsigned int p_residue; - - /* pre-calculated values for playback iso completion */ - unsigned int p_pktsize; - unsigned int p_pktsize_residue; - unsigned int p_framesize; -}; - -#define BUFF_SIZE_MAX (PAGE_SIZE * 16) -#define PRD_SIZE_MAX PAGE_SIZE -#define MIN_PERIODS4 - -static struct snd_pcm_hardware uac2_pcm_hardware = { - .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER -| SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID -| SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, - .rates = SNDRV_PCM_RATE_CONTINUOUS, - .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX, - .buffer_bytes_max = BUFF_SIZE_MAX, - .period_bytes_max = PRD_SIZE_MAX, - .periods_min = MIN_PERIODS, -}; - -struct audio_dev { - u8 ac_intf, ac_alt; - u8 as_out_intf, as_out_alt; - u8 as_in_intf, as_in_alt; - - struct usb_ep *in_ep, *out_ep; - struct usb_function func; - struct usb_gadget *gadget; - - /* The ALSA Sound Card it represents on the USB-Client side */ - struct snd_uac2_chip uac2; -}; - -static inline -struct audio_dev *func_to_agdev(struct usb_function *f) -{ - return container_of(f, struct audio_dev, func); -} - -static inline -struc
Re: [PATCH v4 0/3] USB Audio Gadget refactoring
On Tue, Jun 6, 2017 at 12:41 PM, Felipe Balbiwrote: > > Hi, > > Greg KH writes: >>> > I'm OK with dropping legacy f_uac1 implementation. >>> > >>> > Another idea I was thinking about is to implement simple in-kernel >>> > driver which will do the same as existing alsaloop tool userspace >>> > tool does (so legacy users will need to load two kernel modules >>> > and get same functionality). But this seems to be a wrong way, >>> > since It known that Linux kernel community doesn't like to take drivers >>> > with same functionality as existing userspace tools already have. >>> > >>> > So bottom line: since I'm not a legacy f_uac1 user, there is no >>> > difference for me how to handle it - remove legacy f_uac1 completely, >>> > rename it to f_uac1_legacy or add separate f_uac1_acard function. >>> > >>> > So if dropping of legacy f_uac1 implementation is OK for you, >>> > I can do it quickly in next patchset. >>> >>> Personally, I don't want duplicated functionality and I think the >>> virtual sound card approach is much better. Then again, removing >>> functionality we already support is kind of odd. >>> >>> Greg, Alan, what do you guys think? Do we keep a duplicated function >>> around or do we just tell people to rely on alsaloop? Personally, I >>> think we're better off with the flexibility of the virtual sound card, >>> what's your take? >> >> If the in-kernel driver will do more things, and we don't break the >> existing setups using alsaloop, then I don't see the problem, except >> that we now have to maintain two things :) >> >> If you don't mind the maintenance, fine with me... > > Okay, I don't think many will continue to use f_uac1.c. Ruslan, can you > update your series so that current f_uac1.c gets renamed to > f_uac1_legacy.c and you introduce a *new* f_uac1.c instead? Yes sure, I'll post an updated patch series soon Best regards, Ruslan -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/3] USB Audio Gadget refactoring
Hi, On Fri, Jun 2, 2017 at 12:42 PM, Felipe Balbi <ba...@kernel.org> wrote: > > Hi, > > Ruslan Bilovol <ruslan.bilo...@gmail.com> writes: >> I came to this patch series when wanted to do two things: >> - use UAC1 as virtual ALSA sound card on gadget side, >>just like UAC2 is used so it's possible to do rate >>resampling >> - have both playback/capture support in UAC1 >> >> Since I wanted to have same behavior for both UAC1/UAC2, >> obviously I've got an utility part (u_audio.c) for >> virtual ALSA sound card handling like we have >> for ethernet(u_ether) or serial(u_serial) functions. >> Function-specific parts (f_uac1/f_uac2) became almost >> as storage for class-specific USB descriptors, some >> boilerplate for configfs, binding and few USB >> config request handling. >> >> Originally in RFC [1] I've posted before, there was >> major change to f_uac1 after that it couldn't do >> direct play to existing ALSA sound card anymore, >> representing audio on gadget side as virtual >> ALSA sound card where audio streams are simply >> sinked to and sourced from it, so it may break >> current usecase for some people (and that's why >> it was RFC). >> >> During RFC discussion, it was agreed to not touch >> existing f_uac1 implementation and create new one >> instead. This patchset (v4) introduced new function >> named f_uac1_acard and doesn't touch current f_uac1 >> implementation, so people still can use old behavior > > Do you have a pointer to the original RFC discussion where this was > discussed? If we really *must* keep the old implementation, I would > rather rename that to f_uac1_legacy. Still, I find it unlikely that > anybody will care about the old implementation. It is on LKML (which is down for me) [1] or alternative archive [2] > >> Now, it's possible to use existing user-space >> applications for audio routing between Audio Gadget >> and real sound card. I personally use alsaloop tool >> from alsautils and have ability to create PCM >> loopback between two different ALSA cards using >> rate resampling, which was not possible with previous >> "direct play to ALSA card" approach in f_uac1. > > this is really good result and will actually make it a lot easier for > testing things out. > >> While here, also dropped redundant platform >> driver/device creation in f_uac2 driver (as well as >> didn't add "never implemented" volume/mute functionality >> in f_uac1 to f_uac1_acard) that made this work even >> easier to do. >> >> This series is tested with both legacy g_audio.ko and >> modern configfs approaches under Ubuntu 14.04 (UAC1 and >> UAC2) and under Windows7 x64 (UAC1 only) having >> perfect results in all cases. >> >> Comments, testing are welcome. >> >> v4 changes: >> - renamed f_uac1_newapi to f_uac1_acard that is >>more meaningful > > I really don't get why you wanna keep both f_uac1 and f_uac1_acard. Why > do we need to maintain the old uac1 implementation? Why two separate > files? In first RFC ([1],[2]) I did exactly what you wrote here (removed old uac1 implementation and replaced it by new one) but got feedback that it will break things for existing f_uac1 legacy users and it's better to have separate implementation. I'm OK with dropping legacy f_uac1 implementation. Another idea I was thinking about is to implement simple in-kernel driver which will do the same as existing alsaloop tool userspace tool does (so legacy users will need to load two kernel modules and get same functionality). But this seems to be a wrong way, since It known that Linux kernel community doesn't like to take drivers with same functionality as existing userspace tools already have. So bottom line: since I'm not a legacy f_uac1 user, there is no difference for me how to handle it - remove legacy f_uac1 completely, rename it to f_uac1_legacy or add separate f_uac1_acard function. So if dropping of legacy f_uac1 implementation is OK for you, I can do it quickly in next patchset. [1] https://lkml.org/lkml/2016/5/23/649 [2] https://marc.info/?t=14640475881=1=4 Regards, Ruslan -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 2/3] usb: gadget: f_uac2: split out audio core
On Mon, May 22, 2017 at 6:58 PM, Jassi Brar <jassisinghb...@gmail.com> wrote: > On Thu, May 18, 2017 at 4:07 AM, Ruslan Bilovol > <ruslan.bilo...@gmail.com> wrote: >> Abstract the peripheral side ALSA sound card code from >> the f_uac2 function into a component that can be called >> by various functions, so the various flavors can be split >> apart and selectively reused. >> >> Visible changes: >> - add uac_params structure to pass audio paramteres for >>g_audio_setup >> - make ALSA sound card's name configurable >> - add [in/out]_ep_maxpsize >> - allocate snd_uac_chip structure during g_audio_setup >> - add u_audio_[start/stop]_[capture/playback] functions >> >> Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> >> --- >> drivers/usb/gadget/Kconfig| 4 + >> drivers/usb/gadget/function/Makefile | 1 + >> drivers/usb/gadget/function/f_uac2.c | 721 >> -- >> drivers/usb/gadget/function/u_audio.c | 661 +++ >> drivers/usb/gadget/function/u_audio.h | 95 + >> drivers/usb/gadget/legacy/Kconfig | 1 + >> 6 files changed, 846 insertions(+), 637 deletions(-) >> create mode 100644 drivers/usb/gadget/function/u_audio.c >> create mode 100644 drivers/usb/gadget/function/u_audio.h >> >> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig >> index c164d6b..2ba0ace 100644 >> --- a/drivers/usb/gadget/Kconfig >> +++ b/drivers/usb/gadget/Kconfig >> @@ -158,6 +158,9 @@ config USB_U_SERIAL >> config USB_U_ETHER >> tristate >> >> +config USB_U_AUDIO >> + tristate >> + >> config USB_F_SERIAL >> tristate >> >> @@ -381,6 +384,7 @@ config USB_CONFIGFS_F_UAC2 >> depends on SND >> select USB_LIBCOMPOSITE >> select SND_PCM >> + select USB_U_AUDIO >> select USB_F_UAC2 >> help >> This Audio function is compatible with USB Audio Class >> diff --git a/drivers/usb/gadget/function/Makefile >> b/drivers/usb/gadget/function/Makefile >> index cb8c225..b29f2ae 100644 >> --- a/drivers/usb/gadget/function/Makefile >> +++ b/drivers/usb/gadget/function/Makefile >> @@ -32,6 +32,7 @@ usb_f_mass_storage-y := f_mass_storage.o >> storage_common.o >> obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o >> usb_f_fs-y := f_fs.o >> obj-$(CONFIG_USB_F_FS) += usb_f_fs.o >> +obj-$(CONFIG_USB_U_AUDIO) += u_audio.o >> usb_f_uac1-y := f_uac1.o u_uac1.o >> obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o >> usb_f_uac2-y := f_uac2.o >> diff --git a/drivers/usb/gadget/function/f_uac2.c >> b/drivers/usb/gadget/function/f_uac2.c >> index d4565b5..059a14a 100644 >> --- a/drivers/usb/gadget/function/f_uac2.c >> +++ b/drivers/usb/gadget/function/f_uac2.c >> @@ -15,10 +15,7 @@ >> #include >> #include >> >> -#include >> -#include >> -#include >> - >> +#include "u_audio.h" >> #include "u_uac2.h" >> >> /* >> @@ -50,455 +47,23 @@ >> #define UNFLW_CTRL 8 >> #define OVFLW_CTRL 10 >> >> -struct uac2_req { >> - struct uac2_rtd_params *pp; /* parent param */ >> - struct usb_request *req; >> -}; >> - >> -struct uac2_rtd_params { >> - struct snd_uac2_chip *uac2; /* parent chip */ >> - bool ep_enabled; /* if the ep is enabled */ >> - /* Size of the ring buffer */ >> - size_t dma_bytes; >> - unsigned char *dma_area; >> - >> - struct snd_pcm_substream *ss; >> - >> - /* Ring buffer */ >> - ssize_t hw_ptr; >> - >> - void *rbuf; >> - >> - size_t period_size; >> - >> - unsigned max_psize; >> - struct uac2_req *ureq; >> - >> - spinlock_t lock; >> -}; >> - >> -struct snd_uac2_chip { >> - struct uac2_rtd_params p_prm; >> - struct uac2_rtd_params c_prm; >> - >> - struct snd_card *card; >> - struct snd_pcm *pcm; >> - >> - /* timekeeping for the playback endpoint */ >> - unsigned int p_interval; >> - unsigned int p_residue; >> - >> - /* pre-calculated values for playback iso completion */ >> - unsigned int p_pktsize; >> - unsigned int p_pktsize_residue; >&
Re: [PATCH v3 0/3] USB Audio Gadget refactoring
Hi Felipe, On Mon, Aug 29, 2016 at 11:05 AM, Felipe Balbi <ba...@kernel.org> wrote: > > Hi, > > Ruslan Bilovol <ruslan.bilo...@gmail.com> writes: >> I came to this patch series when wanted to do two things: >> - use UAC1 as virtual ALSA sound card on gadget side, >>just like UAC2 is used so it's possible to do rate >>resampling >> - have both playback/capture support in UAC1 >> >> Since I wanted to have same behavior for both UAC1/UAC2, >> obviously I've got an utility part (u_audio.c) for >> virtual ALSA sound card handling like we have >> for ethernet(u_ether) or serial(u_serial) functions. >> Function-specific parts (f_uac1/f_uac2) became almost >> as storage for class-specific USB descriptors, some >> boilerplate for configfs, binding and few USB >> config request handling. >> >> Originally in RFC [1] I've posted before, there was >> major change to f_uac1 after that it couldn't do >> direct play to existing ALSA sound card anymore, >> representing audio on gadget side as virtual >> ALSA sound card where audio streams are simply >> sinked to and sourced from it, so it may break >> current usecase for some people (and that's why >> it was RFC). >> >> During RFC discussion, it was agreed to not touch >> existing f_uac1 implementation and create new one >> instead. This patchset (v2) introduced new function >> named f_uac1_newapi and doesn't touch current f_uac1 >> implementation, so people still can use old behavior >> >> Now, it's possible to use existing user-space >> applications for audio routing between Audio Gadget >> and real sound card. I personally use alsaloop tool >> from alsautils and have ability to create PCM >> loopback between two different ALSA cards using >> rate resampling, which was not possible with previous >> "direct play to ALSA card" approach in f_uac1. >> >> While here, also dropped redundant platform >> driver/device creation in f_uac2 driver (as well as >> didn't add "never implemented" volume/mute functionality >> in f_uac1 to f_uac1_newapi) that made this work even >> easier to do. >> >> This series is tested with both legacy g_audio.ko and >> modern configfs approaches under Ubuntu 14.04 (UAC1 and >> UAC2) and under Windows7 x64 (UAC1 only) having >> perfect results in all cases. >> >> Comments, testing are welcome. >> >> v3 changes: >> - renamed u_audio exported symbols so they don't >>conflict with old f_uac1 if both are built-in. >> >> v2 changes: >> - do not touch f_uac1, instead created f_uac1_newapi > > f_uac1_newapi What the hell man? :-s Yes, sometimes it's difficult to create laconic name that shows difference to old f_uac1. We can name it alternatively "f_uac1_alsa" or maybe anybody else have good idea here. I just wanted to show here that it's f_uac1 with completely different functionality (expose ALSA card to userspace instead of consuming existing one) > > Sure you can't change f_uac1 to newapi without introducing userland > visible changes? We really don't want to add another copy of f_uac1, > sorry. Do you mean same f_uac1.ko module will be able to use existing ALSA card (old api) and create it own as well (new api) in the same time at runtime? By the way, while I understand your desire to not introduce userland visible changes, in this particular case it doesn't make much sense, since that's, again, two opposite approaches to consume and transfer data to userspace Moreover, now old f_uac1 and new f_uac1_newapi have different functionality exposed to host (first one has only playback, second one - playback+capture), so even USB descriptors are different. So userspace compatibility in this case will make f_uac1 driver too difficult to maintain and add new functionality. So I prefer to keep the new version of f_uac1 function and let it move forward with new features. Best regards, Ruslan -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/3] USB Audio Gadget refactoring
I came to this patch series when wanted to do two things: - use UAC1 as virtual ALSA sound card on gadget side, just like UAC2 is used so it's possible to do rate resampling - have both playback/capture support in UAC1 Since I wanted to have same behavior for both UAC1/UAC2, obviously I've got an utility part (u_audio.c) for virtual ALSA sound card handling like we have for ethernet(u_ether) or serial(u_serial) functions. Function-specific parts (f_uac1/f_uac2) became almost as storage for class-specific USB descriptors, some boilerplate for configfs, binding and few USB config request handling. Originally in RFC [1] I've posted before, there was major change to f_uac1 after that it couldn't do direct play to existing ALSA sound card anymore, representing audio on gadget side as virtual ALSA sound card where audio streams are simply sinked to and sourced from it, so it may break current usecase for some people (and that's why it was RFC). During RFC discussion, it was agreed to not touch existing f_uac1 implementation and create new one instead. This patchset (v2) introduced new function named f_uac1_newapi and doesn't touch current f_uac1 implementation, so people still can use old behavior Now, it's possible to use existing user-space applications for audio routing between Audio Gadget and real sound card. I personally use alsaloop tool from alsautils and have ability to create PCM loopback between two different ALSA cards using rate resampling, which was not possible with previous "direct play to ALSA card" approach in f_uac1. While here, also dropped redundant platform driver/device creation in f_uac2 driver (as well as didn't add "never implemented" volume/mute functionality in f_uac1 to f_uac1_newapi) that made this work even easier to do. This series is tested with both legacy g_audio.ko and modern configfs approaches under Ubuntu 14.04 (UAC1 and UAC2) and under Windows7 x64 (UAC1 only) having perfect results in all cases. Comments, testing are welcome. v3 changes: - renamed u_audio exported symbols so they don't conflict with old f_uac1 if both are built-in. v2 changes: - do not touch f_uac1, instead created f_uac1_newapi - added documentation for f_uac1_newapi - rebased on top of v4.8-rc1 [1] https://lkml.org/lkml/2016/5/23/649 Ruslan Bilovol (3): usb: gadget: f_uac2: remove platform driver/device creation usb: gadget: f_uac2: split out audio core usb: gadget: add f_uac1 variant based on new u_audio api .../ABI/testing/configfs-usb-gadget-uac1_newapi| 12 + Documentation/usb/gadget-testing.txt | 41 ++ drivers/usb/gadget/Kconfig | 25 + drivers/usb/gadget/function/Makefile | 3 + drivers/usb/gadget/function/f_uac1_newapi.c| 795 + drivers/usb/gadget/function/f_uac2.c | 778 +++- drivers/usb/gadget/function/u_audio.c | 632 drivers/usb/gadget/function/u_audio.h | 93 +++ drivers/usb/gadget/function/u_uac1_newapi.h| 39 + drivers/usb/gadget/legacy/Kconfig | 14 +- drivers/usb/gadget/legacy/audio.c | 52 ++ 11 files changed, 1801 insertions(+), 683 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi create mode 100644 drivers/usb/gadget/function/f_uac1_newapi.c create mode 100644 drivers/usb/gadget/function/u_audio.c create mode 100644 drivers/usb/gadget/function/u_audio.h create mode 100644 drivers/usb/gadget/function/u_uac1_newapi.h -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 3/3] usb: gadget: add f_uac1 variant based on new u_audio api
This patch adds new function f_uac1_newapi that uses recently created u_audio api. This makes f_uac1_newapi implementation much simpler by reusing existing u_audio core utilities. This also drops previous f_uac1 approach (write audio samples directly to existing ALSA sound card) and moves to more generic/flexible one - create an f_uac1 ALSA sound card that represents USB Audio function and allows to be used by userspace tools. f_uac1_newapi also has capture support (gadget->host). By default, capture interface has 48000kHz/2ch configuration, same as playback channel has. f_uac1_newapi descriptors naming conventios uses f_uac2 driver naming convention that makes it more common and meaningful. Comparing to f_uac1, the f_uac1_newapi doesn't have volume/mute functionality. This is because the volume/mute feature unit was dummy implementation since that driver creation (2009) and never had real volume control or mute functionality. g_audio can be built using one of existing uac functions (f_uac1, f_uac1_newapi or f_uac2) Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- .../ABI/testing/configfs-usb-gadget-uac1_newapi| 12 + Documentation/usb/gadget-testing.txt | 41 ++ drivers/usb/gadget/Kconfig | 21 + drivers/usb/gadget/function/Makefile | 2 + drivers/usb/gadget/function/f_uac1_newapi.c| 795 + drivers/usb/gadget/function/u_uac1_newapi.h| 39 + drivers/usb/gadget/legacy/Kconfig | 15 +- drivers/usb/gadget/legacy/audio.c | 52 ++ 8 files changed, 975 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi create mode 100644 drivers/usb/gadget/function/f_uac1_newapi.c create mode 100644 drivers/usb/gadget/function/u_uac1_newapi.h diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi new file mode 100644 index 000..d355275 --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi @@ -0,0 +1,12 @@ +What: /config/usb-gadget/gadget/functions/uac1_newapi.name +Date: Aug 2016 +KernelVersion: 4.9 +Description: + The attributes: + + c_chmask - capture channel mask + c_srate - capture sampling rate + c_ssize - capture sample size (bytes) + p_chmask - playback channel mask + p_srate - playback sampling rate + p_ssize - playback sample size (bytes) diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index 5819605..4598d7f 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -20,6 +20,7 @@ provided by gadgets. 17. UAC2 function 18. UVC function 19. PRINTER function +20. UAC1 function (new API) 1. ACM function @@ -770,3 +771,43 @@ host: More advanced testing can be done with the prn_example described in Documentation/usb/gadget-printer.txt. + + +20. UAC1 function (new API, using u_audio) += + +The function is provided by usb_f_uac1_newapi.ko module. + +Function-specific configfs interface + + +The function name to use when creating the function directory +is "uac1_newapi". The uac1_newapi function provides these attributes +in its function directory: + + c_chmask - capture channel mask + c_srate - capture sampling rate + c_ssize - capture sample size (bytes) + p_chmask - playback channel mask + p_srate - playback sampling rate + p_ssize - playback sample size (bytes) + +The attributes have sane default values. + +Testing the UAC1 function +- + +device: run the gadget +host: aplay -l # should list our USB Audio Gadget + +This function does not require real hardware support, it just +sends a stream of audio data to/from the host. In order to +actually hear something at the device side, a command similar +to this must be used at the device side: + +$ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 & + +e.g.: + +$ arecord -f dat -t wav -D hw:CARD=UAC1Gadget,DEV=0 | \ +aplay -D default:CARD=OdroidU3 diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index a25afd8..abcb539 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -194,6 +194,9 @@ config USB_F_FS config USB_F_UAC1 tristate +config USB_F_UAC1_NEWAPI + tristate + config USB_F_UAC2 tristate @@ -397,6 +400,24 @@ config USB_CONFIGFS_F_UAC1 This driver requires a real Audio codec to be present on the device. +config USB_CONFIGFS_F_UAC1_NEWAPI + bool "Audio Class 1.0 (new API)" + depends on USB_CONFIGFS + depends on SND + select USB_LIBCOMPOSITE + select SND_PCM + select USB_U_AUDIO + sele
[PATCH v3 1/3] usb: gadget: f_uac2: remove platform driver/device creation
Simplify f_uac2 by removing platform driver/device creation; use composite's usb_gadget device as parent for sound card and for debug prints. This removes extra layer of code without any functional change. Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- drivers/usb/gadget/function/f_uac2.c | 107 +-- 1 file changed, 28 insertions(+), 79 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index cd214ec8..e14628c 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -54,8 +53,6 @@ #define UNFLW_CTRL 8 #define OVFLW_CTRL 10 -static const char *uac2_name = "snd_uac2"; - struct uac2_req { struct uac2_rtd_params *pp; /* parent param */ struct usb_request *req; @@ -84,9 +81,6 @@ struct uac2_rtd_params { }; struct snd_uac2_chip { - struct platform_device pdev; - struct platform_driver pdrv; - struct uac2_rtd_params p_prm; struct uac2_rtd_params c_prm; @@ -125,6 +119,7 @@ struct audio_dev { struct usb_ep *in_ep, *out_ep; struct usb_function func; + struct usb_gadget *gadget; /* The ALSA Sound Card it represents on the USB-Client side */ struct snd_uac2_chip uac2; @@ -143,12 +138,6 @@ struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u) } static inline -struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p) -{ - return container_of(p, struct snd_uac2_chip, pdev); -} - -static inline struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev) { return container_of(agdev->func.fi, struct f_uac2_opts, func_inst); @@ -257,7 +246,7 @@ agdev_iso_complete(struct usb_ep *ep, struct usb_request *req) exit: if (usb_ep_queue(ep, req, GFP_ATOMIC)) - dev_err(>pdev.dev, "%d Error!\n", __LINE__); + dev_err(uac2->card->dev, "%d Error!\n", __LINE__); if (update_alsa) snd_pcm_period_elapsed(substream); @@ -441,23 +430,22 @@ static struct snd_pcm_ops uac2_pcm_ops = { .prepare = uac2_pcm_null, }; -static int snd_uac2_probe(struct platform_device *pdev) +static int snd_uac2_probe(struct audio_dev *audio_dev) { - struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); + struct snd_uac2_chip *uac2 = _dev->uac2; struct snd_card *card; struct snd_pcm *pcm; - struct audio_dev *audio_dev; struct f_uac2_opts *opts; int err; int p_chmask, c_chmask; - audio_dev = uac2_to_agdev(uac2); opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst); p_chmask = opts->p_chmask; c_chmask = opts->c_chmask; /* Choose any slot, with no id */ - err = snd_card_new(>dev, -1, NULL, THIS_MODULE, 0, ); + err = snd_card_new(_dev->gadget->dev, + -1, NULL, THIS_MODULE, 0, ); if (err < 0) return err; @@ -482,16 +470,15 @@ static int snd_uac2_probe(struct platform_device *pdev) strcpy(card->driver, "UAC2_Gadget"); strcpy(card->shortname, "UAC2_Gadget"); - sprintf(card->longname, "UAC2_Gadget %i", pdev->id); + sprintf(card->longname, "UAC2_Gadget %i", card->dev->id); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX); err = snd_card_register(card); - if (!err) { - platform_set_drvdata(pdev, card); + + if (!err) return 0; - } snd_fail: snd_card_free(card); @@ -502,9 +489,9 @@ snd_fail: return err; } -static int snd_uac2_remove(struct platform_device *pdev) +static int snd_uac2_remove(struct audio_dev *audio_dev) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = audio_dev->uac2.card; if (card) return snd_card_free(card); @@ -512,45 +499,6 @@ static int snd_uac2_remove(struct platform_device *pdev) return 0; } -static void snd_uac2_release(struct device *dev) -{ - dev_dbg(dev, "releasing '%s'\n", dev_name(dev)); -} - -static int alsa_uac2_init(struct audio_dev *agdev) -{ - struct snd_uac2_chip *uac2 = >uac2; - int err; - - uac2->pdrv.probe = snd_uac2_probe; - uac2->pdrv.remove = snd_uac2_remove; - uac2->pdrv.driver.name = uac2_name; - - uac2->pdev.id = 0; - uac2->pdev.name = uac2_name; - uac2->pdev.dev.release = snd_uac2_release; - - /* Register snd_uac2 driver */ - err = platform_driver_register(>pdrv); - if (err) - return err; - -
[PATCH v3 2/3] usb: gadget: f_uac2: split out audio core
Abstract the peripheral side ALSA sound card code from the f_uac2 function into a component that can be called by various functions, so the various flavors can be split apart and selectively reused. Visible changes: - add uac_params structure to pass audio paramteres for g_audio_setup - make ALSA sound card's name configurable - add [in/out]_ep_maxpsize - allocate snd_uac_chip structure during g_audio_setup - add u_audio_[start/stop]_[capture/playback] functions Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- drivers/usb/gadget/Kconfig| 4 + drivers/usb/gadget/function/Makefile | 1 + drivers/usb/gadget/function/f_uac2.c | 699 -- drivers/usb/gadget/function/u_audio.c | 632 ++ drivers/usb/gadget/function/u_audio.h | 93 + drivers/usb/gadget/legacy/Kconfig | 1 + 6 files changed, 813 insertions(+), 617 deletions(-) create mode 100644 drivers/usb/gadget/function/u_audio.c create mode 100644 drivers/usb/gadget/function/u_audio.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 3c3f31c..a25afd8 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -158,6 +158,9 @@ config USB_U_SERIAL config USB_U_ETHER tristate +config USB_U_AUDIO + tristate + config USB_F_SERIAL tristate @@ -400,6 +403,7 @@ config USB_CONFIGFS_F_UAC2 depends on SND select USB_LIBCOMPOSITE select SND_PCM + select USB_U_AUDIO select USB_F_UAC2 help This Audio function is compatible with USB Audio Class diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index cb8c225..b29f2ae 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -32,6 +32,7 @@ usb_f_mass_storage-y := f_mass_storage.o storage_common.o obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o usb_f_fs-y := f_fs.o obj-$(CONFIG_USB_F_FS) += usb_f_fs.o +obj-$(CONFIG_USB_U_AUDIO) += u_audio.o usb_f_uac1-y := f_uac1.o u_uac1.o obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o usb_f_uac2-y := f_uac2.o diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index e14628c..ef8e976 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -15,15 +15,9 @@ #include #include -#include -#include -#include - +#include "u_audio.h" #include "u_uac2.h" -/* Keep everyone on toes */ -#define USB_XFERS 2 - /* * The driver implements a simple UAC_2 topology. * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture @@ -53,453 +47,23 @@ #define UNFLW_CTRL 8 #define OVFLW_CTRL 10 -struct uac2_req { - struct uac2_rtd_params *pp; /* parent param */ - struct usb_request *req; -}; - -struct uac2_rtd_params { - struct snd_uac2_chip *uac2; /* parent chip */ - bool ep_enabled; /* if the ep is enabled */ - /* Size of the ring buffer */ - size_t dma_bytes; - unsigned char *dma_area; - - struct snd_pcm_substream *ss; - - /* Ring buffer */ - ssize_t hw_ptr; - - void *rbuf; - - size_t period_size; - - unsigned max_psize; - struct uac2_req ureq[USB_XFERS]; - - spinlock_t lock; -}; - -struct snd_uac2_chip { - struct uac2_rtd_params p_prm; - struct uac2_rtd_params c_prm; - - struct snd_card *card; - struct snd_pcm *pcm; - - /* timekeeping for the playback endpoint */ - unsigned int p_interval; - unsigned int p_residue; - - /* pre-calculated values for playback iso completion */ - unsigned int p_pktsize; - unsigned int p_pktsize_residue; - unsigned int p_framesize; -}; - -#define BUFF_SIZE_MAX (PAGE_SIZE * 16) -#define PRD_SIZE_MAX PAGE_SIZE -#define MIN_PERIODS4 - -static struct snd_pcm_hardware uac2_pcm_hardware = { - .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER -| SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID -| SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, - .rates = SNDRV_PCM_RATE_CONTINUOUS, - .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX, - .buffer_bytes_max = BUFF_SIZE_MAX, - .period_bytes_max = PRD_SIZE_MAX, - .periods_min = MIN_PERIODS, -}; - -struct audio_dev { - u8 ac_intf, ac_alt; - u8 as_out_intf, as_out_alt; - u8 as_in_intf, as_in_alt; - - struct usb_ep *in_ep, *out_ep; - struct usb_function func; - struct usb_gadget *gadget; - - /* The ALSA Sound Card it represents on the USB-Client side */ - struct snd_uac2_chip uac2; +struct f_uac2 { + 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_al
Re: [PATCH v2 2/3] usb: gadget: f_uac2: split out audio core
On Tue, Aug 16, 2016 at 9:20 PM, kbuild test robot <l...@intel.com> wrote: > Hi Ruslan, > > [auto build test ERROR on balbi-usb/next] > [also build test ERROR on v4.8-rc2 next-20160816] > [if your patch is applied to the wrong git tree, please drop us a note to > help improve the system] > > url: > https://github.com/0day-ci/linux/commits/Ruslan-Bilovol/USB-Audio-Gadget-refactoring/20160814-185318 > base: https://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git next > config: x86_64-randconfig-a0-08162223 (attached as .config) > compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7 > reproduce: > # save the attached .config to linux build tree > make ARCH=x86_64 > > All errors (new ones prefixed by >>): > >drivers/usb/gadget/function/usb_f_uac1.o: In function `gaudio_setup': >>> (.text+0x16ce): multiple definition of `gaudio_setup' >drivers/usb/gadget/function/u_audio.o:u_audio.c:(.text+0x937): first > defined here >drivers/usb/gadget/function/usb_f_uac1.o: In function `gaudio_cleanup': >>> (.text+0x1147): multiple definition of `gaudio_cleanup' >drivers/usb/gadget/function/u_audio.o:u_audio.c:(.text+0x3f): first > defined here > Arrgh, it now conflicts in this patchset where we keep old f_uac1 functionality. Will fix it in next patchset. Best regards, Ruslan -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 0/3] USB Audio Gadget refactoring
On Tue, Aug 16, 2016 at 12:16 PM, Peter Chen <hzpeterc...@gmail.com> wrote: > On Sun, Aug 14, 2016 at 01:21:21AM +0300, Ruslan Bilovol wrote: >> I came to this patch series when wanted to do two things: >> - use UAC1 as virtual ALSA sound card on gadget side, >>just like UAC2 is used so it's possible to do rate >>resampling >> - have both playback/capture support in UAC1 >> >> Since I wanted to have same behavior for both UAC1/UAC2, >> obviously I've got an utility part (u_audio.c) for >> virtual ALSA sound card handling like we have >> for ethernet(u_ether) or serial(u_serial) functions. >> Function-specific parts (f_uac1/f_uac2) became almost >> as storage for class-specific USB descriptors, some >> boilerplate for configfs, binding and few USB >> config request handling. >> >> Originally in RFC [1] I've posted before, there was >> major change to f_uac1 after that it couldn't do >> direct play to existing ALSA sound card anymore, >> representing audio on gadget side as virtual >> ALSA sound card where audio streams are simply >> sinked to and sourced from it, so it may break >> current usecase for some people (and that's why >> it was RFC). >> >> During RFC discussion, it was agreed to not touch >> existing f_uac1 implementation and create new one >> instead. This patchset (v2) introduced new function >> named f_uac1_newapi and doesn't touch current f_uac1 >> implementation, so people still can use old behavior >> >> Now, it's possible to use existing user-space >> applications for audio routing between Audio Gadget >> and real sound card. I personally use alsaloop tool >> from alsautils and have ability to create PCM >> loopback between two different ALSA cards using >> rate resampling, which was not possible with previous >> "direct play to ALSA card" approach in f_uac1. >> >> While here, also dropped redundant platform >> driver/device creation in f_uac2 driver (as well as >> didn't add "never implemented" volume/mute functionality >> in f_uac1 to f_uac1_newapi) that made this work even >> easier to do. >> >> This series is tested with both legacy g_audio.ko and >> modern configfs approaches under Ubuntu 14.04 (UAC1 and >> UAC2) and under Windows7 x64 (UAC1 only) having >> perfect results in all cases. >> > > I find UAC2 (UAC1 is ok) support is not well with the latest mainline > kernel w/o your patch set. The windows7 can't install the driver > successfully and the playback shows underrun (using local codec) > using Linux host. As Clemens already pointed, Windows 7 doesn't have UAC2 support "out of the box". That's why I tested only UAC1 on it. > > Do you use the unchanged mainline kernel? Yes, this patchset is based on v4.8-rc1 tag. > > My configfs parameters like below: > echo 2 > functions/uac2.1/c_ssize > echo 48000 > functions/uac2.1/c_srate > echo 3 > functions/uac2.1/c_chmask > echo 2 > functions/uac2.1/p_ssize > echo 48000 > functions/uac2.1/p_srate > echo 3 > functions/uac2.1/p_chmask I usually don't change these (use default values here) I use BeagleBone Black for this patchset verification. Here is how I configure it through configfs: uac_2 mkdir cfg mount none cfg -t configfs mkdir cfg/usb_gadget/g1 cd cfg/usb_gadget/g1 mkdir configs/c.1 mkdir functions/uac2.0 mkdir strings/0x409 mkdir configs/c.1/strings/0x409 echo 0x0101 > idProduct echo 0x1d6b > idVendor echo my-serial-num > strings/0x409/serialnumber echo my-manufacturer > strings/0x409/manufacturer echo "Test gadget" > strings/0x409/product echo "Conf 1" > configs/c.1/strings/0x409/configuration echo 120 > configs/c.1/MaxPower ln -s functions/uac2.0 configs/c.1 echo musb-hdrc.0.auto > UDC uac_1 (new api) - mkdir cfg mount none cfg -t configfs mkdir cfg/usb_gadget/g1 cd cfg/usb_gadget/g1 mkdir configs/c.1 mkdir functions/uac1_newapi.0 mkdir strings/0x409 mkdir configs/c.1/strings/0x409 echo 0x0101 > idProduct echo 0x1d6b > idVendor echo my-serial-num > strings/0x409/serialnumber echo my-manufacturer > strings/0x409/manufacturer echo "Test gadget" > strings/0x409/product echo "Conf 1" > configs/c.1/strings/0x409/configuration echo 120 > configs/c.1/MaxPower ln -s functions/uac1_newapi.0 configs/c.1 echo musb-hdrc.0.auto > UDC > > > Console output: > root@imx6qdlsolo:~# arecord -f dat -t wav -D hw:1,0 | aplay -D hw:0,0 & > [1] 859 > root@imx6qdlsolo:~# > root@imx6qdlsolo:~# Recording WAVE 'stdin' : Signed 16 bit Little > Endian, Rate 48000 Hz, Stereo > Playing WAVE 'stdin' : Signed 1
Re: [PATCH v2 3/3] usb: gadget: add f_uac1 variant based on new u_audio api
On Tue, Aug 16, 2016 at 5:52 AM, Peter Chen <hzpeterc...@gmail.com> wrote: > On Sun, Aug 14, 2016 at 01:21:24AM +0300, Ruslan Bilovol wrote: >> This patch adds new function f_uac1_newapi that >> uses recently created u_audio api. This makes >> f_uac1_newapi implementation much simpler by >> reusing existing u_audio core utilities. >> >> This also drops previous f_uac1 approach (write >> audio samples directly to existing ALSA sound >> card) and moves to more generic/flexible >> one - create an f_uac1 ALSA sound card that >> represents USB Audio function and allows to >> be used by userspace tools. >> >> f_uac1_newapi also has capture support (gadget->host). >> By default, capture interface has 48000kHz/2ch >> configuration, same as playback channel has. >> >> f_uac1_newapi descriptors naming conventios >> uses f_uac2 driver naming convention that >> makes it more common and meaningful. >> >> Comparing to f_uac1, the f_uac1_newapi doesn't >> have volume/mute functionality. This is because >> the volume/mute feature unit was dummy >> implementation since that driver creation (2009) >> and never had real volume control or mute >> functionality. >> >> g_audio can be built using one of existing >> uac functions (f_uac1, f_uac1_newapi or f_uac2) >> >> Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> >> --- >> .../ABI/testing/configfs-usb-gadget-uac1_newapi| 12 + >> Documentation/usb/gadget-testing.txt | 41 ++ >> drivers/usb/gadget/Kconfig | 21 + >> drivers/usb/gadget/function/Makefile | 2 + >> drivers/usb/gadget/function/f_uac1_newapi.c| 795 >> + >> drivers/usb/gadget/function/u_uac1_newapi.h| 39 + >> drivers/usb/gadget/legacy/Kconfig | 15 +- >> drivers/usb/gadget/legacy/audio.c | 52 ++ >> 8 files changed, 975 insertions(+), 2 deletions(-) >> create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi >> create mode 100644 drivers/usb/gadget/function/f_uac1_newapi.c >> create mode 100644 drivers/usb/gadget/function/u_uac1_newapi.h >> >> diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi >> b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi >> new file mode 100644 >> index 000..d355275 >> --- /dev/null >> +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi >> @@ -0,0 +1,12 @@ >> +What:/config/usb-gadget/gadget/functions/uac1_newapi.name >> +Date:Aug 2016 >> +KernelVersion: 4.9 >> +Description: >> + The attributes: >> + >> + c_chmask - capture channel mask >> + c_srate - capture sampling rate >> + c_ssize - capture sample size (bytes) >> + p_chmask - playback channel mask >> + p_srate - playback sampling rate >> + p_ssize - playback sample size (bytes) >> diff --git a/Documentation/usb/gadget-testing.txt >> b/Documentation/usb/gadget-testing.txt >> index 5819605..4598d7f 100644 >> --- a/Documentation/usb/gadget-testing.txt >> +++ b/Documentation/usb/gadget-testing.txt >> @@ -20,6 +20,7 @@ provided by gadgets. >> 17. UAC2 function >> 18. UVC function >> 19. PRINTER function >> +20. UAC1 function (new API) >> >> >> 1. ACM function >> @@ -770,3 +771,43 @@ host: >> >> More advanced testing can be done with the prn_example >> described in Documentation/usb/gadget-printer.txt. >> + >> + >> +20. UAC1 function (new API, using u_audio) >> += >> + >> +The function is provided by usb_f_uac1_newapi.ko module. >> + >> +Function-specific configfs interface >> + >> + >> +The function name to use when creating the function directory >> +is "uac1_newapi". The uac1_newapi function provides these attributes >> +in its function directory: >> + >> + c_chmask - capture channel mask >> + c_srate - capture sampling rate >> + c_ssize - capture sample size (bytes) >> + p_chmask - playback channel mask >> + p_srate - playback sampling rate >> + p_ssize - playback sample size (bytes) >> + >> +The attributes have sane default values. >> + >> +Testing the UAC1 function >> +- >> + >> +device: run the gadget >> +host: aplay
[PATCH v2 1/3] usb: gadget: f_uac2: remove platform driver/device creation
Simplify f_uac2 by removing platform driver/device creation; use composite's usb_gadget device as parent for sound card and for debug prints. This removes extra layer of code without any functional change. Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- drivers/usb/gadget/function/f_uac2.c | 107 +-- 1 file changed, 28 insertions(+), 79 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index cd214ec8..e14628c 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -54,8 +53,6 @@ #define UNFLW_CTRL 8 #define OVFLW_CTRL 10 -static const char *uac2_name = "snd_uac2"; - struct uac2_req { struct uac2_rtd_params *pp; /* parent param */ struct usb_request *req; @@ -84,9 +81,6 @@ struct uac2_rtd_params { }; struct snd_uac2_chip { - struct platform_device pdev; - struct platform_driver pdrv; - struct uac2_rtd_params p_prm; struct uac2_rtd_params c_prm; @@ -125,6 +119,7 @@ struct audio_dev { struct usb_ep *in_ep, *out_ep; struct usb_function func; + struct usb_gadget *gadget; /* The ALSA Sound Card it represents on the USB-Client side */ struct snd_uac2_chip uac2; @@ -143,12 +138,6 @@ struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u) } static inline -struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p) -{ - return container_of(p, struct snd_uac2_chip, pdev); -} - -static inline struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev) { return container_of(agdev->func.fi, struct f_uac2_opts, func_inst); @@ -257,7 +246,7 @@ agdev_iso_complete(struct usb_ep *ep, struct usb_request *req) exit: if (usb_ep_queue(ep, req, GFP_ATOMIC)) - dev_err(>pdev.dev, "%d Error!\n", __LINE__); + dev_err(uac2->card->dev, "%d Error!\n", __LINE__); if (update_alsa) snd_pcm_period_elapsed(substream); @@ -441,23 +430,22 @@ static struct snd_pcm_ops uac2_pcm_ops = { .prepare = uac2_pcm_null, }; -static int snd_uac2_probe(struct platform_device *pdev) +static int snd_uac2_probe(struct audio_dev *audio_dev) { - struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); + struct snd_uac2_chip *uac2 = _dev->uac2; struct snd_card *card; struct snd_pcm *pcm; - struct audio_dev *audio_dev; struct f_uac2_opts *opts; int err; int p_chmask, c_chmask; - audio_dev = uac2_to_agdev(uac2); opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst); p_chmask = opts->p_chmask; c_chmask = opts->c_chmask; /* Choose any slot, with no id */ - err = snd_card_new(>dev, -1, NULL, THIS_MODULE, 0, ); + err = snd_card_new(_dev->gadget->dev, + -1, NULL, THIS_MODULE, 0, ); if (err < 0) return err; @@ -482,16 +470,15 @@ static int snd_uac2_probe(struct platform_device *pdev) strcpy(card->driver, "UAC2_Gadget"); strcpy(card->shortname, "UAC2_Gadget"); - sprintf(card->longname, "UAC2_Gadget %i", pdev->id); + sprintf(card->longname, "UAC2_Gadget %i", card->dev->id); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX); err = snd_card_register(card); - if (!err) { - platform_set_drvdata(pdev, card); + + if (!err) return 0; - } snd_fail: snd_card_free(card); @@ -502,9 +489,9 @@ snd_fail: return err; } -static int snd_uac2_remove(struct platform_device *pdev) +static int snd_uac2_remove(struct audio_dev *audio_dev) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = audio_dev->uac2.card; if (card) return snd_card_free(card); @@ -512,45 +499,6 @@ static int snd_uac2_remove(struct platform_device *pdev) return 0; } -static void snd_uac2_release(struct device *dev) -{ - dev_dbg(dev, "releasing '%s'\n", dev_name(dev)); -} - -static int alsa_uac2_init(struct audio_dev *agdev) -{ - struct snd_uac2_chip *uac2 = >uac2; - int err; - - uac2->pdrv.probe = snd_uac2_probe; - uac2->pdrv.remove = snd_uac2_remove; - uac2->pdrv.driver.name = uac2_name; - - uac2->pdev.id = 0; - uac2->pdev.name = uac2_name; - uac2->pdev.dev.release = snd_uac2_release; - - /* Register snd_uac2 driver */ - err = platform_driver_register(>pdrv); - if (err) - return err; - -
[PATCH v2 3/3] usb: gadget: add f_uac1 variant based on new u_audio api
This patch adds new function f_uac1_newapi that uses recently created u_audio api. This makes f_uac1_newapi implementation much simpler by reusing existing u_audio core utilities. This also drops previous f_uac1 approach (write audio samples directly to existing ALSA sound card) and moves to more generic/flexible one - create an f_uac1 ALSA sound card that represents USB Audio function and allows to be used by userspace tools. f_uac1_newapi also has capture support (gadget->host). By default, capture interface has 48000kHz/2ch configuration, same as playback channel has. f_uac1_newapi descriptors naming conventios uses f_uac2 driver naming convention that makes it more common and meaningful. Comparing to f_uac1, the f_uac1_newapi doesn't have volume/mute functionality. This is because the volume/mute feature unit was dummy implementation since that driver creation (2009) and never had real volume control or mute functionality. g_audio can be built using one of existing uac functions (f_uac1, f_uac1_newapi or f_uac2) Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com> --- .../ABI/testing/configfs-usb-gadget-uac1_newapi| 12 + Documentation/usb/gadget-testing.txt | 41 ++ drivers/usb/gadget/Kconfig | 21 + drivers/usb/gadget/function/Makefile | 2 + drivers/usb/gadget/function/f_uac1_newapi.c| 795 + drivers/usb/gadget/function/u_uac1_newapi.h| 39 + drivers/usb/gadget/legacy/Kconfig | 15 +- drivers/usb/gadget/legacy/audio.c | 52 ++ 8 files changed, 975 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi create mode 100644 drivers/usb/gadget/function/f_uac1_newapi.c create mode 100644 drivers/usb/gadget/function/u_uac1_newapi.h diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi new file mode 100644 index 000..d355275 --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1_newapi @@ -0,0 +1,12 @@ +What: /config/usb-gadget/gadget/functions/uac1_newapi.name +Date: Aug 2016 +KernelVersion: 4.9 +Description: + The attributes: + + c_chmask - capture channel mask + c_srate - capture sampling rate + c_ssize - capture sample size (bytes) + p_chmask - playback channel mask + p_srate - playback sampling rate + p_ssize - playback sample size (bytes) diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index 5819605..4598d7f 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -20,6 +20,7 @@ provided by gadgets. 17. UAC2 function 18. UVC function 19. PRINTER function +20. UAC1 function (new API) 1. ACM function @@ -770,3 +771,43 @@ host: More advanced testing can be done with the prn_example described in Documentation/usb/gadget-printer.txt. + + +20. UAC1 function (new API, using u_audio) += + +The function is provided by usb_f_uac1_newapi.ko module. + +Function-specific configfs interface + + +The function name to use when creating the function directory +is "uac1_newapi". The uac1_newapi function provides these attributes +in its function directory: + + c_chmask - capture channel mask + c_srate - capture sampling rate + c_ssize - capture sample size (bytes) + p_chmask - playback channel mask + p_srate - playback sampling rate + p_ssize - playback sample size (bytes) + +The attributes have sane default values. + +Testing the UAC1 function +- + +device: run the gadget +host: aplay -l # should list our USB Audio Gadget + +This function does not require real hardware support, it just +sends a stream of audio data to/from the host. In order to +actually hear something at the device side, a command similar +to this must be used at the device side: + +$ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 & + +e.g.: + +$ arecord -f dat -t wav -D hw:CARD=UAC1Gadget,DEV=0 | \ +aplay -D default:CARD=OdroidU3 diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index a25afd8..abcb539 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -194,6 +194,9 @@ config USB_F_FS config USB_F_UAC1 tristate +config USB_F_UAC1_NEWAPI + tristate + config USB_F_UAC2 tristate @@ -397,6 +400,24 @@ config USB_CONFIGFS_F_UAC1 This driver requires a real Audio codec to be present on the device. +config USB_CONFIGFS_F_UAC1_NEWAPI + bool "Audio Class 1.0 (new API)" + depends on USB_CONFIGFS + depends on SND + select USB_LIBCOMPOSITE + select SND_PCM + select USB_U_AUDIO + sele