linux/drivers/usb/gadget/function/u_audio.c
<<
>>
Prefs
   1/*
   2 * u_audio.c -- interface to USB gadget "ALSA sound card" utilities
   3 *
   4 * Copyright (C) 2016
   5 * Author: Ruslan Bilovol <ruslan.bilovol@gmail.com>
   6 *
   7 * Sound card implementation was cut-and-pasted with changes
   8 * from f_uac2.c and has:
   9 *    Copyright (C) 2011
  10 *    Yadwinder Singh (yadi.brar01@gmail.com)
  11 *    Jaswinder Singh (jaswinder.singh@linaro.org)
  12 *
  13 * This program is free software; you can redistribute it and/or modify
  14 * it under the terms of the GNU General Public License as published by
  15 * the Free Software Foundation; either version 2 of the License, or
  16 * (at your option) any later version.
  17 *
  18 * This program is distributed in the hope that it will be useful,
  19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21 * GNU General Public License for more details.
  22 */
  23
  24#include <linux/module.h>
  25#include <sound/core.h>
  26#include <sound/pcm.h>
  27#include <sound/pcm_params.h>
  28
  29#include "u_audio.h"
  30
  31#define BUFF_SIZE_MAX   (PAGE_SIZE * 16)
  32#define PRD_SIZE_MAX    PAGE_SIZE
  33#define MIN_PERIODS     4
  34
  35struct uac_req {
  36        struct uac_rtd_params *pp; /* parent param */
  37        struct usb_request *req;
  38};
  39
  40/* Runtime data params for one stream */
  41struct uac_rtd_params {
  42        struct snd_uac_chip *uac; /* parent chip */
  43        bool ep_enabled; /* if the ep is enabled */
  44        /* Size of the ring buffer */
  45        size_t dma_bytes;
  46        unsigned char *dma_area;
  47
  48        struct snd_pcm_substream *ss;
  49
  50        /* Ring buffer */
  51        ssize_t hw_ptr;
  52
  53        void *rbuf;
  54
  55        size_t period_size;
  56
  57        unsigned max_psize;     /* MaxPacketSize of endpoint */
  58        struct uac_req *ureq;
  59
  60        spinlock_t lock;
  61};
  62
  63struct snd_uac_chip {
  64        struct g_audio *audio_dev;
  65
  66        struct uac_rtd_params p_prm;
  67        struct uac_rtd_params c_prm;
  68
  69        struct snd_card *card;
  70        struct snd_pcm *pcm;
  71
  72        /* timekeeping for the playback endpoint */
  73        unsigned int p_interval;
  74        unsigned int p_residue;
  75
  76        /* pre-calculated values for playback iso completion */
  77        unsigned int p_pktsize;
  78        unsigned int p_pktsize_residue;
  79        unsigned int p_framesize;
  80};
  81
  82static struct snd_pcm_hardware uac_pcm_hardware = {
  83        .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER
  84                 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
  85                 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
  86        .rates = SNDRV_PCM_RATE_CONTINUOUS,
  87        .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX,
  88        .buffer_bytes_max = BUFF_SIZE_MAX,
  89        .period_bytes_max = PRD_SIZE_MAX,
  90        .periods_min = MIN_PERIODS,
  91};
  92
  93static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
  94{
  95        unsigned pending;
  96        unsigned long flags;
  97        unsigned int hw_ptr;
  98        bool update_alsa = false;
  99        int status = req->status;
 100        struct uac_req *ur = req->context;
 101        struct snd_pcm_substream *substream;
 102        struct uac_rtd_params *prm = ur->pp;
 103        struct snd_uac_chip *uac = prm->uac;
 104
 105        /* i/f shutting down */
 106        if (!prm->ep_enabled || req->status == -ESHUTDOWN)
 107                return;
 108
 109        /*
 110         * We can't really do much about bad xfers.
 111         * Afterall, the ISOCH xfers could fail legitimately.
 112         */
 113        if (status)
 114                pr_debug("%s: iso_complete status(%d) %d/%d\n",
 115                        __func__, status, req->actual, req->length);
 116
 117        substream = prm->ss;
 118
 119        /* Do nothing if ALSA isn't active */
 120        if (!substream)
 121                goto exit;
 122
 123        spin_lock_irqsave(&prm->lock, flags);
 124
 125        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 126                /*
 127                 * For each IN packet, take the quotient of the current data
 128                 * rate and the endpoint's interval as the base packet size.
 129                 * If there is a residue from this division, add it to the
 130                 * residue accumulator.
 131                 */
 132                req->length = uac->p_pktsize;
 133                uac->p_residue += uac->p_pktsize_residue;
 134
 135                /*
 136                 * Whenever there are more bytes in the accumulator than we
 137                 * need to add one more sample frame, increase this packet's
 138                 * size and decrease the accumulator.
 139                 */
 140                if (uac->p_residue / uac->p_interval >= uac->p_framesize) {
 141                        req->length += uac->p_framesize;
 142                        uac->p_residue -= uac->p_framesize *
 143                                           uac->p_interval;
 144                }
 145
 146                req->actual = req->length;
 147        }
 148
 149        pending = prm->hw_ptr % prm->period_size;
 150        pending += req->actual;
 151        if (pending >= prm->period_size)
 152                update_alsa = true;
 153
 154        hw_ptr = prm->hw_ptr;
 155        prm->hw_ptr = (prm->hw_ptr + req->actual) % prm->dma_bytes;
 156
 157        spin_unlock_irqrestore(&prm->lock, flags);
 158
 159        /* Pack USB load in ALSA ring buffer */
 160        pending = prm->dma_bytes - hw_ptr;
 161
 162        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 163                if (unlikely(pending < req->actual)) {
 164                        memcpy(req->buf, prm->dma_area + hw_ptr, pending);
 165                        memcpy(req->buf + pending, prm->dma_area,
 166                               req->actual - pending);
 167                } else {
 168                        memcpy(req->buf, prm->dma_area + hw_ptr, req->actual);
 169                }
 170        } else {
 171                if (unlikely(pending < req->actual)) {
 172                        memcpy(prm->dma_area + hw_ptr, req->buf, pending);
 173                        memcpy(prm->dma_area, req->buf + pending,
 174                               req->actual - pending);
 175                } else {
 176                        memcpy(prm->dma_area + hw_ptr, req->buf, req->actual);
 177                }
 178        }
 179
 180exit:
 181        if (usb_ep_queue(ep, req, GFP_ATOMIC))
 182                dev_err(uac->card->dev, "%d Error!\n", __LINE__);
 183
 184        if (update_alsa)
 185                snd_pcm_period_elapsed(substream);
 186}
 187
 188static int uac_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 189{
 190        struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
 191        struct uac_rtd_params *prm;
 192        struct g_audio *audio_dev;
 193        struct uac_params *params;
 194        unsigned long flags;
 195        int err = 0;
 196
 197        audio_dev = uac->audio_dev;
 198        params = &audio_dev->params;
 199
 200        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 201                prm = &uac->p_prm;
 202        else
 203                prm = &uac->c_prm;
 204
 205        spin_lock_irqsave(&prm->lock, flags);
 206
 207        /* Reset */
 208        prm->hw_ptr = 0;
 209
 210        switch (cmd) {
 211        case SNDRV_PCM_TRIGGER_START:
 212        case SNDRV_PCM_TRIGGER_RESUME:
 213                prm->ss = substream;
 214                break;
 215        case SNDRV_PCM_TRIGGER_STOP:
 216        case SNDRV_PCM_TRIGGER_SUSPEND:
 217                prm->ss = NULL;
 218                break;
 219        default:
 220                err = -EINVAL;
 221        }
 222
 223        spin_unlock_irqrestore(&prm->lock, flags);
 224
 225        /* Clear buffer after Play stops */
 226        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !prm->ss)
 227                memset(prm->rbuf, 0, prm->max_psize * params->req_number);
 228
 229        return err;
 230}
 231
 232static snd_pcm_uframes_t uac_pcm_pointer(struct snd_pcm_substream *substream)
 233{
 234        struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
 235        struct uac_rtd_params *prm;
 236
 237        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 238                prm = &uac->p_prm;
 239        else
 240                prm = &uac->c_prm;
 241
 242        return bytes_to_frames(substream->runtime, prm->hw_ptr);
 243}
 244
 245static int uac_pcm_hw_params(struct snd_pcm_substream *substream,
 246                               struct snd_pcm_hw_params *hw_params)
 247{
 248        struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
 249        struct uac_rtd_params *prm;
 250        int err;
 251
 252        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 253                prm = &uac->p_prm;
 254        else
 255                prm = &uac->c_prm;
 256
 257        err = snd_pcm_lib_malloc_pages(substream,
 258                                        params_buffer_bytes(hw_params));
 259        if (err >= 0) {
 260                prm->dma_bytes = substream->runtime->dma_bytes;
 261                prm->dma_area = substream->runtime->dma_area;
 262                prm->period_size = params_period_bytes(hw_params);
 263        }
 264
 265        return err;
 266}
 267
 268static int uac_pcm_hw_free(struct snd_pcm_substream *substream)
 269{
 270        struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
 271        struct uac_rtd_params *prm;
 272
 273        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 274                prm = &uac->p_prm;
 275        else
 276                prm = &uac->c_prm;
 277
 278        prm->dma_area = NULL;
 279        prm->dma_bytes = 0;
 280        prm->period_size = 0;
 281
 282        return snd_pcm_lib_free_pages(substream);
 283}
 284
 285static int uac_pcm_open(struct snd_pcm_substream *substream)
 286{
 287        struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
 288        struct snd_pcm_runtime *runtime = substream->runtime;
 289        struct g_audio *audio_dev;
 290        struct uac_params *params;
 291        int p_ssize, c_ssize;
 292        int p_srate, c_srate;
 293        int p_chmask, c_chmask;
 294
 295        audio_dev = uac->audio_dev;
 296        params = &audio_dev->params;
 297        p_ssize = params->p_ssize;
 298        c_ssize = params->c_ssize;
 299        p_srate = params->p_srate;
 300        c_srate = params->c_srate;
 301        p_chmask = params->p_chmask;
 302        c_chmask = params->c_chmask;
 303        uac->p_residue = 0;
 304
 305        runtime->hw = uac_pcm_hardware;
 306
 307        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 308                spin_lock_init(&uac->p_prm.lock);
 309                runtime->hw.rate_min = p_srate;
 310                switch (p_ssize) {
 311                case 3:
 312                        runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE;
 313                        break;
 314                case 4:
 315                        runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
 316                        break;
 317                default:
 318                        runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
 319                        break;
 320                }
 321                runtime->hw.channels_min = num_channels(p_chmask);
 322                runtime->hw.period_bytes_min = 2 * uac->p_prm.max_psize
 323                                                / runtime->hw.periods_min;
 324        } else {
 325                spin_lock_init(&uac->c_prm.lock);
 326                runtime->hw.rate_min = c_srate;
 327                switch (c_ssize) {
 328                case 3:
 329                        runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE;
 330                        break;
 331                case 4:
 332                        runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
 333                        break;
 334                default:
 335                        runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
 336                        break;
 337                }
 338                runtime->hw.channels_min = num_channels(c_chmask);
 339                runtime->hw.period_bytes_min = 2 * uac->c_prm.max_psize
 340                                                / runtime->hw.periods_min;
 341        }
 342
 343        runtime->hw.rate_max = runtime->hw.rate_min;
 344        runtime->hw.channels_max = runtime->hw.channels_min;
 345
 346        snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
 347
 348        return 0;
 349}
 350
 351/* ALSA cries without these function pointers */
 352static int uac_pcm_null(struct snd_pcm_substream *substream)
 353{
 354        return 0;
 355}
 356
 357static struct snd_pcm_ops uac_pcm_ops = {
 358        .open = uac_pcm_open,
 359        .close = uac_pcm_null,
 360        .ioctl = snd_pcm_lib_ioctl,
 361        .hw_params = uac_pcm_hw_params,
 362        .hw_free = uac_pcm_hw_free,
 363        .trigger = uac_pcm_trigger,
 364        .pointer = uac_pcm_pointer,
 365        .prepare = uac_pcm_null,
 366};
 367
 368static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep)
 369{
 370        struct snd_uac_chip *uac = prm->uac;
 371        struct g_audio *audio_dev;
 372        struct uac_params *params;
 373        int i;
 374
 375        if (!prm->ep_enabled)
 376                return;
 377
 378        prm->ep_enabled = false;
 379
 380        audio_dev = uac->audio_dev;
 381        params = &audio_dev->params;
 382
 383        for (i = 0; i < params->req_number; i++) {
 384                if (prm->ureq[i].req) {
 385                        usb_ep_dequeue(ep, prm->ureq[i].req);
 386                        usb_ep_free_request(ep, prm->ureq[i].req);
 387                        prm->ureq[i].req = NULL;
 388                }
 389        }
 390
 391        if (usb_ep_disable(ep))
 392                dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__);
 393}
 394
 395
 396int u_audio_start_capture(struct g_audio *audio_dev)
 397{
 398        struct snd_uac_chip *uac = audio_dev->uac;
 399        struct usb_gadget *gadget = audio_dev->gadget;
 400        struct device *dev = &gadget->dev;
 401        struct usb_request *req;
 402        struct usb_ep *ep;
 403        struct uac_rtd_params *prm;
 404        struct uac_params *params = &audio_dev->params;
 405        int req_len, i;
 406
 407        ep = audio_dev->out_ep;
 408        prm = &uac->c_prm;
 409        config_ep_by_speed(gadget, &audio_dev->func, ep);
 410        req_len = prm->max_psize;
 411
 412        prm->ep_enabled = true;
 413        usb_ep_enable(ep);
 414
 415        for (i = 0; i < params->req_number; i++) {
 416                if (!prm->ureq[i].req) {
 417                        req = usb_ep_alloc_request(ep, GFP_ATOMIC);
 418                        if (req == NULL)
 419                                return -ENOMEM;
 420
 421                        prm->ureq[i].req = req;
 422                        prm->ureq[i].pp = prm;
 423
 424                        req->zero = 0;
 425                        req->context = &prm->ureq[i];
 426                        req->length = req_len;
 427                        req->complete = u_audio_iso_complete;
 428                        req->buf = prm->rbuf + i * prm->max_psize;
 429                }
 430
 431                if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC))
 432                        dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
 433        }
 434
 435        return 0;
 436}
 437EXPORT_SYMBOL_GPL(u_audio_start_capture);
 438
 439void u_audio_stop_capture(struct g_audio *audio_dev)
 440{
 441        struct snd_uac_chip *uac = audio_dev->uac;
 442
 443        free_ep(&uac->c_prm, audio_dev->out_ep);
 444}
 445EXPORT_SYMBOL_GPL(u_audio_stop_capture);
 446
 447int u_audio_start_playback(struct g_audio *audio_dev)
 448{
 449        struct snd_uac_chip *uac = audio_dev->uac;
 450        struct usb_gadget *gadget = audio_dev->gadget;
 451        struct device *dev = &gadget->dev;
 452        struct usb_request *req;
 453        struct usb_ep *ep;
 454        struct uac_rtd_params *prm;
 455        struct uac_params *params = &audio_dev->params;
 456        unsigned int factor, rate;
 457        const struct usb_endpoint_descriptor *ep_desc;
 458        int req_len, i;
 459
 460        ep = audio_dev->in_ep;
 461        prm = &uac->p_prm;
 462        config_ep_by_speed(gadget, &audio_dev->func, ep);
 463
 464        ep_desc = ep->desc;
 465
 466        /* pre-calculate the playback endpoint's interval */
 467        if (gadget->speed == USB_SPEED_FULL)
 468                factor = 1000;
 469        else
 470                factor = 8000;
 471
 472        /* pre-compute some values for iso_complete() */
 473        uac->p_framesize = params->p_ssize *
 474                            num_channels(params->p_chmask);
 475        rate = params->p_srate * uac->p_framesize;
 476        uac->p_interval = factor / (1 << (ep_desc->bInterval - 1));
 477        uac->p_pktsize = min_t(unsigned int, rate / uac->p_interval,
 478                                prm->max_psize);
 479
 480        if (uac->p_pktsize < prm->max_psize)
 481                uac->p_pktsize_residue = rate % uac->p_interval;
 482        else
 483                uac->p_pktsize_residue = 0;
 484
 485        req_len = uac->p_pktsize;
 486        uac->p_residue = 0;
 487
 488        prm->ep_enabled = true;
 489        usb_ep_enable(ep);
 490
 491        for (i = 0; i < params->req_number; i++) {
 492                if (!prm->ureq[i].req) {
 493                        req = usb_ep_alloc_request(ep, GFP_ATOMIC);
 494                        if (req == NULL)
 495                                return -ENOMEM;
 496
 497                        prm->ureq[i].req = req;
 498                        prm->ureq[i].pp = prm;
 499
 500                        req->zero = 0;
 501                        req->context = &prm->ureq[i];
 502                        req->length = req_len;
 503                        req->complete = u_audio_iso_complete;
 504                        req->buf = prm->rbuf + i * prm->max_psize;
 505                }
 506
 507                if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC))
 508                        dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
 509        }
 510
 511        return 0;
 512}
 513EXPORT_SYMBOL_GPL(u_audio_start_playback);
 514
 515void u_audio_stop_playback(struct g_audio *audio_dev)
 516{
 517        struct snd_uac_chip *uac = audio_dev->uac;
 518
 519        free_ep(&uac->p_prm, audio_dev->in_ep);
 520}
 521EXPORT_SYMBOL_GPL(u_audio_stop_playback);
 522
 523int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
 524                                        const char *card_name)
 525{
 526        struct snd_uac_chip *uac;
 527        struct snd_card *card;
 528        struct snd_pcm *pcm;
 529        struct uac_params *params;
 530        int p_chmask, c_chmask;
 531        int err;
 532
 533        if (!g_audio)
 534                return -EINVAL;
 535
 536        uac = kzalloc(sizeof(*uac), GFP_KERNEL);
 537        if (!uac)
 538                return -ENOMEM;
 539        g_audio->uac = uac;
 540        uac->audio_dev = g_audio;
 541
 542        params = &g_audio->params;
 543        p_chmask = params->p_chmask;
 544        c_chmask = params->c_chmask;
 545
 546        if (c_chmask) {
 547                struct uac_rtd_params *prm = &uac->c_prm;
 548
 549                uac->c_prm.uac = uac;
 550                prm->max_psize = g_audio->out_ep_maxpsize;
 551
 552                prm->ureq = kcalloc(params->req_number, sizeof(struct uac_req),
 553                                GFP_KERNEL);
 554                if (!prm->ureq) {
 555                        err = -ENOMEM;
 556                        goto fail;
 557                }
 558
 559                prm->rbuf = kcalloc(params->req_number, prm->max_psize,
 560                                GFP_KERNEL);
 561                if (!prm->rbuf) {
 562                        prm->max_psize = 0;
 563                        err = -ENOMEM;
 564                        goto fail;
 565                }
 566        }
 567
 568        if (p_chmask) {
 569                struct uac_rtd_params *prm = &uac->p_prm;
 570
 571                uac->p_prm.uac = uac;
 572                prm->max_psize = g_audio->in_ep_maxpsize;
 573
 574                prm->ureq = kcalloc(params->req_number, sizeof(struct uac_req),
 575                                GFP_KERNEL);
 576                if (!prm->ureq) {
 577                        err = -ENOMEM;
 578                        goto fail;
 579                }
 580
 581                prm->rbuf = kcalloc(params->req_number, prm->max_psize,
 582                                GFP_KERNEL);
 583                if (!prm->rbuf) {
 584                        prm->max_psize = 0;
 585                        err = -ENOMEM;
 586                        goto fail;
 587                }
 588        }
 589
 590        /* Choose any slot, with no id */
 591        err = snd_card_new(&g_audio->gadget->dev,
 592                        -1, NULL, THIS_MODULE, 0, &card);
 593        if (err < 0)
 594                goto fail;
 595
 596        uac->card = card;
 597
 598        /*
 599         * Create first PCM device
 600         * Create a substream only for non-zero channel streams
 601         */
 602        err = snd_pcm_new(uac->card, pcm_name, 0,
 603                               p_chmask ? 1 : 0, c_chmask ? 1 : 0, &pcm);
 604        if (err < 0)
 605                goto snd_fail;
 606
 607        strcpy(pcm->name, pcm_name);
 608        pcm->private_data = uac;
 609        uac->pcm = pcm;
 610
 611        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac_pcm_ops);
 612        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac_pcm_ops);
 613
 614        strcpy(card->driver, card_name);
 615        strcpy(card->shortname, card_name);
 616        sprintf(card->longname, "%s %i", card_name, card->dev->id);
 617
 618        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
 619                snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX);
 620
 621        err = snd_card_register(card);
 622
 623        if (!err)
 624                return 0;
 625
 626snd_fail:
 627        snd_card_free(card);
 628fail:
 629        kfree(uac->p_prm.ureq);
 630        kfree(uac->c_prm.ureq);
 631        kfree(uac->p_prm.rbuf);
 632        kfree(uac->c_prm.rbuf);
 633        kfree(uac);
 634
 635        return err;
 636}
 637EXPORT_SYMBOL_GPL(g_audio_setup);
 638
 639void g_audio_cleanup(struct g_audio *g_audio)
 640{
 641        struct snd_uac_chip *uac;
 642        struct snd_card *card;
 643
 644        if (!g_audio || !g_audio->uac)
 645                return;
 646
 647        uac = g_audio->uac;
 648        card = uac->card;
 649        if (card)
 650                snd_card_free(card);
 651
 652        kfree(uac->p_prm.ureq);
 653        kfree(uac->c_prm.ureq);
 654        kfree(uac->p_prm.rbuf);
 655        kfree(uac->c_prm.rbuf);
 656        kfree(uac);
 657}
 658EXPORT_SYMBOL_GPL(g_audio_cleanup);
 659
 660MODULE_LICENSE("GPL");
 661MODULE_DESCRIPTION("USB gadget \"ALSA sound card\" utilities");
 662MODULE_AUTHOR("Ruslan Bilovol");
 663