~fboudra/qemu-linaro/new-upstream-release-1.2.0-2012.09-0ubuntu1

« back to all changes in this revision

Viewing changes to hw/usb/dev-audio.c

  • Committer: Fathi Boudra
  • Author(s): Fathi Boudra
  • Date: 2012-08-21 06:47:11 UTC
  • mfrom: (0.1.16)
  • Revision ID: fathi.boudra@linaro.org-20120821064711-7yxmubp2v8a44xce
Tags: 1.1.50-2012.08-0ubuntu1
* New upstream release.
  - support emulated systems with more than 2G of memory. (LP: #1030588)
* Drop powerpc-missing-include.patch - merged upstream.
* Update debian/control: 
  - drop perl build dependency.
  - add libfdt-dev build dependency.
* Update debian/qemu-keymaps.install file.
* Update debian/rules:
  - update QEMU_CPU for ARM architecture: armv4l -> armv7l.
  - update conf_audio_drv: default to PulseAudio since PA is the default on
    Ubuntu.
  - enable KVM on ARM architecture.
  - enable flat device tree support (--enable-fdt). (LP: #1030594)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * QEMU USB audio device
 
3
 *
 
4
 * written by:
 
5
 *  H. Peter Anvin <hpa@linux.intel.com>
 
6
 *  Gerd Hoffmann <kraxel@redhat.com>
 
7
 *
 
8
 * lousely based on usb net device code which is:
 
9
 *
 
10
 * Copyright (c) 2006 Thomas Sailer
 
11
 * Copyright (c) 2008 Andrzej Zaborowski
 
12
 *
 
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
14
 * of this software and associated documentation files (the "Software"), to deal
 
15
 * in the Software without restriction, including without limitation the rights
 
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
17
 * copies of the Software, and to permit persons to whom the Software is
 
18
 * furnished to do so, subject to the following conditions:
 
19
 *
 
20
 * The above copyright notice and this permission notice shall be included in
 
21
 * all copies or substantial portions of the Software.
 
22
 *
 
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
26
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
29
 * THE SOFTWARE.
 
30
 */
 
31
 
 
32
#include "qemu-common.h"
 
33
#include "hw/usb.h"
 
34
#include "hw/usb/desc.h"
 
35
#include "hw/hw.h"
 
36
#include "hw/audiodev.h"
 
37
#include "audio/audio.h"
 
38
 
 
39
#define USBAUDIO_VENDOR_NUM     0x46f4 /* CRC16() of "QEMU" */
 
40
#define USBAUDIO_PRODUCT_NUM    0x0002
 
41
 
 
42
#define DEV_CONFIG_VALUE        1 /* The one and only */
 
43
 
 
44
/* Descriptor subtypes for AC interfaces */
 
45
#define DST_AC_HEADER           1
 
46
#define DST_AC_INPUT_TERMINAL   2
 
47
#define DST_AC_OUTPUT_TERMINAL  3
 
48
#define DST_AC_FEATURE_UNIT     6
 
49
/* Descriptor subtypes for AS interfaces */
 
50
#define DST_AS_GENERAL          1
 
51
#define DST_AS_FORMAT_TYPE      2
 
52
/* Descriptor subtypes for endpoints */
 
53
#define DST_EP_GENERAL          1
 
54
 
 
55
enum usb_audio_strings {
 
56
    STRING_NULL,
 
57
    STRING_MANUFACTURER,
 
58
    STRING_PRODUCT,
 
59
    STRING_SERIALNUMBER,
 
60
    STRING_CONFIG,
 
61
    STRING_USBAUDIO_CONTROL,
 
62
    STRING_INPUT_TERMINAL,
 
63
    STRING_FEATURE_UNIT,
 
64
    STRING_OUTPUT_TERMINAL,
 
65
    STRING_NULL_STREAM,
 
66
    STRING_REAL_STREAM,
 
67
};
 
68
 
 
69
static const USBDescStrings usb_audio_stringtable = {
 
70
    [STRING_MANUFACTURER]       = "QEMU",
 
71
    [STRING_PRODUCT]            = "QEMU USB Audio",
 
72
    [STRING_SERIALNUMBER]       = "1",
 
73
    [STRING_CONFIG]             = "Audio Configuration",
 
74
    [STRING_USBAUDIO_CONTROL]   = "Audio Device",
 
75
    [STRING_INPUT_TERMINAL]     = "Audio Output Pipe",
 
76
    [STRING_FEATURE_UNIT]       = "Audio Output Volume Control",
 
77
    [STRING_OUTPUT_TERMINAL]    = "Audio Output Terminal",
 
78
    [STRING_NULL_STREAM]        = "Audio Output - Disabled",
 
79
    [STRING_REAL_STREAM]        = "Audio Output - 48 kHz Stereo",
 
80
};
 
81
 
 
82
#define U16(x) ((x) & 0xff), (((x) >> 8) & 0xff)
 
83
#define U24(x) U16(x), (((x) >> 16) & 0xff)
 
84
#define U32(x) U24(x), (((x) >> 24) & 0xff)
 
85
 
 
86
/*
 
87
 * A Basic Audio Device uses these specific values
 
88
 */
 
89
#define USBAUDIO_PACKET_SIZE     192
 
90
#define USBAUDIO_SAMPLE_RATE     48000
 
91
#define USBAUDIO_PACKET_INTERVAL 1
 
92
 
 
93
static const USBDescIface desc_iface[] = {
 
94
    {
 
95
        .bInterfaceNumber              = 0,
 
96
        .bNumEndpoints                 = 0,
 
97
        .bInterfaceClass               = USB_CLASS_AUDIO,
 
98
        .bInterfaceSubClass            = USB_SUBCLASS_AUDIO_CONTROL,
 
99
        .bInterfaceProtocol            = 0x04,
 
100
        .iInterface                    = STRING_USBAUDIO_CONTROL,
 
101
        .ndesc                         = 4,
 
102
        .descs = (USBDescOther[]) {
 
103
            {
 
104
                /* Headphone Class-Specific AC Interface Header Descriptor */
 
105
                .data = (uint8_t[]) {
 
106
                    0x09,                       /*  u8  bLength */
 
107
                    USB_DT_CS_INTERFACE,        /*  u8  bDescriptorType */
 
108
                    DST_AC_HEADER,              /*  u8  bDescriptorSubtype */
 
109
                    U16(0x0100),                /* u16  bcdADC */
 
110
                    U16(0x2b),                  /* u16  wTotalLength */
 
111
                    0x01,                       /*  u8  bInCollection */
 
112
                    0x01,                       /*  u8  baInterfaceNr */
 
113
                }
 
114
            },{
 
115
                /* Generic Stereo Input Terminal ID1 Descriptor */
 
116
                .data = (uint8_t[]) {
 
117
                    0x0c,                       /*  u8  bLength */
 
118
                    USB_DT_CS_INTERFACE,        /*  u8  bDescriptorType */
 
119
                    DST_AC_INPUT_TERMINAL,      /*  u8  bDescriptorSubtype */
 
120
                    0x01,                       /*  u8  bTerminalID */
 
121
                    U16(0x0101),                /* u16  wTerminalType */
 
122
                    0x00,                       /*  u8  bAssocTerminal */
 
123
                    0x02,                       /* u16  bNrChannels */
 
124
                    U16(0x0003),                /* u16  wChannelConfig */
 
125
                    0x00,                       /*  u8  iChannelNames */
 
126
                    STRING_INPUT_TERMINAL,      /*  u8  iTerminal */
 
127
                }
 
128
            },{
 
129
                /* Generic Stereo Feature Unit ID2 Descriptor */
 
130
                .data = (uint8_t[]) {
 
131
                    0x0d,                       /*  u8  bLength */
 
132
                    USB_DT_CS_INTERFACE,        /*  u8  bDescriptorType */
 
133
                    DST_AC_FEATURE_UNIT,        /*  u8  bDescriptorSubtype */
 
134
                    0x02,                       /*  u8  bUnitID */
 
135
                    0x01,                       /*  u8  bSourceID */
 
136
                    0x02,                       /*  u8  bControlSize */
 
137
                    U16(0x0001),                /* u16  bmaControls(0) */
 
138
                    U16(0x0002),                /* u16  bmaControls(1) */
 
139
                    U16(0x0002),                /* u16  bmaControls(2) */
 
140
                    STRING_FEATURE_UNIT,        /*  u8  iFeature */
 
141
                }
 
142
            },{
 
143
                /* Headphone Ouptut Terminal ID3 Descriptor */
 
144
                .data = (uint8_t[]) {
 
145
                    0x09,                       /*  u8  bLength */
 
146
                    USB_DT_CS_INTERFACE,        /*  u8  bDescriptorType */
 
147
                    DST_AC_OUTPUT_TERMINAL,     /*  u8  bDescriptorSubtype */
 
148
                    0x03,                       /*  u8  bUnitID */
 
149
                    U16(0x0301),                /* u16  wTerminalType (SPK) */
 
150
                    0x00,                       /*  u8  bAssocTerminal */
 
151
                    0x02,                       /*  u8  bSourceID */
 
152
                    STRING_OUTPUT_TERMINAL,     /*  u8  iTerminal */
 
153
                }
 
154
            }
 
155
        },
 
156
    },{
 
157
        .bInterfaceNumber              = 1,
 
158
        .bAlternateSetting             = 0,
 
159
        .bNumEndpoints                 = 0,
 
160
        .bInterfaceClass               = USB_CLASS_AUDIO,
 
161
        .bInterfaceSubClass            = USB_SUBCLASS_AUDIO_STREAMING,
 
162
        .iInterface                    = STRING_NULL_STREAM,
 
163
    },{
 
164
        .bInterfaceNumber              = 1,
 
165
        .bAlternateSetting             = 1,
 
166
        .bNumEndpoints                 = 1,
 
167
        .bInterfaceClass               = USB_CLASS_AUDIO,
 
168
        .bInterfaceSubClass            = USB_SUBCLASS_AUDIO_STREAMING,
 
169
        .iInterface                    = STRING_REAL_STREAM,
 
170
        .ndesc                         = 2,
 
171
        .descs = (USBDescOther[]) {
 
172
            {
 
173
                /* Headphone Class-specific AS General Interface Descriptor */
 
174
                .data = (uint8_t[]) {
 
175
                    0x07,                       /*  u8  bLength */
 
176
                    USB_DT_CS_INTERFACE,        /*  u8  bDescriptorType */
 
177
                    DST_AS_GENERAL,             /*  u8  bDescriptorSubtype */
 
178
                    0x01,                       /*  u8  bTerminalLink */
 
179
                    0x00,                       /*  u8  bDelay */
 
180
                    0x01, 0x00,                 /* u16  wFormatTag */
 
181
                }
 
182
            },{
 
183
                /* Headphone Type I Format Type Descriptor */
 
184
                .data = (uint8_t[]) {
 
185
                    0x0b,                       /*  u8  bLength */
 
186
                    USB_DT_CS_INTERFACE,        /*  u8  bDescriptorType */
 
187
                    DST_AS_FORMAT_TYPE,         /*  u8  bDescriptorSubtype */
 
188
                    0x01,                       /*  u8  bFormatType */
 
189
                    0x02,                       /*  u8  bNrChannels */
 
190
                    0x02,                       /*  u8  bSubFrameSize */
 
191
                    0x10,                       /*  u8  bBitResolution */
 
192
                    0x01,                       /*  u8  bSamFreqType */
 
193
                    U24(USBAUDIO_SAMPLE_RATE),  /* u24  tSamFreq */
 
194
                }
 
195
            }
 
196
        },
 
197
        .eps = (USBDescEndpoint[]) {
 
198
            {
 
199
                .bEndpointAddress      = USB_DIR_OUT | 0x01,
 
200
                .bmAttributes          = 0x0d,
 
201
                .wMaxPacketSize        = USBAUDIO_PACKET_SIZE,
 
202
                .bInterval             = 1,
 
203
                .is_audio              = 1,
 
204
                /* Stereo Headphone Class-specific
 
205
                   AS Audio Data Endpoint Descriptor */
 
206
                .extra = (uint8_t[]) {
 
207
                    0x07,                       /*  u8  bLength */
 
208
                    USB_DT_CS_ENDPOINT,         /*  u8  bDescriptorType */
 
209
                    DST_EP_GENERAL,             /*  u8  bDescriptorSubtype */
 
210
                    0x00,                       /*  u8  bmAttributes */
 
211
                    0x00,                       /*  u8  bLockDelayUnits */
 
212
                    U16(0x0000),                /* u16  wLockDelay */
 
213
                },
 
214
            },
 
215
        }
 
216
    }
 
217
};
 
218
 
 
219
static const USBDescDevice desc_device = {
 
220
    .bcdUSB                        = 0x0200,
 
221
    .bMaxPacketSize0               = 64,
 
222
    .bNumConfigurations            = 1,
 
223
    .confs = (USBDescConfig[]) {
 
224
        {
 
225
            .bNumInterfaces        = 2,
 
226
            .bConfigurationValue   = DEV_CONFIG_VALUE,
 
227
            .iConfiguration        = STRING_CONFIG,
 
228
            .bmAttributes          = 0xc0,
 
229
            .bMaxPower             = 0x32,
 
230
            .nif = ARRAY_SIZE(desc_iface),
 
231
            .ifs = desc_iface,
 
232
        },
 
233
    },
 
234
};
 
235
 
 
236
static const USBDesc desc_audio = {
 
237
    .id = {
 
238
        .idVendor          = USBAUDIO_VENDOR_NUM,
 
239
        .idProduct         = USBAUDIO_PRODUCT_NUM,
 
240
        .bcdDevice         = 0,
 
241
        .iManufacturer     = STRING_MANUFACTURER,
 
242
        .iProduct          = STRING_PRODUCT,
 
243
        .iSerialNumber     = STRING_SERIALNUMBER,
 
244
    },
 
245
    .full = &desc_device,
 
246
    .str  = usb_audio_stringtable,
 
247
};
 
248
 
 
249
/*
 
250
 * A USB audio device supports an arbitrary number of alternate
 
251
 * interface settings for each interface.  Each corresponds to a block
 
252
 * diagram of parameterized blocks.  This can thus refer to things like
 
253
 * number of channels, data rates, or in fact completely different
 
254
 * block diagrams.  Alternative setting 0 is always the null block diagram,
 
255
 * which is used by a disabled device.
 
256
 */
 
257
enum usb_audio_altset {
 
258
    ALTSET_OFF  = 0x00,         /* No endpoint */
 
259
    ALTSET_ON   = 0x01,         /* Single endpoint */
 
260
};
 
261
 
 
262
/*
 
263
 * Class-specific control requests
 
264
 */
 
265
#define CR_SET_CUR      0x01
 
266
#define CR_GET_CUR      0x81
 
267
#define CR_SET_MIN      0x02
 
268
#define CR_GET_MIN      0x82
 
269
#define CR_SET_MAX      0x03
 
270
#define CR_GET_MAX      0x83
 
271
#define CR_SET_RES      0x04
 
272
#define CR_GET_RES      0x84
 
273
#define CR_SET_MEM      0x05
 
274
#define CR_GET_MEM      0x85
 
275
#define CR_GET_STAT     0xff
 
276
 
 
277
/*
 
278
 * Feature Unit Control Selectors
 
279
 */
 
280
#define MUTE_CONTROL                    0x01
 
281
#define VOLUME_CONTROL                  0x02
 
282
#define BASS_CONTROL                    0x03
 
283
#define MID_CONTROL                     0x04
 
284
#define TREBLE_CONTROL                  0x05
 
285
#define GRAPHIC_EQUALIZER_CONTROL       0x06
 
286
#define AUTOMATIC_GAIN_CONTROL          0x07
 
287
#define DELAY_CONTROL                   0x08
 
288
#define BASS_BOOST_CONTROL              0x09
 
289
#define LOUDNESS_CONTROL                0x0a
 
290
 
 
291
/*
 
292
 * buffering
 
293
 */
 
294
 
 
295
struct streambuf {
 
296
    uint8_t *data;
 
297
    uint32_t size;
 
298
    uint32_t prod;
 
299
    uint32_t cons;
 
300
};
 
301
 
 
302
static void streambuf_init(struct streambuf *buf, uint32_t size)
 
303
{
 
304
    g_free(buf->data);
 
305
    buf->size = size - (size % USBAUDIO_PACKET_SIZE);
 
306
    buf->data = g_malloc(buf->size);
 
307
    buf->prod = 0;
 
308
    buf->cons = 0;
 
309
}
 
310
 
 
311
static void streambuf_fini(struct streambuf *buf)
 
312
{
 
313
    g_free(buf->data);
 
314
    buf->data = NULL;
 
315
}
 
316
 
 
317
static int streambuf_put(struct streambuf *buf, USBPacket *p)
 
318
{
 
319
    uint32_t free = buf->size - (buf->prod - buf->cons);
 
320
 
 
321
    if (!free) {
 
322
        return 0;
 
323
    }
 
324
    assert(free >= USBAUDIO_PACKET_SIZE);
 
325
    usb_packet_copy(p, buf->data + (buf->prod % buf->size),
 
326
                    USBAUDIO_PACKET_SIZE);
 
327
    buf->prod += USBAUDIO_PACKET_SIZE;
 
328
    return USBAUDIO_PACKET_SIZE;
 
329
}
 
330
 
 
331
static uint8_t *streambuf_get(struct streambuf *buf)
 
332
{
 
333
    uint32_t used = buf->prod - buf->cons;
 
334
    uint8_t *data;
 
335
 
 
336
    if (!used) {
 
337
        return NULL;
 
338
    }
 
339
    assert(used >= USBAUDIO_PACKET_SIZE);
 
340
    data = buf->data + (buf->cons % buf->size);
 
341
    buf->cons += USBAUDIO_PACKET_SIZE;
 
342
    return data;
 
343
}
 
344
 
 
345
typedef struct USBAudioState {
 
346
    /* qemu interfaces */
 
347
    USBDevice dev;
 
348
    QEMUSoundCard card;
 
349
 
 
350
    /* state */
 
351
    struct {
 
352
        enum usb_audio_altset altset;
 
353
        struct audsettings as;
 
354
        SWVoiceOut *voice;
 
355
        bool mute;
 
356
        uint8_t vol[2];
 
357
        struct streambuf buf;
 
358
    } out;
 
359
 
 
360
    /* properties */
 
361
    uint32_t debug;
 
362
    uint32_t buffer;
 
363
} USBAudioState;
 
364
 
 
365
static void output_callback(void *opaque, int avail)
 
366
{
 
367
    USBAudioState *s = opaque;
 
368
    uint8_t *data;
 
369
 
 
370
    for (;;) {
 
371
        if (avail < USBAUDIO_PACKET_SIZE) {
 
372
            return;
 
373
        }
 
374
        data = streambuf_get(&s->out.buf);
 
375
        if (NULL == data) {
 
376
            return;
 
377
        }
 
378
        AUD_write(s->out.voice, data, USBAUDIO_PACKET_SIZE);
 
379
        avail -= USBAUDIO_PACKET_SIZE;
 
380
    }
 
381
}
 
382
 
 
383
static int usb_audio_set_output_altset(USBAudioState *s, int altset)
 
384
{
 
385
    switch (altset) {
 
386
    case ALTSET_OFF:
 
387
        streambuf_init(&s->out.buf, s->buffer);
 
388
        AUD_set_active_out(s->out.voice, false);
 
389
        break;
 
390
    case ALTSET_ON:
 
391
        AUD_set_active_out(s->out.voice, true);
 
392
        break;
 
393
    default:
 
394
        return -1;
 
395
    }
 
396
 
 
397
    if (s->debug) {
 
398
        fprintf(stderr, "usb-audio: set interface %d\n", altset);
 
399
    }
 
400
    s->out.altset = altset;
 
401
    return 0;
 
402
}
 
403
 
 
404
/*
 
405
 * Note: we arbitrarily map the volume control range onto -inf..+8 dB
 
406
 */
 
407
#define ATTRIB_ID(cs, attrib, idif)     \
 
408
    (((cs) << 24) | ((attrib) << 16) | (idif))
 
409
 
 
410
static int usb_audio_get_control(USBAudioState *s, uint8_t attrib,
 
411
                                 uint16_t cscn, uint16_t idif,
 
412
                                 int length, uint8_t *data)
 
413
{
 
414
    uint8_t cs = cscn >> 8;
 
415
    uint8_t cn = cscn - 1;      /* -1 for the non-present master control */
 
416
    uint32_t aid = ATTRIB_ID(cs, attrib, idif);
 
417
    int ret = USB_RET_STALL;
 
418
 
 
419
    switch (aid) {
 
420
    case ATTRIB_ID(MUTE_CONTROL, CR_GET_CUR, 0x0200):
 
421
        data[0] = s->out.mute;
 
422
        ret = 1;
 
423
        break;
 
424
    case ATTRIB_ID(VOLUME_CONTROL, CR_GET_CUR, 0x0200):
 
425
        if (cn < 2) {
 
426
            uint16_t vol = (s->out.vol[cn] * 0x8800 + 127) / 255 + 0x8000;
 
427
            data[0] = vol;
 
428
            data[1] = vol >> 8;
 
429
            ret = 2;
 
430
        }
 
431
        break;
 
432
    case ATTRIB_ID(VOLUME_CONTROL, CR_GET_MIN, 0x0200):
 
433
        if (cn < 2) {
 
434
            data[0] = 0x01;
 
435
            data[1] = 0x80;
 
436
            ret = 2;
 
437
        }
 
438
        break;
 
439
    case ATTRIB_ID(VOLUME_CONTROL, CR_GET_MAX, 0x0200):
 
440
        if (cn < 2) {
 
441
            data[0] = 0x00;
 
442
            data[1] = 0x08;
 
443
            ret = 2;
 
444
        }
 
445
        break;
 
446
    case ATTRIB_ID(VOLUME_CONTROL, CR_GET_RES, 0x0200):
 
447
        if (cn < 2) {
 
448
            data[0] = 0x88;
 
449
            data[1] = 0x00;
 
450
            ret = 2;
 
451
        }
 
452
        break;
 
453
    }
 
454
 
 
455
    return ret;
 
456
}
 
457
static int usb_audio_set_control(USBAudioState *s, uint8_t attrib,
 
458
                                 uint16_t cscn, uint16_t idif,
 
459
                                 int length, uint8_t *data)
 
460
{
 
461
    uint8_t cs = cscn >> 8;
 
462
    uint8_t cn = cscn - 1;      /* -1 for the non-present master control */
 
463
    uint32_t aid = ATTRIB_ID(cs, attrib, idif);
 
464
    int ret = USB_RET_STALL;
 
465
    bool set_vol = false;
 
466
 
 
467
    switch (aid) {
 
468
    case ATTRIB_ID(MUTE_CONTROL, CR_SET_CUR, 0x0200):
 
469
        s->out.mute = data[0] & 1;
 
470
        set_vol = true;
 
471
        ret = 0;
 
472
        break;
 
473
    case ATTRIB_ID(VOLUME_CONTROL, CR_SET_CUR, 0x0200):
 
474
        if (cn < 2) {
 
475
            uint16_t vol = data[0] + (data[1] << 8);
 
476
 
 
477
            if (s->debug) {
 
478
                fprintf(stderr, "usb-audio: vol %04x\n", (uint16_t)vol);
 
479
            }
 
480
 
 
481
            vol -= 0x8000;
 
482
            vol = (vol * 255 + 0x4400) / 0x8800;
 
483
            if (vol > 255) {
 
484
                vol = 255;
 
485
            }
 
486
 
 
487
            s->out.vol[cn] = vol;
 
488
            set_vol = true;
 
489
            ret = 0;
 
490
        }
 
491
        break;
 
492
    }
 
493
 
 
494
    if (set_vol) {
 
495
        if (s->debug) {
 
496
            fprintf(stderr, "usb-audio: mute %d, lvol %3d, rvol %3d\n",
 
497
                    s->out.mute, s->out.vol[0], s->out.vol[1]);
 
498
        }
 
499
        AUD_set_volume_out(s->out.voice, s->out.mute,
 
500
                           s->out.vol[0], s->out.vol[1]);
 
501
    }
 
502
 
 
503
    return ret;
 
504
}
 
505
 
 
506
static int usb_audio_handle_control(USBDevice *dev, USBPacket *p,
 
507
                                    int request, int value, int index,
 
508
                                    int length, uint8_t *data)
 
509
{
 
510
    USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev);
 
511
    int ret = 0;
 
512
 
 
513
    if (s->debug) {
 
514
        fprintf(stderr, "usb-audio: control transaction: "
 
515
                "request 0x%04x value 0x%04x index 0x%04x length 0x%04x\n",
 
516
                request, value, index, length);
 
517
    }
 
518
 
 
519
    ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
 
520
    if (ret >= 0) {
 
521
        return ret;
 
522
    }
 
523
 
 
524
    switch (request) {
 
525
    case ClassInterfaceRequest | CR_GET_CUR:
 
526
    case ClassInterfaceRequest | CR_GET_MIN:
 
527
    case ClassInterfaceRequest | CR_GET_MAX:
 
528
    case ClassInterfaceRequest | CR_GET_RES:
 
529
        ret = usb_audio_get_control(s, request & 0xff, value, index,
 
530
                                    length, data);
 
531
        if (ret < 0) {
 
532
            if (s->debug) {
 
533
                fprintf(stderr, "usb-audio: fail: get control\n");
 
534
            }
 
535
            goto fail;
 
536
        }
 
537
        break;
 
538
 
 
539
    case ClassInterfaceOutRequest | CR_SET_CUR:
 
540
    case ClassInterfaceOutRequest | CR_SET_MIN:
 
541
    case ClassInterfaceOutRequest | CR_SET_MAX:
 
542
    case ClassInterfaceOutRequest | CR_SET_RES:
 
543
        ret = usb_audio_set_control(s, request & 0xff, value, index,
 
544
                                    length, data);
 
545
        if (ret < 0) {
 
546
            if (s->debug) {
 
547
                fprintf(stderr, "usb-audio: fail: set control\n");
 
548
            }
 
549
            goto fail;
 
550
        }
 
551
        break;
 
552
 
 
553
    default:
 
554
fail:
 
555
        if (s->debug) {
 
556
            fprintf(stderr, "usb-audio: failed control transaction: "
 
557
                    "request 0x%04x value 0x%04x index 0x%04x length 0x%04x\n",
 
558
                    request, value, index, length);
 
559
        }
 
560
        ret = USB_RET_STALL;
 
561
        break;
 
562
    }
 
563
    return ret;
 
564
}
 
565
 
 
566
static void usb_audio_set_interface(USBDevice *dev, int iface,
 
567
                                    int old, int value)
 
568
{
 
569
    USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev);
 
570
 
 
571
    if (iface == 1) {
 
572
        usb_audio_set_output_altset(s, value);
 
573
    }
 
574
}
 
