diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c
index e7bfc32387bf..3484aa237354 100644
--- a/drivers/usb/gadget/function/f_uac1.c
+++ b/drivers/usb/gadget/function/f_uac1.c
@@ -498,35 +498,6 @@ static struct usb_descriptor_header *f_audio_ss_desc[] = {
 	NULL,
 };
 
-enum {
-	STR_AC_IF,
-	STR_USB_OUT_IT,
-	STR_USB_OUT_IT_CH_NAMES,
-	STR_IO_OUT_OT,
-	STR_IO_IN_IT,
-	STR_IO_IN_IT_CH_NAMES,
-	STR_USB_IN_OT,
-	STR_FU_IN,
-	STR_FU_OUT,
-	STR_AS_OUT_IF_ALT0,
-	STR_AS_OUT_IF_ALT1,
-	STR_AS_IN_IF_ALT0,
-	STR_AS_IN_IF_ALT1,
-	NUM_STR_DESCRIPTORS,
-};
-
-static struct usb_string strings_uac1[NUM_STR_DESCRIPTORS + 1] = {};
-
-static struct usb_gadget_strings str_uac1 = {
-	.language = 0x0409,	/* en-us */
-	.strings = strings_uac1,
-};
-
-static struct usb_gadget_strings *uac1_strings[] = {
-	&str_uac1,
-	NULL,
-};
-
 /*
  * This function is an ALSA sound card following USB Audio Class Spec 1.0.
  */
@@ -1163,6 +1134,93 @@ f_audio_suspend(struct usb_function *f)
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * String handling
+ */
+
+#define MAX_STRINGS 256
+
+static int add_string(struct usb_string *strings, const char *s)
+{
+	int i;
+
+	if (!s || s[0] == '\0')
+		return 0;
+
+	for (i = 0; i < MAX_STRINGS; i++) {
+		if (!strings[i].s) {
+			strings[i].s = s;
+			return 0; /* IDs aren't allocated yet */
+		}
+
+		if (!strcmp(s, strings[i].s))
+			return strings[i].id;
+	}
+
+	return -1;
+}
+
+static void add_alt_strings(struct usb_string *strings, struct f_uac1_alt_opts *alt_opts, bool fu)
+{
+	add_string(strings, alt_opts->name);
+	add_string(strings, alt_opts->it_name);
+	add_string(strings, alt_opts->it_ch_name);
+	add_string(strings, alt_opts->ot_name);
+	if (fu)
+		add_string(strings, alt_opts->fu_vol_name);
+}
+
+static struct usb_string *attach_strings(struct usb_composite_dev *cdev,
+					 struct f_uac1_opts *audio_opts)
+{
+	struct usb_string	*strings = kzalloc(sizeof(struct usb_string) * MAX_STRINGS,
+						   GFP_KERNEL);
+	struct f_uac1_alt_opts	*alt_opts;
+	struct usb_string	*us;
+	int			strings_uac1_length;
+
+	struct usb_gadget_strings str_uac1 = {
+		.language = 0x0409,	/* en-us */
+		.strings = strings
+	};
+
+	struct usb_gadget_strings *uac1_strings[] = {
+		&str_uac1,
+		NULL,
+	};
+
+	if (!strings)
+		return ERR_PTR(-ENOMEM);
+
+	/* Add all the strings from all the alt mode options */
+	add_string(strings, audio_opts->function_name);
+	add_string(strings, audio_opts->c_alt_0_opts.name);
+	add_string(strings, audio_opts->p_alt_0_opts.name);
+	add_alt_strings(strings, &audio_opts->c_alt_1_opts, FUOUT_EN(audio_opts));
+	add_alt_strings(strings, &audio_opts->p_alt_1_opts, FUIN_EN(audio_opts));
+	list_for_each_entry(alt_opts, &audio_opts->c_alt_opts, list) {
+		add_alt_strings(strings, alt_opts, FUOUT_EN(audio_opts));
+	}
+	list_for_each_entry(alt_opts, &audio_opts->p_alt_opts, list) {
+		add_alt_strings(strings, alt_opts, FUIN_EN(audio_opts));
+	}
+
+	for (strings_uac1_length = 0; strings[strings_uac1_length].s; strings_uac1_length++)
+		;
+
+	/* Attach strings to the composite device and get string IDs assigned */
+	us = usb_gstrings_attach(cdev, uac1_strings, strings_uac1_length);
+
+	/* Strings are now copied to the composite device and we use the
+	 * copy in "us" going forward, that has all the string IDs.
+	 */
+	kfree(strings);
+
+	return us;
+}
+
+/*-------------------------------------------------------------------------*/
+
 static int set_ep_max_packet_size_bint(struct device *dev, const struct f_uac1_alt_opts *alt_opts,
 					struct usb_endpoint_descriptor *ep_desc,
 					enum usb_device_speed speed, bool is_playback)
@@ -1526,23 +1584,11 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
 	if (status)
 		return status;
 
