Commit a7339e4f authored by Julian Scheel's avatar Julian Scheel Committed by Greg Kroah-Hartman

usb: gadget: f_uac2: Support multiple sampling rates

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 (stored in
struct f_uac2) is updated.

The gadget no longer supports only one frequency. Therefore USB strings
corresponding to the clock sources are renamed from specific Hz value to
general names Input clock/Output clock.

Config strings with single value stay compatible with the previous
version.

Multiple samplerates passed as configuration arrays to g_audio module
when built for f_uac2.
Signed-off-by: default avatarJulian Scheel <julian@jusst.de>
Signed-off-by: default avatarPavel Hofman <pavel.hofman@ivitera.com>
Link: https://lore.kernel.org/r/20220121155308.48794-6-pavel.hofman@ivitera.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent eb3a1ce6
...@@ -6,7 +6,7 @@ Description: ...@@ -6,7 +6,7 @@ Description:
===================== ======================================= ===================== =======================================
c_chmask capture channel mask 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) c_ssize capture sample size (bytes)
c_sync capture synchronization type c_sync capture synchronization type
(async/adaptive) (async/adaptive)
...@@ -20,7 +20,7 @@ Description: ...@@ -20,7 +20,7 @@ Description:
(in 1/256 dB) (in 1/256 dB)
fb_max maximum extra bandwidth in async mode fb_max maximum extra bandwidth in async mode
p_chmask playback channel mask 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) p_ssize playback sample size (bytes)
p_mute_present playback mute control enable p_mute_present playback mute control enable
p_volume_present playback volume control enable p_volume_present playback volume control enable
......
...@@ -726,7 +726,7 @@ The uac2 function provides these attributes in its function directory: ...@@ -726,7 +726,7 @@ The uac2 function provides these attributes in its function directory:
================ ==================================================== ================ ====================================================
c_chmask capture channel mask 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) c_ssize capture sample size (bytes)
c_sync capture synchronization type (async/adaptive) c_sync capture synchronization type (async/adaptive)
c_mute_present capture mute control enable c_mute_present capture mute control enable
...@@ -736,7 +736,7 @@ The uac2 function provides these attributes in its function directory: ...@@ -736,7 +736,7 @@ The uac2 function provides these attributes in its function directory:
c_volume_res capture volume control resolution (in 1/256 dB) c_volume_res capture volume control resolution (in 1/256 dB)
fb_max maximum extra bandwidth in async mode fb_max maximum extra bandwidth in async mode
p_chmask playback channel mask 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) p_ssize playback sample size (bytes)
p_mute_present playback mute control enable p_mute_present playback mute control enable
p_volume_present playback volume control enable p_volume_present playback volume control enable
......
This diff is collapsed.
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#define U_UAC2_H #define U_UAC2_H
#include <linux/usb/composite.h> #include <linux/usb/composite.h>
#include "uac_common.h"
#define UAC2_DEF_PCHMASK 0x3 #define UAC2_DEF_PCHMASK 0x3
#define UAC2_DEF_PSRATE 48000 #define UAC2_DEF_PSRATE 48000
...@@ -35,10 +36,10 @@ ...@@ -35,10 +36,10 @@
struct f_uac2_opts { struct f_uac2_opts {
struct usb_function_instance func_inst; struct usb_function_instance func_inst;
int p_chmask; int p_chmask;
int p_srate; int p_srates[UAC_MAX_RATES];
int p_ssize; int p_ssize;
int c_chmask; int c_chmask;
int c_srate; int c_srates[UAC_MAX_RATES];
int c_ssize; int c_ssize;
int c_sync; int c_sync;
......
...@@ -26,9 +26,10 @@ module_param(p_chmask, uint, 0444); ...@@ -26,9 +26,10 @@ module_param(p_chmask, uint, 0444);
MODULE_PARM_DESC(p_chmask, "Playback Channel Mask"); MODULE_PARM_DESC(p_chmask, "Playback Channel Mask");
/* Playback Default 48 KHz */ /* Playback Default 48 KHz */
static int p_srate = UAC2_DEF_PSRATE; static int p_srates[UAC_MAX_RATES] = {UAC2_DEF_PSRATE};
module_param(p_srate, uint, 0444); static int p_srates_cnt = 1;
MODULE_PARM_DESC(p_srate, "Playback Sampling Rate"); module_param_array_named(p_srate, p_srates, uint, &p_srates_cnt, 0444);
MODULE_PARM_DESC(p_srate, "Playback Sampling Rates (array)");
/* Playback Default 16bits/sample */ /* Playback Default 16bits/sample */
static int p_ssize = UAC2_DEF_PSSIZE; static int p_ssize = UAC2_DEF_PSSIZE;
...@@ -41,9 +42,10 @@ module_param(c_chmask, uint, 0444); ...@@ -41,9 +42,10 @@ module_param(c_chmask, uint, 0444);
MODULE_PARM_DESC(c_chmask, "Capture Channel Mask"); MODULE_PARM_DESC(c_chmask, "Capture Channel Mask");
/* Capture Default 64 KHz */ /* Capture Default 64 KHz */
static int c_srate = UAC2_DEF_CSRATE; static int c_srates[UAC_MAX_RATES] = {UAC2_DEF_CSRATE};
module_param(c_srate, uint, 0444); static int c_srates_cnt = 1;
MODULE_PARM_DESC(c_srate, "Capture Sampling Rate"); module_param_array_named(c_srate, c_srates, uint, &c_srates_cnt, 0444);
MODULE_PARM_DESC(c_srate, "Capture Sampling Rates (array)");
/* Capture Default 16bits/sample */ /* Capture Default 16bits/sample */
static int c_ssize = UAC2_DEF_CSSIZE; static int c_ssize = UAC2_DEF_CSSIZE;
...@@ -237,6 +239,7 @@ static int audio_bind(struct usb_composite_dev *cdev) ...@@ -237,6 +239,7 @@ static int audio_bind(struct usb_composite_dev *cdev)
{ {
#ifndef CONFIG_GADGET_UAC1 #ifndef CONFIG_GADGET_UAC1
struct f_uac2_opts *uac2_opts; struct f_uac2_opts *uac2_opts;
int i;
#else #else
#ifndef CONFIG_GADGET_UAC1_LEGACY #ifndef CONFIG_GADGET_UAC1_LEGACY
struct f_uac1_opts *uac1_opts; struct f_uac1_opts *uac1_opts;
...@@ -263,10 +266,16 @@ static int audio_bind(struct usb_composite_dev *cdev) ...@@ -263,10 +266,16 @@ static int audio_bind(struct usb_composite_dev *cdev)
#ifndef CONFIG_GADGET_UAC1 #ifndef CONFIG_GADGET_UAC1
uac2_opts = container_of(fi_uac2, struct f_uac2_opts, func_inst); uac2_opts = container_of(fi_uac2, struct f_uac2_opts, func_inst);
uac2_opts->p_chmask = p_chmask; uac2_opts->p_chmask = p_chmask;
uac2_opts->p_srate = p_srate;
for (i = 0; i < p_srates_cnt; ++i)
uac2_opts->p_srates[i] = p_srates[i];
uac2_opts->p_ssize = p_ssize; uac2_opts->p_ssize = p_ssize;
uac2_opts->c_chmask = c_chmask; uac2_opts->c_chmask = c_chmask;
uac2_opts->c_srate = c_srate;
for (i = 0; i < c_srates_cnt; ++i)
uac2_opts->c_srates[i] = c_srates[i];
uac2_opts->c_ssize = c_ssize; uac2_opts->c_ssize = c_ssize;
uac2_opts->req_number = UAC2_DEF_REQ_NUM; uac2_opts->req_number = UAC2_DEF_REQ_NUM;
#else #else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment