aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-05-22 04:01:29 -0400
committerTakashi Iwai <tiwai@suse.de>2011-05-22 04:01:29 -0400
commit02e5fbf622aabf68bdc02282a17a3aeed054237a (patch)
tree60f2d4e09464dbf338c832bb39f861f29779b86b /sound/usb
parentb759b3ac9aee3afb01c21b603970ebb200c8048e (diff)
parentbfe9fc8aebc997ce8bcf8ac0586c84a247812064 (diff)
Merge branch 'topic/misc' into for-linus
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/6fire/control.c105
-rw-r--r--sound/usb/6fire/control.h17
-rw-r--r--sound/usb/6fire/firmware.c73
-rw-r--r--sound/usb/6fire/pcm.c97
-rw-r--r--sound/usb/Kconfig10
-rw-r--r--sound/usb/clock.c11
-rw-r--r--sound/usb/debug.h2
-rw-r--r--sound/usb/format.c1
-rw-r--r--sound/usb/mixer.c10
-rw-r--r--sound/usb/mixer_quirks.c12
-rw-r--r--sound/usb/quirks-table.h47
-rw-r--r--sound/usb/quirks.c1
12 files changed, 273 insertions, 113 deletions
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c
index 24846351118..ac828eff1a6 100644
--- a/sound/usb/6fire/control.c
+++ b/sound/usb/6fire/control.c
@@ -65,6 +65,15 @@ init_data[] = {
65 { 0 } /* TERMINATING ENTRY */ 65 { 0 } /* TERMINATING ENTRY */
66}; 66};
67 67
68static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
69/* values to write to soundcard register for all samplerates */
70static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
71static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
72
73enum {
74 DIGITAL_THRU_ONLY_SAMPLERATE = 3
75};
76
68static void usb6fire_control_master_vol_update(struct control_runtime *rt) 77static void usb6fire_control_master_vol_update(struct control_runtime *rt)
69{ 78{
70 struct comm_runtime *comm_rt = rt->chip->comm; 79 struct comm_runtime *comm_rt = rt->chip->comm;
@@ -95,6 +104,67 @@ static void usb6fire_control_opt_coax_update(struct control_runtime *rt)
95 } 104 }
96} 105}
97 106
107static int usb6fire_control_set_rate(struct control_runtime *rt, int rate)
108{
109 int ret;
110 struct usb_device *device = rt->chip->dev;
111 struct comm_runtime *comm_rt = rt->chip->comm;
112
113 if (rate < 0 || rate >= CONTROL_N_RATES)
114 return -EINVAL;
115
116 ret = usb_set_interface(device, 1, rates_altsetting[rate]);
117 if (ret < 0)
118 return ret;
119
120 /* set soundcard clock */
121 ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rate],
122 rates_6fire_vh[rate]);
123 if (ret < 0)
124 return ret;
125
126 return 0;
127}
128
129static int usb6fire_control_set_channels(
130 struct control_runtime *rt, int n_analog_out,
131 int n_analog_in, bool spdif_out, bool spdif_in)
132{
133 int ret;
134 struct comm_runtime *comm_rt = rt->chip->comm;
135
136 /* enable analog inputs and outputs
137 * (one bit per stereo-channel) */
138 ret = comm_rt->write16(comm_rt, 0x02, 0x02,
139 (1 << (n_analog_out / 2)) - 1,
140 (1 << (n_analog_in / 2)) - 1);
141 if (ret < 0)
142 return ret;
143
144 /* disable digital inputs and outputs */
145 /* TODO: use spdif_x to enable/disable digital channels */
146 ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
147 if (ret < 0)
148 return ret;
149
150 return 0;
151}
152
153static int usb6fire_control_streaming_update(struct control_runtime *rt)
154{
155 struct comm_runtime *comm_rt = rt->chip->comm;
156
157 if (comm_rt) {
158 if (!rt->usb_streaming && rt->digital_thru_switch)
159 usb6fire_control_set_rate(rt,
160 DIGITAL_THRU_ONLY_SAMPLERATE);
161 return comm_rt->write16(comm_rt, 0x02, 0x00, 0x00,
162 (rt->usb_streaming ? 0x01 : 0x00) |
163 (rt->digital_thru_switch ? 0x08 : 0x00));
164 }
165 return -EINVAL;
166}
167
98static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, 168static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol,
99 struct snd_ctl_elem_info *uinfo) 169 struct snd_ctl_elem_info *uinfo)
100{ 170{
@@ -195,6 +265,28 @@ static int usb6fire_control_opt_coax_get(struct snd_kcontrol *kcontrol,
195 return 0; 265 return 0;
196} 266}
197 267
268static int usb6fire_control_digital_thru_put(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol)
270{
271 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
272 int changed = 0;
273
274 if (rt->digital_thru_switch != ucontrol->value.integer.value[0]) {
275 rt->digital_thru_switch = ucontrol->value.integer.value[0];
276 usb6fire_control_streaming_update(rt);
277 changed = 1;
278 }
279 return changed;
280}
281
282static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol,
283 struct snd_ctl_elem_value *ucontrol)
284{
285 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
286 ucontrol->value.integer.value[0] = rt->digital_thru_switch;
287 return 0;
288}
289
198static struct __devinitdata snd_kcontrol_new elements[] = { 290static struct __devinitdata snd_kcontrol_new elements[] = {
199 { 291 {
200 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -223,6 +315,15 @@ static struct __devinitdata snd_kcontrol_new elements[] = {
223 .get = usb6fire_control_opt_coax_get, 315 .get = usb6fire_control_opt_coax_get,
224 .put = usb6fire_control_opt_coax_put 316 .put = usb6fire_control_opt_coax_put
225 }, 317 },
318 {
319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
320 .name = "Digital Thru Playback Route",
321 .index = 0,
322 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
323 .info = snd_ctl_boolean_mono_info,
324 .get = usb6fire_control_digital_thru_get,
325 .put = usb6fire_control_digital_thru_put
326 },
226 {} 327 {}
227}; 328};
228 329
@@ -238,6 +339,9 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip)
238 return -ENOMEM; 339 return -ENOMEM;
239 340
240 rt->chip = chip; 341 rt->chip = chip;
342 rt->update_streaming = usb6fire_control_streaming_update;
343 rt->set_rate = usb6fire_control_set_rate;
344 rt->set_channels = usb6fire_control_set_channels;
241 345
242 i = 0; 346 i = 0;
243 while (init_data[i].type) { 347 while (init_data[i].type) {
@@ -249,6 +353,7 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip)
249 usb6fire_control_opt_coax_update(rt); 353 usb6fire_control_opt_coax_update(rt);
250 usb6fire_control_line_phono_update(rt); 354 usb6fire_control_line_phono_update(rt);
251 usb6fire_control_master_vol_update(rt); 355 usb6fire_control_master_vol_update(rt);
356 usb6fire_control_streaming_update(rt);
252 357
253 i = 0; 358 i = 0;
254 while (elements[i].name) { 359 while (elements[i].name) {
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h
index b534c777ab0..8f5aeead2e3 100644
--- a/sound/usb/6fire/control.h
+++ b/sound/usb/6fire/control.h
@@ -21,12 +21,29 @@ enum {
21 CONTROL_MAX_ELEMENTS = 32 21 CONTROL_MAX_ELEMENTS = 32
22}; 22};
23 23
24enum {
25 CONTROL_RATE_44KHZ,
26 CONTROL_RATE_48KHZ,
27 CONTROL_RATE_88KHZ,
28 CONTROL_RATE_96KHZ,
29 CONTROL_RATE_176KHZ,
30 CONTROL_RATE_192KHZ,
31 CONTROL_N_RATES
32};
33
24struct control_runtime { 34struct control_runtime {
35 int (*update_streaming)(struct control_runtime *rt);
36 int (*set_rate)(struct control_runtime *rt, int rate);
37 int (*set_channels)(struct control_runtime *rt, int n_analog_out,
38 int n_analog_in, bool spdif_out, bool spdif_in);
39
25 struct sfire_chip *chip; 40 struct sfire_chip *chip;
26 41
27 struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS]; 42 struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS];
28 bool opt_coax_switch; 43 bool opt_coax_switch;
29 bool line_phono_switch; 44 bool line_phono_switch;
45 bool digital_thru_switch;
46 bool usb_streaming;
30 u8 master_vol; 47 u8 master_vol;
31}; 48};
32 49
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index 86c1a310376..d47beffedb0 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -3,12 +3,6 @@
3 * 3 *
4 * Firmware loader 4 * Firmware loader
5 * 5 *
6 * Currently not working for all devices. To be able to use the device
7 * in linux, it is also possible to let the windows driver upload the firmware.
8 * For that, start the computer in windows and reboot.
9 * As long as the device is connected to the power supply, no firmware reload
10 * needs to be performed.
11 *
12 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
13 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
14 * Version: 0.3.0 8 * Version: 0.3.0
@@ -21,6 +15,7 @@
21 */ 15 */
22 16
23#include <linux/firmware.h> 17#include <linux/firmware.h>
18#include <linux/bitrev.h>
24 19
25#include "firmware.h" 20#include "firmware.h"
26#include "chip.h" 21#include "chip.h"
@@ -33,32 +28,6 @@ enum {
33 FPGA_BUFSIZE = 512, FPGA_EP = 2 28 FPGA_BUFSIZE = 512, FPGA_EP = 2
34}; 29};
35 30
36static const u8 BIT_REVERSE_TABLE[256] = {
37 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50,
38 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8,
39 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04,
40 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4,
41 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c,
42 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82,
43 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32,
44 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
45 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46,
46 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6,
47 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e,
48 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
49 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71,
50 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99,
51 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25,
52 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
53 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d,
54 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3,
55 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b,
56 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb,
57 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67,
58 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f,
59 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f,
60 0xbf, 0x7f, 0xff };
61
62/* 31/*
63 * wMaxPacketSize of pcm endpoints. 32 * wMaxPacketSize of pcm endpoints.
64 * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c 33 * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c
@@ -72,6 +41,10 @@ static const u8 ep_w_max_packet_size[] = {
72 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */ 41 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
73}; 42};
74 43
44static const u8 known_fw_versions[][4] = {
45 { 0x03, 0x01, 0x0b, 0x00 }
46};
47
75struct ihex_record { 48struct ihex_record {
76 u16 address; 49 u16 address;
77 u8 len; 50 u8 len;
@@ -340,7 +313,7 @@ static int usb6fire_fw_fpga_upload(
340 313
341 while (c != end) { 314 while (c != end) {
342 for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++) 315 for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++)
343 buffer[i] = BIT_REVERSE_TABLE[(u8) *c]; 316 buffer[i] = byte_rev_table[(u8) *c];
344 317
345 ret = usb6fire_fw_fpga_write(device, buffer, i); 318 ret = usb6fire_fw_fpga_write(device, buffer, i);
346 if (ret < 0) { 319 if (ret < 0) {
@@ -363,6 +336,25 @@ static int usb6fire_fw_fpga_upload(
363 return 0; 336 return 0;
364} 337}
365 338
339/* check, if the firmware version the devices has currently loaded
340 * is known by this driver. 'version' needs to have 4 bytes version
341 * info data. */
342static int usb6fire_fw_check(u8 *version)
343{
344 int i;
345
346 for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++)
347 if (!memcmp(version, known_fw_versions + i, 4))
348 return 0;
349
350 snd_printk(KERN_ERR PREFIX "invalid fimware version in device: "
351 "%02x %02x %02x %02x. "
352 "please reconnect to power. if this failure "
353 "still happens, check your firmware installation.",
354 version[0], version[1], version[2], version[3]);
355 return -EINVAL;
356}
357
366int usb6fire_fw_init(struct usb_interface *intf) 358int usb6fire_fw_init(struct usb_interface *intf)
367{ 359{
368 int i; 360 int i;
@@ -378,9 +370,7 @@ int usb6fire_fw_init(struct usb_interface *intf)
378 "firmware state.\n"); 370 "firmware state.\n");
379 return ret; 371 return ret;
380 } 372 }
381 if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55 373 if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) {
382 || buffer[4] != 0x03 || buffer[5] != 0x01 || buffer[7]
383 != 0x00) {
384 snd_printk(KERN_ERR PREFIX "unknown device firmware state " 374 snd_printk(KERN_ERR PREFIX "unknown device firmware state "
385 "received from device: "); 375 "received from device: ");
386 for (i = 0; i < 8; i++) 376 for (i = 0; i < 8; i++)
@@ -389,7 +379,7 @@ int usb6fire_fw_init(struct usb_interface *intf)
389 return -EIO; 379 return -EIO;
390 } 380 }
391 /* do we need fpga loader ezusb firmware? */ 381 /* do we need fpga loader ezusb firmware? */
392 if (buffer[3] == 0x01 && buffer[6] == 0x19) { 382 if (buffer[3] == 0x01) {
393 ret = usb6fire_fw_ezusb_upload(intf, 383 ret = usb6fire_fw_ezusb_upload(intf,
394 "6fire/dmx6firel2.ihx", 0, NULL, 0); 384 "6fire/dmx6firel2.ihx", 0, NULL, 0);
395 if (ret < 0) 385 if (ret < 0)
@@ -397,7 +387,10 @@ int usb6fire_fw_init(struct usb_interface *intf)
397 return FW_NOT_READY; 387 return FW_NOT_READY;
398 } 388 }
399 /* do we need fpga firmware and application ezusb firmware? */ 389 /* do we need fpga firmware and application ezusb firmware? */
400 else if (buffer[3] == 0x02 && buffer[6] == 0x0b) { 390 else if (buffer[3] == 0x02) {
391 ret = usb6fire_fw_check(buffer + 4);
392 if (ret < 0)
393 return ret;
401 ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); 394 ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin");
402 if (ret < 0) 395 if (ret < 0)
403 return ret; 396 return ret;
@@ -410,8 +403,8 @@ int usb6fire_fw_init(struct usb_interface *intf)
410 return FW_NOT_READY; 403 return FW_NOT_READY;
411 } 404 }
412 /* all fw loaded? */ 405 /* all fw loaded? */
413 else if (buffer[3] == 0x03 && buffer[6] == 0x0b) 406 else if (buffer[3] == 0x03)
414 return 0; 407 return usb6fire_fw_check(buffer + 4);
415 /* unknown data? */ 408 /* unknown data? */
416 else { 409 else {
417 snd_printk(KERN_ERR PREFIX "unknown device firmware state " 410 snd_printk(KERN_ERR PREFIX "unknown device firmware state "
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index ba62c7468ba..b137b25865c 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -17,26 +17,23 @@
17#include "pcm.h" 17#include "pcm.h"
18#include "chip.h" 18#include "chip.h"
19#include "comm.h" 19#include "comm.h"
20#include "control.h"
20 21
21enum { 22enum {
22 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4 23 OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4
23}; 24};
24 25
25/* keep next two synced with 26/* keep next two synced with
26 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE */ 27 * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE
28 * and CONTROL_RATE_XXX in control.h */
27static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 }; 29static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 };
28static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 }; 30static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 };
29static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 }; 31static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
30static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
31static const int rates_alsaid[] = { 32static const int rates_alsaid[] = {
32 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000, 33 SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000,
33 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000, 34 SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000,
34 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 }; 35 SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 };
35 36
36/* values to write to soundcard register for all samplerates */
37static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
38static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
39
40enum { /* settings for pcm */ 37enum { /* settings for pcm */
41 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024 38 OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024
42}; 39};
@@ -48,15 +45,6 @@ enum { /* pcm streaming states */
48 STREAM_STOPPING 45 STREAM_STOPPING
49}; 46};
50 47
51enum { /* pcm sample rates (also index into RATES_XXX[]) */
52 RATE_44KHZ,
53 RATE_48KHZ,
54 RATE_88KHZ,
55 RATE_96KHZ,
56 RATE_176KHZ,
57 RATE_192KHZ
58};
59
60static const struct snd_pcm_hardware pcm_hw = { 48static const struct snd_pcm_hardware pcm_hw = {
61 .info = SNDRV_PCM_INFO_MMAP | 49 .info = SNDRV_PCM_INFO_MMAP |
62 SNDRV_PCM_INFO_INTERLEAVED | 50 SNDRV_PCM_INFO_INTERLEAVED |
@@ -64,7 +52,7 @@ static const struct snd_pcm_hardware pcm_hw = {
64 SNDRV_PCM_INFO_MMAP_VALID | 52 SNDRV_PCM_INFO_MMAP_VALID |
65 SNDRV_PCM_INFO_BATCH, 53 SNDRV_PCM_INFO_BATCH,
66 54
67 .formats = SNDRV_PCM_FMTBIT_S24_LE, 55 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
68 56
69 .rates = SNDRV_PCM_RATE_44100 | 57 .rates = SNDRV_PCM_RATE_44100 |
70 SNDRV_PCM_RATE_48000 | 58 SNDRV_PCM_RATE_48000 |
@@ -87,57 +75,34 @@ static const struct snd_pcm_hardware pcm_hw = {
87static int usb6fire_pcm_set_rate(struct pcm_runtime *rt) 75static int usb6fire_pcm_set_rate(struct pcm_runtime *rt)
88{ 76{
89 int ret; 77 int ret;
90 struct usb_device *device = rt->chip->dev; 78 struct control_runtime *ctrl_rt = rt->chip->control;
91 struct comm_runtime *comm_rt = rt->chip->comm;
92 79
93 if (rt->rate >= ARRAY_SIZE(rates)) 80 ctrl_rt->usb_streaming = false;
94 return -EINVAL; 81 ret = ctrl_rt->update_streaming(ctrl_rt);
95 /* disable streaming */
96 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x00);
97 if (ret < 0) { 82 if (ret < 0) {
98 snd_printk(KERN_ERR PREFIX "error stopping streaming while " 83 snd_printk(KERN_ERR PREFIX "error stopping streaming while "
99 "setting samplerate %d.\n", rates[rt->rate]); 84 "setting samplerate %d.\n", rates[rt->rate]);
100 return ret; 85 return ret;
101 } 86 }
102 87
103 ret = usb_set_interface(device, 1, rates_altsetting[rt->rate]); 88 ret = ctrl_rt->set_rate(ctrl_rt, rt->rate);
104 if (ret < 0) {
105 snd_printk(KERN_ERR PREFIX "error setting interface "
106 "altsetting %d for samplerate %d.\n",
107 rates_altsetting[rt->rate], rates[rt->rate]);
108 return ret;
109 }
110
111 /* set soundcard clock */
112 ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rt->rate],
113 rates_6fire_vh[rt->rate]);
114 if (ret < 0) { 89 if (ret < 0) {
115 snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n", 90 snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n",
116 rates[rt->rate]); 91 rates[rt->rate]);
117 return ret; 92 return ret;
118 } 93 }
119 94
120 /* enable analog inputs and outputs 95 ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS,
121 * (one bit per stereo-channel) */ 96 false, false);
122 ret = comm_rt->write16(comm_rt, 0x02, 0x02,
123 (1 << (OUT_N_CHANNELS / 2)) - 1,
124 (1 << (IN_N_CHANNELS / 2)) - 1);
125 if (ret < 0) { 97 if (ret < 0) {
126 snd_printk(KERN_ERR PREFIX "error initializing analog channels " 98 snd_printk(KERN_ERR PREFIX "error initializing channels "
127 "while setting samplerate %d.\n", 99 "while setting samplerate %d.\n",
128 rates[rt->rate]); 100 rates[rt->rate]);
129 return ret; 101 return ret;
130 } 102 }
131 /* disable digital inputs and outputs */
132 ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
133 if (ret < 0) {
134 snd_printk(KERN_ERR PREFIX "error initializing digital "
135 "channels while setting samplerate %d.\n",
136 rates[rt->rate]);
137 return ret;
138 }
139 103
140 ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x01); 104 ctrl_rt->usb_streaming = true;
105 ret = ctrl_rt->update_streaming(ctrl_rt);
141 if (ret < 0) { 106 if (ret < 0) {
142 snd_printk(KERN_ERR PREFIX "error starting streaming while " 107 snd_printk(KERN_ERR PREFIX "error starting streaming while "
143 "setting samplerate %d.\n", rates[rt->rate]); 108 "setting samplerate %d.\n", rates[rt->rate]);
@@ -168,12 +133,15 @@ static struct pcm_substream *usb6fire_pcm_get_substream(
168static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt) 133static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
169{ 134{
170 int i; 135 int i;
136 struct control_runtime *ctrl_rt = rt->chip->control;
171 137
172 if (rt->stream_state != STREAM_DISABLED) { 138 if (rt->stream_state != STREAM_DISABLED) {
173 for (i = 0; i < PCM_N_URBS; i++) { 139 for (i = 0; i < PCM_N_URBS; i++) {
174 usb_kill_urb(&rt->in_urbs[i].instance); 140 usb_kill_urb(&rt->in_urbs[i].instance);
175 usb_kill_urb(&rt->out_urbs[i].instance); 141 usb_kill_urb(&rt->out_urbs[i].instance);
176 } 142 }
143 ctrl_rt->usb_streaming = false;
144 ctrl_rt->update_streaming(ctrl_rt);
177 rt->stream_state = STREAM_DISABLED; 145 rt->stream_state = STREAM_DISABLED;
178 } 146 }
179} 147}
@@ -228,7 +196,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
228 unsigned int total_length = 0; 196 unsigned int total_length = 0;
229 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); 197 struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
230 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; 198 struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
231 u32 *src = (u32 *) urb->buffer; 199 u32 *src = NULL;
232 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off 200 u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
233 * (alsa_rt->frame_bits >> 3)); 201 * (alsa_rt->frame_bits >> 3));
234 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size 202 u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
@@ -244,7 +212,12 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
244 else 212 else
245 frame_count = 0; 213 frame_count = 0;
246 214
247 src = (u32 *) (urb->buffer + total_length); 215 if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
216 src = (u32 *) (urb->buffer + total_length);
217 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
218 src = (u32 *) (urb->buffer - 1 + total_length);
219 else
220 return;
248 src++; /* skip leading 4 bytes of every packet */ 221 src++; /* skip leading 4 bytes of every packet */
249 total_length += urb->packets[i].length; 222 total_length += urb->packets[i].length;
250 for (frame = 0; frame < frame_count; frame++) { 223 for (frame = 0; frame < frame_count; frame++) {
@@ -274,9 +247,18 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub,
274 * (alsa_rt->frame_bits >> 3)); 247 * (alsa_rt->frame_bits >> 3));
275 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size 248 u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
276 * (alsa_rt->frame_bits >> 3)); 249 * (alsa_rt->frame_bits >> 3));
277 u32 *dest = (u32 *) urb->buffer; 250 u32 *dest;
278 int bytes_per_frame = alsa_rt->channels << 2; 251 int bytes_per_frame = alsa_rt->channels << 2;
279 252
253 if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
254 dest = (u32 *) (urb->buffer - 1);
255 else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
256 dest = (u32 *) (urb->buffer);
257 else {
258 snd_printk(KERN_ERR PREFIX "Unknown sample format.");
259 return;
260 }
261
280 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { 262 for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
281 /* at least 4 header bytes for valid packet. 263 /* at least 4 header bytes for valid packet.
282 * after that: 32 bits per sample for analog channels */ 264 * after that: 32 bits per sample for analog channels */
@@ -456,7 +438,7 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
456 /* all substreams closed? if so, stop streaming */ 438 /* all substreams closed? if so, stop streaming */
457 if (!rt->playback.instance && !rt->capture.instance) { 439 if (!rt->playback.instance && !rt->capture.instance) {
458 usb6fire_pcm_stream_stop(rt); 440 usb6fire_pcm_stream_stop(rt);
459 rt->rate = -1; 441 rt->rate = ARRAY_SIZE(rates);
460 } 442 }
461 } 443 }
462 mutex_unlock(&rt->stream_mutex); 444 mutex_unlock(&rt->stream_mutex);
@@ -480,7 +462,6 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
480 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); 462 struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
481 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); 463 struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
482 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; 464 struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
483 int i;
484 int ret; 465 int ret;
485 466
486 if (rt->panic) 467 if (rt->panic)
@@ -493,12 +474,10 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
493 sub->period_off = 0; 474 sub->period_off = 0;
494 475
495 if (rt->stream_state == STREAM_DISABLED) { 476 if (rt->stream_state == STREAM_DISABLED) {
496 for (i = 0; i < ARRAY_SIZE(rates); i++) 477 for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++)
497 if (alsa_rt->rate == rates[i]) { 478 if (alsa_rt->rate == rates[rt->rate])
498 rt->rate = i;
499 break; 479 break;
500 } 480 if (rt->rate == ARRAY_SIZE(rates)) {
501 if (i == ARRAY_SIZE(rates)) {
502 mutex_unlock(&rt->stream_mutex); 481 mutex_unlock(&rt->stream_mutex);
503 snd_printk("invalid rate %d in prepare.\n", 482 snd_printk("invalid rate %d in prepare.\n",
504 alsa_rt->rate); 483 alsa_rt->rate);
@@ -613,7 +592,7 @@ int __devinit usb6fire_pcm_init(struct sfire_chip *chip)
613 592
614 rt->chip = chip; 593 rt->chip = chip;
615 rt->stream_state = STREAM_DISABLED; 594 rt->stream_state = STREAM_DISABLED;
616 rt->rate = -1; 595 rt->rate = ARRAY_SIZE(rates);
617 init_waitqueue_head(&rt->stream_wait_queue); 596 init_waitqueue_head(&rt->stream_wait_queue);
618 mutex_init(&rt->stream_mutex); 597 mutex_init(&rt->stream_mutex);
619 598
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 97724d8fa9f..8beb77563da 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -100,19 +100,17 @@ config SND_USB_US122L
100 100
101config SND_USB_6FIRE 101config SND_USB_6FIRE
102 tristate "TerraTec DMX 6Fire USB" 102 tristate "TerraTec DMX 6Fire USB"
103 depends on EXPERIMENTAL
104 select FW_LOADER 103 select FW_LOADER
104 select BITREVERSE
105 select SND_RAWMIDI 105 select SND_RAWMIDI
106 select SND_PCM 106 select SND_PCM
107 help 107 help
108 Say Y here to include support for TerraTec 6fire DMX USB interface. 108 Say Y here to include support for TerraTec 6fire DMX USB interface.
109 109
110 You will need firmware files in order to be able to use the device 110 You will need firmware files in order to be able to use the device
111 after it has been coldstarted. This driver currently does not support 111 after it has been coldstarted. An install script for the firmware
112 firmware loading for all devices. If you own such a device, 112 and further help can be found at
113 you could start windows and let the windows driver upload 113 http://sixfireusb.sourceforge.net
114 the firmware. As long as you do not unplug your device from power,
115 it should be usable.
116 114
117endif # SND_USB 115endif # SND_USB
118 116
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 7754a103454..075195e8661 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -104,6 +104,15 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
104 int err; 104 int err;
105 unsigned char data; 105 unsigned char data;
106 struct usb_device *dev = chip->dev; 106 struct usb_device *dev = chip->dev;
107 struct uac_clock_source_descriptor *cs_desc =
108 snd_usb_find_clock_source(chip->ctrl_intf, source_id);
109
110 if (!cs_desc)
111 return 0;
112
113 /* If a clock source can't tell us whether it's valid, we assume it is */
114 if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID))
115 return 1;
107 116
108 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, 117 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
109 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 118 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
@@ -114,7 +123,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
114 if (err < 0) { 123 if (err < 0) {
115 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", 124 snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n",
116 __func__, source_id); 125 __func__, source_id);
117 return err; 126 return 0;
118 } 127 }
119 128
120 return !!data; 129 return !!data;
diff --git a/sound/usb/debug.h b/sound/usb/debug.h
index 343ec2d9ee6..58030176f00 100644
--- a/sound/usb/debug.h
+++ b/sound/usb/debug.h
@@ -8,7 +8,7 @@
8#ifdef HW_CONST_DEBUG 8#ifdef HW_CONST_DEBUG
9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args) 9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
10#else 10#else
11#define hwc_debug(fmt, args...) /**/ 11#define hwc_debug(fmt, args...) do { } while(0)
12#endif 12#endif
13 13
14#endif /* __USBAUDIO_DEBUG_H */ 14#endif /* __USBAUDIO_DEBUG_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
index f079b5e2ab2..8d042dce0d1 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -30,6 +30,7 @@
30#include "helper.h" 30#include "helper.h"
31#include "debug.h" 31#include "debug.h"
32#include "clock.h" 32#include "clock.h"
33#include "format.h"
33 34
34/* 35/*
35 * parse the audio format type I descriptor 36 * parse the audio format type I descriptor
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 6ec33b62e6c..eab06edcc9b 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1097,11 +1097,13 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1097 append_ctl_name(kctl, control == UAC_FU_MUTE ? 1097 append_ctl_name(kctl, control == UAC_FU_MUTE ?
1098 " Switch" : " Volume"); 1098 " Switch" : " Volume");
1099 if (control == UAC_FU_VOLUME) { 1099 if (control == UAC_FU_VOLUME) {
1100 kctl->tlv.c = mixer_vol_tlv;
1101 kctl->vd[0].access |=
1102 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1103 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1104 check_mapped_dB(map, cval); 1100 check_mapped_dB(map, cval);
1101 if (cval->dBmin < cval->dBmax) {
1102 kctl->tlv.c = mixer_vol_tlv;
1103 kctl->vd[0].access |=
1104 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1105 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1106 }
1105 } 1107 }
1106 break; 1108 break;
1107 1109
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 73dcc8256bc..9146cffa6ed 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -61,6 +61,7 @@ static const struct rc_config {
61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ 61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ 62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
63 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */ 63 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */
64 { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
64 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ 65 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
65}; 66};
66 67
@@ -188,6 +189,12 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
188 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 189 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
189 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 190 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
190 !value, 0, NULL, 0, 100); 191 !value, 0, NULL, 0, 100);
192 /* USB X-Fi S51 Pro */
193 if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
194 err = snd_usb_ctl_msg(mixer->chip->dev,
195 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
196 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
197 !value, 0, NULL, 0, 100);
191 else 198 else
192 err = snd_usb_ctl_msg(mixer->chip->dev, 199 err = snd_usb_ctl_msg(mixer->chip->dev,
193 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, 200 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
@@ -234,9 +241,13 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
234 /* USB X-Fi S51 doesn't have a CMSS LED */ 241 /* USB X-Fi S51 doesn't have a CMSS LED */
235 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) 242 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
236 continue; 243 continue;
244 /* USB X-Fi S51 Pro doesn't have one either */
245 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
246 continue;
237 if (i > 1 && /* Live24ext has 2 LEDs only */ 247 if (i > 1 && /* Live24ext has 2 LEDs only */
238 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || 248 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
239 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || 249 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
250 mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
240 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) 251 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
241 break; 252 break;
242 err = snd_ctl_add(mixer->chip->card, 253 err = snd_ctl_add(mixer->chip->card,
@@ -512,6 +523,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
512 case USB_ID(0x041e, 0x3020): 523 case USB_ID(0x041e, 0x3020):
513 case USB_ID(0x041e, 0x3040): 524 case USB_ID(0x041e, 0x3040):
514 case USB_ID(0x041e, 0x3042): 525 case USB_ID(0x041e, 0x3042):
526 case USB_ID(0x041e, 0x30df):
515 case USB_ID(0x041e, 0x3048): 527 case USB_ID(0x041e, 0x3048):
516 err = snd_audigy2nx_controls_create(mixer); 528 err = snd_audigy2nx_controls_create(mixer);
517 if (err < 0) 529 if (err < 0)
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index c66d3f64dcf..78792a8900c 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -1651,6 +1651,32 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1651 } 1651 }
1652 } 1652 }
1653}, 1653},
1654{
1655 USB_DEVICE(0x0582, 0x0127),
1656 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1657 /* .vendor_name = "Roland", */
1658 /* .product_name = "GR-55", */
1659 .ifnum = QUIRK_ANY_INTERFACE,
1660 .type = QUIRK_COMPOSITE,
1661 .data = (const struct snd_usb_audio_quirk[]) {
1662 {
1663 .ifnum = 0,
1664 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1665 },
1666 {
1667 .ifnum = 1,
1668 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1669 },
1670 {
1671 .ifnum = 2,
1672 .type = QUIRK_MIDI_STANDARD_INTERFACE
1673 },
1674 {
1675 .ifnum = -1
1676 }
1677 }
1678 }
1679},
1654 1680
1655/* Guillemot devices */ 1681/* Guillemot devices */
1656{ 1682{
@@ -1953,7 +1979,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1953 } 1979 }
1954}, 1980},
1955{ 1981{
1956 USB_DEVICE(0x0763, 0x2080), 1982 USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080),
1957 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1983 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1958 /* .vendor_name = "M-Audio", */ 1984 /* .vendor_name = "M-Audio", */
1959 /* .product_name = "Fast Track Ultra", */ 1985 /* .product_name = "Fast Track Ultra", */
@@ -2020,7 +2046,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2020 } 2046 }
2021}, 2047},
2022{ 2048{
2023 USB_DEVICE(0x0763, 0x2081), 2049 USB_DEVICE_VENDOR_SPEC(0x0763, 0x2081),
2024 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 2050 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2025 /* .vendor_name = "M-Audio", */ 2051 /* .vendor_name = "M-Audio", */
2026 /* .product_name = "Fast Track Ultra 8R", */ 2052 /* .product_name = "Fast Track Ultra 8R", */
@@ -2179,6 +2205,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2179 } 2205 }
2180}, 2206},
2181 2207
2208/* KORG devices */
2209{
2210 USB_DEVICE_VENDOR_SPEC(0x0944, 0x0200),
2211 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2212 .vendor_name = "KORG, Inc.",
2213 /* .product_name = "PANDORA PX5D", */
2214 .ifnum = 3,
2215 .type = QUIRK_MIDI_STANDARD_INTERFACE,
2216 }
2217},
2218
2182/* AKAI devices */ 2219/* AKAI devices */
2183{ 2220{
2184 USB_DEVICE(0x09e8, 0x0062), 2221 USB_DEVICE(0x09e8, 0x0062),
@@ -2332,6 +2369,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2332 2369
2333/* Native Instruments MK2 series */ 2370/* Native Instruments MK2 series */
2334{ 2371{
2372 /* Komplete Audio 6 */
2373 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
2374 .idVendor = 0x17cc,
2375 .idProduct = 0x1000,
2376},
2377{
2335 /* Traktor Audio 6 */ 2378 /* Traktor Audio 6 */
2336 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 2379 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
2337 .idVendor = 0x17cc, 2380 .idVendor = 0x17cc,
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 1b94ec3a336..bd13d725724 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -540,6 +540,7 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
540 /* Access Music VirusTI Desktop */ 540 /* Access Music VirusTI Desktop */
541 return snd_usb_accessmusic_boot_quirk(dev); 541 return snd_usb_accessmusic_boot_quirk(dev);
542 542
543 case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
543 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ 544 case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
544 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ 545 case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
545 return snd_usb_nativeinstruments_boot_quirk(dev); 546 return snd_usb_nativeinstruments_boot_quirk(dev);