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:
Коммит
962556b57c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче