]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: gadget: f_uac2: Expose all string descriptors through configfs.
authorChris Wulff <Chris.Wulff@biamp.com>
Sun, 4 Aug 2024 00:19:24 +0000 (20:19 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Aug 2024 08:37:05 +0000 (10:37 +0200)
This makes all string descriptors configurable for the UAC2 gadget
so the user can configure names of terminals and controls. Alt mode
names are not included for now and will be in future work related
to adding alternate settings.

discussion thread for api changes for alt mode settings:
https://lore.kernel.org/linux-usb/35be4668-58d3-894a-72cf-de1afaacae45@ivitera.com/T/

Signed-off-by: Chris Wulff <chris.wulff@biamp.com>
Link: https://lore.kernel.org/r/20240804001923.3279431-2-crwulff@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/ABI/testing/configfs-usb-gadget-uac2
Documentation/usb/gadget-testing.rst
drivers/usb/gadget/function/f_uac2.c
drivers/usb/gadget/function/u_uac2.h

index a2bf4fd82a5b7c3ec512256a39ae72dc8995f844..133e995c3e92803d225481f902d6b4aafd860735 100644 (file)
@@ -35,6 +35,17 @@ Description:
                req_number              the number of pre-allocated requests
                                        for both capture and playback
                function_name           name of the interface
+               if_ctrl_name            topology control name
+               clksrc_in_name          input clock name
+               clksrc_out_name         output clock name
+               p_it_name               playback input terminal name
+               p_it_ch_name            playback input first channel name
+               p_ot_name               playback output terminal name
+               p_fu_vol_name           playback mute/volume function unit name
+               c_it_name               capture input terminal name
+               c_it_ch_name            capture input first channel name
+               c_ot_name               capture output terminal name
+               c_fu_vol_name           capture mute/volume functional unit name
                c_terminal_type         code of the capture terminal type
                p_terminal_type         code of the playback terminal type
                =====================   =======================================
index a89b49e639c3170184fbb04eb2c1e1a38991fcfd..8092e250ec27bac5efdad24ec2ce67f217f5e70c 100644 (file)
@@ -765,6 +765,17 @@ The uac2 function provides these attributes in its function directory:
        req_number       the number of pre-allocated request for both capture
                         and playback
        function_name    name of the interface
+       if_ctrl_name     topology control name
+       clksrc_in_name   input clock name
+       clksrc_out_name  output clock name
+       p_it_name        playback input terminal name
+       p_it_ch_name     playback input first channel name
+       p_ot_name        playback output terminal name
+       p_fu_vol_name    playback function unit name
+       c_it_name        capture input terminal name
+       c_it_ch_name     capture input first channel name
+       c_ot_name        capture output terminal name
+       c_fu_vol_name    capture functional unit name
        c_terminal_type  code of the capture terminal type
        p_terminal_type  code of the playback terminal type
        ================ ====================================================
index 2d6d3286ffde2ce10e4fbb078d5c3fdac7398083..1cdda44455b343fdb0d1ef32ab727e2a91bf2d57 100644 (file)
@@ -95,7 +95,9 @@ enum {
        STR_CLKSRC_IN,
        STR_CLKSRC_OUT,
        STR_USB_IT,
+       STR_USB_IT_CH,
        STR_IO_IT,
+       STR_IO_IT_CH,
        STR_USB_OT,
        STR_IO_OT,
        STR_FU_IN,
@@ -104,25 +106,10 @@ enum {
        STR_AS_OUT_ALT1,
        STR_AS_IN_ALT0,
        STR_AS_IN_ALT1,
+       NUM_STR_DESCRIPTORS,
 };
 
-static struct usb_string strings_fn[] = {
-       /* [STR_ASSOC].s = DYNAMIC, */
-       [STR_IF_CTRL].s = "Topology Control",
-       [STR_CLKSRC_IN].s = "Input Clock",
-       [STR_CLKSRC_OUT].s = "Output Clock",
-       [STR_USB_IT].s = "USBH Out",
-       [STR_IO_IT].s = "USBD Out",
-       [STR_USB_OT].s = "USBH In",
-       [STR_IO_OT].s = "USBD In",
-       [STR_FU_IN].s = "Capture Volume",
-       [STR_FU_OUT].s = "Playback Volume",
-       [STR_AS_OUT_ALT0].s = "Playback Inactive",
-       [STR_AS_OUT_ALT1].s = "Playback Active",
-       [STR_AS_IN_ALT0].s = "Capture Inactive",
-       [STR_AS_IN_ALT1].s = "Capture Active",
-       { },
-};
+static struct usb_string strings_fn[NUM_STR_DESCRIPTORS + 1] = {};
 
 static const char *const speed_names[] = {
        [USB_SPEED_UNKNOWN] = "UNKNOWN",
@@ -1049,6 +1036,23 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
                return ret;
 
        strings_fn[STR_ASSOC].s = uac2_opts->function_name;
+       strings_fn[STR_IF_CTRL].s = uac2_opts->if_ctrl_name;
+       strings_fn[STR_CLKSRC_IN].s = uac2_opts->clksrc_in_name;
+       strings_fn[STR_CLKSRC_OUT].s = uac2_opts->clksrc_out_name;
+
+       strings_fn[STR_USB_IT].s = uac2_opts->c_it_name;
+       strings_fn[STR_USB_IT_CH].s = uac2_opts->c_it_ch_name;
+       strings_fn[STR_IO_OT].s = uac2_opts->c_ot_name;
+       strings_fn[STR_FU_OUT].s = uac2_opts->c_fu_vol_name;
+       strings_fn[STR_AS_OUT_ALT0].s = "Playback Inactive";
+       strings_fn[STR_AS_OUT_ALT1].s = "Playback Active";
+
+       strings_fn[STR_IO_IT].s = uac2_opts->p_it_name;
+       strings_fn[STR_IO_IT_CH].s = uac2_opts->p_it_ch_name;
+       strings_fn[STR_USB_OT].s = uac2_opts->p_ot_name;
+       strings_fn[STR_FU_IN].s = uac2_opts->p_fu_vol_name;
+       strings_fn[STR_AS_IN_ALT0].s = "Capture Inactive";
+       strings_fn[STR_AS_IN_ALT1].s = "Capture Active";
 
        us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn));
        if (IS_ERR(us))
@@ -1072,7 +1076,9 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
        in_clk_src_desc.iClockSource = us[STR_CLKSRC_IN].id;
        out_clk_src_desc.iClockSource = us[STR_CLKSRC_OUT].id;
        usb_out_it_desc.iTerminal = us[STR_USB_IT].id;
+       usb_out_it_desc.iChannelNames = us[STR_USB_IT_CH].id;
        io_in_it_desc.iTerminal = us[STR_IO_IT].id;
+       io_in_it_desc.iChannelNames = us[STR_IO_IT_CH].id;
        usb_in_ot_desc.iTerminal = us[STR_USB_OT].id;
        io_out_ot_desc.iTerminal = us[STR_IO_OT].id;
        std_as_out_if0_desc.iInterface = us[STR_AS_OUT_ALT0].id;
@@ -2100,10 +2106,24 @@ UAC2_ATTRIBUTE(s16, c_volume_max);
 UAC2_ATTRIBUTE(s16, c_volume_res);
 UAC2_ATTRIBUTE(u32, fb_max);
 UAC2_ATTRIBUTE_STRING(function_name);
+UAC2_ATTRIBUTE_STRING(if_ctrl_name);
+UAC2_ATTRIBUTE_STRING(clksrc_in_name);
+UAC2_ATTRIBUTE_STRING(clksrc_out_name);
+
+UAC2_ATTRIBUTE_STRING(p_it_name);
+UAC2_ATTRIBUTE_STRING(p_it_ch_name);
+UAC2_ATTRIBUTE_STRING(p_ot_name);
+UAC2_ATTRIBUTE_STRING(p_fu_vol_name);
+
+UAC2_ATTRIBUTE_STRING(c_it_name);
+UAC2_ATTRIBUTE_STRING(c_it_ch_name);
+UAC2_ATTRIBUTE_STRING(c_ot_name);
+UAC2_ATTRIBUTE_STRING(c_fu_vol_name);
 
 UAC2_ATTRIBUTE(s16, p_terminal_type);
 UAC2_ATTRIBUTE(s16, c_terminal_type);
 
+
 static struct configfs_attribute *f_uac2_attrs[] = {
        &f_uac2_opts_attr_p_chmask,
        &f_uac2_opts_attr_p_srate,
@@ -2130,6 +2150,19 @@ static struct configfs_attribute *f_uac2_attrs[] = {
        &f_uac2_opts_attr_c_volume_res,
 
        &f_uac2_opts_attr_function_name,
+       &f_uac2_opts_attr_if_ctrl_name,
+       &f_uac2_opts_attr_clksrc_in_name,
+       &f_uac2_opts_attr_clksrc_out_name,
+
+       &f_uac2_opts_attr_p_it_name,
+       &f_uac2_opts_attr_p_it_ch_name,
+       &f_uac2_opts_attr_p_ot_name,
+       &f_uac2_opts_attr_p_fu_vol_name,
+
+       &f_uac2_opts_attr_c_it_name,
+       &f_uac2_opts_attr_c_it_ch_name,
+       &f_uac2_opts_attr_c_ot_name,
+       &f_uac2_opts_attr_c_fu_vol_name,
 
        &f_uac2_opts_attr_p_terminal_type,
        &f_uac2_opts_attr_c_terminal_type,
@@ -2191,6 +2224,19 @@ static struct usb_function_instance *afunc_alloc_inst(void)
        opts->fb_max = FBACK_FAST_MAX;
 
        scnprintf(opts->function_name, sizeof(opts->function_name), "Source/Sink");
+       scnprintf(opts->if_ctrl_name, sizeof(opts->if_ctrl_name), "Topology Control");
+       scnprintf(opts->clksrc_in_name, sizeof(opts->clksrc_in_name), "Input Clock");
+       scnprintf(opts->clksrc_out_name, sizeof(opts->clksrc_out_name), "Output Clock");
+
+       scnprintf(opts->p_it_name, sizeof(opts->p_it_name), "USBD Out");
+       scnprintf(opts->p_it_ch_name, sizeof(opts->p_it_ch_name), "Capture Channels");
+       scnprintf(opts->p_ot_name, sizeof(opts->p_ot_name), "USBH In");
+       scnprintf(opts->p_fu_vol_name, sizeof(opts->p_fu_vol_name), "Capture Volume");
+
+       scnprintf(opts->c_it_name, sizeof(opts->c_it_name), "USBH Out");
+       scnprintf(opts->c_it_ch_name, sizeof(opts->c_it_ch_name), "Playback Channels");
+       scnprintf(opts->c_ot_name, sizeof(opts->c_ot_name), "USBD In");
+       scnprintf(opts->c_fu_vol_name, sizeof(opts->c_fu_vol_name), "Playback Volume");
 
        opts->p_terminal_type = UAC2_DEF_P_TERM_TYPE;
        opts->c_terminal_type = UAC2_DEF_C_TERM_TYPE;
index 5e81bdd6c5fbab1075704cb4cb0cdfe4d58c86b2..0df808289ded0d0fb8eb4aac99ce2dd54315ce0c 100644 (file)
@@ -68,7 +68,20 @@ struct f_uac2_opts {
        int                             fb_max;
        bool                    bound;
 
-       char                    function_name[32];
+       char                    function_name[USB_MAX_STRING_LEN];
+       char                    if_ctrl_name[USB_MAX_STRING_LEN];
+       char                    clksrc_in_name[USB_MAX_STRING_LEN];
+       char                    clksrc_out_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_vol_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_vol_name[USB_MAX_STRING_LEN];
 
        s16                             p_terminal_type;
        s16                             c_terminal_type;