Merge tag 'sound-4.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound updates from Takashi Iwai:
 "After a heavy storm by syzkaller in 4.5 cycle, we have relatively few
  changes in the core at this time while a lot of changes are found in
  the driver side, unsurprisingly.  Below are some highlights:

  ALSA core:
   - A few more hardening in ALSA timer codes
   - An extension of sequencer API for advertising the card / pid
   - Small fixes in compress-offload and jack layers

  HD-audio:
   - Dynamic PCM assignment in HDMI/DP codec; preparation for upcoming
     DP-MST support
   - Lots of code refactoring for sharing with ASoC SKL driver
   - Regression fixes for Intel HDMI/DP
   - Fixups for CX20724 codec, Lenovo AiO

  USB-audio:
   - Add quirk_alias option to make quirk debugging easier
   - Fixes for possible Oops by malformed firmware

  Firewire:
   - Add support for FW-1804 in tascam driver
   - Improvements / changes in card registration, multi stream handling,
     etc for DICE
   - Lots of code refactoring

  ASoC:
   - Enhancements of still ongoing topology API
   - Lots of commits for Intel Skylake support including HDMI support
   - A few Intel Atom driver updates for recent devices
   - Lots of improvements to the Renesas drivers
   - Capture support for Qualcomm drivers
   - Support for TI DaVinci DRA7xxx devices
   - New machine drivers for Freescale systems with Cirrus CODECs,
     Mediatek systems with RT5650 CODECs
   - New CPU drivers for Allwinner S/PDIF controllers
   - New CODEC drivers for Maxim MAX9867 and MAX98926 and Realtek RT5514"

* tag 'sound-4.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (291 commits)
  ALSA: hda - Fix mutex deadlock at HDMI/DP hotplug
  ALSA: ctl: change return value in compatibility layer so that it's the same value in core implementation
  ALSA: mixart: silence an uninitialized variable warning
  ALSA: usb-audio: Add sanity checks for endpoint accesses
  ALSA: usb-audio: Minor code cleanup in create_fixed_stream_quirk()
  ALSA: usb-audio: Fix NULL dereference in create_fixed_stream_quirk()
  ALSA: hda - Limit i915 HDMI binding only for HSW and later
  ALSA: hda - Fix unconditional GPIO toggle via automute
  ALSA: mixart: silence unitialized variable warnings
  ALSA: hda - Fixes double fault in nvhdmi_chmap_cea_alloc_validate_get_type
  ALSA: intel8x0: Add clock quirk entry for AD1981B on IBM ThinkPad X41.
  ALSA: hda - Add new GPU codec ID 0x10de0082 to snd-hda
  ASoC: rsnd: add simplified module explanation
  ASoC: hdac_hdmi: Add broxton device ID
  ASoC: Intel: Bxtn: Add Broxton PCI ID
  ASoC: Intel: Skylake: Move Skylake dsp ops & loader ops
  ASoC: Intel: add dmabuffer to common sst_dsp
  ASoC: Intel: Skylake: Unstatify skl_dsp_enable_core
  ASoC: Intel: Skylake: Fix whitepsace issues
  ASoC: Intel: Skylake: Move module id defines
  ...
This commit is contained in:
Linus Torvalds
2016-03-18 10:05:46 -07:00
202 changed files with 12802 additions and 4392 deletions

View File

