diff options
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 135 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 10 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 101 |
5 files changed, 240 insertions, 12 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 8fd745cb3f36..70bb365a08d2 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1965,7 +1965,7 @@ static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new vmaster_mute_mode = { +static const struct snd_kcontrol_new vmaster_mute_mode = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Mute-LED Mode", .info = vmaster_mute_mode_info, @@ -2705,7 +2705,7 @@ static int spdif_share_sw_put(struct snd_kcontrol *kcontrol, return 0; } -static struct snd_kcontrol_new spdif_share_sw = { +static const struct snd_kcontrol_new spdif_share_sw = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "IEC958 Default PCM Playback Switch", .info = snd_ctl_boolean_mono_info, diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c8256a89375a..59ab34fa0bc8 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -77,6 +77,7 @@ enum { POS_FIX_POSBUF, POS_FIX_VIACOMBO, POS_FIX_COMBO, + POS_FIX_SKL, }; /* Defines for ATI HD Audio support in SB450 south bridge */ @@ -148,7 +149,7 @@ module_param_array(model, charp, NULL, 0444); MODULE_PARM_DESC(model, "Use the given board model."); module_param_array(position_fix, int, NULL, 0444); MODULE_PARM_DESC(position_fix, "DMA pointer read method." - "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO)."); + "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+)."); module_param_array(bdl_pos_adj, int, NULL, 0644); MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); module_param_array(probe_mask, int, NULL, 0444); @@ -534,9 +535,101 @@ static void bxt_reduce_dma_latency(struct azx *chip) { u32 val; - val = azx_readl(chip, SKL_EM4L); + val = azx_readl(chip, VS_EM4L); val &= (0x3 << 20); - azx_writel(chip, SKL_EM4L, val); + azx_writel(chip, VS_EM4L, val); +} + +/* + * ML_LCAP bits: + * bit 0: 6 MHz Supported + * bit 1: 12 MHz Supported + * bit 2: 24 MHz Supported + * bit 3: 48 MHz Supported + * bit 4: 96 MHz Supported + * bit 5: 192 MHz Supported + */ +static int intel_get_lctl_scf(struct azx *chip) +{ + struct hdac_bus *bus = azx_bus(chip); + static int preferred_bits[] = { 2, 3, 1, 4, 5 }; + u32 val, t; + int i; + + val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCAP); + + for (i = 0; i < ARRAY_SIZE(preferred_bits); i++) { + t = preferred_bits[i]; + if (val & (1 << t)) + return t; + } + + dev_warn(chip->card->dev, "set audio clock frequency to 6MHz"); + return 0; +} + +static int intel_ml_lctl_set_power(struct azx *chip, int state) +{ + struct hdac_bus *bus = azx_bus(chip); + u32 val; + int timeout; + + /* + * the codecs are sharing the first link setting by default + * If other links are enabled for stream, they need similar fix + */ + val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL); + val &= ~AZX_MLCTL_SPA; + val |= state << AZX_MLCTL_SPA_SHIFT; + writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL); + /* wait for CPA */ + timeout = 50; + while (timeout) { + if (((readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL)) & + AZX_MLCTL_CPA) == (state << AZX_MLCTL_CPA_SHIFT)) + return 0; + timeout--; + udelay(10); + } + + return -1; +} + +static void intel_init_lctl(struct azx *chip) +{ + struct hdac_bus *bus = azx_bus(chip); + u32 val; + int ret; + + /* 0. check lctl register value is correct or not */ + val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL); + /* if SCF is already set, let's use it */ + if ((val & ML_LCTL_SCF_MASK) != 0) + return; + + /* + * Before operating on SPA, CPA must match SPA. + * Any deviation may result in undefined behavior. + */ + if (((val & AZX_MLCTL_SPA) >> AZX_MLCTL_SPA_SHIFT) != + ((val & AZX_MLCTL_CPA) >> AZX_MLCTL_CPA_SHIFT)) + return; + + /* 1. turn link down: set SPA to 0 and wait CPA to 0 */ + ret = intel_ml_lctl_set_power(chip, 0); + udelay(100); + if (ret) + goto set_spa; + + /* 2. update SCF to select a properly audio clock*/ + val &= ~ML_LCTL_SCF_MASK; + val |= intel_get_lctl_scf(chip); + writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL); + +set_spa: + /* 4. turn link up: set SPA to 1 and wait CPA to 1 */ + intel_ml_lctl_set_power(chip, 1); + udelay(100); } static void hda_intel_init_chip(struct azx *chip, bool full_reset) @@ -564,6 +657,9 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset) /* reduce dma latency to avoid noise */ if (IS_BXT(pci)) bxt_reduce_dma_latency(chip); + + if (bus->mlcap != NULL) + intel_init_lctl(chip); } /* calculate runtime delay from LPIB */ @@ -815,6 +911,31 @@ static unsigned int azx_via_get_position(struct azx *chip, return bound_pos + mod_dma_pos; } +static unsigned int azx_skl_get_dpib_pos(struct azx *chip, + struct azx_dev *azx_dev) +{ + return _snd_hdac_chip_readl(azx_bus(chip), + AZX_REG_VS_SDXDPIB_XBASE + + (AZX_REG_VS_SDXDPIB_XINTERVAL * + azx_dev->core.index)); +} + +/* get the current DMA position with correction on SKL+ chips */ +static unsigned int azx_get_pos_skl(struct azx *chip, struct azx_dev *azx_dev) +{ + /* DPIB register gives a more accurate position for playback */ + if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + return azx_skl_get_dpib_pos(chip, azx_dev); + + /* For capture, we need to read posbuf, but it requires a delay + * for the possible boundary overlap; the read of DPIB fetches the + * actual posbuf + */ + udelay(20); + azx_skl_get_dpib_pos(chip, azx_dev); + return azx_get_pos_posbuf(chip, azx_dev); +} + #ifdef CONFIG_PM static DEFINE_MUTEX(card_list_lock); static LIST_HEAD(card_list); @@ -1351,6 +1472,7 @@ static int check_position_fix(struct azx *chip, int fix) case POS_FIX_POSBUF: case POS_FIX_VIACOMBO: case POS_FIX_COMBO: + case POS_FIX_SKL: return fix; } @@ -1371,6 +1493,10 @@ static int check_position_fix(struct azx *chip, int fix) dev_dbg(chip->card->dev, "Using LPIB position fix\n"); return POS_FIX_LPIB; } + if (IS_SKL_PLUS(chip->pci)) { + dev_dbg(chip->card->dev, "Using SKL position fix\n"); + return POS_FIX_SKL; + } return POS_FIX_AUTO; } @@ -1382,6 +1508,7 @@ static void assign_position_fix(struct azx *chip, int fix) [POS_FIX_POSBUF] = azx_get_pos_posbuf, [POS_FIX_VIACOMBO] = azx_via_get_position, [POS_FIX_COMBO] = azx_get_pos_lpib, + [POS_FIX_SKL] = azx_get_pos_skl, }; chip->get_position[0] = chip->get_position[1] = callbacks[fix]; @@ -1390,7 +1517,7 @@ static void assign_position_fix(struct azx *chip, int fix) if (fix == POS_FIX_COMBO) chip->get_position[1] = NULL; - if (fix == POS_FIX_POSBUF && + if ((fix == POS_FIX_POSBUF || fix == POS_FIX_SKL) && (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) { chip->get_delay[0] = chip->get_delay[1] = azx_get_delay_from_lpib; diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 07a9deb17477..a148176c16a9 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -857,7 +857,7 @@ static int chipio_write_address(struct hda_codec *codec, chip_addx >> 16); } - spec->curr_chip_addx = (res < 0) ? ~0UL : chip_addx; + spec->curr_chip_addx = (res < 0) ? ~0U : chip_addx; return res; } @@ -882,7 +882,7 @@ static int chipio_write_data(struct hda_codec *codec, unsigned int data) /*If no error encountered, automatically increment the address as per chip behaviour*/ spec->curr_chip_addx = (res != -EIO) ? - (spec->curr_chip_addx + 4) : ~0UL; + (spec->curr_chip_addx + 4) : ~0U; return res; } @@ -933,7 +933,7 @@ static int chipio_read_data(struct hda_codec *codec, unsigned int *data) /*If no error encountered, automatically increment the address as per chip behaviour*/ spec->curr_chip_addx = (res != -EIO) ? - (spec->curr_chip_addx + 4) : ~0UL; + (spec->curr_chip_addx + 4) : ~0U; return res; } @@ -1168,7 +1168,7 @@ static int dspio_write_multiple(struct hda_codec *codec, int status = 0; unsigned int count; - if ((buffer == NULL)) + if (buffer == NULL) return -EINVAL; count = 0; @@ -1210,7 +1210,7 @@ static int dspio_read_multiple(struct hda_codec *codec, unsigned int *buffer, unsigned int skip_count; unsigned int dummy; - if ((buffer == NULL)) + if (buffer == NULL) return -1; count = 0; diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 1461ef8eb749..37f11560186a 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -383,7 +383,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, return 0; } -static struct snd_kcontrol_new eld_bytes_ctl = { +static const struct snd_kcontrol_new eld_bytes_ctl = { .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "ELD", diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 299835d1fbaa..9371f1a95b33 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4833,6 +4833,8 @@ enum { ALC290_FIXUP_SUBWOOFER_HSJACK, ALC269_FIXUP_THINKPAD_ACPI, ALC269_FIXUP_DMIC_THINKPAD_ACPI, + ALC255_FIXUP_ACER_MIC_NO_PRESENCE, + ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, ALC255_FIXUP_HEADSET_MODE, @@ -4872,6 +4874,11 @@ enum { ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, ALC269_FIXUP_ATIV_BOOK_8, ALC221_FIXUP_HP_MIC_NO_PRESENCE, + ALC256_FIXUP_ASUS_HEADSET_MODE, + ALC256_FIXUP_ASUS_MIC, + ALC256_FIXUP_ASUS_AIO_GPIO2, + ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, + ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, }; static const struct hda_fixup alc269_fixups[] = { @@ -5289,6 +5296,24 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_THINKPAD_ACPI, }, + [ALC255_FIXUP_ACER_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 = ALC255_FIXUP_HEADSET_MODE + }, + [ALC255_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 = ALC255_FIXUP_HEADSET_MODE + }, [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -5579,6 +5604,50 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_HEADSET_MODE }, + [ALC256_FIXUP_ASUS_HEADSET_MODE] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_headset_mode, + }, + [ALC256_FIXUP_ASUS_MIC] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x13, 0x90a60160 }, /* use as internal mic */ + { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */ + { } + }, + .chained = true, + .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE + }, + [ALC256_FIXUP_ASUS_AIO_GPIO2] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + /* Set up GPIO2 for the speaker amp */ + { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, + { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, + { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, + {} + }, + }, + [ALC233_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_MIC + }, + [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + /* Enables internal speaker */ + {0x20, AC_VERB_SET_COEF_INDEX, 0x40}, + {0x20, AC_VERB_SET_PROC_COEF, 0x8800}, + {} + }, + .chained = true, + .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -5692,15 +5761,27 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), @@ -5875,6 +5956,18 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {0x21, 0x03211020} static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE, + {0x12, 0x90a601c0}, + {0x14, 0x90171120}, + {0x21, 0x02211030}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, + {0x14, 0x90170110}, + {0x1b, 0x90a70130}, + {0x21, 0x03211020}), + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, + {0x1a, 0x90a70130}, + {0x1b, 0x90170110}, + {0x21, 0x03211020}), SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, ALC225_STANDARD_PINS, {0x12, 0xb7a60130}, @@ -5995,6 +6088,14 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x21, 0x02211020}), SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ALC256_STANDARD_PINS), + SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC, + {0x14, 0x90170110}, + {0x1b, 0x90a70130}, + {0x21, 0x04211020}), + SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC, + {0x14, 0x90170110}, + {0x1b, 0x90a70130}, + {0x21, 0x03211020}), SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, {0x12, 0x90a60130}, {0x14, 0x90170110}, |