aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/ac97/ac97_patch.c2
-rw-r--r--sound/pci/ctxfi/cthw20k1.c14
-rw-r--r--sound/pci/emu10k1/emu10k1x.c2
-rw-r--r--sound/pci/hda/Kconfig4
-rw-r--r--sound/pci/hda/hda_codec.c28
-rw-r--r--sound/pci/hda/hda_intel.c117
-rw-r--r--sound/pci/hda/hda_intel.h1
-rw-r--r--sound/pci/hda/hda_tegra.c50
-rw-r--r--sound/pci/hda/patch_hdmi.c32
-rw-r--r--sound/pci/hda/patch_realtek.c190
-rw-r--r--sound/pci/ice1712/ice1712.c3
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c4
12 files changed, 342 insertions, 105 deletions
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index ebf926728c5f..45ef0f52ec55 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -1356,7 +1356,7 @@ static int patch_cx20551(struct snd_ac97 *ac97)
}
/*
- * Analog Device AD18xx, AD19xx codecs
+ * Analog Devices AD18xx, AD19xx codecs
*/
#ifdef CONFIG_PM
static void ad18xx_resume(struct snd_ac97 *ac97)
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index 6e3177bcc709..015c0d676897 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -168,7 +168,7 @@ static int src_get_rsc_ctrl_blk(void **rblk)
static int src_put_rsc_ctrl_blk(void *blk)
{
- kfree((struct src_rsc_ctrl_blk *)blk);
+ kfree(blk);
return 0;
}
@@ -494,7 +494,7 @@ static int src_mgr_get_ctrl_blk(void **rblk)
static int src_mgr_put_ctrl_blk(void *blk)
{
- kfree((struct src_mgr_ctrl_blk *)blk);
+ kfree(blk);
return 0;
}
@@ -515,7 +515,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk)
static int srcimp_mgr_put_ctrl_blk(void *blk)
{
- kfree((struct srcimp_mgr_ctrl_blk *)blk);
+ kfree(blk);
return 0;
}
@@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk)
static int amixer_rsc_put_ctrl_blk(void *blk)
{
- kfree((struct amixer_rsc_ctrl_blk *)blk);
+ kfree(blk);
return 0;
}
@@ -909,7 +909,7 @@ static int dai_get_ctrl_blk(void **rblk)
static int dai_put_ctrl_blk(void *blk)
{
- kfree((struct dai_ctrl_blk *)blk);
+ kfree(blk);
return 0;
}
@@ -958,7 +958,7 @@ static int dao_get_ctrl_blk(void **rblk)
static int dao_put_ctrl_blk(void *blk)
{
- kfree((struct dao_ctrl_blk *)blk);
+ kfree(blk);
return 0;
}
@@ -1156,7 +1156,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
static int daio_mgr_put_ctrl_blk(void *blk)
{
- kfree((struct daio_mgr_ctrl_blk *)blk);
+ kfree(blk);
return 0;
}
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index ddb7c2ce3f7c..def8161cde4c 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1040,7 +1040,7 @@ static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry,
if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
continue;
- if (reg < 0x49 && val <= 0xffffffff && channel_id <= 2)
+ if (reg < 0x49 && channel_id <= 2)
snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
}
}
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index e1d3082a4fe9..7ba542e45a3d 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -99,10 +99,10 @@ comment "Set to Y if you want auto-loading the codec driver"
depends on SND_HDA=y && SND_HDA_CODEC_REALTEK=m
config SND_HDA_CODEC_ANALOG
- tristate "Build Analog Device HD-audio codec support"
+ tristate "Build Analog Devices HD-audio codec support"
select SND_HDA_GENERIC
help
- Say Y or M here to include Analog Device HD-audio codec support in
+ Say Y or M here to include Analog Devices HD-audio codec support in
snd-hda-intel driver, such as AD1986A.
comment "Set to Y if you want auto-loading the codec driver"
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index a34a2c9f4bcf..7e3ae4534df9 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -641,8 +641,18 @@ static void hda_jackpoll_work(struct work_struct *work)
struct hda_codec *codec =
container_of(work, struct hda_codec, jackpoll_work.work);
- snd_hda_jack_set_dirty_all(codec);
- snd_hda_jack_poll_all(codec);
+ /* for non-polling trigger: we need nothing if already powered on */
+ if (!codec->jackpoll_interval && snd_hdac_is_power_on(&codec->core))
+ return;
+
+ /* the power-up/down sequence triggers the runtime resume */
+ snd_hda_power_up_pm(codec);
+ /* update jacks manually if polling is required, too */
+ if (codec->jackpoll_interval) {
+ snd_hda_jack_set_dirty_all(codec);
+ snd_hda_jack_poll_all(codec);
+ }
+ snd_hda_power_down_pm(codec);
if (!codec->jackpoll_interval)
return;
@@ -2951,18 +2961,14 @@ static int hda_codec_runtime_resume(struct device *dev)
static int hda_codec_force_resume(struct device *dev)
{
struct hda_codec *codec = dev_to_hda_codec(dev);
- bool forced_resume = !codec->relaxed_resume && codec->jacktbl.used;
int ret;
- /* The get/put pair below enforces the runtime resume even if the
- * device hasn't been used at suspend time. This trick is needed to
- * update the jack state change during the sleep.
- */
- if (forced_resume)
- pm_runtime_get_noresume(dev);
ret = pm_runtime_force_resume(dev);
- if (forced_resume)
- pm_runtime_put(dev);
+ /* schedule jackpoll work for jack detection update */
+ if (codec->jackpoll_interval ||
+ (pm_runtime_suspended(dev) && hda_codec_need_resume(codec)))
+ schedule_delayed_work(&codec->jackpoll_work,
+ codec->jackpoll_interval);
return ret;
}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index bd093593f8fb..11ec5c56c80e 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1004,7 +1004,8 @@ static void __azx_runtime_resume(struct azx *chip, bool from_rt)
if (status && from_rt) {
list_for_each_codec(codec, &chip->bus)
- if (status & (1 << codec->addr))
+ if (!codec->relaxed_resume &&
+ (status & (1 << codec->addr)))
schedule_delayed_work(&codec->jackpoll_work,
codec->jackpoll_interval);
}
@@ -1027,7 +1028,7 @@ static int azx_suspend(struct device *dev)
chip = card->private_data;
bus = azx_bus(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- __azx_runtime_suspend(chip);
+ pm_runtime_force_suspend(dev);
if (bus->irq >= 0) {
free_irq(bus->irq, chip);
bus->irq = -1;
@@ -1055,7 +1056,8 @@ static int azx_resume(struct device *dev)
chip->msi = 0;
if (azx_acquire_irq(chip, 1) < 0)
return -EIO;
- __azx_runtime_resume(chip, false);
+
+ pm_runtime_force_resume(dev);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
trace_azx_resume(chip);
@@ -1071,6 +1073,8 @@ static int azx_freeze_noirq(struct device *dev)
struct azx *chip = card->private_data;
struct pci_dev *pci = to_pci_dev(dev);
+ if (!azx_is_pm_ready(card))
+ return 0;
if (chip->driver_type == AZX_DRIVER_SKL)
pci_set_power_state(pci, PCI_D3hot);
@@ -1083,6 +1087,8 @@ static int azx_thaw_noirq(struct device *dev)
struct azx *chip = card->private_data;
struct pci_dev *pci = to_pci_dev(dev);
+ if (!azx_is_pm_ready(card))
+ return 0;
if (chip->driver_type == AZX_DRIVER_SKL)
pci_set_power_state(pci, PCI_D0);
@@ -1098,12 +1104,12 @@ static int azx_runtime_suspend(struct device *dev)
if (!azx_is_pm_ready(card))
return 0;
chip = card->private_data;
- if (!azx_has_pm_runtime(chip))
- return 0;
/* enable controller wake up event */
- azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
- STATESTS_INT_MASK);
+ if (snd_power_get_state(card) == SNDRV_CTL_POWER_D0) {
+ azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
+ STATESTS_INT_MASK);
+ }
__azx_runtime_suspend(chip);
trace_azx_runtime_suspend(chip);
@@ -1114,17 +1120,18 @@ static int azx_runtime_resume(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
+ bool from_rt = snd_power_get_state(card) == SNDRV_CTL_POWER_D0;
if (!azx_is_pm_ready(card))
return 0;
chip = card->private_data;
- if (!azx_has_pm_runtime(chip))
- return 0;
- __azx_runtime_resume(chip, true);
+ __azx_runtime_resume(chip, from_rt);
/* disable controller Wake Up event*/
- azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
- ~STATESTS_INT_MASK);
+ if (from_rt) {
+ azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
+ ~STATESTS_INT_MASK);
+ }
trace_azx_runtime_resume(chip);
return 0;
@@ -1199,10 +1206,8 @@ static void azx_vs_set_state(struct pci_dev *pci,
if (!disabled) {
dev_info(chip->card->dev,
"Start delayed initialization\n");
- if (azx_probe_continue(chip) < 0) {
+ if (azx_probe_continue(chip) < 0)
dev_err(chip->card->dev, "initialization error\n");
- hda->init_failed = true;
- }
}
} else {
dev_info(chip->card->dev, "%s via vga_switcheroo\n",
@@ -1335,12 +1340,15 @@ static int register_vga_switcheroo(struct azx *chip)
/*
* destructor
*/
-static int azx_free(struct azx *chip)
+static void azx_free(struct azx *chip)
{
struct pci_dev *pci = chip->pci;
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
struct hdac_bus *bus = azx_bus(chip);
+ if (hda->freed)
+ return;
+
if (azx_has_pm_runtime(chip) && chip->running)
pm_runtime_get_noresume(&pci->dev);
chip->running = 0;
@@ -1384,9 +1392,8 @@ static int azx_free(struct azx *chip)
if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT)
snd_hdac_i915_exit(bus);
- kfree(hda);
- return 0;
+ hda->freed = 1;
}
static int azx_dev_disconnect(struct snd_device *device)
@@ -1402,7 +1409,8 @@ static int azx_dev_disconnect(struct snd_device *device)
static int azx_dev_free(struct snd_device *device)
{
- return azx_free(device->device_data);
+ azx_free(device->device_data);
+ return 0;
}
#ifdef SUPPORT_VGA_SWITCHEROO
@@ -1769,7 +1777,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
if (err < 0)
return err;
- hda = kzalloc(sizeof(*hda), GFP_KERNEL);
+ hda = devm_kzalloc(&pci->dev, sizeof(*hda), GFP_KERNEL);
if (!hda) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1810,7 +1818,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
err = azx_bus_init(chip, model[dev]);
if (err < 0) {
- kfree(hda);
pci_disable_device(pci);
return err;
}
@@ -2005,7 +2012,7 @@ static int azx_first_init(struct azx *chip)
/* codec detection */
if (!azx_bus(chip)->codec_mask) {
dev_err(card->dev, "no codecs found!\n");
- return -ENODEV;
+ /* keep running the rest for the runtime PM */
}
if (azx_acquire_irq(chip, 0) < 0)
@@ -2027,24 +2034,15 @@ static void azx_firmware_cb(const struct firmware *fw, void *context)
{
struct snd_card *card = context;
struct azx *chip = card->private_data;
- struct pci_dev *pci = chip->pci;
-
- if (!fw) {
- dev_err(card->dev, "Cannot load firmware, aborting\n");
- goto error;
- }
- chip->fw = fw;
+ if (fw)
+ chip->fw = fw;
+ else
+ dev_err(card->dev, "Cannot load firmware, continue without patching\n");
if (!chip->disabled) {
/* continue probing */
- if (azx_probe_continue(chip))
- goto error;
+ azx_probe_continue(chip);
}
- return; /* OK */
-
- error:
- snd_card_free(card);
- pci_set_drvdata(pci, NULL);
}
#endif
@@ -2080,10 +2078,10 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream,
* some HD-audio PCI entries are exposed without any codecs, and such devices
* should be ignored from the beginning.
*/
-static const struct snd_pci_quirk driver_blacklist[] = {
- SND_PCI_QUIRK(0x1043, 0x874f, "ASUS ROG Zenith II / Strix", 0),
- SND_PCI_QUIRK(0x1462, 0xcb59, "MSI TRX40 Creator", 0),
- SND_PCI_QUIRK(0x1462, 0xcb60, "MSI TRX40", 0),
+static const struct pci_device_id driver_blacklist[] = {
+ { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1043, 0x874f) }, /* ASUS ROG Zenith II / Strix */
+ { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb59) }, /* MSI TRX40 Creator */
+ { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb60) }, /* MSI TRX40 */
{}
};
@@ -2103,7 +2101,7 @@ static int azx_probe(struct pci_dev *pci,
bool schedule_probe;
int err;
- if (snd_pci_quirk_lookup(pci, driver_blacklist)) {
+ if (pci_match_id(driver_blacklist, pci)) {
dev_info(&pci->dev, "Skipping the blacklisted device\n");
return -ENODEV;
}
@@ -2308,9 +2306,11 @@ static int azx_probe_continue(struct azx *chip)
#endif
/* create codec instances */
- err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
- if (err < 0)
- goto out_free;
+ if (bus->codec_mask) {
+ err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
+ if (err < 0)
+ goto out_free;
+ }
#ifdef CONFIG_SND_HDA_PATCH_LOADER
if (chip->fw) {
@@ -2324,7 +2324,7 @@ static int azx_probe_continue(struct azx *chip)
#endif
}
#endif
- if ((probe_only[dev] & 1) == 0) {
+ if (bus->codec_mask && !(probe_only[dev] & 1)) {
err = azx_codec_configure(chip);
if (err < 0)
goto out_free;
@@ -2341,17 +2341,23 @@ static int azx_probe_continue(struct azx *chip)
set_default_power_save(chip);
- if (azx_has_pm_runtime(chip))
+ if (azx_has_pm_runtime(chip)) {
+ pm_runtime_use_autosuspend(&pci->dev);
+ pm_runtime_allow(&pci->dev);
pm_runtime_put_autosuspend(&pci->dev);
+ }
out_free:
- if (err < 0 || !hda->need_i915_power)
+ if (err < 0) {
+ azx_free(chip);
+ return err;
+ }
+
+ if (!hda->need_i915_power)
display_power(chip, false);
- if (err < 0)
- hda->init_failed = 1;
complete_all(&hda->probe_wait);
to_hda_bus(bus)->bus_probing = 0;
- return err;
+ return 0;
}
static void azx_remove(struct pci_dev *pci)
@@ -2464,6 +2470,9 @@ static const struct pci_device_id azx_ids[] = {
/* Icelake */
{ PCI_DEVICE(0x8086, 0x34c8),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+ /* Icelake-H */
+ { PCI_DEVICE(0x8086, 0x3dc8),
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
/* Jasperlake */
{ PCI_DEVICE(0x8086, 0x38c8),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
@@ -2472,9 +2481,14 @@ static const struct pci_device_id azx_ids[] = {
/* Tigerlake */
{ PCI_DEVICE(0x8086, 0xa0c8),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+ /* Tigerlake-H */
+ { PCI_DEVICE(0x8086, 0x43c8),
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
/* Elkhart Lake */
{ PCI_DEVICE(0x8086, 0x4b55),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+ { PCI_DEVICE(0x8086, 0x4b58),
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
/* Broxton-P(Apollolake) */
{ PCI_DEVICE(0x8086, 0x5a98),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
@@ -2656,6 +2670,9 @@ static const struct pci_device_id azx_ids[] = {
{ PCI_DEVICE(0x1002, 0xab20),
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
AZX_DCAPS_PM_RUNTIME },
+ { PCI_DEVICE(0x1002, 0xab28),
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+ AZX_DCAPS_PM_RUNTIME },
{ PCI_DEVICE(0x1002, 0xab38),
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
AZX_DCAPS_PM_RUNTIME },
diff --git a/sound/pci/hda/hda_intel.h b/sound/pci/hda/hda_intel.h
index 2acfff3da1a0..3fb119f09040 100644
--- a/sound/pci/hda/hda_intel.h
+++ b/sound/pci/hda/hda_intel.h
@@ -27,6 +27,7 @@ struct hda_intel {
unsigned int use_vga_switcheroo:1;
unsigned int vga_switcheroo_registered:1;
unsigned int init_failed:1; /* delayed init failed */
+ unsigned int freed:1; /* resources already released */
bool need_i915_power:1; /* the hda controller needs i915 power */
};
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index 773992a07efa..0cc5fad1af8a 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -52,10 +52,21 @@
#define HDA_IPFS_INTR_MASK 0x188
#define HDA_IPFS_EN_INTR (1 << 16)
+/* FPCI */
+#define FPCI_DBG_CFG_2 0x10F4
+#define FPCI_GCAP_NSDO_SHIFT 18
+#define FPCI_GCAP_NSDO_MASK (0x3 << FPCI_GCAP_NSDO_SHIFT)
+
/* max number of SDs */
#define NUM_CAPTURE_SD 1
#define NUM_PLAYBACK_SD 1
+/*
+ * Tegra194 does not reflect correct number of SDO lines. Below macro
+ * is used to update the GCAP register to workaround the issue.
+ */
+#define TEGRA194_NUM_SDO_LINES 4
+
struct hda_tegra {
struct azx chip;
struct device *dev;
@@ -275,6 +286,7 @@ static int hda_tegra_init_clk(struct hda_tegra *hda)
static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
{
+ struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip);
struct hdac_bus *bus = azx_bus(chip);
struct snd_card *card = chip->card;
int err;
@@ -298,6 +310,26 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
bus->irq = irq_id;
card->sync_irq = bus->irq;
+ /*
+ * Tegra194 has 4 SDO lines and the STRIPE can be used to
+ * indicate how many of the SDO lines the stream should be
+ * striped. But GCAP register does not reflect the true
+ * capability of HW. Below workaround helps to fix this.
+ *
+ * GCAP_NSDO is bits 19:18 in T_AZA_DBG_CFG_2,
+ * 0 for 1 SDO, 1 for 2 SDO, 2 for 4 SDO lines.
+ */
+ if (of_device_is_compatible(np, "nvidia,tegra194-hda")) {
+ u32 val;
+
+ dev_info(card->dev, "Override SDO lines to %u\n",
+ TEGRA194_NUM_SDO_LINES);
+
+ val = readl(hda->regs + FPCI_DBG_CFG_2) & ~FPCI_GCAP_NSDO_MASK;
+ val |= (TEGRA194_NUM_SDO_LINES >> 1) << FPCI_GCAP_NSDO_SHIFT;
+ writel(val, hda->regs + FPCI_DBG_CFG_2);
+ }
+
gcap = azx_readw(chip, GCAP);
dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap);
@@ -332,6 +364,23 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
/* initialize chip */
azx_init_chip(chip, 1);
+ /*
+ * Playback (for 44.1K/48K, 2-channel, 16-bps) fails with
+ * 4 SDO lines due to legacy design limitation. Following
+ * is, from HD Audio Specification (Revision 1.0a), used to
+ * control striping of the stream across multiple SDO lines
+ * for sample rates <= 48K.
+ *
+ * { ((num_channels * bits_per_sample) / number of SDOs) >= 8 }
+ *
+ * Due to legacy design issue it is recommended that above
+ * ratio must be greater than 8. Since number of SDO lines is
+ * in powers of 2, next available ratio is 16 which can be
+ * used as a limiting factor here.
+ */
+ if (of_device_is_compatible(np, "nvidia,tegra194-hda"))
+ chip->bus.core.sdo_limit = 16;
+
/* codec detection */
if (!bus->codec_mask) {
dev_err(card->dev, "no codecs found!\n");
@@ -408,6 +457,7 @@ static int hda_tegra_create(struct snd_card *card,
static const struct of_device_id hda_tegra_match[] = {
{ .compatible = "nvidia,tegra30-hda" },
+ { .compatible = "nvidia,tegra194-hda" },
{},
};
MODULE_DEVICE_TABLE(of, hda_tegra_match);
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 403baca89452..e2b21ef5d7d1 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -38,6 +38,10 @@ static bool static_hdmi_pcm;
module_param(static_hdmi_pcm, bool, 0644);
MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
+static bool enable_acomp = true;
+module_param(enable_acomp, bool, 0444);
+MODULE_PARM_DESC(enable_acomp, "Enable audio component binding (default=yes)");
+
struct hdmi_spec_per_cvt {
hda_nid_t cvt_nid;
int assigned;
@@ -1844,8 +1848,10 @@ static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
/* Add sanity check to pass klockwork check.
* This should never happen.
*/
- if (WARN_ON(spdif == NULL))
+ if (WARN_ON(spdif == NULL)) {
+ mutex_unlock(&codec->spdif_mutex);
return true;
+ }
non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO);
mutex_unlock(&codec->spdif_mutex);
return non_pcm;
@@ -2018,7 +2024,7 @@ static const struct hda_pcm_ops generic_ops = {
static int hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
{
- struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
+ struct hda_codec *codec = hdac_to_hda_codec(hdac);
struct hdmi_spec *spec = codec->spec;
struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
@@ -2031,7 +2037,7 @@ static int hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
static void hdmi_get_chmap(struct hdac_device *hdac, int pcm_idx,
unsigned char *chmap)
{
- struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
+ struct hda_codec *codec = hdac_to_hda_codec(hdac);
struct hdmi_spec *spec = codec->spec;
struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
@@ -2045,7 +2051,7 @@ static void hdmi_get_chmap(struct hdac_device *hdac, int pcm_idx,
static void hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
unsigned char *chmap, int prepared)
{
- struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
+ struct hda_codec *codec = hdac_to_hda_codec(hdac);
struct hdmi_spec *spec = codec->spec;
struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
@@ -2061,7 +2067,7 @@ static void hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
static bool is_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
{
- struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
+ struct hda_codec *codec = hdac_to_hda_codec(hdac);
struct hdmi_spec *spec = codec->spec;
struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
@@ -2194,7 +2200,9 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
+ struct hdmi_eld *pin_eld = &per_pin->sink_eld;
+ pin_eld->eld_valid = false;
hdmi_present_sense(per_pin, 0);
}
@@ -2505,6 +2513,11 @@ static void generic_acomp_init(struct hda_codec *codec,
{
struct hdmi_spec *spec = codec->spec;
+ if (!enable_acomp) {
+ codec_info(codec, "audio component disabled by module option\n");
+ return;
+ }
+
spec->port2pin = port2pin;
setup_drm_audio_ops(codec, ops);
if (!snd_hdac_acomp_init(&codec->bus->core, &spec->drm_audio_ops,
@@ -3774,7 +3787,7 @@ static int atihdmi_paired_chmap_validate(struct hdac_chmap *chmap,
static int atihdmi_pin_set_slot_channel(struct hdac_device *hdac,
hda_nid_t pin_nid, int hdmi_slot, int stream_channel)
{
- struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
+ struct hda_codec *codec = hdac_to_hda_codec(hdac);
int verb;
int ati_channel_setup = 0;
@@ -3810,7 +3823,7 @@ static int atihdmi_pin_set_slot_channel(struct hdac_device *hdac,
static int atihdmi_pin_get_slot_channel(struct hdac_device *hdac,
hda_nid_t pin_nid, int asp_slot)
{
- struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
+ struct hda_codec *codec = hdac_to_hda_codec(hdac);
bool was_odd = false;
int ati_asp_slot = asp_slot;
int verb;
@@ -4132,6 +4145,11 @@ HDA_CODEC_ENTRY(0x10de0095, "GPU 95 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0097, "GPU 97 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0098, "GPU 98 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0099, "GPU 99 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de009a, "GPU 9a HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de009d, "GPU 9d HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de009e, "GPU 9e HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de009f, "GPU 9f HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de00a0, "GPU a0 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch),
HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI", patch_nvhdmi_2ch),
HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index de2826f90d34..737ef82a75fd 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -17,6 +17,7 @@
#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/input.h>
+#include <linux/leds.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/hda_codec.h>
@@ -81,6 +82,7 @@ struct alc_spec {
/* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
int mute_led_polarity;
+ int micmute_led_polarity;
hda_nid_t mute_led_nid;
hda_nid_t cap_mute_led_nid;
@@ -377,12 +379,14 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
case 0x10ec0233:
case 0x10ec0235:
case 0x10ec0236:
+ case 0x10ec0245:
case 0x10ec0255:
case 0x10ec0256:
case 0x10ec0257:
case 0x10ec0282:
case 0x10ec0283:
case 0x10ec0286:
+ case 0x10ec0287:
case 0x10ec0288:
case 0x10ec0285:
case 0x10ec0298:
@@ -797,9 +801,11 @@ static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
{
if (!alc_subsystem_id(codec, ports)) {
struct alc_spec *spec = codec->spec;
- codec_dbg(codec,
- "realtek: Enable default setup for auto mode as fallback\n");
- spec->init_amp = ALC_INIT_DEFAULT;
+ if (spec->init_amp == ALC_INIT_UNDEFINED) {
+ codec_dbg(codec,
+ "realtek: Enable default setup for auto mode as fallback\n");
+ spec->init_amp = ALC_INIT_DEFAULT;
+ }
}
}
@@ -2454,6 +2460,8 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950),
+ SND_PCI_QUIRK(0x1458, 0xa0ce, "Gigabyte X570 Aorus Xtreme", ALC1220_FIXUP_CLEVO_P950),
+ SND_PCI_QUIRK(0x1462, 0x11f7, "MSI-GE63", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x1275, "MSI-GL63", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950),
@@ -2469,6 +2477,9 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+ SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+ SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+ SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
@@ -4072,11 +4083,9 @@ static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec,
/* update LED status via GPIO */
static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
- bool enabled)
+ int polarity, bool enabled)
{
- struct alc_spec *spec = codec->spec;
-
- if (spec->mute_led_polarity)
+ if (polarity)
enabled = !enabled;
alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */
}
@@ -4087,7 +4096,8 @@ static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
struct hda_codec *codec = private_data;
struct alc_spec *spec = codec->spec;
- alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
+ alc_update_gpio_led(codec, spec->gpio_mute_led_mask,
+ spec->mute_led_polarity, enabled);
}
/* turn on/off mic-mute LED via GPIO per capture hook */
@@ -4096,9 +4106,30 @@ static void alc_gpio_micmute_update(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
+ spec->micmute_led_polarity,
spec->gen.micmute_led.led_value);
}
+#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
+static int micmute_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent);
+ struct alc_spec *spec = codec->spec;
+
+ alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
+ spec->micmute_led_polarity, !!brightness);
+ return 0;
+}
+
+static struct led_classdev micmute_led_cdev = {
+ .name = "hda::micmute",
+ .max_brightness = 1,
+ .brightness_set_blocking = micmute_led_set,
+ .default_trigger = "audio-micmute",
+};
+#endif
+
/* setup mute and mic-mute GPIO bits, add hooks appropriately */
static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
int action,
@@ -4106,6 +4137,9 @@ static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
unsigned int micmute_mask)
{
struct alc_spec *spec = codec->spec;
+#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
+ int err;
+#endif
alc_fixup_gpio(codec, action, mute_mask | micmute_mask);
@@ -4118,6 +4152,13 @@ static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
if (micmute_mask) {
spec->gpio_mic_led_mask = micmute_mask;
snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update);
+
+#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO)
+ micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE);
+ err = devm_led_classdev_register(&codec->core.dev, &micmute_led_cdev);
+ if (err)
+ codec_warn(codec, "failed to register micmute LED\n");
+#endif
}
}
@@ -4130,7 +4171,11 @@ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
static void alc285_fixup_hp_gpio_led(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
- alc_fixup_hp_gpio_led(codec, action, 0x04, 0x00);
+ struct alc_spec *spec = codec->spec;
+
+ spec->micmute_led_polarity = 1;
+
+ alc_fixup_hp_gpio_led(codec, action, 0x04, 0x01);
}
static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
@@ -5477,18 +5522,9 @@ static void alc_fixup_tpt470_dock(struct hda_codec *codec,
{ 0x19, 0x21a11010 }, /* dock mic */
{ }
};
- /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
- * the speaker output becomes too low by some reason on Thinkpads with
- * ALC298 codec
- */
- static const hda_nid_t preferred_pairs[] = {
- 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
- 0
- };
struct alc_spec *spec = codec->spec;
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
- spec->gen.preferred_dacs = preferred_pairs;
spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
snd_hda_apply_pincfgs(codec, pincfgs);
} else if (action == HDA_FIXUP_ACT_INIT) {
@@ -5501,6 +5537,23 @@ static void alc_fixup_tpt470_dock(struct hda_codec *codec,
}
}
+static void alc_fixup_tpt470_dacs(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
+ * the speaker output becomes too low by some reason on Thinkpads with
+ * ALC298 codec
+ */
+ static const hda_nid_t preferred_pairs[] = {
+ 0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
+ 0
+ };
+ struct alc_spec *spec = codec->spec;
+
+ if (action == HDA_FIXUP_ACT_PRE_PROBE)
+ spec->gen.preferred_dacs = preferred_pairs;
+}
+
static void alc_shutup_dell_xps13(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -5792,7 +5845,8 @@ static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
snd_hda_gen_hp_automute(codec, jack);
/* mute_led_polarity is set to 0, so we pass inverted value here */
- alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
+ alc_update_gpio_led(codec, 0x10, spec->mute_led_polarity,
+ !spec->gen.hp_jack_present);
}
/* Manage GPIOs for HP EliteBook Folio 9480m.
@@ -5853,6 +5907,15 @@ static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec,
}
}
+static void alc225_fixup_s3_pop_noise(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ if (action != HDA_FIXUP_ACT_PRE_PROBE)
+ return;
+
+ codec->power_save_node = 1;
+}
+
/* Forcibly assign NID 0x03 to HP/LO while NID 0x02 to SPK for EQ */
static void alc274_fixup_bind_dacs(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
@@ -5957,6 +6020,7 @@ enum {
ALC269_FIXUP_HP_LINE1_MIC1_LED,
ALC269_FIXUP_INV_DMIC,
ALC269_FIXUP_LENOVO_DOCK,
+ ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST,
ALC269_FIXUP_NO_SHUTUP,
ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
@@ -6042,9 +6106,11 @@ enum {
ALC233_FIXUP_ACER_HEADSET_MIC,
ALC294_FIXUP_LENOVO_MIC_LOCATION,
ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE,
+ ALC225_FIXUP_S3_POP_NOISE,
ALC700_FIXUP_INTEL_REFERENCE,
ALC274_FIXUP_DELL_BIND_DACS,
ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
+ ALC298_FIXUP_TPT470_DOCK_FIX,
ALC298_FIXUP_TPT470_DOCK,
ALC255_FIXUP_DUMMY_LINEOUT_VERB,
ALC255_FIXUP_DELL_HEADSET_MIC,
@@ -6077,9 +6143,12 @@ enum {
ALC294_FIXUP_ASUS_DUAL_SPK,
ALC285_FIXUP_THINKPAD_HEADSET_JACK,
ALC294_FIXUP_ASUS_HPE,
+ ALC294_FIXUP_ASUS_COEF_1B,
ALC285_FIXUP_HP_GPIO_LED,
ALC285_FIXUP_HP_MUTE_LED,
ALC236_FIXUP_HP_MUTE_LED,
+ ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
+ ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
};
static const struct hda_fixup alc269_fixups[] = {
@@ -6277,6 +6346,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
},
+ [ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc269_fixup_limit_int_mic_boost,
+ .chained = true,
+ .chain_id = ALC269_FIXUP_LENOVO_DOCK,
+ },
[ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc269_fixup_pincfg_no_hp_to_lineout,
@@ -6929,6 +7004,12 @@ static const struct hda_fixup alc269_fixups[] = {
{ }
},
.chained = true,
+ .chain_id = ALC225_FIXUP_S3_POP_NOISE
+ },
+ [ALC225_FIXUP_S3_POP_NOISE] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc225_fixup_s3_pop_noise,
+ .chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
},
[ALC700_FIXUP_INTEL_REFERENCE] = {
@@ -6961,12 +7042,18 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC274_FIXUP_DELL_BIND_DACS
},
- [ALC298_FIXUP_TPT470_DOCK] = {
+ [ALC298_FIXUP_TPT470_DOCK_FIX] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_tpt470_dock,
.chained = true,
.chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
},
+ [ALC298_FIXUP_TPT470_DOCK] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc_fixup_tpt470_dacs,
+ .chained = true,
+ .chain_id = ALC298_FIXUP_TPT470_DOCK_FIX
+ },
[ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
@@ -7201,6 +7288,17 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
},
+ [ALC294_FIXUP_ASUS_COEF_1B] = {
+ .type = HDA_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ /* Set bit 10 to correct noisy output after reboot from
+ * Windows 10 (due to pop noise reduction?)
+ */
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x1b },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x4e4b },
+ { }
+ },
+ },
[ALC285_FIXUP_HP_GPIO_LED] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc285_fixup_hp_gpio_led,
@@ -7213,6 +7311,22 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc236_fixup_hp_mute_led,
},
+ [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = {
+ .type = HDA_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc5 },
+ { }
+ },
+ },
+ [ALC295_FIXUP_ASUS_MIC_NO_PRESENCE] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+ { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
+ { }
+ },
+ .chained = true,
+ .chain_id = ALC269_FIXUP_HEADSET_MODE
+ },
};
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -7357,6 +7471,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
+ SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
+ SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED),
@@ -7378,9 +7494,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
+ SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1b11, "ASUS UX431DA", ALC294_FIXUP_ASUS_COEF_1B),
SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -7406,6 +7525,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
+ SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
+ SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
@@ -7416,12 +7537,13 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
+ SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
- SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
+ SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST),
SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
@@ -7560,6 +7682,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
{.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
{.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
+ {.id = ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST, .name = "lenovo-dock-limit-boost"},
{.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
{.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"},
{.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
@@ -7571,6 +7694,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
{.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
{.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
+ {.id = ALC298_FIXUP_TPT470_DOCK_FIX, .name = "tpt470-dock-fix"},
{.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
{.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
{.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
@@ -7988,6 +8112,18 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
{0x12, 0x90a60130},
{0x17, 0x90170110},
{0x21, 0x03211020}),
+ SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
+ {0x12, 0x90a60120},
+ {0x17, 0x90170110},
+ {0x21, 0x04211030}),
+ SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
+ {0x12, 0x90a60130},
+ {0x17, 0x90170110},
+ {0x21, 0x03211020}),
+ SND_HDA_PIN_QUIRK(0x10ec0295, 0x1043, "ASUS", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
+ {0x12, 0x90a60130},
+ {0x17, 0x90170110},
+ {0x21, 0x03211020}),
SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
{0x14, 0x90170110},
{0x21, 0x04211020}),
@@ -8028,6 +8164,12 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
ALC225_STANDARD_PINS,
{0x12, 0xb7a60130},
{0x17, 0x90170110}),
+ SND_HDA_PIN_QUIRK(0x10ec0623, 0x17aa, "Lenovo", ALC283_FIXUP_HEADSET_MIC,
+ {0x14, 0x01014010},
+ {0x17, 0x90170120},
+ {0x18, 0x02a11030},
+ {0x19, 0x02a1103f},
+ {0x21, 0x0221101f}),
{}
};
@@ -8195,7 +8337,9 @@ static int patch_alc269(struct hda_codec *codec)
spec->gen.mixer_nid = 0;
break;
case 0x10ec0215:
+ case 0x10ec0245:
case 0x10ec0285:
+ case 0x10ec0287:
case 0x10ec0289:
spec->codec_variant = ALC269_TYPE_ALC215;
spec->shutup = alc225_shutup;
@@ -8203,8 +8347,6 @@ static int patch_alc269(struct hda_codec *codec)
spec->gen.mixer_nid = 0;
break;
case 0x10ec0225:
- codec->power_save_node = 1;
- /* fall through */
case 0x10ec0295:
case 0x10ec0299:
spec->codec_variant = ALC269_TYPE_ALC225;
@@ -9456,6 +9598,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
+ HDA_CODEC_ENTRY(0x10ec0245, "ALC245", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
@@ -9475,6 +9618,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
+ HDA_CODEC_ENTRY(0x10ec0287, "ALC287", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 884d0cdec08c..73e1e5400506 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2332,7 +2332,8 @@ static int snd_ice1712_chip_init(struct snd_ice1712 *ice)
pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]);
pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]);
pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]);
- if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24) {
+ if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24 &&
+ ice->eeprom.subvendor != ICE1712_SUBDEVICE_STAUDIO_ADCIII) {
ice->gpio.write_mask = ice->eeprom.gpiomask;
ice->gpio.direction = ice->eeprom.gpiodir;
snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK,
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index 6a0520c4fb5a..cf801a235df9 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -460,7 +460,7 @@ static void xonar_st_init(struct oxygen *chip)
data->generic.anti_pop_delay = 100;
data->h6 = chip->model.dac_channels_mixer > 2;
- data->has_cs2000 = 1;
+ data->has_cs2000 = true;
data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1;
data->broken_i2c = true;
@@ -502,7 +502,7 @@ static void xonar_xense_init(struct oxygen *chip)
xonar_init_ext_power(chip);
data->generic.anti_pop_delay = 100;
- data->has_cs2000 = 1;
+ data->has_cs2000 = true;
data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1;
oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,