Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2fbbada1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "Most of commits are regression fixes for HD-audio: a few corner case
  fixes for regmap transition, and i915 binding issues.

  In addition, a quirk for another USB-audio device supporting DSD"

* tag 'sound-4.1-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - Abort the probe without i915 binding for HSW/BDW
  ALSA: hda - Re-add the lost fake mute support
  ALSA: hda - Continue probing even if i915 binding fails
  ALSA: hda - Don't actually write registers for caps overwrites
  ALSA: hda - fix number of devices query on hotplug
  ALSA: usb-audio: add native DSD support for JLsounds I2SoverUSB
parents c8d17b45 535115b5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@
#include <sound/core.h>
#include <sound/hdaudio.h>

#define AC_AMP_FAKE_MUTE	0x10	/* fake mute bit set to amp verbs */

int snd_hdac_regmap_init(struct hdac_device *codec);
void snd_hdac_regmap_exit(struct hdac_device *codec);
int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec,
+8 −0
Original line number Diff line number Diff line
@@ -246,6 +246,9 @@ static int hda_reg_read(void *context, unsigned int reg, unsigned int *val)
		return hda_reg_read_stereo_amp(codec, reg, val);
	if (verb == AC_VERB_GET_PROC_COEF)
		return hda_reg_read_coef(codec, reg, val);
	if ((verb & 0x700) == AC_VERB_SET_AMP_GAIN_MUTE)
		reg &= ~AC_AMP_FAKE_MUTE;

	err = snd_hdac_exec_verb(codec, reg, 0, val);
	if (err < 0)
		return err;
@@ -265,6 +268,9 @@ static int hda_reg_write(void *context, unsigned int reg, unsigned int val)
	unsigned int verb;
	int i, bytes, err;

	if (codec->caps_overwriting)
		return 0;

	reg &= ~0x00080000U; /* drop GET bit */
	reg |= (codec->addr << 28);
	verb = get_verb(reg);
@@ -280,6 +286,8 @@ static int hda_reg_write(void *context, unsigned int reg, unsigned int val)

	switch (verb & 0xf00) {
	case AC_VERB_SET_AMP_GAIN_MUTE:
		if ((reg & AC_AMP_FAKE_MUTE) && (val & AC_AMP_MUTE))
			val = 0;
		verb = AC_VERB_SET_AMP_GAIN_MUTE;
		if (reg & AC_AMP_GET_LEFT)
			verb |= AC_AMP_SET_LEFT >> 8;
+26 −1
Original line number Diff line number Diff line
@@ -436,7 +436,7 @@ static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
	    get_wcaps_type(wcaps) != AC_WID_PIN)
		return 0;

	parm = snd_hda_param_read(codec, nid, AC_PAR_DEVLIST_LEN);
	parm = snd_hdac_read_parm_uncached(&codec->core, nid, AC_PAR_DEVLIST_LEN);
	if (parm == -1 && codec->bus->rirb_error)
		parm = 0;
	return parm & AC_DEV_LIST_LEN_MASK;
@@ -1375,6 +1375,31 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
}
EXPORT_SYMBOL_GPL(snd_hda_override_amp_caps);

/**
 * snd_hda_codec_amp_update - update the AMP mono value
 * @codec: HD-audio codec
 * @nid: NID to read the AMP value
 * @ch: channel to update (0 or 1)
 * @dir: #HDA_INPUT or #HDA_OUTPUT
 * @idx: the index value (only for input direction)
 * @mask: bit mask to set
 * @val: the bits value to set
 *
 * Update the AMP values for the given channel, direction and index.
 */
int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid,
			     int ch, int dir, int idx, int mask, int val)
{
	unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);

	/* enable fake mute if no h/w mute but min=mute */
	if ((query_amp_caps(codec, nid, dir) &
	     (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) == AC_AMPCAP_MIN_MUTE)
		cmd |= AC_AMP_FAKE_MUTE;
	return snd_hdac_regmap_update_raw(&codec->core, cmd, mask, val);
}
EXPORT_SYMBOL_GPL(snd_hda_codec_amp_update);

/**
 * snd_hda_codec_amp_stereo - update the AMP stereo values
 * @codec: HD-audio codec
+17 −2
Original line number Diff line number Diff line
@@ -340,6 +340,11 @@ enum {
#define use_vga_switcheroo(chip)	0
#endif

#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
					((pci)->device == 0x0c0c) || \
					((pci)->device == 0x0d0c) || \
					((pci)->device == 0x160c))

static char *driver_short_names[] = {
	[AZX_DRIVER_ICH] = "HDA Intel",
	[AZX_DRIVER_PCH] = "HDA Intel PCH",
@@ -1854,8 +1859,17 @@ static int azx_probe_continue(struct azx *chip)
	if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
#ifdef CONFIG_SND_HDA_I915
		err = hda_i915_init(hda);
		if (err < 0)
		if (err < 0) {
			/* if the controller is bound only with HDMI/DP
			 * (for HSW and BDW), we need to abort the probe;
			 * for other chips, still continue probing as other
			 * codecs can be on the same link.
			 */
			if (CONTROLLER_IN_GPU(pci))
				goto out_free;
			else
				goto skip_i915;
		}
		err = hda_display_power(hda, true);
		if (err < 0) {
			dev_err(chip->card->dev,
@@ -1865,6 +1879,7 @@ static int azx_probe_continue(struct azx *chip)
#endif
	}

 skip_i915:
	err = azx_first_init(chip);
	if (err < 0)
		goto out_free;
+2 −2
Original line number Diff line number Diff line
@@ -129,8 +129,8 @@ int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
/* lowlevel accessor with caching; use carefully */
#define snd_hda_codec_amp_read(codec, nid, ch, dir, idx) \
	snd_hdac_regmap_get_amp(&(codec)->core, nid, ch, dir, idx)
#define snd_hda_codec_amp_update(codec, nid, ch, dir, idx, mask, val) \
	snd_hdac_regmap_update_amp(&(codec)->core, nid, ch, dir, idx, mask, val)
int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid,
			     int ch, int dir, int idx, int mask, int val);
int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
			     int dir, int idx, int mask, int val);
int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch,
Loading