sound fixes for 4.14-rc6

We've got slightly more fixes than wished, but heading to a good
 shape.  Most of changes are about HD-audio fixes, one for a buggy code
 that went into 4.13, and another for avoiding a crash due to buggy
 BIOS.
 
 Apart from HD-audio, a sequencer core change that is only for UP
 config (which must be pretty rare nowadays), and a USB-audio quirk as
 usual.
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEECxfAB4MH3rD5mfB6bDGAVD0pKaQFAlnonUQOHHRpd2FpQHN1
 c2UuZGUACgkQbDGAVD0pKaSnrg//fpNJWcF2sCUMSsqxA+6iy5oVcsNEueockO/q
 iUj60clC9f+GKx2f/ZxWGQTZA1ffZiD6anc77O0adDG+pXyeaRHzUgEgGm0sjeR3
 TOy0izBZfI7iJBC0EwPKSohqZK/ogk0dXRosTooJ4EY2w+3RSBXhYKTFO812LpvA
 z/t8Rbyw1Iurjrc/3myx3CNIgHfM07Oc1PZmlJXIHyMBLgEC+PfA/7yI4P0wp1VD
 73TpRRszVKkpmqF3KaQjQ0HGTaL6Afx/JMYCSz2LQiKLi5Q9+faI/EGDRxpwh7LY
 be8hwe7J6mRSEq5ffWO9o0cz8VNVbGL7C7FXvFTJT8HjnrypdtX3qgn+9sa0kiKk
 Zr2gygoItkDKIz5zmgGrxTAHh15O76YJga0qQ1de1mqKEiBsEZO5jFAh4H4MXMRQ
 TXWT76J015m87d2ujdMrD0OmML4UXmRcy+cZd883iDpJvGBhIROFd0J7fY96fAqd
 +mD+hL847FkRGXql04wj73m7HzbZ8ZZ6juSViDy8ioKoYkFmNaIeUtlgPWPcw50j
 qi8SYkg+DCXbGWGaPh+l+n685Ibz2W4VdtiPaAu4WkIrKEkxa/J020GzRgHm6+ke
 CD+MGqo/S5a3MJoLZGUtYKl2FYJv51MueKHk00p+ZkyHWtC9xo+wLg4dc3Ip83ir
 jWrpVSg=
 =YGib
 -----END PGP SIGNATURE-----

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

Pull sound fixes from Takashi Iwai:
 "We've got slightly more fixes than wished, but heading to a good
  shape. Most of changes are about HD-audio fixes, one for a buggy code
  that went into 4.13, and another for avoiding a crash due to buggy
  BIOS.

  Apart from HD-audio, a sequencer core change that is only for UP
  config (which must be pretty rare nowadays), and a USB-audio quirk as
  usual"

* tag 'sound-4.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - Fix incorrect TLV callback check introduced during set_fs() removal
  ALSA: hda: Remove superfluous '-' added by printk conversion
  ALSA: hda: Abort capability probe at invalid register read
  ALSA: seq: Enable 'use' locking in all configurations
  ALSA: usb-audio: Add native DSD support for Pro-Ject Pre Box S2 Digital
This commit is contained in:
Linus Torvalds 2017-10-19 16:15:17 -04:00
commit 962556b57c
7 changed files with 95 additions and 58 deletions

View file

@ -248,6 +248,9 @@ int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
void *private_data);
void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
#define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true)
int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
int (*func)(struct snd_kcontrol *, void *),
void *arg);
/*
* Helper functions for jack-detection controls

View file

@ -23,8 +23,6 @@
#include <sound/core.h>
#include "seq_lock.h"
#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
/* wait until all locks are released */
void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
{
@ -41,5 +39,3 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
}
}
EXPORT_SYMBOL(snd_use_lock_sync_helper);
#endif

View file

@ -3,8 +3,6 @@
#include <linux/sched.h>
#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
typedef atomic_t snd_use_lock_t;
/* initialize lock */
@ -20,14 +18,4 @@ typedef atomic_t snd_use_lock_t;
void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line);
#define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__)
#else /* SMP || CONFIG_SND_DEBUG */
typedef spinlock_t snd_use_lock_t; /* dummy */
#define snd_use_lock_init(lockp) /**/
#define snd_use_lock_use(lockp) /**/
#define snd_use_lock_free(lockp) /**/
#define snd_use_lock_sync(lockp) /**/
#endif /* SMP || CONFIG_SND_DEBUG */
#endif /* __SND_SEQ_LOCK_H */

View file

@ -484,3 +484,34 @@ void snd_ctl_sync_vmaster(struct snd_kcontrol *kcontrol, bool hook_only)
master->hook(master->hook_private_data, master->val);
}
EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster);
/**
* snd_ctl_apply_vmaster_slaves - Apply function to each vmaster slave
* @kctl: vmaster kctl element
* @func: function to apply
* @arg: optional function argument
*
* Apply the function @func to each slave kctl of the given vmaster kctl.
* Returns 0 if successful, or a negative error code.
*/
int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
int (*func)(struct snd_kcontrol *, void *),
void *arg)
{
struct link_master *master;
struct link_slave *slave;
int err;
master = snd_kcontrol_chip(kctl);
err = master_init(master);
if (err < 0)
return err;
list_for_each_entry(slave, &master->slaves, list) {
err = func(&slave->slave, arg);
if (err < 0)
return err;
}
return 0;
}
EXPORT_SYMBOL_GPL(snd_ctl_apply_vmaster_slaves);

View file

@ -284,6 +284,11 @@ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
(cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
if (cur_cap == -1) {
dev_dbg(bus->dev, "Invalid capability reg read\n");
break;
}
switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
case AZX_ML_CAP_ID:
dev_dbg(bus->dev, "Found ML capability\n");

View file

@ -1803,36 +1803,6 @@ static int check_slave_present(struct hda_codec *codec,
return 1;
}
/* guess the value corresponding to 0dB */
static int get_kctl_0dB_offset(struct hda_codec *codec,
struct snd_kcontrol *kctl, int *step_to_check)
{
int _tlv[4];
const int *tlv = NULL;
int val = -1;
if ((kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) &&
kctl->tlv.c == snd_hda_mixer_amp_tlv) {
get_ctl_amp_tlv(kctl, _tlv);
tlv = _tlv;
} else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
tlv = kctl->tlv.p;
if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) {
int step = tlv[3];
step &= ~TLV_DB_SCALE_MUTE;
if (!step)
return -1;
if (*step_to_check && *step_to_check != step) {
codec_err(codec, "Mismatching dB step for vmaster slave (%d!=%d)\n",
- *step_to_check, step);
return -1;
}
*step_to_check = step;
val = -tlv[2] / step;
}
return val;
}
/* call kctl->put with the given value(s) */
static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
{
@ -1847,19 +1817,58 @@ static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
return 0;
}
/* initialize the slave volume with 0dB */
static int init_slave_0dB(struct hda_codec *codec,
void *data, struct snd_kcontrol *slave)
struct slave_init_arg {
struct hda_codec *codec;
int step;
};
/* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */
static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
{
int offset = get_kctl_0dB_offset(codec, slave, data);
if (offset > 0)
put_kctl_with_value(slave, offset);
struct slave_init_arg *arg = _arg;
int _tlv[4];
const int *tlv = NULL;
int step;
int val;
if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
if (kctl->tlv.c != snd_hda_mixer_amp_tlv) {
codec_err(arg->codec,
"Unexpected TLV callback for slave %s:%d\n",
kctl->id.name, kctl->id.index);
return 0; /* ignore */
}
get_ctl_amp_tlv(kctl, _tlv);
tlv = _tlv;
} else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
tlv = kctl->tlv.p;
if (!tlv || tlv[0] != SNDRV_CTL_TLVT_DB_SCALE)
return 0;
step = tlv[3];
step &= ~TLV_DB_SCALE_MUTE;
if (!step)
return 0;
if (arg->step && arg->step != step) {
codec_err(arg->codec,
"Mismatching dB step for vmaster slave (%d!=%d)\n",
arg->step, step);
return 0;
}
arg->step = step;
val = -tlv[2] / step;
if (val > 0) {
put_kctl_with_value(kctl, val);
return val;
}
return 0;
}
/* unmute the slave */
static int init_slave_unmute(struct hda_codec *codec,
void *data, struct snd_kcontrol *slave)
/* unmute the slave via snd_ctl_apply_vmaster_slaves() */
static int init_slave_unmute(struct snd_kcontrol *slave, void *_arg)
{
return put_kctl_with_value(slave, 1);
}
@ -1919,9 +1928,13 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
/* init with master mute & zero volume */
put_kctl_with_value(kctl, 0);
if (init_slave_vol) {
int step = 0;
map_slaves(codec, slaves, suffix,
tlv ? init_slave_0dB : init_slave_unmute, &step);
struct slave_init_arg arg = {
.codec = codec,
.step = 0,
};
snd_ctl_apply_vmaster_slaves(kctl,
tlv ? init_slave_0dB : init_slave_unmute,
&arg);
}
if (ctl_ret)

View file

@ -1354,6 +1354,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */
case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */
case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */
case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
if (fp->altsetting == 2)
return SNDRV_PCM_FMTBIT_DSD_U32_BE;
break;