summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorChris Wulff <Chris.Wulff@biamp.com>2024-08-04 02:19:24 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-08-13 10:37:05 +0200
commit8952e50e16e383ff7fce873ac7676e0d68a3552b (patch)
treee013a2dbfa805c51c5b7c9e93dc206862c6fa0f1 /drivers/usb/gadget
parentusb: phy: mxs: enable weak 1p1 regulator for imx6ul during suspend (diff)
downloadlinux-8952e50e16e383ff7fce873ac7676e0d68a3552b.tar.xz
linux-8952e50e16e383ff7fce873ac7676e0d68a3552b.zip
usb: gadget: f_uac2: Expose all string descriptors through configfs.
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>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/function/f_uac2.c80
-rw-r--r--drivers/usb/gadget/function/u_uac2.h15
2 files changed, 77 insertions, 18 deletions
diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
index 2d6d3286ffde..1cdda44455b3 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -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;
diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h
index 5e81bdd6c5fb..0df808289ded 100644
--- a/drivers/usb/gadget/function/u_uac2.h
+++ b/drivers/usb/gadget/function/u_uac2.h
@@ -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;