From 3b7e5c7e36ed4a046bbea6d36c9be9d1d6107ae0 Mon Sep 17 00:00:00 2001 From: Jurgen Kramer Date: Fri, 5 Jun 2015 09:42:49 +0200 Subject: ALSA: usb-audio: add native DSD support for JLsounds I2SoverUSB This patch adds native DSD support for the XMOS based JLsounds I2SoverUSB board Signed-off-by: Jurgen Kramer Cc: Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index b8c97d0..754e689 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1267,8 +1267,9 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, if (fp->altsetting == 2) return SNDRV_PCM_FMTBIT_DSD_U32_BE; break; - /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */ - case USB_ID(0x20b1, 0x2009): + + case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */ + case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */ if (fp->altsetting == 3) return SNDRV_PCM_FMTBIT_DSD_U32_BE; break; -- cgit v1.1 From 132bd96bc56f9cafd24b71de389984d0e83a0956 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 9 Jun 2015 13:39:31 +1000 Subject: ALSA: hda - fix number of devices query on hotplug The new regmap code seems to cache this, which isn't helpful for the hotplug dock situation where this gets updated. Use the uncached query for this. Signed-off-by: Dave Airlie Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index b49feff..b778221 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -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; -- cgit v1.1 From 98a226ed21949601b270f7ea20abc9f72f7b0be9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 10 Jun 2015 10:27:00 +0200 Subject: ALSA: hda - Don't actually write registers for caps overwrites Along with the transition to regmap for managing the cached parameter reads, the caps overwrite was also moved to regmap cache. The cache change itself works, but it still tries to write the non-existing verb (the HDA parameter is read-only) wrongly. It's harmless in most cases, but some chips are picky and may result in the codec communication stall. This patch avoids it just by adding the missing flag check in reg_write ops. Signed-off-by: Takashi Iwai --- sound/hda/hdac_regmap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/hda/hdac_regmap.c b/sound/hda/hdac_regmap.c index 7371e0c..c4f5e61 100644 --- a/sound/hda/hdac_regmap.c +++ b/sound/hda/hdac_regmap.c @@ -265,6 +265,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); -- cgit v1.1 From bf06848bdbe549175d25d2327ab9f37d4bd556b7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 10 Jun 2015 12:03:49 +0200 Subject: ALSA: hda - Continue probing even if i915 binding fails Currently snd-hda-intel driver aborts the probing of Intel HD-audio controller with i915 power well management when binding with i915 driver via hda_i915_init() fails. This is no big problem for Haswell and Broadwell where the HD-audio controllers are dedicated to HDMI/DP, thus i915 link is mandatory. However, Skylake, Baytrail and Braswell have only one controller and both HDMI/DP and analog codecs share the same bus. Thus, even if HDMI/DP isn't usable, we should keep the controller working for other codecs. For fixing this, this patch simply allows continuing the probing even if hda_i915_init() call fails. This may leave stale sound components for HDMI/DP devices that are unbound with graphics. We could abort the probing selectively, but from the code simplicity POV, it's better to continue in all cases. Reported-by: Libin Yang Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index fea198c..8a0af67 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1855,7 +1855,7 @@ static int azx_probe_continue(struct azx *chip) #ifdef CONFIG_SND_HDA_I915 err = hda_i915_init(hda); if (err < 0) - goto out_free; + goto skip_i915; err = hda_display_power(hda, true); if (err < 0) { dev_err(chip->card->dev, @@ -1865,6 +1865,7 @@ static int azx_probe_continue(struct azx *chip) #endif } + skip_i915: err = azx_first_init(chip); if (err < 0) goto out_free; -- cgit v1.1 From a686ec4c5f28eb1b384e4b87b08543155c970072 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 11 Jun 2015 10:51:28 +0200 Subject: ALSA: hda - Re-add the lost fake mute support Yet another regression by the transition to regmap cache; for better usability, we had the fake mute control using the zero amp value for Conexant codecs, and this was forgotten in the new hda core code. Since the bits 4-7 are unused for the amp registers (as we follow the syntax of AMP_GET verb), the bit 4 is now used to indicate the fake mute. For setting this flag, snd_hda_codec_amp_update() becomes a function from a simple macro. The bonus is that it gained a proper function description. Signed-off-by: Takashi Iwai --- include/sound/hda_regmap.h | 2 ++ sound/hda/hdac_regmap.c | 5 +++++ sound/pci/hda/hda_codec.c | 25 +++++++++++++++++++++++++ sound/pci/hda/hda_local.h | 4 ++-- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/include/sound/hda_regmap.h b/include/sound/hda_regmap.h index 53a18b3..df70590 100644 --- a/include/sound/hda_regmap.h +++ b/include/sound/hda_regmap.h @@ -9,6 +9,8 @@ #include #include +#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, diff --git a/sound/hda/hdac_regmap.c b/sound/hda/hdac_regmap.c index c4f5e61..1eabcdf 100644 --- a/sound/hda/hdac_regmap.c +++ b/sound/hda/hdac_regmap.c @@ -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; @@ -283,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; diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index b778221..5645481 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1376,6 +1376,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 * @nid: NID to read the AMP value diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 3b567f4..bed66c3 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -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, -- cgit v1.1 From 535115b5ff51c702a9a22feb918707c2fe1fbd17 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 12 Jun 2015 07:53:58 +0200 Subject: ALSA: hda - Abort the probe without i915 binding for HSW/BDW The previous patch tried to continue the probe if i915 binding fails. For for simplicity reason, we haven't implemented abort even for controller chips that are dedicated for HDMI/DP on HSW and BDW. However, Mengdong suggested that this can be dangerous; BIOS may disable gfx power well although the PCI entry for HD-audio is left, and this may result in the unexpected behavior, kernel errors, etc. For avoiding this situation, abort the probe at i915 binding failure only for HSW/BDW chips selectively. For other chips, it still continues. Fixes: bf06848bdbe5 ('ALSA: hda - Continue probing even if i915 binding fails') Reported-by: Mengdong Lin Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 8a0af67..a244ba7 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -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) - goto skip_i915; + 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, -- cgit v1.1