575
 
 
576
static void usb_audio_handle_reset(USBDevice *dev)
 
577
{
 
578
    USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev);
 
579
 
 
580
    if (s->debug) {
 
581
        fprintf(stderr, "usb-audio: reset\n");
 
582
    }
 
583
    usb_audio_set_output_altset(s, ALTSET_OFF);
 
584
}
 
585
 
 
586
static int usb_audio_handle_dataout(USBAudioState *s, USBPacket *p)
 
587
{
 
588
    int rc;
 
589
 
 
590
    if (s->out.altset == ALTSET_OFF) {
 
591
        return USB_RET_STALL;
 
592
    }
 
593
 
 
594
    rc = streambuf_put(&s->out.buf, p);
 
595
    if (rc < p->iov.size && s->debug > 1) {
 
596
        fprintf(stderr, "usb-audio: output overrun (%zd bytes)\n",
 
597
                p->iov.size - rc);
 
598
    }
 
599
 
 
600
    return 0;
 
601
}
 
602
 
 
603
static int usb_audio_handle_data(USBDevice *dev, USBPacket *p)
 
604
{
 
605
    USBAudioState *s = (USBAudioState *) dev;
 
606
    int ret = 0;
 
607
 
 
608
    switch (p->pid) {
 
609
    case USB_TOKEN_OUT:
 
610
        switch (p->ep->nr) {
 
611
        case 1:
 
612
            ret = usb_audio_handle_dataout(s, p);
 
613
            break;
 
614
        default:
 
615
            goto fail;
 
616
        }
 
617
        break;
 
618
 
 
619
    default:
 
620
fail:
 
621
        ret = USB_RET_STALL;
 
622
        break;
 
623
    }
 
624
    if (ret == USB_RET_STALL && s->debug) {
 
625
        fprintf(stderr, "usb-audio: failed data transaction: "
 
626
                        "pid 0x%x ep 0x%x len 0x%zx\n",
 
627
                        p->pid, p->ep->nr, p->iov.size);
 
628
    }
 
629
    return ret;
 
630
}
 
