This makes all string descriptors configurable for the UAC1 gadget so the user can configure names of terminals/controls/alt modes. Signed-off-by: Chris Wulff <chris.wulff@xxxxxxxxx> --- v2: Improved naming of parameters to be mode user friendly. Added documentation. v1: https://lore.kernel.org/linux-usb/CO1PR17MB54198F836C3ED1B4FA5F14A9E10D2@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/ .../ABI/testing/configfs-usb-gadget-uac1 | 12 +++ Documentation/usb/gadget-testing.rst | 12 +++ drivers/usb/gadget/function/f_uac1.c | 75 +++++++++++++++---- drivers/usb/gadget/function/u_uac1.h | 16 +++- 4 files changed, 98 insertions(+), 17 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1 index c4ba92f004c3..cf93b98b274d 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac1 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1 @@ -30,4 +30,16 @@ Description: req_number the number of pre-allocated requests for both capture and playback function_name name of the interface + p_it_name playback input terminal name + p_it_ch_name playback channels name + p_ot_name playback output terminal name + p_fu_name playback functional unit name + p_alt0_name playback alt mode 0 name + p_alt1_name playback alt mode 1 name + c_it_name capture input terminal name + c_it_ch_name capture channels name + c_ot_name capture output terminal name + c_fu_name capture functional unit name + c_alt0_name capture alt mode 0 name + c_alt1_name capture alt mode 1 name ===================== ======================================= diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index b086c7ab72f0..a89b49e639c3 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -957,6 +957,18 @@ The uac1 function provides these attributes in its function directory: req_number the number of pre-allocated requests for both capture and playback function_name name of the interface + p_it_name playback input terminal name + p_it_ch_name playback channels name + p_ot_name playback output terminal name + p_fu_name playback functional unit name + p_alt0_name playback alt mode 0 name + p_alt1_name playback alt mode 1 name + c_it_name capture input terminal name + c_it_ch_name capture channels name + c_ot_name capture output terminal name + c_fu_name capture functional unit name + c_alt0_name capture alt mode 0 name + c_alt1_name capture alt mode 1 name ================ ==================================================== The attributes have sane default values. diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 7de74a3dd392..f7dd6a2466b0 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -377,24 +377,10 @@ enum { STR_AS_OUT_IF_ALT1, STR_AS_IN_IF_ALT0, STR_AS_IN_IF_ALT1, + NUM_STR_DESCRIPTORS, }; -static struct usb_string strings_uac1[] = { - /* [STR_AC_IF].s = DYNAMIC, */ - [STR_USB_OUT_IT].s = "Playback Input terminal", - [STR_USB_OUT_IT_CH_NAMES].s = "Playback Channels", - [STR_IO_OUT_OT].s = "Playback Output terminal", - [STR_IO_IN_IT].s = "Capture Input terminal", - [STR_IO_IN_IT_CH_NAMES].s = "Capture Channels", - [STR_USB_IN_OT].s = "Capture Output terminal", - [STR_FU_IN].s = "Capture Volume", - [STR_FU_OUT].s = "Playback Volume", - [STR_AS_OUT_IF_ALT0].s = "Playback Inactive", - [STR_AS_OUT_IF_ALT1].s = "Playback Active", - [STR_AS_IN_IF_ALT0].s = "Capture Inactive", - [STR_AS_IN_IF_ALT1].s = "Capture Active", - { }, -}; +static struct usb_string strings_uac1[NUM_STR_DESCRIPTORS + 1] = {}; static struct usb_gadget_strings str_uac1 = { .language = 0x0409, /* en-us */ @@ -1265,6 +1251,20 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) strings_uac1[STR_AC_IF].s = audio_opts->function_name; + strings_uac1[STR_USB_OUT_IT].s = audio_opts->p_it_name; + strings_uac1[STR_USB_OUT_IT_CH_NAMES].s = audio_opts->p_it_ch_name; + strings_uac1[STR_IO_OUT_OT].s = audio_opts->p_ot_name; + strings_uac1[STR_FU_OUT].s = audio_opts->p_fu_name; + strings_uac1[STR_AS_OUT_IF_ALT0].s = audio_opts->p_alt0_name; + strings_uac1[STR_AS_OUT_IF_ALT1].s = audio_opts->p_alt1_name; + + strings_uac1[STR_IO_IN_IT].s = audio_opts->c_it_name; + strings_uac1[STR_IO_IN_IT_CH_NAMES].s = audio_opts->c_it_ch_name; + strings_uac1[STR_USB_IN_OT].s = audio_opts->c_ot_name; + strings_uac1[STR_FU_IN].s = audio_opts->c_fu_name; + strings_uac1[STR_AS_IN_IF_ALT0].s = audio_opts->c_alt0_name; + strings_uac1[STR_AS_IN_IF_ALT1].s = audio_opts->c_alt1_name; + us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); if (IS_ERR(us)) return PTR_ERR(us); @@ -1681,8 +1681,23 @@ UAC1_ATTRIBUTE(bool, c_volume_present); UAC1_ATTRIBUTE(s16, c_volume_min); UAC1_ATTRIBUTE(s16, c_volume_max); UAC1_ATTRIBUTE(s16, c_volume_res); + UAC1_ATTRIBUTE_STRING(function_name); +UAC1_ATTRIBUTE_STRING(p_it_name); +UAC1_ATTRIBUTE_STRING(p_it_ch_name); +UAC1_ATTRIBUTE_STRING(p_ot_name); +UAC1_ATTRIBUTE_STRING(p_fu_name); +UAC1_ATTRIBUTE_STRING(p_alt0_name); +UAC1_ATTRIBUTE_STRING(p_alt1_name); + +UAC1_ATTRIBUTE_STRING(c_it_name); +UAC1_ATTRIBUTE_STRING(c_it_ch_name); +UAC1_ATTRIBUTE_STRING(c_ot_name); +UAC1_ATTRIBUTE_STRING(c_fu_name); +UAC1_ATTRIBUTE_STRING(c_alt0_name); +UAC1_ATTRIBUTE_STRING(c_alt1_name); + static struct configfs_attribute *f_uac1_attrs[] = { &f_uac1_opts_attr_c_chmask, &f_uac1_opts_attr_c_srate, @@ -1706,6 +1721,20 @@ static struct configfs_attribute *f_uac1_attrs[] = { &f_uac1_opts_attr_function_name, + &f_uac1_opts_attr_p_it_name, + &f_uac1_opts_attr_p_it_ch_name, + &f_uac1_opts_attr_p_ot_name, + &f_uac1_opts_attr_p_fu_name, + &f_uac1_opts_attr_p_alt0_name, + &f_uac1_opts_attr_p_alt1_name, + + &f_uac1_opts_attr_c_it_name, + &f_uac1_opts_attr_c_it_ch_name, + &f_uac1_opts_attr_c_ot_name, + &f_uac1_opts_attr_c_fu_name, + &f_uac1_opts_attr_c_alt0_name, + &f_uac1_opts_attr_c_alt1_name, + NULL, }; @@ -1760,6 +1789,20 @@ static struct usb_function_instance *f_audio_alloc_inst(void) scnprintf(opts->function_name, sizeof(opts->function_name), "AC Interface"); + scnprintf(opts->p_it_name, sizeof(opts->p_it_name), "Playback Input terminal"); + scnprintf(opts->p_it_ch_name, sizeof(opts->p_it_ch_name), "Playback Channels"); + scnprintf(opts->p_ot_name, sizeof(opts->p_ot_name), "Playback Output terminal"); + scnprintf(opts->p_fu_name, sizeof(opts->p_fu_name), "Playback Volume"); + scnprintf(opts->p_alt0_name, sizeof(opts->p_alt0_name), "Playback Inactive"); + scnprintf(opts->p_alt1_name, sizeof(opts->p_alt1_name), "Playback Active"); + + scnprintf(opts->c_it_name, sizeof(opts->c_it_name), "Capture Input terminal"); + scnprintf(opts->c_it_ch_name, sizeof(opts->c_it_ch_name), "Capture Channels"); + scnprintf(opts->c_ot_name, sizeof(opts->c_ot_name), "Capture Output terminal"); + scnprintf(opts->c_fu_name, sizeof(opts->c_fu_name), "Capture Volume"); + scnprintf(opts->c_alt0_name, sizeof(opts->c_alt0_name), "Capture Inactive"); + scnprintf(opts->c_alt1_name, sizeof(opts->c_alt1_name), "Capture Active"); + return &opts->func_inst; } diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index f7a616760e31..67784de9782b 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h @@ -52,7 +52,21 @@ struct f_uac1_opts { int req_number; unsigned bound:1; - char function_name[32]; + char function_name[USB_MAX_STRING_LEN]; + + char p_it_name[USB_MAX_STRING_LEN]; + char p_it_ch_name[USB_MAX_STRING_LEN]; + char p_ot_name[USB_MAX_STRING_LEN]; + char p_fu_name[USB_MAX_STRING_LEN]; + char p_alt0_name[USB_MAX_STRING_LEN]; + char p_alt1_name[USB_MAX_STRING_LEN]; + + char c_it_name[USB_MAX_STRING_LEN]; + char c_it_ch_name[USB_MAX_STRING_LEN]; + char c_ot_name[USB_MAX_STRING_LEN]; + char c_fu_name[USB_MAX_STRING_LEN]; + char c_alt0_name[USB_MAX_STRING_LEN]; + char c_alt1_name[USB_MAX_STRING_LEN]; struct mutex lock; int refcnt; -- 2.34.1