usb: gadget: function: f_uac1: implement get_alt()
PATCH 1/1 usb: gadget: function: f_uac1: implement get_alt()
After commit 7e4da3fcf7c9 ("usb: gadget: composite:
Test get_alt() presence instead of set_alt()") f_uac1 function became broken because it doesn't have get_alt() callback implementation and composite framework never set altsetting 1 for audiostreaming interface. On host site it looks like:
[424339.017711] 21:1:1: usb_set_interface failed (-32)
Since host can't set altsetting 1, it can't start playing audio.
In order to fix it implemented get_alt along with minor improvements (error conditions checking) similar to what existing f_uac2 has.
Cc Krzysztof Opasiak <[email protected]>
Signed-off-by Ruslan Bilovol <[email protected]>
--- drivers/usb/gadget/function/f_uac1.c | 40 +++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-)
drivers/usb/gadget/function/f_uac1.c +39 -1
@@ -277,6 +277,9 @@ static void f_audio_buffer_free(struct f_audio_buf *audio_buf)struct f_audio {struct gaudio card; +u8 ac_intf, ac_alt; +u8 as_intf, as_alt; +/* endpoints handle full and/or high speeds */ struct usb_ep *out_ep;
@@ -586,7 +589,20 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) req_count = opts->req_count; audio_buf_size = opts->audio_buf_size; -if (intf ==1 ) { +/* No i/f has more than 2 alt settings */ +if (alt >1 ) { +ERROR (cdev,"%s:%d Error!\n" , __func__, __LINE__); +return -EINVAL ; + } + +if (intf == audio->ac_intf) { +/* Control I/f has only 1 AltSetting - 0 */ +if (alt) { +ERROR (cdev,"%s:%d Error!\n" , __func__, __LINE__); +return -EINVAL ; + } +return 0 ; + }else if (intf == audio->as_intf) {if (alt ==1 ) { err =config_ep_by_speed (cdev->gadget, f, out_ep);if (err)
@@ -631,11 +647,28 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt)schedule_work (&audio->playback_work); } } + audio->as_alt = alt; }return err; } +static int f_audio_get_alt (struct usb_function *f,unsigned intf) +{ +struct f_audio *audio =func_to_audio (f); +struct usb_composite_dev *cdev = f->config->cdev; + +if (intf == audio->ac_intf) +return audio->ac_alt; +else if (intf == audio->as_intf) +return audio->as_alt; +else +ERROR (cdev,"%s:%d Invalid Interface %d!\n" , + __func__, __LINE__, intf); + +return -EINVAL ; +} +static void f_audio_disable (struct usb_function *f) {return ;
@@ -702,12 +735,16 @@ static void f_audio_build_desc(struct f_audio *audio)if (status <0 ) goto fail; ac_interface_desc.bInterfaceNumber = status; + audio->ac_intf = status; + audio->ac_alt =0 ; status =usb_interface_id (c, f);if (status <0 ) goto fail; as_interface_alt_0_desc.bInterfaceNumber = status; as_interface_alt_1_desc.bInterfaceNumber = status; + audio->as_intf = status; + audio->as_alt =0 ; status = -ENODEV ;
@@ -966,6 +1003,7 @@ static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) audio->card.func.bind = f_audio_bind; audio->card.func.unbind = f_audio_unbind; audio->card.func.set_alt = f_audio_set_alt; + audio->card.func.get_alt = f_audio_get_alt; audio->card.func.setup = f_audio_setup; audio->card.func.disable = f_audio_disable; audio->card.func.free_func = f_audio_free;
Signature · 1 line
1.9.1