Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/usb/quirks.c
10814 views
1
/*
2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
6
*
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
11
*
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
*/
16
17
#include <linux/init.h>
18
#include <linux/slab.h>
19
#include <linux/usb.h>
20
#include <linux/usb/audio.h>
21
22
#include <sound/control.h>
23
#include <sound/core.h>
24
#include <sound/info.h>
25
#include <sound/pcm.h>
26
27
#include "usbaudio.h"
28
#include "card.h"
29
#include "mixer.h"
30
#include "mixer_quirks.h"
31
#include "midi.h"
32
#include "quirks.h"
33
#include "helper.h"
34
#include "endpoint.h"
35
#include "pcm.h"
36
#include "clock.h"
37
38
/*
39
* handle the quirks for the contained interfaces
40
*/
41
static int create_composite_quirk(struct snd_usb_audio *chip,
42
struct usb_interface *iface,
43
struct usb_driver *driver,
44
const struct snd_usb_audio_quirk *quirk)
45
{
46
int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
47
int err;
48
49
for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
50
iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
51
if (!iface)
52
continue;
53
if (quirk->ifnum != probed_ifnum &&
54
usb_interface_claimed(iface))
55
continue;
56
err = snd_usb_create_quirk(chip, iface, driver, quirk);
57
if (err < 0)
58
return err;
59
if (quirk->ifnum != probed_ifnum)
60
usb_driver_claim_interface(driver, iface, (void *)-1L);
61
}
62
return 0;
63
}
64
65
static int ignore_interface_quirk(struct snd_usb_audio *chip,
66
struct usb_interface *iface,
67
struct usb_driver *driver,
68
const struct snd_usb_audio_quirk *quirk)
69
{
70
return 0;
71
}
72
73
74
/*
75
* Allow alignment on audio sub-slot (channel samples) rather than
76
* on audio slots (audio frames)
77
*/
78
static int create_align_transfer_quirk(struct snd_usb_audio *chip,
79
struct usb_interface *iface,
80
struct usb_driver *driver,
81
const struct snd_usb_audio_quirk *quirk)
82
{
83
chip->txfr_quirk = 1;
84
return 1; /* Continue with creating streams and mixer */
85
}
86
87
static int create_any_midi_quirk(struct snd_usb_audio *chip,
88
struct usb_interface *intf,
89
struct usb_driver *driver,
90
const struct snd_usb_audio_quirk *quirk)
91
{
92
return snd_usbmidi_create(chip->card, intf, &chip->midi_list, quirk);
93
}
94
95
/*
96
* create a stream for an interface with proper descriptors
97
*/
98
static int create_standard_audio_quirk(struct snd_usb_audio *chip,
99
struct usb_interface *iface,
100
struct usb_driver *driver,
101
const struct snd_usb_audio_quirk *quirk)
102
{
103
struct usb_host_interface *alts;
104
struct usb_interface_descriptor *altsd;
105
int err;
106
107
alts = &iface->altsetting[0];
108
altsd = get_iface_desc(alts);
109
err = snd_usb_parse_audio_endpoints(chip, altsd->bInterfaceNumber);
110
if (err < 0) {
111
snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
112
altsd->bInterfaceNumber, err);
113
return err;
114
}
115
/* reset the current interface */
116
usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
117
return 0;
118
}
119
120
/*
121
* create a stream for an endpoint/altsetting without proper descriptors
122
*/
123
static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
124
struct usb_interface *iface,
125
struct usb_driver *driver,
126
const struct snd_usb_audio_quirk *quirk)
127
{
128
struct audioformat *fp;
129
struct usb_host_interface *alts;
130
int stream, err;
131
unsigned *rate_table = NULL;
132
133
fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
134
if (! fp) {
135
snd_printk(KERN_ERR "cannot memdup\n");
136
return -ENOMEM;
137
}
138
if (fp->nr_rates > 0) {
139
rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
140
if (!rate_table) {
141
kfree(fp);
142
return -ENOMEM;
143
}
144
memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates);
145
fp->rate_table = rate_table;
146
}
147
148
stream = (fp->endpoint & USB_DIR_IN)
149
? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
150
err = snd_usb_add_audio_endpoint(chip, stream, fp);
151
if (err < 0) {
152
kfree(fp);
153
kfree(rate_table);
154
return err;
155
}
156
if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
157
fp->altset_idx >= iface->num_altsetting) {
158
kfree(fp);
159
kfree(rate_table);
160
return -EINVAL;
161
}
162
alts = &iface->altsetting[fp->altset_idx];
163
fp->datainterval = snd_usb_parse_datainterval(chip, alts);
164
fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
165
usb_set_interface(chip->dev, fp->iface, 0);
166
snd_usb_init_pitch(chip, fp->iface, alts, fp);
167
snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max);
168
return 0;
169
}
170
171
/*
172
* Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
173
* The only way to detect the sample rate is by looking at wMaxPacketSize.
174
*/
175
static int create_uaxx_quirk(struct snd_usb_audio *chip,
176
struct usb_interface *iface,
177
struct usb_driver *driver,
178
const struct snd_usb_audio_quirk *quirk)
179
{
180
static const struct audioformat ua_format = {
181
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
182
.channels = 2,
183
.fmt_type = UAC_FORMAT_TYPE_I,
184
.altsetting = 1,
185
.altset_idx = 1,
186
.rates = SNDRV_PCM_RATE_CONTINUOUS,
187
};
188
struct usb_host_interface *alts;
189
struct usb_interface_descriptor *altsd;
190
struct audioformat *fp;
191
int stream, err;
192
193
/* both PCM and MIDI interfaces have 2 or more altsettings */
194
if (iface->num_altsetting < 2)
195
return -ENXIO;
196
alts = &iface->altsetting[1];
197
altsd = get_iface_desc(alts);
198
199
if (altsd->bNumEndpoints == 2) {
200
static const struct snd_usb_midi_endpoint_info ua700_ep = {
201
.out_cables = 0x0003,
202
.in_cables = 0x0003
203
};
204
static const struct snd_usb_audio_quirk ua700_quirk = {
205
.type = QUIRK_MIDI_FIXED_ENDPOINT,
206
.data = &ua700_ep
207
};
208
static const struct snd_usb_midi_endpoint_info uaxx_ep = {
209
.out_cables = 0x0001,
210
.in_cables = 0x0001
211
};
212
static const struct snd_usb_audio_quirk uaxx_quirk = {
213
.type = QUIRK_MIDI_FIXED_ENDPOINT,
214
.data = &uaxx_ep
215
};
216
const struct snd_usb_audio_quirk *quirk =
217
chip->usb_id == USB_ID(0x0582, 0x002b)
218
? &ua700_quirk : &uaxx_quirk;
219
return snd_usbmidi_create(chip->card, iface,
220
&chip->midi_list, quirk);
221
}
222
223
if (altsd->bNumEndpoints != 1)
224
return -ENXIO;
225
226
fp = kmalloc(sizeof(*fp), GFP_KERNEL);
227
if (!fp)
228
return -ENOMEM;
229
memcpy(fp, &ua_format, sizeof(*fp));
230
231
fp->iface = altsd->bInterfaceNumber;
232
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
233
fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
234
fp->datainterval = 0;
235
fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
236
237
switch (fp->maxpacksize) {
238
case 0x120:
239
fp->rate_max = fp->rate_min = 44100;
240
break;
241
case 0x138:
242
case 0x140:
243
fp->rate_max = fp->rate_min = 48000;
244
break;
245
case 0x258:
246
case 0x260:
247
fp->rate_max = fp->rate_min = 96000;
248
break;
249
default:
250
snd_printk(KERN_ERR "unknown sample rate\n");
251
kfree(fp);
252
return -ENXIO;
253
}
254
255
stream = (fp->endpoint & USB_DIR_IN)
256
? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
257
err = snd_usb_add_audio_endpoint(chip, stream, fp);
258
if (err < 0) {
259
kfree(fp);
260
return err;
261
}
262
usb_set_interface(chip->dev, fp->iface, 0);
263
return 0;
264
}
265
266
/*
267
* Create a standard mixer for the specified interface.
268
*/
269
static int create_standard_mixer_quirk(struct snd_usb_audio *chip,
270
struct usb_interface *iface,
271
struct usb_driver *driver,
272
const struct snd_usb_audio_quirk *quirk)
273
{
274
if (quirk->ifnum < 0)
275
return 0;
276
277
return snd_usb_create_mixer(chip, quirk->ifnum, 0);
278
}
279
280
/*
281
* audio-interface quirks
282
*
283
* returns zero if no standard audio/MIDI parsing is needed.
284
* returns a positive value if standard audio/midi interfaces are parsed
285
* after this.
286
* returns a negative value at error.
287
*/
288
int snd_usb_create_quirk(struct snd_usb_audio *chip,
289
struct usb_interface *iface,
290
struct usb_driver *driver,
291
const struct snd_usb_audio_quirk *quirk)
292
{
293
typedef int (*quirk_func_t)(struct snd_usb_audio *,
294
struct usb_interface *,
295
struct usb_driver *,
296
const struct snd_usb_audio_quirk *);
297
static const quirk_func_t quirk_funcs[] = {
298
[QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
299
[QUIRK_COMPOSITE] = create_composite_quirk,
300
[QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
301
[QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
302
[QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
303
[QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
304
[QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
305
[QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk,
306
[QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
307
[QUIRK_MIDI_CME] = create_any_midi_quirk,
308
[QUIRK_MIDI_AKAI] = create_any_midi_quirk,
309
[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
310
[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
311
[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
312
[QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk,
313
[QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
314
};
315
316
if (quirk->type < QUIRK_TYPE_COUNT) {
317
return quirk_funcs[quirk->type](chip, iface, driver, quirk);
318
} else {
319
snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
320
return -ENXIO;
321
}
322
}
323
324
/*
325
* boot quirks
326
*/
327
328
#define EXTIGY_FIRMWARE_SIZE_OLD 794
329
#define EXTIGY_FIRMWARE_SIZE_NEW 483
330
331
static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
332
{
333
struct usb_host_config *config = dev->actconfig;
334
int err;
335
336
if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
337
le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
338
snd_printdd("sending Extigy boot sequence...\n");
339
/* Send message to force it to reconnect with full interface. */
340
err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
341
0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000);
342
if (err < 0) snd_printdd("error sending boot message: %d\n", err);
343
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
344
&dev->descriptor, sizeof(dev->descriptor));
345
config = dev->actconfig;
346
if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
347
err = usb_reset_configuration(dev);
348
if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
349
snd_printdd("extigy_boot: new boot length = %d\n",
350
le16_to_cpu(get_cfg_desc(config)->wTotalLength));
351
return -ENODEV; /* quit this anyway */
352
}
353
return 0;
354
}
355
356
static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
357
{
358
u8 buf = 1;
359
360
snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
361
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
362
0, 0, &buf, 1, 1000);
363
if (buf == 0) {
364
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
365
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
366
1, 2000, NULL, 0, 1000);
367
return -ENODEV;
368
}
369
return 0;
370
}
371
372
/*
373
* C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
374
* documented in the device's data sheet.
375
*/
376
static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value)
377
{
378
u8 buf[4];
379
buf[0] = 0x20;
380
buf[1] = value & 0xff;
381
buf[2] = (value >> 8) & 0xff;
382
buf[3] = reg;
383
return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
384
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
385
0, 0, &buf, 4, 1000);
386
}
387
388
static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
389
{
390
/*
391
* Enable line-out driver mode, set headphone source to front
392
* channels, enable stereo mic.
393
*/
394
return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
395
}
396
397
/*
398
* C-Media CM6206 is based on CM106 with two additional
399
* registers that are not documented in the data sheet.
400
* Values here are chosen based on sniffing USB traffic
401
* under Windows.
402
*/
403
static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
404
{
405
int err, reg;
406
int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
407
408
for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
409
err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
410
if (err < 0)
411
return err;
412
}
413
414
return err;
415
}
416
417
/*
418
* This call will put the synth in "USB send" mode, i.e it will send MIDI
419
* messages through USB (this is disabled at startup). The synth will
420
* acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
421
* sign on its LCD. Values here are chosen based on sniffing USB traffic
422
* under Windows.
423
*/
424
static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
425
{
426
int err, actual_length;
427
428
/* "midi send" enable */
429
static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
430
431
void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
432
if (!buf)
433
return -ENOMEM;
434
err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
435
ARRAY_SIZE(seq), &actual_length, 1000);
436
kfree(buf);
437
if (err < 0)
438
return err;
439
440
return 0;
441
}
442
443
/*
444
* Some sound cards from Native Instruments are in fact compliant to the USB
445
* audio standard of version 2 and other approved USB standards, even though
446
* they come up as vendor-specific device when first connected.
447
*
448
* However, they can be told to come up with a new set of descriptors
449
* upon their next enumeration, and the interfaces announced by the new
450
* descriptors will then be handled by the kernel's class drivers. As the
451
* product ID will also change, no further checks are required.
452
*/
453
454
static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
455
{
456
int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
457
0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
458
cpu_to_le16(1), 0, NULL, 0, 1000);
459
460
if (ret < 0)
461
return ret;
462
463
usb_reset_device(dev);
464
465
/* return -EAGAIN, so the creation of an audio interface for this
466
* temporary device is aborted. The device will reconnect with a
467
* new product ID */
468
return -EAGAIN;
469
}
470
471
/*
472
* Setup quirks
473
*/
474
#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
475
#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */
476
#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
477
#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
478
#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */
479
#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */
480
#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */
481
#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */
482
#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */
483
#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */
484
485
static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
486
int iface,
487
int altno)
488
{
489
/* Reset ALL ifaces to 0 altsetting.
490
* Call it for every possible altsetting of every interface.
491
*/
492
usb_set_interface(chip->dev, iface, 0);
493
494
if (chip->setup & AUDIOPHILE_SET) {
495
if ((chip->setup & AUDIOPHILE_SET_DTS)
496
&& altno != 6)
497
return 1; /* skip this altsetting */
498
if ((chip->setup & AUDIOPHILE_SET_96K)
499
&& altno != 1)
500
return 1; /* skip this altsetting */
501
if ((chip->setup & AUDIOPHILE_SET_MASK) ==
502
AUDIOPHILE_SET_24B_48K_DI && altno != 2)
503
return 1; /* skip this altsetting */
504
if ((chip->setup & AUDIOPHILE_SET_MASK) ==
505
AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
506
return 1; /* skip this altsetting */
507
if ((chip->setup & AUDIOPHILE_SET_MASK) ==
508
AUDIOPHILE_SET_16B_48K_DI && altno != 4)
509
return 1; /* skip this altsetting */
510
if ((chip->setup & AUDIOPHILE_SET_MASK) ==
511
AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
512
return 1; /* skip this altsetting */
513
}
514
515
return 0; /* keep this altsetting */
516
}
517
518
int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
519
int iface,
520
int altno)
521
{
522
/* audiophile usb: skip altsets incompatible with device_setup */
523
if (chip->usb_id == USB_ID(0x0763, 0x2003))
524
return audiophile_skip_setting_quirk(chip, iface, altno);
525
526
return 0;
527
}
528
529
int snd_usb_apply_boot_quirk(struct usb_device *dev,
530
struct usb_interface *intf,
531
const struct snd_usb_audio_quirk *quirk)
532
{
533
u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
534
le16_to_cpu(dev->descriptor.idProduct));
535
536
switch (id) {
537
case USB_ID(0x041e, 0x3000):
538
/* SB Extigy needs special boot-up sequence */
539
/* if more models come, this will go to the quirk list. */
540
return snd_usb_extigy_boot_quirk(dev, intf);
541
542
case USB_ID(0x041e, 0x3020):
543
/* SB Audigy 2 NX needs its own boot-up magic, too */
544
return snd_usb_audigy2nx_boot_quirk(dev);
545
546
case USB_ID(0x10f5, 0x0200):
547
/* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
548
return snd_usb_cm106_boot_quirk(dev);
549
550
case USB_ID(0x0d8c, 0x0102):
551
/* C-Media CM6206 / CM106-Like Sound Device */
552
case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
553
return snd_usb_cm6206_boot_quirk(dev);
554
555
case USB_ID(0x133e, 0x0815):
556
/* Access Music VirusTI Desktop */
557
return snd_usb_accessmusic_boot_quirk(dev);
558
559
case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
560
case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
561
case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
562
return snd_usb_nativeinstruments_boot_quirk(dev);
563
}
564
565
return 0;
566
}
567
568
/*
569
* check if the device uses big-endian samples
570
*/
571
int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
572
{
573
switch (chip->usb_id) {
574
case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
575
if (fp->endpoint & USB_DIR_IN)
576
return 1;
577
break;
578
case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
579
if (chip->setup == 0x00 ||
580
fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
581
return 1;
582
}
583
return 0;
584
}
585
586
/*
587
* For E-Mu 0404USB/0202USB/TrackerPre/0204 sample rate should be set for device,
588
* not for interface.
589
*/
590
591
enum {
592
EMU_QUIRK_SR_44100HZ = 0,
593
EMU_QUIRK_SR_48000HZ,
594
EMU_QUIRK_SR_88200HZ,
595
EMU_QUIRK_SR_96000HZ,
596
EMU_QUIRK_SR_176400HZ,
597
EMU_QUIRK_SR_192000HZ
598
};
599
600
static void set_format_emu_quirk(struct snd_usb_substream *subs,
601
struct audioformat *fmt)
602
{
603
unsigned char emu_samplerate_id = 0;
604
605
/* When capture is active
606
* sample rate shouldn't be changed
607
* by playback substream
608
*/
609
if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
610
if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
611
return;
612
}
613
614
switch (fmt->rate_min) {
615
case 48000:
616
emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
617
break;
618
case 88200:
619
emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
620
break;
621
case 96000:
622
emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
623
break;
624
case 176400:
625
emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
626
break;
627
case 192000:
628
emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
629
break;
630
default:
631
emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
632
break;
633
}
634
snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
635
}
636
637
void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
638
struct audioformat *fmt)
639
{
640
switch (subs->stream->chip->usb_id) {
641
case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
642
case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
643
case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
644
case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
645
set_format_emu_quirk(subs, fmt);
646
break;
647
}
648
}
649
650
651