linux/drivers/usb/gadget/audio.c
<<
>>
Prefs
   1/*
   2 * audio.c -- Audio gadget driver
   3 *
   4 * Copyright (C) 2008 Bryan Wu <cooloney@kernel.org>
   5 * Copyright (C) 2008 Analog Devices, Inc
   6 *
   7 * Enter bugs at http://blackfin.uclinux.org/
   8 *
   9 * Licensed under the GPL-2 or later.
  10 */
  11
  12/* #define VERBOSE_DEBUG */
  13
  14#include <linux/kernel.h>
  15#include <linux/utsname.h>
  16
  17#include "u_audio.h"
  18
  19#define DRIVER_DESC             "Linux USB Audio Gadget"
  20#define DRIVER_VERSION          "Dec 18, 2008"
  21
  22/*-------------------------------------------------------------------------*/
  23
  24/*
  25 * Kbuild is not very cooperative with respect to linking separately
  26 * compiled library objects into one module.  So for now we won't use
  27 * separate compilation ... ensuring init/exit sections work to shrink
  28 * the runtime footprint, and giving us at least some parts of what
  29 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
  30 */
  31#include "composite.c"
  32#include "usbstring.c"
  33#include "config.c"
  34#include "epautoconf.c"
  35
  36#include "u_audio.c"
  37#include "f_audio.c"
  38
  39/*-------------------------------------------------------------------------*/
  40
  41/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
  42 * Instead:  allocate your own, using normal USB-IF procedures.
  43 */
  44
  45/* Thanks to Linux Foundation for donating this product ID. */
  46#define AUDIO_VENDOR_NUM                0x1d6b  /* Linux Foundation */
  47#define AUDIO_PRODUCT_NUM               0x0101  /* Linux-USB Audio Gadget */
  48
  49/*-------------------------------------------------------------------------*/
  50
  51static struct usb_device_descriptor device_desc = {
  52        .bLength =              sizeof device_desc,
  53        .bDescriptorType =      USB_DT_DEVICE,
  54
  55        .bcdUSB =               __constant_cpu_to_le16(0x200),
  56
  57        .bDeviceClass =         USB_CLASS_PER_INTERFACE,
  58        .bDeviceSubClass =      0,
  59        .bDeviceProtocol =      0,
  60        /* .bMaxPacketSize0 = f(hardware) */
  61
  62        /* Vendor and product id defaults change according to what configs
  63         * we support.  (As does bNumConfigurations.)  These values can
  64         * also be overridden by module parameters.
  65         */
  66        .idVendor =             __constant_cpu_to_le16(AUDIO_VENDOR_NUM),
  67        .idProduct =            __constant_cpu_to_le16(AUDIO_PRODUCT_NUM),
  68        /* .bcdDevice = f(hardware) */
  69        /* .iManufacturer = DYNAMIC */
  70        /* .iProduct = DYNAMIC */
  71        /* NO SERIAL NUMBER */
  72        .bNumConfigurations =   1,
  73};
  74
  75static struct usb_otg_descriptor otg_descriptor = {
  76        .bLength =              sizeof otg_descriptor,
  77        .bDescriptorType =      USB_DT_OTG,
  78
  79        /* REVISIT SRP-only hardware is possible, although
  80         * it would not be called "OTG" ...
  81         */
  82        .bmAttributes =         USB_OTG_SRP | USB_OTG_HNP,
  83};
  84
  85static const struct usb_descriptor_header *otg_desc[] = {
  86        (struct usb_descriptor_header *) &otg_descriptor,
  87        NULL,
  88};
  89
  90/*-------------------------------------------------------------------------*/
  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)
 207{
 208        /* FIXME alloc iConfiguration string, set it in c->strings */
 209
 210        if (gadget_is_otg(c->cdev->gadget)) {
 211                c->descriptors = otg_desc;
 212                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 213        }
 214
 215        audio_bind_config(c);
 216
 217        return 0;
 218}
 219
 220static struct usb_configuration audio_config_driver = {
 221        .label                  = DRIVER_DESC,
 222        .bind                   = audio_do_config,
 223        .setup                  = audio_setup,
 224        .bConfigurationValue    = 1,
 225        /* .iConfiguration = DYNAMIC */
 226        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
 227};
 228
 229/*-------------------------------------------------------------------------*/
 230
 231static int __init audio_bind(struct usb_composite_dev *cdev)
 232{
 233        int                     gcnum;
 234        int                     status;
 235
 236        gcnum = usb_gadget_controller_number(cdev->gadget);
 237        if (gcnum >= 0)
 238                device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
 239        else {
 240                ERROR(cdev, "controller '%s' not recognized; trying %s\n",
 241                        cdev->gadget->name,
 242                        audio_config_driver.label);
 243                device_desc.bcdDevice =
 244                        __constant_cpu_to_le16(0x0300 | 0x0099);
 245        }
 246
 247        /* device descriptor strings: manufacturer, product */
 248        snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
 249                init_utsname()->sysname, init_utsname()->release,
 250                cdev->gadget->name);
 251        status = usb_string_id(cdev);
 252        if (status < 0)
 253                goto fail;
 254        strings_dev[STRING_MANUFACTURER_IDX].id = status;
 255        device_desc.iManufacturer = status;
 256
 257        status = usb_string_id(cdev);
 258        if (status < 0)
 259                goto fail;
 260        strings_dev[STRING_PRODUCT_IDX].id = status;
 261        device_desc.iProduct = status;
 262
 263        status = usb_add_config(cdev, &audio_config_driver);
 264        if (status < 0)
 265                goto fail;
 266
 267        INFO(cdev, "%s, version: %s\n", DRIVER_DESC, DRIVER_VERSION);
 268        return 0;
 269
 270fail:
 271        return status;
 272}
 273
 274static int __exit audio_unbind(struct usb_composite_dev *cdev)
 275{
 276        return 0;
 277}
 278
 279static struct usb_composite_driver audio_driver = {
 280        .name           = "g_audio",
 281        .dev            = &device_desc,
 282        .strings        = audio_strings,
 283        .bind           = audio_bind,
 284        .unbind         = __exit_p(audio_unbind),
 285};
 286
 287static int __init init(void)
 288{
 289        return usb_composite_register(&audio_driver);
 290}
 291module_init(init);
 292
 293static void __exit cleanup(void)
 294{
 295        usb_composite_unregister(&audio_driver);
 296}
 297module_exit(cleanup);
 298
 299MODULE_DESCRIPTION(DRIVER_DESC);
 300MODULE_AUTHOR("Bryan Wu <cooloney@kernel.org>");
 301MODULE_LICENSE("GPL");
 302
 303