aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2009-10-20 18:03:39 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:55:15 -0500
commit0ad72524ef623f32f6899e656951bb5646caead1 (patch)
tree369642d6f8e64a063f5fcdb8ec5aa93b77fb66e7 /drivers/usb
parent5242658d1b97771d658991cf29be32bcf81d5859 (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')
-rw-r--r--drivers/usb/gadget/audio.c115
-rw-r--r--drivers/usb/gadget/f_audio.c76
2 files changed, 74 insertions, 117 deletions
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
index a3a0f4a27ef0..58f220323847 100644
--- a/drivers/usb/gadget/audio.c
+++ b/drivers/usb/gadget/audio.c
@@ -89,120 +89,6 @@ static const struct usb_descriptor_header *otg_desc[] = {
89 89
90/*-------------------------------------------------------------------------*/ 90/*-------------------------------------------------------------------------*/
91 91
92/**
93 * Handle USB audio endpoint set/get command in setup class request
94 */
95
96static int audio_set_endpoint_req(struct usb_configuration *c,
97 const struct usb_ctrlrequest *ctrl)
98{
99 struct usb_composite_dev *cdev = c->cdev;
100 int value = -EOPNOTSUPP;
101 u16 ep = le16_to_cpu(ctrl->wIndex);
102 u16 len = le16_to_cpu(ctrl->wLength);
103 u16 w_value = le16_to_cpu(ctrl->wValue);
104
105 DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
106 ctrl->bRequest, w_value, len, ep);
107
108 switch (ctrl->bRequest) {
109 case UAC_SET_CUR:
110 value = 0;
111 break;
112
113 case UAC_SET_MIN:
114 break;
115
116 case UAC_SET_MAX:
117 break;
118
119 case UAC_SET_RES:
120 break;
121
122 case UAC_SET_MEM:
123 break;
124
125 default:
126 break;
127 }
128
129 return value;
130}
131
132static int audio_get_endpoint_req(struct usb_configuration *c,
133 const struct usb_ctrlrequest *ctrl)
134{
135 struct usb_composite_dev *cdev = c->cdev;
136 int value = -EOPNOTSUPP;
137 u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF);
138 u16 len = le16_to_cpu(ctrl->wLength);
139 u16 w_value = le16_to_cpu(ctrl->wValue);
140
141 DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n",
142 ctrl->bRequest, w_value, len, ep);
143
144 switch (ctrl->bRequest) {
145 case UAC_GET_CUR:
146 case UAC_GET_MIN:
147 case UAC_GET_MAX:
148 case UAC_GET_RES:
149 value = 3;
150 break;
151 case UAC_GET_MEM:
152 break;
153 default:
154 break;
155 }
156
157 return value;
158}
159
160static int
161audio_setup(struct usb_configuration *c, const struct usb_ctrlrequest *ctrl)
162{
163 struct usb_composite_dev *cdev = c->cdev;
164 struct usb_request *req = cdev->req;
165 int value = -EOPNOTSUPP;
166 u16 w_index = le16_to_cpu(ctrl->wIndex);
167 u16 w_value = le16_to_cpu(ctrl->wValue);
168 u16 w_length = le16_to_cpu(ctrl->wLength);
169
170 /* composite driver infrastructure handles everything except
171 * Audio class messages; interface activation uses set_alt().
172 */
173 switch (ctrl->bRequestType) {
174 case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
175 value = audio_set_endpoint_req(c, ctrl);
176 break;
177
178 case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT:
179 value = audio_get_endpoint_req(c, ctrl);
180 break;
181
182 default:
183 ERROR(cdev, "Invalid control req%02x.%02x v%04x i%04x l%d\n",
184 ctrl->bRequestType, ctrl->bRequest,
185 w_value, w_index, w_length);
186 }
187
188 /* respond with data transfer or status phase? */
189 if (value >= 0) {
190 DBG(cdev, "Audio req%02x.%02x v%04x i%04x l%d\n",
191 ctrl->bRequestType, ctrl->bRequest,
192 w_value, w_index, w_length);
193 req->zero = 0;
194 req->length = value;
195 value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
196 if (value < 0)
197 ERROR(cdev, "Audio response on err %d\n", value);
198 }
199
200 /* device either stalls (value < 0) or reports success */
201 return value;
202}
203
204/*-------------------------------------------------------------------------*/
205
206static int __init audio_do_config(struct usb_configuration *c) 92static int __init audio_do_config(struct usb_configuration *c)
207{ 93{
208 /* FIXME alloc iConfiguration string, set it in c->strings */ 94 /* FIXME alloc iConfiguration string, set it in c->strings */
@@ -220,7 +106,6 @@ static int __init audio_do_config(struct usb_configuration *c)
220static struct usb_configuration audio_config_driver = { 106static struct usb_configuration audio_config_driver = {
221 .label = DRIVER_DESC, 107 .label = DRIVER_DESC,
222 .bind = audio_do_config, 108 .bind = audio_do_config,
223 .setup = audio_setup,
224 .bConfigurationValue = 1, 109 .bConfigurationValue = 1,
225 /* .iConfiguration = DYNAMIC */ 110 /* .iConfiguration = DYNAMIC */
226 .bmAttributes = USB_CONFIG_ATT_SELFPOWER, 111 .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
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
448static 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
484static 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
448static int 512static int
449f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) 513f_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,