-	strings_uac1[STR_AC_IF].s = audio_opts->function_name;
-
-	strings_uac1[STR_USB_OUT_IT].s = audio_opts->c_it_name;
-	strings_uac1[STR_USB_OUT_IT_CH_NAMES].s = audio_opts->c_it_ch_name;
-	strings_uac1[STR_IO_OUT_OT].s = audio_opts->c_ot_name;
-	strings_uac1[STR_FU_OUT].s = audio_opts->c_fu_vol_name;
-	strings_uac1[STR_AS_OUT_IF_ALT0].s = "Playback Inactive";
-	strings_uac1[STR_AS_OUT_IF_ALT1].s = "Playback Active";
-
-	strings_uac1[STR_IO_IN_IT].s = audio_opts->p_it_name;
-	strings_uac1[STR_IO_IN_IT_CH_NAMES].s = audio_opts->p_it_ch_name;
-	strings_uac1[STR_USB_IN_OT].s = audio_opts->p_ot_name;
-	strings_uac1[STR_FU_IN].s = audio_opts->p_fu_vol_name;
-	strings_uac1[STR_AS_IN_IF_ALT0].s = "Capture Inactive";
-	strings_uac1[STR_AS_IN_IF_ALT1].s = "Capture Active";
+	/* Past this point, all settings that apply to an alt mode should
+	 * be used from their alt mode opts.
+	 */
 
-	us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1));
+	us = attach_strings(cdev, audio_opts);
 	if (IS_ERR(us))
 		return PTR_ERR(us);
 
@@ -1565,31 +1611,37 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
 		}
 	}
 
-	ac_interface_desc.iInterface = us[STR_AC_IF].id;
-	usb_out_it_desc.iTerminal = us[STR_USB_OUT_IT].id;
-	usb_out_it_desc.iChannelNames = us[STR_USB_OUT_IT_CH_NAMES].id;
-	io_out_ot_desc.iTerminal = us[STR_IO_OUT_OT].id;
-	as_out_interface_alt_0_desc.iInterface = us[STR_AS_OUT_IF_ALT0].id;
-	as_out_interface_alt_1_desc.iInterface = us[STR_AS_OUT_IF_ALT1].id;
-	io_in_it_desc.iTerminal = us[STR_IO_IN_IT].id;
-	io_in_it_desc.iChannelNames = us[STR_IO_IN_IT_CH_NAMES].id;
-	usb_in_ot_desc.iTerminal = us[STR_USB_IN_OT].id;
-	as_in_interface_alt_0_desc.iInterface = us[STR_AS_IN_IF_ALT0].id;
-	as_in_interface_alt_1_desc.iInterface = us[STR_AS_IN_IF_ALT1].id;
+	ac_interface_desc.iInterface = add_string(us, audio_opts->function_name);
+	usb_out_it_desc.iTerminal = add_string(us, audio_opts->c_alt_1_opts.it_name);
+	usb_out_it_desc.iChannelNames = add_string(us, audio_opts->c_alt_1_opts.it_ch_name);
+	io_out_ot_desc.iTerminal = add_string(us, audio_opts->c_alt_1_opts.ot_name);
+	as_out_interface_alt_0_desc.iInterface = add_string(us, audio_opts->c_alt_0_opts.name);
+	as_out_interface_alt_1_desc.iInterface = add_string(us, audio_opts->c_alt_1_opts.name);
+	io_in_it_desc.iTerminal = add_string(us, audio_opts->p_alt_1_opts.it_name);
+	io_in_it_desc.iChannelNames = add_string(us, audio_opts->p_alt_1_opts.it_ch_name);
+	usb_in_ot_desc.iTerminal = add_string(us, audio_opts->p_alt_1_opts.ot_name);
+	as_in_interface_alt_0_desc.iInterface = add_string(us, audio_opts->p_alt_0_opts.name);
+	as_in_interface_alt_1_desc.iInterface = add_string(us, audio_opts->p_alt_1_opts.name);
 
 	if (FUOUT_EN(audio_opts)) {
 		u8 *i_feature;
 
 		i_feature = (u8 *)out_feature_unit_desc +
 					out_feature_unit_desc->bLength - 1;
-		*i_feature = us[STR_FU_OUT].id;
+		*i_feature = add_string(us, audio_opts->c_alt_1_opts.fu_vol_name);
 	}
 	if (FUIN_EN(audio_opts)) {
 		u8 *i_feature;
 
 		i_feature = (u8 *)in_feature_unit_desc +
 					in_feature_unit_desc->bLength - 1;
-		*i_feature = us[STR_FU_IN].id;
+		*i_feature = add_string(us, audio_opts->p_alt_1_opts.fu_vol_name);
+	}
+
+	us = attach_strings(cdev, audio_opts);
+	if (IS_ERR(us)) {
+		status = PTR_ERR(us);
+		goto fail;
 	}
 
 	/* Set channel numbers */
