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
  92static int __init audio_do_config(struct usb_configuration *c)
  93{
  94        /* FIXME alloc iConfiguration string, set it in c->strings */
  95
  96        if (gadget_is_otg(c->cdev->gadget)) {
  97                c->descriptors = otg_desc;
  98                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
  99        }
 100
 101        audio_bind_config(c);
 102
 103        return 0;
 104}
 105
 106static struct usb_configuration audio_config_driver = {
 107        .label                  = DRIVER_DESC,
 108        .bind                   = audio_do_config,
 109        .bConfigurationValue    = 1,
 110        /* .iConfiguration = DYNAMIC */
 111        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
 112};
 113
 114/*-------------------------------------------------------------------------*/
 115
 116static int __init audio_bind(struct usb_composite_dev *cdev)
 117{
 118        int                     gcnum;
 119        int                     status;
 120
 121        gcnum = usb_gadget_controller_number(cdev->gadget);
 122        if (gcnum >= 0)
 123                device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
 124        else {
 125                ERROR(cdev, "controller '%s' not recognized; trying %s\n",
 126                        cdev->gadget->name,
 127                        audio_config_driver.label);
 128                device_desc.bcdDevice =
 129                        __constant_cpu_to_le16(0x0300 | 0x0099);
 130        }
 131
 132        /* device descriptor strings: manufacturer, product */
 133        snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
 134                init_utsname()->sysname, init_utsname()->release,
 135                cdev->gadget->name);
 136        status = usb_string_id(cdev);
 137        if (status < 0)
 138                goto fail;
 139        strings_dev[STRING_MANUFACTURER_IDX].id = status;
 140        device_desc.iManufacturer = status;
 141
 142        status = usb_string_id(cdev);
 143        if (status < 0)
 144                goto fail;
 145        strings_dev[STRING_PRODUCT_IDX].id = status;
 146        device_desc.iProduct = status;
 147
 148        status = usb_add_config(cdev, &audio_config_driver);
 149        if (status < 0)
 150                goto fail;
 151
 152        INFO(cdev, "%s, version: %s\n", DRIVER_DESC, DRIVER_VERSION);
 153        return 0;
 154
 155fail:
 156        return status;
 157}
 158
 159static int __exit audio_unbind(struct usb_composite_dev *cdev)
 160{
 161        gaudio_cleanup();
 162        return 0;
 163}
 164
 165static struct usb_composite_driver audio_driver = {
 166        .name           = "g_audio",
 167        .dev            = &device_desc,
 168        .strings        = audio_strings,
 169        .bind           = audio_bind,
 170        .unbind         = __exit_p(audio_unbind),
 171};
 172
 173static int __init init(void)
 174{
 175        return usb_composite_register(&audio_driver);
 176}
 177module_init(init);
 178
 179static void __exit cleanup(void)
 180{
 181        usb_composite_unregister(&audio_driver);
 182}
 183module_exit(cleanup);
 184
 185MODULE_DESCRIPTION(DRIVER_DESC);
 186MODULE_AUTHOR("Bryan Wu <cooloney@kernel.org>");
 187MODULE_LICENSE("GPL");
 188
 189
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.