mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (214 commits) ALSA: hda - Add pin-fix for HP dc5750 ALSA: als4000: Fix potentially invalid DMA mode setup ALSA: als4000: enable burst mode ALSA: hda - Fix initial capsrc selection in patch_alc269() ASoC: TWL4030: Capture route runtime DAPM ordering fix ALSA: hda - Add PC-beep whitelist for an Intel board ALSA: hda - More relax for pending period handling ALSA: hda - Define AC_FMT_* constants ALSA: hda - Fix beep frequency on IDT 92HD73xx and 92HD71Bxx codecs ALSA: hda - Add support for HDMI HBR passthrough ALSA: hda - Set Stream Type in Stream Format according to AES0 ALSA: hda - Fix Thinkpad X300 so SPDIF is not exposed ALSA: hda - FIX to not expose SPDIF on Thinkpad X301, since it does not have the ability to use SPDIF ASoC: wm9081: fix resource reclaim in wm9081_register error path ASoC: wm8978: fix a memory leak if a wm8978_register fail ASoC: wm8974: fix a memory leak if another WM8974 is registered ASoC: wm8961: fix resource reclaim in wm8961_register error path ASoC: wm8955: fix resource reclaim in wm8955_register error path ASoC: wm8940: fix a memory leak if wm8940_register return error ASoC: wm8904: fix resource reclaim in wm8904_register error path ...
This commit is contained in:
commit
faa38b5e0e
194 changed files with 10998 additions and 1418 deletions
|
|
@ -217,7 +217,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
|
|||
|
||||
switch (protocol) {
|
||||
case UAC_VERSION_1: {
|
||||
struct uac_ac_header_descriptor_v1 *h1 = control_header;
|
||||
struct uac1_ac_header_descriptor *h1 = control_header;
|
||||
|
||||
if (!h1->bInCollection) {
|
||||
snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
|
||||
|
|
|
|||
|
|
@ -19,33 +19,19 @@
|
|||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/usb/audio.h>
|
||||
#include <linux/usb/audio-v2.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/info.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/initval.h>
|
||||
|
||||
#include "usbaudio.h"
|
||||
#include "card.h"
|
||||
#include "midi.h"
|
||||
#include "mixer.h"
|
||||
#include "proc.h"
|
||||
#include "quirks.h"
|
||||
#include "endpoint.h"
|
||||
#include "helper.h"
|
||||
#include "debug.h"
|
||||
#include "pcm.h"
|
||||
#include "urb.h"
|
||||
#include "format.h"
|
||||
#include "clock.h"
|
||||
|
||||
static struct uac_clock_source_descriptor *
|
||||
snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface,
|
||||
|
|
@ -134,10 +120,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
|
|||
return !!data;
|
||||
}
|
||||
|
||||
/* Try to find the clock source ID of a given clock entity */
|
||||
|
||||
static int __uac_clock_find_source(struct snd_usb_audio *chip,
|
||||
struct usb_host_interface *host_iface,
|
||||
int entity_id, unsigned long *visited)
|
||||
{
|
||||
struct uac_clock_source_descriptor *source;
|
||||
|
|
@ -154,11 +137,11 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
|
|||
}
|
||||
|
||||
/* first, see if the ID we're looking for is a clock source already */
|
||||
source = snd_usb_find_clock_source(host_iface, entity_id);
|
||||
source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
|
||||
if (source)
|
||||
return source->bClockID;
|
||||
|
||||
selector = snd_usb_find_clock_selector(host_iface, entity_id);
|
||||
selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
|
||||
if (selector) {
|
||||
int ret;
|
||||
|
||||
|
|
@ -168,6 +151,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Selector values are one-based */
|
||||
|
||||
if (ret > selector->bNrInPins || ret < 1) {
|
||||
printk(KERN_ERR
|
||||
"%s(): selector reported illegal value, id %d, ret %d\n",
|
||||
|
|
@ -176,27 +161,35 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
return __uac_clock_find_source(chip, host_iface,
|
||||
selector->baCSourceID[ret-1],
|
||||
return __uac_clock_find_source(chip, selector->baCSourceID[ret-1],
|
||||
visited);
|
||||
}
|
||||
|
||||
/* FIXME: multipliers only act as pass-thru element for now */
|
||||
multiplier = snd_usb_find_clock_multiplier(host_iface, entity_id);
|
||||
multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
|
||||
if (multiplier)
|
||||
return __uac_clock_find_source(chip, host_iface,
|
||||
multiplier->bCSourceID, visited);
|
||||
return __uac_clock_find_source(chip, multiplier->bCSourceID,
|
||||
visited);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int snd_usb_clock_find_source(struct snd_usb_audio *chip,
|
||||
struct usb_host_interface *host_iface,
|
||||
int entity_id)
|
||||
/*
|
||||
* For all kinds of sample rate settings and other device queries,
|
||||
* the clock source (end-leaf) must be used. However, clock selectors,
|
||||
* clock multipliers and sample rate converters may be specified as
|
||||
* clock source input to terminal. This functions walks the clock path
|
||||
* to its end and tries to find the source.
|
||||
*
|
||||
* The 'visited' bitfield is used internally to detect recursive loops.
|
||||
*
|
||||
* Returns the clock source UnitID (>=0) on success, or an error.
|
||||
*/
|
||||
int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id)
|
||||
{
|
||||
DECLARE_BITMAP(visited, 256);
|
||||
memset(visited, 0, sizeof(visited));
|
||||
return __uac_clock_find_source(chip, host_iface, entity_id, visited);
|
||||
return __uac_clock_find_source(chip, entity_id, visited);
|
||||
}
|
||||
|
||||
static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
|
||||
|
|
@ -211,11 +204,8 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
|
|||
ep = get_endpoint(alts, 0)->bEndpointAddress;
|
||||
|
||||
/* if endpoint doesn't have sampling rate control, bail out */
|
||||
if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE)) {
|
||||
snd_printk(KERN_WARNING "%d:%d:%d: endpoint lacks sample rate attribute bit, cannot set.\n",
|
||||
dev->devnum, iface, fmt->altsetting);
|
||||
if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE))
|
||||
return 0;
|
||||
}
|
||||
|
||||
data[0] = rate;
|
||||
data[1] = rate >> 8;
|
||||
|
|
@ -254,12 +244,13 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
|
|||
struct usb_device *dev = chip->dev;
|
||||
unsigned char data[4];
|
||||
int err, crate;
|
||||
int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fmt->clock);
|
||||
int clock = snd_usb_clock_find_source(chip, fmt->clock);
|
||||
|
||||
if (clock < 0)
|
||||
return clock;
|
||||
|
||||
if (!uac_clock_source_is_valid(chip, clock)) {
|
||||
/* TODO: should we try to find valid clock setups by ourself? */
|
||||
snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n",
|
||||
dev->devnum, iface, fmt->altsetting, clock);
|
||||
return -ENXIO;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
|
|||
struct usb_host_interface *alts,
|
||||
struct audioformat *fmt, int rate);
|
||||
|
||||
int snd_usb_clock_find_source(struct snd_usb_audio *chip,
|
||||
struct usb_host_interface *host_iface,
|
||||
int entity_id);
|
||||
int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id);
|
||||
|
||||
#endif /* __USBAUDIO_CLOCK_H */
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "pcm.h"
|
||||
#include "helper.h"
|
||||
#include "format.h"
|
||||
#include "clock.h"
|
||||
|
||||
/*
|
||||
* free a substream
|
||||
|
|
@ -275,7 +276,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
|
|||
/* get audio formats */
|
||||
switch (protocol) {
|
||||
case UAC_VERSION_1: {
|
||||
struct uac_as_header_descriptor_v1 *as =
|
||||
struct uac1_as_header_descriptor *as =
|
||||
snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
|
||||
|
||||
if (!as) {
|
||||
|
|
@ -297,7 +298,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
|
|||
case UAC_VERSION_2: {
|
||||
struct uac2_input_terminal_descriptor *input_term;
|
||||
struct uac2_output_terminal_descriptor *output_term;
|
||||
struct uac_as_header_descriptor_v2 *as =
|
||||
struct uac2_as_header_descriptor *as =
|
||||
snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
|
||||
|
||||
if (!as) {
|
||||
|
|
|
|||
|
|
@ -264,13 +264,12 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets,
|
|||
* on the audioformat table (audio class v2).
|
||||
*/
|
||||
static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
|
||||
struct audioformat *fp,
|
||||
struct usb_host_interface *iface)
|
||||
struct audioformat *fp)
|
||||
{
|
||||
struct usb_device *dev = chip->dev;
|
||||
unsigned char tmp[2], *data;
|
||||
int nr_triplets, data_size, ret = 0;
|
||||
int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fp->clock);
|
||||
int clock = snd_usb_clock_find_source(chip, fp->clock);
|
||||
|
||||
if (clock < 0) {
|
||||
snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n",
|
||||
|
|
@ -391,7 +390,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
|
|||
break;
|
||||
case UAC_VERSION_2:
|
||||
/* fp->channels is already set in this case */
|
||||
ret = parse_audio_format_rates_v2(chip, fp, iface);
|
||||
ret = parse_audio_format_rates_v2(chip, fp);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -450,7 +449,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
|
|||
framesize = le16_to_cpu(fmt->wSamplesPerFrame);
|
||||
snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
|
||||
fp->frame_size = framesize;
|
||||
ret = parse_audio_format_rates_v2(chip, fp, iface);
|
||||
ret = parse_audio_format_rates_v2(chip, fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ static void snd_usbmidi_maudio_broken_running_status_input(
|
|||
u8 cin = buffer[i] & 0x0f;
|
||||
struct usbmidi_in_port *port = &ep->ports[cable];
|
||||
int length;
|
||||
|
||||
|
||||
length = snd_usbmidi_cin_length[cin];
|
||||
if (cin == 0xf && buffer[i + 1] >= 0xf8)
|
||||
; /* realtime msg: no running status change */
|
||||
|
|
@ -628,13 +628,13 @@ static struct usb_protocol_ops snd_usbmidi_standard_ops = {
|
|||
|
||||
static struct usb_protocol_ops snd_usbmidi_midiman_ops = {
|
||||
.input = snd_usbmidi_midiman_input,
|
||||
.output = snd_usbmidi_standard_output,
|
||||
.output = snd_usbmidi_standard_output,
|
||||
.output_packet = snd_usbmidi_output_midiman_packet,
|
||||
};
|
||||
|
||||
static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = {
|
||||
.input = snd_usbmidi_maudio_broken_running_status_input,
|
||||
.output = snd_usbmidi_standard_output,
|
||||
.output = snd_usbmidi_standard_output,
|
||||
.output_packet = snd_usbmidi_output_standard_packet,
|
||||
};
|
||||
|
||||
|
|
@ -1248,7 +1248,7 @@ static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep
|
|||
*/
|
||||
static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
|
||||
struct snd_usb_midi_endpoint_info* ep_info,
|
||||
struct snd_usb_midi_endpoint* rep)
|
||||
struct snd_usb_midi_endpoint* rep)
|
||||
{
|
||||
struct snd_usb_midi_out_endpoint* ep;
|
||||
unsigned int i;
|
||||
|
|
@ -1398,7 +1398,7 @@ static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi)
|
|||
}
|
||||
|
||||
static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi* umidi,
|
||||
int stream, int number)
|
||||
int stream, int number)
|
||||
{
|
||||
struct list_head* list;
|
||||
|
||||
|
|
@ -1811,7 +1811,7 @@ static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi,
|
|||
snd_usbmidi_switch_roland_altsetting(umidi);
|
||||
|
||||
if (endpoint[0].out_ep || endpoint[0].in_ep)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
intf = umidi->iface;
|
||||
if (!intf || intf->num_altsetting < 1)
|
||||
|
|
@ -1849,7 +1849,7 @@ static int snd_usbmidi_detect_per_port_endpoints(struct snd_usb_midi* umidi,
|
|||
struct snd_usb_midi_endpoint_info* endpoints)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
|
||||
err = snd_usbmidi_detect_endpoints(umidi, endpoints, MIDI_MAX_ENDPOINTS);
|
||||
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
|
||||
if (endpoints[i].out_ep)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,22 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODOs, for both the mixer and the streaming interfaces:
|
||||
*
|
||||
* - support for UAC2 effect units
|
||||
* - support for graphical equalizers
|
||||
* - RANGE and MEM set commands (UAC2)
|
||||
* - RANGE and MEM interrupt dispatchers (UAC2)
|
||||
* - audio channel clustering (UAC2)
|
||||
* - audio sample rate converter units (UAC2)
|
||||
* - proper handling of clock multipliers (UAC2)
|
||||
* - dispatch clock change notifications (UAC2)
|
||||
* - stop PCM streams which use a clock that became invalid
|
||||
* - stop PCM streams which use a clock selector that has changed
|
||||
* - parse available sample rates again when clock sources changed
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
|
|
@ -275,28 +291,28 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
|
|||
|
||||
static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
|
||||
{
|
||||
struct snd_usb_audio *chip = cval->mixer->chip;
|
||||
unsigned char buf[2];
|
||||
int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
|
||||
int timeout = 10;
|
||||
|
||||
while (timeout-- > 0) {
|
||||
if (snd_usb_ctl_msg(cval->mixer->chip->dev,
|
||||
usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
|
||||
request,
|
||||
if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
|
||||
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
|
||||
validx, cval->mixer->ctrlif | (cval->id << 8),
|
||||
validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
|
||||
buf, val_len, 100) >= val_len) {
|
||||
*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
|
||||
request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type);
|
||||
request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
|
||||
{
|
||||
struct snd_usb_audio *chip = cval->mixer->chip;
|
||||
unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
|
||||
unsigned char *val;
|
||||
int ret, size;
|
||||
|
|
@ -312,16 +328,14 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
|
|||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
ret = snd_usb_ctl_msg(cval->mixer->chip->dev,
|
||||
usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
|
||||
bRequest,
|
||||
ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
|
||||
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
|
||||
validx, cval->mixer->ctrlif | (cval->id << 8),
|
||||
validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
|
||||
buf, size, 1000);
|
||||
|
||||
if (ret < 0) {
|
||||
snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
|
||||
request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type);
|
||||
request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -397,6 +411,7 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
|
|||
int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
|
||||
int request, int validx, int value_set)
|
||||
{
|
||||
struct snd_usb_audio *chip = cval->mixer->chip;
|
||||
unsigned char buf[2];
|
||||
int val_len, timeout = 10;
|
||||
|
||||
|
|
@ -419,15 +434,14 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
|
|||
buf[0] = value_set & 0xff;
|
||||
buf[1] = (value_set >> 8) & 0xff;
|
||||
while (timeout-- > 0)
|
||||
if (snd_usb_ctl_msg(cval->mixer->chip->dev,
|
||||
usb_sndctrlpipe(cval->mixer->chip->dev, 0),
|
||||
request,
|
||||
if (snd_usb_ctl_msg(chip->dev,
|
||||
usb_sndctrlpipe(chip->dev, 0), request,
|
||||
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
|
||||
validx, cval->mixer->ctrlif | (cval->id << 8),
|
||||
validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
|
||||
buf, val_len, 100) >= 0)
|
||||
return 0;
|
||||
snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
|
||||
request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type, buf[0], buf[1]);
|
||||
request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -582,9 +596,9 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
|
|||
switch (iterm->type >> 16) {
|
||||
case UAC_SELECTOR_UNIT:
|
||||
strcpy(name, "Selector"); return 8;
|
||||
case UAC_PROCESSING_UNIT_V1:
|
||||
case UAC1_PROCESSING_UNIT:
|
||||
strcpy(name, "Process Unit"); return 12;
|
||||
case UAC_EXTENSION_UNIT_V1:
|
||||
case UAC1_EXTENSION_UNIT:
|
||||
strcpy(name, "Ext Unit"); return 8;
|
||||
case UAC_MIXER_UNIT:
|
||||
strcpy(name, "Mixer"); return 5;
|
||||
|
|
@ -672,8 +686,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
|
|||
term->name = uac_selector_unit_iSelector(d);
|
||||
return 0;
|
||||
}
|
||||
case UAC_PROCESSING_UNIT_V1:
|
||||
case UAC_EXTENSION_UNIT_V1: {
|
||||
case UAC1_PROCESSING_UNIT:
|
||||
case UAC1_EXTENSION_UNIT: {
|
||||
struct uac_processing_unit_descriptor *d = p1;
|
||||
if (d->bNrInPins) {
|
||||
id = d->baSourceID[0];
|
||||
|
|
@ -745,6 +759,8 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
|
|||
*/
|
||||
static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
|
||||
{
|
||||
struct snd_usb_audio *chip = cval->mixer->chip;
|
||||
|
||||
/* for failsafe */
|
||||
cval->min = default_min;
|
||||
cval->max = cval->min + 1;
|
||||
|
|
@ -767,7 +783,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
|
|||
if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
|
||||
get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
|
||||
snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
|
||||
cval->id, cval->mixer->ctrlif, cval->control, cval->id);
|
||||
cval->id, snd_usb_ctrl_intf(chip), cval->control, cval->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
|
||||
|
|
@ -1199,14 +1215,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
|
|||
}
|
||||
} else { /* UAC_VERSION_2 */
|
||||
for (i = 0; i < 30/2; i++) {
|
||||
/* From the USB Audio spec v2.0:
|
||||
bmaControls() is a (ch+1)-element array of 4-byte bitmaps,
|
||||
each containing a set of bit pairs. If a Control is present,
|
||||
it must be Host readable. If a certain Control is not
|
||||
present then the bit pair must be set to 0b00.
|
||||
If a Control is present but read-only, the bit pair must be
|
||||
set to 0b01. If a Control is also Host programmable, the bit
|
||||
pair must be set to 0b11. The value 0b10 is not allowed. */
|
||||
unsigned int ch_bits = 0;
|
||||
unsigned int ch_read_only = 0;
|
||||
|
||||
|
|
@ -1855,13 +1863,13 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
|
|||
return parse_audio_selector_unit(state, unitid, p1);
|
||||
case UAC_FEATURE_UNIT:
|
||||
return parse_audio_feature_unit(state, unitid, p1);
|
||||
case UAC_PROCESSING_UNIT_V1:
|
||||
case UAC1_PROCESSING_UNIT:
|
||||
/* UAC2_EFFECT_UNIT has the same value */
|
||||
if (state->mixer->protocol == UAC_VERSION_1)
|
||||
return parse_audio_processing_unit(state, unitid, p1);
|
||||
else
|
||||
return 0; /* FIXME - effect units not implemented yet */
|
||||
case UAC_EXTENSION_UNIT_V1:
|
||||
case UAC1_EXTENSION_UNIT:
|
||||
/* UAC2_PROCESSING_UNIT_V2 has the same value */
|
||||
if (state->mixer->protocol == UAC_VERSION_1)
|
||||
return parse_audio_extension_unit(state, unitid, p1);
|
||||
|
|
@ -1905,7 +1913,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
|
|||
struct usb_host_interface *hostif;
|
||||
void *p;
|
||||
|
||||
hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
|
||||
hostif = mixer->chip->ctrl_intf;
|
||||
memset(&state, 0, sizeof(state));
|
||||
state.chip = mixer->chip;
|
||||
state.mixer = mixer;
|
||||
|
|
@ -1925,7 +1933,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
|
|||
p = NULL;
|
||||
while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) {
|
||||
if (mixer->protocol == UAC_VERSION_1) {
|
||||
struct uac_output_terminal_descriptor_v1 *desc = p;
|
||||
struct uac1_output_terminal_descriptor *desc = p;
|
||||
|
||||
if (desc->bLength < sizeof(*desc))
|
||||
continue; /* invalid descriptor? */
|
||||
|
|
@ -1997,7 +2005,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
|
|||
list_for_each_entry(mixer, &chip->mixer_list, list) {
|
||||
snd_iprintf(buffer,
|
||||
"USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
|
||||
chip->usb_id, mixer->ctrlif,
|
||||
chip->usb_id, snd_usb_ctrl_intf(chip),
|
||||
mixer->ignore_ctl_error);
|
||||
snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
|
||||
for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
|
||||
|
|
@ -2115,7 +2123,7 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
|
|||
int buffer_length;
|
||||
unsigned int epnum;
|
||||
|
||||
hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
|
||||
hostif = mixer->chip->ctrl_intf;
|
||||
/* we need one interrupt input endpoint */
|
||||
if (get_iface_desc(hostif)->bNumEndpoints < 1)
|
||||
return 0;
|
||||
|
|
@ -2158,7 +2166,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
|
|||
if (!mixer)
|
||||
return -ENOMEM;
|
||||
mixer->chip = chip;
|
||||
mixer->ctrlif = ctrlif;
|
||||
mixer->ignore_ctl_error = ignore_error;
|
||||
mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems),
|
||||
GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
struct usb_mixer_interface {
|
||||
struct snd_usb_audio *chip;
|
||||
unsigned int ctrlif;
|
||||
struct list_head list;
|
||||
unsigned int ignore_ctl_error;
|
||||
struct urb *urb;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,5 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
|
|||
struct usb_host_interface *alts,
|
||||
struct audioformat *fmt);
|
||||
|
||||
int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
|
||||
struct usb_host_interface *alts,
|
||||
struct audioformat *fmt, int rate);
|
||||
|
||||
#endif /* __USBAUDIO_PCM_H */
|
||||
|
|
|
|||
|
|
@ -2152,91 +2152,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
|
|||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7201),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7202),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7203),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7204),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7205),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7250),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7230),
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7240),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
|
|
@ -2249,6 +2165,104 @@ YAMAHA_DEVICE(0x7010, "UB99"),
|
|||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7210),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7217),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x721b),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x721e),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x721f),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7280),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE_VENDOR_SPEC(0x0fd9, 0x0008),
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
|
||||
USB_DEVICE_ID_MATCH_INT_CLASS |
|
||||
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
|
||||
.bInterfaceClass = USB_CLASS_AUDIO,
|
||||
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
||||
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
|
||||
.vendor_name = "Hauppauge",
|
||||
.product_name = "HVR-950Q",
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
|
||||
}
|
||||
},
|
||||
|
||||
/* Digidesign Mbox */
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "helper.h"
|
||||
#include "endpoint.h"
|
||||
#include "pcm.h"
|
||||
#include "clock.h"
|
||||
|
||||
/*
|
||||
* handle the quirks for the contained interfaces
|
||||
|
|
|
|||
Loading…
Reference in a new issue