@@ -83,6 +83,7 @@ static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
static bool ignore_ctl_error;
static bool autoclock = true;
static char *quirk_alias[SNDRV_CARDS];
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
@@ -101,6 +102,8 @@ MODULE_PARM_DESC(ignore_ctl_error,
"Ignore errors from USB controller for mixer interfaces.");
module_param(autoclock, bool, 0444);
MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes).");
module_param_array(quirk_alias, charp, NULL, 0444);
MODULE_PARM_DESC(quirk_alias, "Quirk aliases, e.g. 0123abcd:5678beef.");
/*
* we keep the snd_usb_audio_t instances by ourselves for merging
@@ -172,8 +175,9 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int
if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
int err = snd_usbmidi_create(chip->card, iface,
&chip->midi_list, NULL);
int err = __snd_usbmidi_create(chip->card, iface,
&chip->midi_list, NULL,
chip->usb_id);
if (err < 0) {
dev_err(&dev->dev,
"%u:%d: cannot create sequencer device\n",
@@ -312,6 +316,7 @@ static int snd_usb_audio_free(struct snd_usb_audio *chip)
snd_usb_endpoint_free(ep);
mutex_destroy(&chip->mutex);
dev_set_drvdata(&chip->dev->dev, NULL);
kfree(chip);
return 0;
}
@@ -456,6 +461,48 @@ static int snd_usb_audio_create(struct usb_interface *intf,
return 0;
}
/* look for a matching quirk alias id */
static bool get_alias_id(struct usb_device *dev, unsigned int *id)
{
int i;
unsigned int src, dst;
for (i = 0; i < ARRAY_SIZE(quirk_alias); i++) {
if (!quirk_alias[i] ||
sscanf(quirk_alias[i], "%x:%x", &src, &dst) != 2 ||
src != *id)
continue;
dev_info(&dev->dev,
"device (%04x:%04x): applying quirk alias %04x:%04x\n",
USB_ID_VENDOR(*id), USB_ID_PRODUCT(*id),
USB_ID_VENDOR(dst), USB_ID_PRODUCT(dst));
*id = dst;
return true;
}
return false;
}
static struct usb_device_id usb_audio_ids[]; /* defined below */
/* look for the corresponding quirk */
static const struct snd_usb_audio_quirk *
get_alias_quirk(struct usb_device *dev, unsigned int id)
{
const struct usb_device_id *p;
for (p = usb_audio_ids; p->match_flags; p++) {
/* FIXME: this checks only vendor:product pair in the list */
if ((p->match_flags & USB_DEVICE_ID_MATCH_DEVICE) ==
USB_DEVICE_ID_MATCH_DEVICE &&
p->idVendor == USB_ID_VENDOR(id) &&
p->idProduct == USB_ID_PRODUCT(id))
return (const struct snd_usb_audio_quirk *)p->driver_info;
}
return NULL;
}
/*
* probe the active usb device
*
@@ -482,10 +529,12 @@ static int usb_audio_probe(struct usb_interface *intf,
ifnum = get_iface_desc(alts)->bInterfaceNumber;
id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
if (get_alias_id(dev, &id))
quirk = get_alias_quirk(dev, id);
if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
return -ENXIO;
err = snd_usb_apply_boot_quirk(dev, intf, quirk);
err = snd_usb_apply_boot_quirk(dev, intf, quirk, id);
if (err < 0)
return err;
@@ -504,6 +553,7 @@ static int usb_audio_probe(struct usb_interface *intf,
goto __error;
}
chip = usb_chip[i];
dev_set_drvdata(&dev->dev, chip);
atomic_inc(&chip->active); /* avoid autopm */
break;
}

View File

@@ -285,6 +285,8 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
unsigned char data[3];
int err, crate;
if (get_iface_desc(alts)->bNumEndpoints < 1)
return -EINVAL;
ep = get_endpoint(alts, 0)->bEndpointAddress;
/* if endpoint doesn't have sampling rate control, bail out */

View File

@@ -438,6 +438,9 @@ exit_clear:
*
* New endpoints will be added to chip->ep_list and must be freed by
* calling snd_usb_endpoint_free().
*
* For SND_USB_ENDPOINT_TYPE_SYNC, the caller needs to guarantee that
* bNumEndpoints > 1 beforehand.
*/
struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
struct usb_host_interface *alts,

View File

