aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/usbaudio.c54
-rw-r--r--sound/usb/usbmixer.c27
-rw-r--r--sound/usb/usbmixer_maps.c24
-rw-r--r--sound/usb/usbquirks.h5
4 files changed, 106 insertions, 4 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 1b7f499c549d..49248fa7aef4 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -68,7 +68,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
68static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 68static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
69static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Vendor ID for this card */ 69static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Vendor ID for this card */
70static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */ 70static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */
71static int nrpacks = 4; /* max. number of packets per urb */ 71static int nrpacks = 8; /* max. number of packets per urb */
72static int async_unlink = 1; 72static int async_unlink = 1;
73static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/ 73static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/
74 74
@@ -100,7 +100,7 @@ MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
100 * 100 *
101 */ 101 */
102 102
103#define MAX_PACKS 10 103#define MAX_PACKS 20
104#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ 104#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
105#define MAX_URBS 8 105#define MAX_URBS 8
106#define SYNC_URBS 4 /* always four urbs for sync */ 106#define SYNC_URBS 4 /* always four urbs for sync */
@@ -123,6 +123,7 @@ struct audioformat {
123 unsigned int rate_min, rate_max; /* min/max rates */ 123 unsigned int rate_min, rate_max; /* min/max rates */
124 unsigned int nr_rates; /* number of rate table entries */ 124 unsigned int nr_rates; /* number of rate table entries */
125 unsigned int *rate_table; /* rate table */ 125 unsigned int *rate_table; /* rate table */
126 unsigned int needs_knot; /* any unusual rates? */
126}; 127};
127 128
128struct snd_usb_substream; 129struct snd_usb_substream;
@@ -1759,6 +1760,9 @@ static int check_hw_params_convention(struct snd_usb_substream *subs)
1759 } 1760 }
1760 channels[f->format] |= (1 << f->channels); 1761 channels[f->format] |= (1 << f->channels);
1761 rates[f->format] |= f->rates; 1762 rates[f->format] |= f->rates;
1763 /* needs knot? */
1764 if (f->needs_knot)
1765 goto __out;
1762 } 1766 }
1763 /* check whether channels and rates match for all formats */ 1767 /* check whether channels and rates match for all formats */
1764 cmaster = rmaster = 0; 1768 cmaster = rmaster = 0;
@@ -1799,6 +1803,38 @@ static int check_hw_params_convention(struct snd_usb_substream *subs)
1799 return err; 1803 return err;
1800} 1804}
1801 1805
1806/*
1807 * If the device supports unusual bit rates, does the request meet these?
1808 */
1809static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
1810 struct snd_usb_substream *subs)
1811{
1812 struct list_head *p;
1813 struct snd_pcm_hw_constraint_list constraints_rates;
1814 int err;
1815
1816 list_for_each(p, &subs->fmt_list) {
1817 struct audioformat *fp;
1818 fp = list_entry(p, struct audioformat, list);
1819
1820 if (!fp->needs_knot)
1821 continue;
1822
1823 constraints_rates.count = fp->nr_rates;
1824 constraints_rates.list = fp->rate_table;
1825 constraints_rates.mask = 0;
1826
1827 err = snd_pcm_hw_constraint_list(runtime, 0,
1828 SNDRV_PCM_HW_PARAM_RATE,
1829 &constraints_rates);
1830
1831 if (err < 0)
1832 return err;
1833 }
1834
1835 return 0;
1836}
1837
1802 1838
1803/* 1839/*
1804 * set up the runtime hardware information. 1840 * set up the runtime hardware information.
@@ -1861,6 +1897,8 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
1861 SNDRV_PCM_HW_PARAM_CHANNELS, 1897 SNDRV_PCM_HW_PARAM_CHANNELS,
1862 -1)) < 0) 1898 -1)) < 0)
1863 return err; 1899 return err;
1900 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
1901 return err;
1864 } 1902 }
1865 return 0; 1903 return 0;
1866} 1904}
@@ -2049,7 +2087,7 @@ static struct usb_driver usb_audio_driver = {
2049}; 2087};
2050 2088
2051 2089
2052#if defined(CONFIG_PROCFS) && defined(CONFIG_SND_VERBOSE_PROCFS) 2090#if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS)
2053 2091
2054/* 2092/*
2055 * proc interface for list the supported pcm formats 2093 * proc interface for list the supported pcm formats
@@ -2406,6 +2444,7 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2406 unsigned char *fmt, int offset) 2444 unsigned char *fmt, int offset)
2407{ 2445{
2408 int nr_rates = fmt[offset]; 2446 int nr_rates = fmt[offset];
2447 int found;
2409 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { 2448 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
2410 snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", 2449 snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n",
2411 chip->dev->devnum, fp->iface, fp->altsetting); 2450 chip->dev->devnum, fp->iface, fp->altsetting);
@@ -2428,6 +2467,7 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2428 return -1; 2467 return -1;
2429 } 2468 }
2430 2469
2470 fp->needs_knot = 0;
2431 fp->nr_rates = nr_rates; 2471 fp->nr_rates = nr_rates;
2432 fp->rate_min = fp->rate_max = combine_triple(&fmt[8]); 2472 fp->rate_min = fp->rate_max = combine_triple(&fmt[8]);
2433 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { 2473 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
@@ -2436,13 +2476,19 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2436 fp->rate_min = rate; 2476 fp->rate_min = rate;
2437 else if (rate > fp->rate_max) 2477 else if (rate > fp->rate_max)
2438 fp->rate_max = rate; 2478 fp->rate_max = rate;
2479 found = 0;
2439 for (c = 0; c < (int)ARRAY_SIZE(conv_rates); c++) { 2480 for (c = 0; c < (int)ARRAY_SIZE(conv_rates); c++) {
2440 if (rate == conv_rates[c]) { 2481 if (rate == conv_rates[c]) {
2482 found = 1;
2441 fp->rates |= (1 << c); 2483 fp->rates |= (1 << c);
2442 break; 2484 break;
2443 } 2485 }
2444 } 2486 }
2487 if (!found)
2488 fp->needs_knot = 1;
2445 } 2489 }
2490 if (fp->needs_knot)
2491 fp->rates |= SNDRV_PCM_RATE_KNOT;
2446 } else { 2492 } else {
2447 /* continuous rates */ 2493 /* continuous rates */
2448 fp->rates = SNDRV_PCM_RATE_CONTINUOUS; 2494 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
@@ -3499,7 +3545,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
3499 } 3545 }
3500 usb_chip[chip->index] = NULL; 3546 usb_chip[chip->index] = NULL;
3501 mutex_unlock(&register_mutex); 3547 mutex_unlock(&register_mutex);
3502 snd_card_free(card); 3548 snd_card_free_when_closed(card);
3503 } else { 3549 } else {
3504 mutex_unlock(&register_mutex); 3550 mutex_unlock(&register_mutex);
3505 } 3551 }
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 491e975a0c87..e516d6adbb22 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -37,6 +37,7 @@
37#include <sound/control.h> 37#include <sound/control.h>
38#include <sound/hwdep.h> 38#include <sound/hwdep.h>
39#include <sound/info.h> 39#include <sound/info.h>
40#include <sound/tlv.h>
40 41
41#include "usbaudio.h" 42#include "usbaudio.h"
42 43
@@ -416,6 +417,26 @@ static inline int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channe
416 return set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, value); 417 return set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, value);
417} 418}
418 419
420/*
421 * TLV callback for mixer volume controls
422 */
423static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
424 unsigned int size, unsigned int __user *_tlv)
425{
426 struct usb_mixer_elem_info *cval = kcontrol->private_data;
427 DECLARE_TLV_DB_SCALE(scale, 0, 0, 0);
428
429 if (size < sizeof(scale))
430 return -ENOMEM;
431 /* USB descriptions contain the dB scale in 1/256 dB unit
432 * while ALSA TLV contains in 1/100 dB unit
433 */
434 scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256;
435 scale[3] = (convert_signed_value(cval, cval->res) * 100) / 256;
436 if (copy_to_user(_tlv, scale, sizeof(scale)))
437 return -EFAULT;
438 return 0;
439}
419 440
420/* 441/*
421 * parser routines begin here... 442 * parser routines begin here...
@@ -933,6 +954,12 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
933 } 954 }
934 strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume", 955 strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume",
935 sizeof(kctl->id.name)); 956 sizeof(kctl->id.name));
957 if (control == USB_FEATURE_VOLUME) {
958 kctl->tlv.c = mixer_vol_tlv;
959 kctl->vd[0].access |=
960 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
961 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
962 }
936 break; 963 break;
937 964
938 default: 965 default:
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c
index 37accb68652d..7c4dcb3f436a 100644
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/usbmixer_maps.c
@@ -234,6 +234,26 @@ static struct usbmix_name_map justlink_map[] = {
234 { 0 } /* terminator */ 234 { 0 } /* terminator */
235}; 235};
236 236
237/* TerraTec Aureon 5.1 MkII USB */
238static struct usbmix_name_map aureon_51_2_map[] = {
239 /* 1: IT USB */
240 /* 2: IT Mic */
241 /* 3: IT Line */
242 /* 4: IT SPDIF */
243 /* 5: OT SPDIF */
244 /* 6: OT Speaker */
245 /* 7: OT USB */
246 { 8, "Capture Source" }, /* SU */
247 { 9, "Master Playback" }, /* FU */
248 { 10, "Mic Capture" }, /* FU */
249 { 11, "Line Capture" }, /* FU */
250 { 12, "IEC958 In Capture" }, /* FU */
251 { 13, "Mic Playback" }, /* FU */
252 { 14, "Line Playback" }, /* FU */
253 /* 15: MU */
254 {} /* terminator */
255};
256
237/* 257/*
238 * Control map entries 258 * Control map entries
239 */ 259 */
@@ -276,6 +296,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
276 .id = USB_ID(0x0c45, 0x1158), 296 .id = USB_ID(0x0c45, 0x1158),
277 .map = justlink_map, 297 .map = justlink_map,
278 }, 298 },
299 {
300 .id = USB_ID(0x0ccd, 0x0028),
301 .map = aureon_51_2_map,
302 },
279 { 0 } /* terminator */ 303 { 0 } /* terminator */
280}; 304};
281 305
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 9351846d7a9d..a7e9563a01df 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -123,6 +123,10 @@ YAMAHA_DEVICE(0x103e, NULL),
123YAMAHA_DEVICE(0x103f, NULL), 123YAMAHA_DEVICE(0x103f, NULL),
124YAMAHA_DEVICE(0x1040, NULL), 124YAMAHA_DEVICE(0x1040, NULL),
125YAMAHA_DEVICE(0x1041, NULL), 125YAMAHA_DEVICE(0x1041, NULL),
126YAMAHA_DEVICE(0x1042, NULL),
127YAMAHA_DEVICE(0x1043, NULL),
128YAMAHA_DEVICE(0x1044, NULL),
129YAMAHA_DEVICE(0x1045, NULL),
126YAMAHA_DEVICE(0x2000, "DGP-7"), 130YAMAHA_DEVICE(0x2000, "DGP-7"),
127YAMAHA_DEVICE(0x2001, "DGP-5"), 131YAMAHA_DEVICE(0x2001, "DGP-5"),
128YAMAHA_DEVICE(0x2002, NULL), 132YAMAHA_DEVICE(0x2002, NULL),
@@ -141,6 +145,7 @@ YAMAHA_DEVICE(0x500b, "DME64N"),
141YAMAHA_DEVICE(0x500c, "DME24N"), 145YAMAHA_DEVICE(0x500c, "DME24N"),
142YAMAHA_DEVICE(0x500d, NULL), 146YAMAHA_DEVICE(0x500d, NULL),
143YAMAHA_DEVICE(0x500e, NULL), 147YAMAHA_DEVICE(0x500e, NULL),
148YAMAHA_DEVICE(0x500f, NULL),
144YAMAHA_DEVICE(0x7000, "DTX"), 149YAMAHA_DEVICE(0x7000, "DTX"),
145YAMAHA_DEVICE(0x7010, "UB99"), 150YAMAHA_DEVICE(0x7010, "UB99"),
146#undef YAMAHA_DEVICE 151#undef YAMAHA_DEVICE