diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2009-10-20 18:03:39 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 14:55:15 -0500 |
commit | 0ad72524ef623f32f6899e656951bb5646caead1 (patch) | |
tree | 369642d6f8e64a063f5fcdb8ec5aa93b77fb66e7 /drivers/usb/gadget/f_audio.c | |
parent | 5242658d1b97771d658991cf29be32bcf81d5859 (diff) |
USB audio gadget: handle endpoint control requests at the function level
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>
Diffstat (limited to 'drivers/usb/gadget/f_audio.c')
-rw-r--r-- | drivers/usb/gadget/f_audio.c | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index 98e9bb977291..c43c89ffa2c8 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c | |||
@@ -445,6 +445,70 @@ static int audio_get_intf_req(struct usb_function *f, | |||
445 | return len; | 445 | return len; |
446 | } | 446 | } |
447 | 447 | ||
448 | static int audio_set_endpoint_req(struct usb_function *f, | ||
449 | const struct usb_ctrlrequest *ctrl) | ||
450 | { | ||
451 | struct usb_composite_dev *cdev = f->config->cdev; | ||
452 | int value = -EOPNOTSUPP; | ||
453 | u16 ep = le16_to_cpu(ctrl->wIndex); | ||
454 | u16 len = le16_to_cpu(ctrl->wLength); | ||
455 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
456 | |||
457 | DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", | ||
458 | ctrl->bRequest, w_value, len, ep); | ||
459 | |||
460 | switch (ctrl->bRequest) { | ||
461 | case UAC_SET_CUR: | ||
462 | value = 0; | ||
463 | break; | ||
464 | |||
465 | case UAC_SET_MIN: | ||
466 | break; | ||
467 | |||
468 | case UAC_SET_MAX: | ||
469 | break; | ||
470 | |||
471 | case UAC_SET_RES: | ||
472 | break; | ||
473 | |||
474 | case UAC_SET_MEM: | ||
475 | break; | ||
476 | |||
477 | default: | ||
478 | break; | ||
479 | } | ||
480 | |||
481 | return value; | ||
482 | } | ||
483 | |||
484 | static int audio_get_endpoint_req(struct usb_function *f, | ||
485 | const struct usb_ctrlrequest *ctrl) | ||
486 | { | ||
487 | struct usb_composite_dev *cdev = f->config->cdev; | ||
488 | int value = -EOPNOTSUPP; | ||
489 | u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); | ||
490 | u16 len = le16_to_cpu(ctrl->wLength); | ||
491 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
492 | |||
493 | DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", | ||
494 | ctrl->bRequest, w_value, len, ep); | ||
495 | |||
496 | switch (ctrl->bRequest) { | ||
497 | case UAC_GET_CUR: | ||
498 | case UAC_GET_MIN: | ||
499 | case UAC_GET_MAX: | ||
500 | case UAC_GET_RES: | ||
501 | value = 3; | ||
502 | break; | ||
503 | case UAC_GET_MEM: | ||
504 | break; | ||
505 | default: | ||
506 | break; | ||
507 | } | ||
508 | |||
509 | return value; | ||
510 | } | ||
511 | |||
448 | static int | 512 | static int |
449 | f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | 513 | f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) |
450 | { | 514 | { |
@@ -455,8 +519,8 @@ f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | |||
455 | u16 w_value = le16_to_cpu(ctrl->wValue); | 519 | u16 w_value = le16_to_cpu(ctrl->wValue); |
456 | u16 w_length = le16_to_cpu(ctrl->wLength); | 520 | u16 w_length = le16_to_cpu(ctrl->wLength); |
457 | 521 | ||
458 | /* composite driver infrastructure handles everything except | 522 | /* composite driver infrastructure handles everything; interface |
459 | * Audio class messages; interface activation uses set_alt(). | 523 | * activation uses set_alt(). |
460 | */ | 524 | */ |
461 | switch (ctrl->bRequestType) { | 525 | switch (ctrl->bRequestType) { |
462 | case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE: | 526 | 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) | |||
467 | value = audio_get_intf_req(f, ctrl); | 531 | value = audio_get_intf_req(f, ctrl); |
468 | break; | 532 | break; |
469 | 533 | ||
534 | case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: | ||
535 | value = audio_set_endpoint_req(f, ctrl); | ||
536 | break; | ||
537 | |||
538 | case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: | ||
539 | value = audio_get_endpoint_req(f, ctrl); | ||
540 | break; | ||
541 | |||
470 | default: | 542 | default: |
471 | ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n", | 543 | ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n", |
472 | ctrl->bRequestType, ctrl->bRequest, | 544 | ctrl->bRequestType, ctrl->bRequest, |