@@ -2320,10 +2320,11 @@ EXPORT_SYMBOL(snd_usbmidi_resume);
/*
* Creates and registers everything needed for a MIDI streaming interface.
*/
int snd_usbmidi_create(struct snd_card *card,
struct usb_interface *iface,
struct list_head *midi_list,
const struct snd_usb_audio_quirk *quirk)
int __snd_usbmidi_create(struct snd_card *card,
struct usb_interface *iface,
struct list_head *midi_list,
const struct snd_usb_audio_quirk *quirk,
unsigned int usb_id)
{
struct snd_usb_midi *umidi;
struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS];
@@ -2341,8 +2342,10 @@ int snd_usbmidi_create(struct snd_card *card,
spin_lock_init(&umidi->disc_lock);
init_rwsem(&umidi->disc_rwsem);
mutex_init(&umidi->mutex);
umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor),
if (!usb_id)
usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor),
le16_to_cpu(umidi->dev->descriptor.idProduct));
umidi->usb_id = usb_id;
setup_timer(&umidi->error_timer, snd_usbmidi_error_timer,
(unsigned long)umidi);
@@ -2463,4 +2466,4 @@ int snd_usbmidi_create(struct snd_card *card,
list_add_tail(&umidi->list, midi_list);
return 0;
}
EXPORT_SYMBOL(snd_usbmidi_create);
EXPORT_SYMBOL(__snd_usbmidi_create);

View File

