summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/function/f_audio_source.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/usb/gadget/function/f_audio_source.c b/drivers/usb/gadget/function/f_audio_source.c
index ec73b67096c5..7d8bfe62b148 100644
--- a/drivers/usb/gadget/function/f_audio_source.c
+++ b/drivers/usb/gadget/function/f_audio_source.c
@@ -591,14 +591,38 @@ static int audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
pr_debug("audio_set_alt intf %d, alt %d\n", intf, alt);
+ if (!alt) {
+ usb_ep_disable(audio->in_ep);
+ return 0;
+ }
+
ret = config_ep_by_speed(cdev->gadget, f, audio->in_ep);
- if (ret)
+ if (ret) {
+ audio->in_ep->desc = NULL;
+ pr_err("config_ep fail for audio ep ret %d\n", ret);
+ return ret;
+ }
+ ret = usb_ep_enable(audio->in_ep);
+ if (ret) {
+ audio->in_ep->desc = NULL;
+ pr_err("failed to enable audio ret %d\n", ret);
return ret;
+ }
- usb_ep_enable(audio->in_ep);
return 0;
}
+/*
+ * Because the data interface supports multiple altsettings,
+ * this audio_source function *MUST* implement a get_alt() method.
+ */
+static int audio_get_alt(struct usb_function *f, unsigned int intf)
+{
+ struct audio_dev *audio = func_to_audio(f);
+
+ return audio->in_ep->enabled ? 1 : 0;
+}
+
static void audio_disable(struct usb_function *f)
{
struct audio_dev *audio = func_to_audio(f);
@@ -862,6 +886,7 @@ static struct audio_dev _audio_dev = {
.bind = audio_bind,
.unbind = audio_unbind,
.set_alt = audio_set_alt,
+ .get_alt = audio_get_alt,
.setup = audio_setup,
.disable = audio_disable,
.free_func = audio_free_func,