631
 
 
632
static void usb_audio_handle_destroy(USBDevice *dev)
 
633
{
 
634
    USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev);
 
635
 
 
636
    if (s->debug) {
 
637
        fprintf(stderr, "usb-audio: destroy\n");
 
638
    }
 
639
 
 
640
    usb_audio_set_output_altset(s, ALTSET_OFF);
 
641
    AUD_close_out(&s->card, s->out.voice);
 
642
    AUD_remove_card(&s->card);
 
643
 
 
644
    streambuf_fini(&s->out.buf);
 
645
}
 
646
 
 
647
static int usb_audio_initfn(USBDevice *dev)
 
648
{
 
649
    USBAudioState *s = DO_UPCAST(USBAudioState, dev, dev);
 
650
 
 
651
    usb_desc_create_serial(dev);
 
652
    usb_desc_init(dev);
 
653
    s->dev.opaque = s;
 
654
    AUD_register_card("usb-audio", &s->card);
 
655
 
 
656
    s->out.altset        = ALTSET_OFF;
 
657
    s->out.mute          = false;
 
658
    s->out.vol[0]        = 240; /* 0 dB */
 
659
    s->out.vol[1]        = 240; /* 0 dB */
 
660
    s->out.as.freq       = USBAUDIO_SAMPLE_RATE;
 
661
    s->out.as.nchannels  = 2;
 
662
    s->out.as.fmt        = AUD_FMT_S16;
 
663
    s->out.as.endianness = 0;
 
664
    streambuf_init(&s->out.buf, s->buffer);
 
665
 
 
666
    s->out.voice = AUD_open_out(&s->card, s->out.voice, "usb-audio",
 
667
                                s, output_callback, &s->out.as);
 
668
    AUD_set_volume_out(s->out.voice, s->out.mute, s->out.vol[0], s->out.vol[1]);
 
669
    AUD_set_active_out(s->out.voice, 0);
 
670
    return 0;
 
671
}
 
