diff options
author | Thibault LE MEUR <Thibault.LeMeur@supelec.fr> | 2006-03-14 05:44:53 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-03-22 04:38:38 -0500 |
commit | e311334ee6bdd173d53be52f4fdffa5f39652e26 (patch) | |
tree | b3c7a0f588ccb160b1d9446f0421be662f775033 /sound/usb/usbaudio.c | |
parent | ecefb192525c369dde67bf0addd4f96692a801c3 (diff) |
[ALSA] Fixes audiophile usb analog capture with the new device_setup parameter
Modules: Documentation,USB generic driver
The patch adds the 'device_setup' module parameter and a specific
quirk to correctly initialize the audiophile usb device: this fixes
the distorted sound bug on the Analog capture port. Backward
compatibility is achieved by simply omitting the new parameter.
Signed-off-by: Thibault LE MEUR <Thibault.LeMeur@supelec.fr>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r-- | sound/usb/usbaudio.c | 52 |
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 | |||
70 | static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */ | 70 | static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */ |
71 | static int nrpacks = 4; /* max. number of packets per urb */ | 71 | static int nrpacks = 4; /* max. number of packets per urb */ |
72 | static int async_unlink = 1; | 72 | static int async_unlink = 1; |
73 | static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/ | ||
73 | 74 | ||
74 | module_param_array(index, int, NULL, 0444); | 75 | module_param_array(index, int, NULL, 0444); |
75 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); | 76 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); |
@@ -85,6 +86,8 @@ module_param(nrpacks, int, 0644); | |||
85 | MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); | 86 | MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); |
86 | module_param(async_unlink, bool, 0444); | 87 | module_param(async_unlink, bool, 0444); |
87 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); | 88 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); |
89 | module_param_array(device_setup, int, NULL, 0444); | ||
90 | MODULE_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 | ||
2553 | static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | ||
2554 | int iface, int altno); | ||
2550 | static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | 2555 | static 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 | |||
3111 | static 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 |