USB audio gadget: handle endpoint control requests at the function level
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Tue, 20 Oct 2009 22:03:39 +0000 (00:03 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 11 Dec 2009 19:55:15 +0000 (11:55 -0800)
Now that control requests targeted at an endpoint can be handled at the
function level, move the UAC-specific control request handling code from
the audio gadget driver to the audio function driver.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/gadget/audio.c
drivers/usb/gadget/f_audio.c

index a3a0f4a27ef0d9edea1720aba630050ab9abd7ab..58f2203238471ae06f0504ae26b71b53b27bd71f 100644 (file)
@@ -89,120 +89,6 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 /*-------------------------------------------------------------------------*/
 
-/**
- * Handle USB audio endpoint set/get command in setup class request
- */
-
-static int audio_set_endpoint_req(struct usb_configuration *c,
-               const struct usb_ctrlrequest *ctrl)
-{
-       struct usb_composite_dev *cdev = c->cdev;
-       int                     value = -EOPNOTSUPP;
-       u16                     ep = le16_to_cpu(ctrl->wIndex);
-       u16                     len = le16_to_cpu(ctrl->wLength);
-       u16                     w_value = le16_to_cpu(ctrl->wValue);
-
-       DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
-                       ctrl->bRequest, w_value, len, ep);
-
-       switch (ctrl->bRequest) {
-       case UAC_SET_CUR:
-               value = 0;
-               break;
-
-       case UAC_SET_MIN:
-               break;
-
-       case UAC_SET_MAX:
-               break;
-
-       case UAC_SET_RES:
-               break;
-
-       case UAC_SET_MEM:
-               break;
-
-       default:
-               break;
-       }
-
-       return value;
-}
-
-static int audio_get_endpoint_req(struct usb_configuration *c,
-               const struct usb_ctrlrequest *ctrl)
-{
-       struct usb_composite_dev *cdev = c->cdev;
-       int value = -EOPNOTSUPP;
-       u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF);
-       u16 len = le16_to_cpu(ctrl->wLength);
-       u16 w_value = le16_to_cpu(ctrl->wValue);
-
-       DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
-                       ctrl->bRequest, w_value, len, ep);
-
-       switch (ctrl->bRequest) {
-       case UAC_GET_CUR:
-       case UAC_GET_MIN:
-       case UAC_GET_MAX:
-       case UAC_GET_RES:
-               value = 3;
-               break;
-       case UAC_GET_MEM:
-               break;
-       default:
-               break;
-       }
-
-       return value;
-}
-
-static int
-audio_setup(struct usb_configuration *c, const struct usb_ctrlrequest *ctrl)
-{
-       struct usb_composite_dev *cdev = c->cdev;
-       struct usb_request *req = cdev->req;
-       int value = -EOPNOTSUPP;
-       u16 w_index = le16_to_cpu(ctrl->wIndex);
-       u16 w_value = le16_to_cpu(ctrl->wValue);
-       u16 w_length = le16_to_cpu(ctrl->wLength);
-
-       /* composite driver infrastructure handles everything except
-        * Audio class messages; interface activation uses set_alt().
-        */
-       switch (ctrl->bRequestType) {
-       case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
-               value = audio_set_endpoint_req(c, ctrl);
-               break;
-
-       case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
-               value = audio_get_endpoint_req(c, ctrl);
-               break;
-
-       default:
-               ERROR(cdev, "Invalid control req%02x.%02x v%04x i%04x l%d\n",
-                       ctrl->bRequestType, ctrl->bRequest,
-                       w_value, w_index, w_length);
-       }
-
-       /* respond with data transfer or status phase? */
-       if (value >= 0) {
-               DBG(cdev, "Audio req%02x.%02x v%04x i%04x l%d\n",
-                       ctrl->bRequestType, ctrl->bRequest,
-                       w_value, w_index, w_length);
-               req->zero = 0;
-               req->length = value;
-               value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
-               if (value < 0)
-                       ERROR(cdev, "Audio response on err %d\n", value);
-       }
-
-       /* device either stalls (value < 0) or reports success */
-       return value;
-}
-
-/*-------------------------------------------------------------------------*/
-
 static int __init audio_do_config(struct usb_configuration *c)
 {
        /* FIXME alloc iConfiguration string, set it in c->strings */
@@ -220,7 +106,6 @@ static int __init audio_do_config(struct usb_configuration *c)
 static struct usb_configuration audio_config_driver = {
        .label                  = DRIVER_DESC,
        .bind                   = audio_do_config,
-       .setup                  = audio_setup,
        .bConfigurationValue    = 1,
        /* .iConfiguration = DYNAMIC */
        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
index 98e9bb977291f3b61139c945df3cd5d9c4fda2a9..c43c89ffa2c89b07fd690afeca58cb34651b0358 100644 (file)
@@ -445,6 +445,70 @@ static int audio_get_intf_req(struct usb_function *f,
        return len;
 }
 
+static int audio_set_endpoint_req(struct usb_function *f,
+               const struct usb_ctrlrequest *ctrl)
+{
+       struct usb_composite_dev *cdev = f->config->cdev;
+       int                     value = -EOPNOTSUPP;
+       u16                     ep = le16_to_cpu(ctrl->wIndex);
+       u16                     len = le16_to_cpu(ctrl->wLength);
+       u16                     w_value = le16_to_cpu(ctrl->wValue);
+
+       DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
+                       ctrl->bRequest, w_value, len, ep);
+
+       switch (ctrl->bRequest) {
+       case UAC_SET_CUR:
+               value = 0;
+               break;
+
+       case UAC_SET_MIN:
+               break;
+
+       case UAC_SET_MAX:
+               break;
+
+       case UAC_SET_RES:
+               break;
+
+       case UAC_SET_MEM:
+               break;
+
+       default:
+               break;
+       }
+
+       return value;
+}
+
+static int audio_get_endpoint_req(struct usb_function *f,
+               const struct usb_ctrlrequest *ctrl)
+{
+       struct usb_composite_dev *cdev = f->config->cdev;
+       int value = -EOPNOTSUPP;
+       u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF);
+       u16 len = le16_to_cpu(ctrl->wLength);
+       u16 w_value = le16_to_cpu(ctrl->wValue);
+
+       DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
+                       ctrl->bRequest, w_value, len, ep);
+
+       switch (ctrl->bRequest) {
+       case UAC_GET_CUR:
+       case UAC_GET_MIN:
+       case UAC_GET_MAX:
+       case UAC_GET_RES:
+               value = 3;
+               break;
+       case UAC_GET_MEM:
+               break;
+       default:
+               break;
+       }
+
+       return value;
+}
+
 static int
 f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
 {
@@ -455,8 +519,8 @@ f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
        u16                     w_value = le16_to_cpu(ctrl->wValue);
        u16                     w_length = le16_to_cpu(ctrl->wLength);
 
-       /* composite driver infrastructure handles everything except
-        * Audio class messages; interface activation uses set_alt().
+       /* composite driver infrastructure handles everything; interface
+        * activation uses set_alt().
         */
        switch (ctrl->bRequestType) {
        case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE:
@@ -467,6 +531,14 @@ f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
                value = audio_get_intf_req(f, ctrl);
                break;
 
+       case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
+               value = audio_set_endpoint_req(f, ctrl);
+               break;
+
+       case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
+               value = audio_get_endpoint_req(f, ctrl);
+               break;
+
        default:
                ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
                        ctrl->bRequestType, ctrl->bRequest,