672
 
 
673
static const VMStateDescription vmstate_usb_audio = {
 
674
    .name = "usb-audio",
 
675
    .unmigratable = 1,
 
676
};
 
677
 
 
678
static Property usb_audio_properties[] = {
 
679
    DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0),
 
680
    DEFINE_PROP_UINT32("buffer", USBAudioState, buffer,
 
681
                       8 * USBAUDIO_PACKET_SIZE),
 
682
    DEFINE_PROP_END_OF_LIST(),
 
683
};
 
684
 
 
685
static void usb_audio_class_init(ObjectClass *klass, void *data)
 
686
{
 
687
    DeviceClass *dc = DEVICE_CLASS(klass);
 
688
    USBDeviceClass *k = USB_DEVICE_CLASS(klass);
 
689
 
 
690
    dc->vmsd          = &vmstate_usb_audio;
 
691
    dc->props         = usb_audio_properties;
 
692
    k->product_desc   = "QEMU USB Audio Interface";
 
693
    k->usb_desc       = &desc_audio;
 
694
    k->init           = usb_audio_initfn;
 
695
    k->handle_reset   = usb_audio_handle_reset;
 
696
    k->handle_control = usb_audio_handle_control;
 
697
    k->handle_data    = usb_audio_handle_data;
 
698
    k->handle_destroy = usb_audio_handle_destroy;
 
699
    k->set_interface  = usb_audio_set_interface;
 
700
}
 
701
 
 
702
static TypeInfo usb_audio_info = {
 
703
    .name          = "usb-audio",
 
704
    .parent        = TYPE_USB_DEVICE,
 
705
    .instance_size = sizeof(USBAudioState),
 
706
    .class_init    = usb_audio_class_init,
 
707
};
 
708
 
 
709
static void usb_audio_register_types(void)
 
710
{
 
711
    type_register_static(&usb_audio_info);
 
712
    usb_legacy_register("usb-audio", "audio", NULL);
 
713
}
 
714
 
 
715
type_init(usb_audio_register_types)