Merge branch 'for-next' into for-linus
This commit is contained in:
@@ -350,6 +350,7 @@ static int snd_usb_audio_create(struct usb_interface *intf,
|
||||
case USB_SPEED_HIGH:
|
||||
case USB_SPEED_WIRELESS:
|
||||
case USB_SPEED_SUPER:
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
break;
|
||||
default:
|
||||
dev_err(&dev->dev, "unknown device speed %d\n", snd_usb_get_speed(dev));
|
||||
@@ -450,6 +451,9 @@ static int snd_usb_audio_create(struct usb_interface *intf,
|
||||
case USB_SPEED_SUPER:
|
||||
strlcat(card->longname, ", super speed", sizeof(card->longname));
|
||||
break;
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
strlcat(card->longname, ", super speed plus", sizeof(card->longname));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -309,6 +309,9 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
|
||||
* support reading */
|
||||
if (snd_usb_get_sample_rate_quirk(chip))
|
||||
return 0;
|
||||
/* the firmware is likely buggy, don't repeat to fail too many times */
|
||||
if (chip->sample_rate_read_error > 2)
|
||||
return 0;
|
||||
|
||||
if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
|
||||
USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
|
||||
@@ -316,6 +319,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
|
||||
data, sizeof(data))) < 0) {
|
||||
dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n",
|
||||
iface, fmt->altsetting, ep);
|
||||
chip->sample_rate_read_error++;
|
||||
return 0; /* some devices don't support reading */
|
||||
}
|
||||
|
||||
|
@@ -120,6 +120,7 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
|
||||
case USB_SPEED_HIGH:
|
||||
case USB_SPEED_WIRELESS:
|
||||
case USB_SPEED_SUPER:
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
if (get_endpoint(alts, 0)->bInterval >= 1 &&
|
||||
get_endpoint(alts, 0)->bInterval <= 4)
|
||||
return get_endpoint(alts, 0)->bInterval - 1;
|
||||
|
@@ -911,6 +911,7 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
|
||||
switch (snd_usb_get_speed(ep->umidi->dev)) {
|
||||
case USB_SPEED_HIGH:
|
||||
case USB_SPEED_SUPER:
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
count = 1;
|
||||
break;
|
||||
default:
|
||||
|
@@ -45,6 +45,7 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/usb.h>
|
||||
@@ -1378,6 +1379,71 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
|
||||
snd_usb_mixer_add_control(&cval->head, kctl);
|
||||
}
|
||||
|
||||
static int parse_clock_source_unit(struct mixer_build *state, int unitid,
|
||||
void *_ftr)
|
||||
{
|
||||
struct uac_clock_source_descriptor *hdr = _ftr;
|
||||
struct usb_mixer_elem_info *cval;
|
||||
struct snd_kcontrol *kctl;
|
||||
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
int ret;
|
||||
|
||||
if (state->mixer->protocol != UAC_VERSION_2)
|
||||
return -EINVAL;
|
||||
|
||||
if (hdr->bLength != sizeof(*hdr)) {
|
||||
usb_audio_dbg(state->chip,
|
||||
"Bogus clock source descriptor length of %d, ignoring.\n",
|
||||
hdr->bLength);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The only property of this unit we are interested in is the
|
||||
* clock source validity. If that isn't readable, just bail out.
|
||||
*/
|
||||
if (!uac2_control_is_readable(hdr->bmControls,
|
||||
ilog2(UAC2_CS_CONTROL_CLOCK_VALID)))
|
||||
return 0;
|
||||
|
||||
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
|
||||
if (!cval)
|
||||
return -ENOMEM;
|
||||
|
||||
snd_usb_mixer_elem_init_std(&cval->head, state->mixer, hdr->bClockID);
|
||||
|
||||
cval->min = 0;
|
||||
cval->max = 1;
|
||||
cval->channels = 1;
|
||||
cval->val_type = USB_MIXER_BOOLEAN;
|
||||
cval->control = UAC2_CS_CONTROL_CLOCK_VALID;
|
||||
|
||||
if (uac2_control_is_writeable(hdr->bmControls,
|
||||
ilog2(UAC2_CS_CONTROL_CLOCK_VALID)))
|
||||
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
|
||||
else {
|
||||
cval->master_readonly = 1;
|
||||
kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
|
||||
}
|
||||
|
||||
if (!kctl) {
|
||||
kfree(cval);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
kctl->private_free = snd_usb_mixer_elem_free;
|
||||
ret = snd_usb_copy_string_desc(state, hdr->iClockSource,
|
||||
name, sizeof(name));
|
||||
if (ret > 0)
|
||||
snprintf(kctl->id.name, sizeof(kctl->id.name),
|
||||
"%s Validity", name);
|
||||
else
|
||||
snprintf(kctl->id.name, sizeof(kctl->id.name),
|
||||
"Clock Source %d Validity", hdr->bClockID);
|
||||
|
||||
return snd_usb_mixer_add_control(&cval->head, kctl);
|
||||
}
|
||||
|
||||
/*
|
||||
* parse a feature unit
|
||||
*
|
||||
@@ -2126,10 +2192,11 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
|
||||
|
||||
switch (p1[2]) {
|
||||
case UAC_INPUT_TERMINAL:
|
||||
case UAC2_CLOCK_SOURCE:
|
||||
return 0; /* NOP */
|
||||
case UAC_MIXER_UNIT:
|
||||
return parse_audio_mixer_unit(state, unitid, p1);
|
||||
case UAC2_CLOCK_SOURCE:
|
||||
return parse_clock_source_unit(state, unitid, p1);
|
||||
case UAC_SELECTOR_UNIT:
|
||||
case UAC2_CLOCK_SELECTOR:
|
||||
return parse_audio_selector_unit(state, unitid, p1);
|
||||
@@ -2307,6 +2374,7 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
|
||||
__u8 unitid = (index >> 8) & 0xff;
|
||||
__u8 control = (value >> 8) & 0xff;
|
||||
__u8 channel = value & 0xff;
|
||||
unsigned int count = 0;
|
||||
|
||||
if (channel >= MAX_CHANNELS) {
|
||||
usb_audio_dbg(mixer->chip,
|
||||
@@ -2315,6 +2383,12 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
|
||||
return;
|
||||
}
|
||||
|
||||
for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem)
|
||||
count++;
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) {
|
||||
struct usb_mixer_elem_info *info;
|
||||
|
||||
@@ -2322,7 +2396,7 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
|
||||
continue;
|
||||
|
||||
info = (struct usb_mixer_elem_info *)list;
|
||||
if (info->control != control)
|
||||
if (count > 1 && info->control != control)
|
||||
continue;
|
||||
|
||||
switch (attribute) {
|
||||
|
@@ -47,6 +47,7 @@ struct snd_usb_audio {
|
||||
|
||||
int num_interfaces;
|
||||
int num_suspended_intf;
|
||||
int sample_rate_read_error;
|
||||
|
||||
struct list_head pcm_list; /* list of pcm streams */
|
||||
struct list_head ep_list; /* list of audio-related endpoints */
|
||||
|
Reference in New Issue
Block a user