aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/usbaudio.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 6fad2c40c77c..4e614ac39f21 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -70,6 +70,7 @@ static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Vendor ID for
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 = 4; /* 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*/
73 74
74module_param_array(index, int, NULL, 0444); 75module_param_array(index, int, NULL, 0444);
75MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); 76MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
@@ -85,6 +86,8 @@ module_param(nrpacks, int, 0644);
85MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); 86MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
86module_param(async_unlink, bool, 0444); 87module_param(async_unlink, bool, 0444);
87MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); 88MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
89module_param_array(device_setup, int, NULL, 0444);
90MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
88 91
89 92
90/* 93/*
@@ -2547,6 +2550,8 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp
2547 return 0; 2550 return 0;
2548} 2551}
2549 2552
2553static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
2554 int iface, int altno);
2550static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) 2555static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2551{ 2556{
2552 struct usb_device *dev; 2557 struct usb_device *dev;
@@ -2581,6 +2586,12 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2581 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? 2586 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
2582 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; 2587 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
2583 altno = altsd->bAlternateSetting; 2588 altno = altsd->bAlternateSetting;
2589
2590 /* audiophile usb: skip altsets incompatible with device_setup
2591 */
2592 if (chip->usb_id == USB_ID(0x0763, 0x2003) &&
2593 audiophile_skip_setting_quirk(chip, iface_no, altno))
2594 continue;
2584 2595
2585 /* get audio formats */ 2596 /* get audio formats */
2586 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); 2597 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL);
@@ -2675,7 +2686,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2675 continue; 2686 continue;
2676 } 2687 }
2677 2688
2678 snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, i, fp->endpoint); 2689 snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, altno, fp->endpoint);
2679 err = add_audio_endpoint(chip, stream, fp); 2690 err = add_audio_endpoint(chip, stream, fp);
2680 if (err < 0) { 2691 if (err < 0) {
2681 kfree(fp->rate_table); 2692 kfree(fp->rate_table);
@@ -3083,6 +3094,45 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
3083 return 0; 3094 return 0;
3084} 3095}
3085 3096
3097/*
3098 * Setup quirks
3099 */
3100#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
3101#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */
3102#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
3103#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
3104#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */
3105#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */
3106#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */
3107#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */
3108#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */
3109#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */
3110
3111static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
3112 int iface, int altno)
3113{
3114 if (device_setup[chip->index] & AUDIOPHILE_SET) {
3115 if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS)
3116 && altno != 6)
3117 return 1; /* skip this altsetting */
3118 if ((device_setup[chip->index] & AUDIOPHILE_SET_96K)
3119 && altno != 1)
3120 return 1; /* skip this altsetting */
3121 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3122 AUDIOPHILE_SET_24B_48K_DI && altno != 2)
3123 return 1; /* skip this altsetting */
3124 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3125 AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
3126 return 1; /* skip this altsetting */
3127 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3128 AUDIOPHILE_SET_16B_48K_DI && altno != 4)
3129 return 1; /* skip this altsetting */
3130 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3131 AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
3132 return 1; /* skip this altsetting */
3133 }
3134 return 0; /* keep this altsetting */
3135}
3086 3136
3087/* 3137/*
3088 * audio-interface quirks 3138 * audio-interface quirks