@@ -39,10 +39,20 @@ struct snd_usb_midi_endpoint_info {
/* for QUIRK_MIDI_AKAI, data is NULL */
int snd_usbmidi_create(struct snd_card *card,
int __snd_usbmidi_create(struct snd_card *card,
struct usb_interface *iface,
struct list_head *midi_list,
const struct snd_usb_audio_quirk *quirk,
unsigned int usb_id);
static inline int snd_usbmidi_create(struct snd_card *card,
struct usb_interface *iface,
struct list_head *midi_list,
const struct snd_usb_audio_quirk *quirk);
const struct snd_usb_audio_quirk *quirk)
{
return __snd_usbmidi_create(card, iface, midi_list, quirk, 0);
}
void snd_usbmidi_input_stop(struct list_head *p);
void snd_usbmidi_input_start(struct list_head *p);
void snd_usbmidi_disconnect(struct list_head *p);

View File

@@ -1519,7 +1519,11 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
/* use known values for that card: interface#1 altsetting#1 */
iface = usb_ifnum_to_if(chip->dev, 1);
if (!iface || iface->num_altsetting < 2)
return -EINVAL;
alts = &iface->altsetting[1];
if (get_iface_desc(alts)->bNumEndpoints < 1)
return -EINVAL;
ep = get_endpoint(alts, 0)->bEndpointAddress;
err = snd_usb_ctl_msg(chip->dev,

View File

@@ -160,6 +160,8 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
unsigned char data[1];
int err;
if (get_iface_desc(alts)->bNumEndpoints < 1)
return -EINVAL;
ep = get_endpoint(alts, 0)->bEndpointAddress;
data[0] = 1;

View File

@@ -167,19 +167,20 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
stream = (fp->endpoint & USB_DIR_IN)
? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
err = snd_usb_add_audio_stream(chip, stream, fp);
if (err < 0) {
kfree(fp);
kfree(rate_table);
return err;
}
if (err < 0)
goto error;
if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
fp->altset_idx >= iface->num_altsetting) {
kfree(fp);
kfree(rate_table);
return -EINVAL;
err = -EINVAL;
goto error;
}
alts = &iface->altsetting[fp->altset_idx];
altsd = get_iface_desc(alts);
if (altsd->bNumEndpoints < 1) {
err = -EINVAL;
goto error;
}
fp->protocol = altsd->bInterfaceProtocol;
if (fp->datainterval == 0)
@@ -190,6 +191,11 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
snd_usb_init_pitch(chip, fp->iface, alts, fp);
snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max);
return 0;
error:
kfree(fp);
kfree(rate_table);
return err;
}
static int create_auto_pcm_quirk(struct snd_usb_audio *chip,
@@ -446,8 +452,9 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
const struct snd_usb_audio_quirk *quirk =
chip->usb_id == USB_ID(0x0582, 0x002b)
? &ua700_quirk : &uaxx_quirk;
return snd_usbmidi_create(chip->card, iface,
&chip->midi_list, quirk);
return __snd_usbmidi_create(chip->card, iface,
&chip->midi_list, quirk,
chip->usb_id);
}
if (altsd->bNumEndpoints != 1)
@@ -974,11 +981,9 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
int snd_usb_apply_boot_quirk(struct usb_device *dev,
struct usb_interface *intf,
const struct snd_usb_audio_quirk *quirk)
const struct snd_usb_audio_quirk *quirk,
unsigned int id)
{
u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
switch (id) {
case USB_ID(0x041e, 0x3000):
/* SB Extigy needs special boot-up sequence */
@@ -1184,7 +1189,7 @@ void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
* "Playback Design" products send bogus feedback data at the start
* of the stream. Ignore them.
*/
if ((le16_to_cpu(ep->chip->dev->descriptor.idVendor) == 0x23ba) &&
if (USB_ID_VENDOR(ep->chip->usb_id) == 0x23ba &&
ep->type == SND_USB_ENDPOINT_TYPE_SYNC)
ep->skip_packets = 4;
@@ -1203,11 +1208,15 @@ void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
void snd_usb_set_interface_quirk(struct usb_device *dev)
{
struct snd_usb_audio *chip = dev_get_drvdata(&dev->dev);
if (!chip)
return;
/*
* "Playback Design" products need a 50ms delay after setting the
* USB interface.
*/
switch (le16_to_cpu(dev->descriptor.idVendor)) {
switch (USB_ID_VENDOR(chip->usb_id)) {
case 0x23ba: /* Playback Design */
case 0x0644: /* TEAC Corp. */
mdelay(50);
@@ -1215,15 +1224,20 @@ void snd_usb_set_interface_quirk(struct usb_device *dev)
}
}
/* quirk applied after snd_usb_ctl_msg(); not applied during boot quirks */
void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
__u8 request, __u8 requesttype, __u16 value,
__u16 index, void *data, __u16 size)
{
struct snd_usb_audio *chip = dev_get_drvdata(&dev->dev);
if (!chip)
return;
/*
* "Playback Design" products need a 20ms delay after each
* class compliant request
*/
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x23ba) &&
if (USB_ID_VENDOR(chip->usb_id) == 0x23ba &&
(requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
mdelay(20);
@@ -1231,23 +1245,21 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
* "TEAC Corp." products need a 20ms delay after each
* class compliant request
*/
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x0644) &&
if (USB_ID_VENDOR(chip->usb_id) == 0x0644 &&
(requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
mdelay(20);
/* Marantz/Denon devices with USB DAC functionality need a delay
* after each class compliant request
*/
if (is_marantz_denon_dac(USB_ID(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct)))
if (is_marantz_denon_dac(chip->usb_id)
&& (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
mdelay(20);
/* Zoom R16/24 needs a tiny delay here, otherwise requests like
* get/set frequency return as failed despite actually succeeding.
*/
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1686) &&
(le16_to_cpu(dev->descriptor.idProduct) == 0x00dd) &&
if (chip->usb_id == USB_ID(0x1686, 0x00dd) &&
(requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
mdelay(1);
}
@@ -1264,7 +1276,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
unsigned int sample_bytes)
{
/* Playback Designs */
if (le16_to_cpu(chip->dev->descriptor.idVendor) == 0x23ba) {
if (USB_ID_VENDOR(chip->usb_id) == 0x23ba) {
switch (fp->altsetting) {
case 1:
fp->dsd_dop = true;

View File

@@ -16,7 +16,8 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
int snd_usb_apply_boot_quirk(struct usb_device *dev,
struct usb_interface *intf,
const struct snd_usb_audio_quirk *quirk);
const struct snd_usb_audio_quirk *quirk,
unsigned int usb_id);
void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
struct audioformat *fmt);