diff mbox series

ALSA: hda/realtek: Add quirk for Lenovo Ideapad S740

Message ID 20210416081211.20059-1-tiwai@suse.de (mailing list archive)
State New
Headers show
Series ALSA: hda/realtek: Add quirk for Lenovo Ideapad S740 | expand

Commit Message

Takashi Iwai April 16, 2021, 8:12 a.m. UTC
Lenovo Ideapad S740 requires quite a few COEF setups to make its
speakers working.  The verb table was provided from Ryan Prescott as
the result of investigation via qemu:
  https://github.com/ryanprescott/realtek-verb-tools/wiki/How-to-sniff-verbs-from-a-Windows-sound-driver

BugLink: https://github.com/thesofproject/linux/issues/2748
Tested-by: Ryan Prescott <ryan@cousinscomputers.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/pci/hda/ideapad_s740_helper.c | 492 ++++++++++++++++++++++++++++
 sound/pci/hda/patch_realtek.c       |  11 +
 2 files changed, 503 insertions(+)
 create mode 100644 sound/pci/hda/ideapad_s740_helper.c

Comments

Jaroslav Kysela April 16, 2021, 8:47 a.m. UTC | #1
Dne 16. 04. 21 v 10:12 Takashi Iwai napsal(a):
> Lenovo Ideapad S740 requires quite a few COEF setups to make its
> speakers working.  The verb table was provided from Ryan Prescott as
> the result of investigation via qemu:
>   https://github.com/ryanprescott/realtek-verb-tools/wiki/How-to-sniff-verbs-from-a-Windows-sound-driver

[Cc: to Kailang / Realtek]

I believe that this sequence contains I2C writes to amplifier chips. It would
be really helpful, if Realtek can provide more information for the I2C master
interface for their codecs (describe basic I2C I/O).

				Thank you,
						Jaroslav
						

> 
> BugLink: https://github.com/thesofproject/linux/issues/2748
> Tested-by: Ryan Prescott <ryan@cousinscomputers.net>
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> ---
>  sound/pci/hda/ideapad_s740_helper.c | 492 ++++++++++++++++++++++++++++
>  sound/pci/hda/patch_realtek.c       |  11 +
>  2 files changed, 503 insertions(+)
>  create mode 100644 sound/pci/hda/ideapad_s740_helper.c
> 
> diff --git a/sound/pci/hda/ideapad_s740_helper.c b/sound/pci/hda/ideapad_s740_helper.c
> new file mode 100644
> index 000000000000..564b9086e52d
> --- /dev/null
> +++ b/sound/pci/hda/ideapad_s740_helper.c
> @@ -0,0 +1,492 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Fixes for Lenovo Ideapad S740, to be included from codec driver */
> +
> +static const struct hda_verb alc285_ideapad_s740_coefs[] = {
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x10 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0320 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
> +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
> +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
> +{}
> +};
> +
> +static void alc285_fixup_ideapad_s740_coef(struct hda_codec *codec,
> +					   const struct hda_fixup *fix,
> +					   int action)
> +{
> +	switch (action) {
> +	case HDA_FIXUP_ACT_PRE_PROBE:
> +		snd_hda_add_verbs(codec, alc285_ideapad_s740_coefs);
> +		break;
> +	}
> +}
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index 50437ec1b9af..1ef40f3ca259 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -6239,6 +6239,9 @@ static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
>  /* for alc295_fixup_hp_top_speakers */
>  #include "hp_x360_helper.c"
>  
> +/* for alc285_fixup_ideapad_s740_coef() */
> +#include "ideapad_s740_helper.c"
> +
>  enum {
>  	ALC269_FIXUP_GPIO2,
>  	ALC269_FIXUP_SONY_VAIO,
> @@ -6436,6 +6439,7 @@ enum {
>  	ALC282_FIXUP_ACER_DISABLE_LINEOUT,
>  	ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST,
>  	ALC256_FIXUP_ACER_HEADSET_MIC,
> +	ALC285_FIXUP_IDEAPAD_S740_COEF,
>  };
>  
>  static const struct hda_fixup alc269_fixups[] = {
> @@ -7920,6 +7924,12 @@ static const struct hda_fixup alc269_fixups[] = {
>  		.chained = true,
>  		.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
>  	},
> +	[ALC285_FIXUP_IDEAPAD_S740_COEF] = {
> +		.type = HDA_FIXUP_FUNC,
> +		.v.func = alc285_fixup_ideapad_s740_coef,
> +		.chained = true,
> +		.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
> +	},
>  };
>  
>  static const struct snd_pci_quirk alc269_fixup_tbl[] = {
> @@ -8263,6 +8273,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
>  	SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
>  	SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
>  	SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME),
> +	SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF),
>  	SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
>  	SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
>  	SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
>
Takashi Iwai April 16, 2021, 8:52 a.m. UTC | #2
On Fri, 16 Apr 2021 10:47:32 +0200,
Jaroslav Kysela wrote:
> 
> Dne 16. 04. 21 v 10:12 Takashi Iwai napsal(a):
> > Lenovo Ideapad S740 requires quite a few COEF setups to make its
> > speakers working.  The verb table was provided from Ryan Prescott as
> > the result of investigation via qemu:
> >   https://github.com/ryanprescott/realtek-verb-tools/wiki/How-to-sniff-verbs-from-a-Windows-sound-driver
> 
> [Cc: to Kailang / Realtek]
> 
> I believe that this sequence contains I2C writes to amplifier chips. It would
> be really helpful, if Realtek can provide more information for the I2C master
> interface for their codecs (describe basic I2C I/O).

Indeed.  Already a few drivers need the initialization of the chip
behind HD-audio, and it'd be good if we have some standard interface
for that.


thanks,

Takashi
Pierre-Louis Bossart April 16, 2021, 4:05 p.m. UTC | #3
On 4/16/21 3:47 AM, Jaroslav Kysela wrote:
> Dne 16. 04. 21 v 10:12 Takashi Iwai napsal(a):
>> Lenovo Ideapad S740 requires quite a few COEF setups to make its
>> speakers working.  The verb table was provided from Ryan Prescott as
>> the result of investigation via qemu:
>>    https://github.com/ryanprescott/realtek-verb-tools/wiki/How-to-sniff-verbs-from-a-Windows-sound-driver
> 
> [Cc: to Kailang / Realtek]
> 
> I believe that this sequence contains I2C writes to amplifier chips. It would
> be really helpful, if Realtek can provide more information for the I2C master
> interface for their codecs (describe basic I2C I/O).

The biggest problem is to figure what address/value pairs to write with 
I2C into the amplifiers, and here the catch is that those I2C/I2S 
amplifiers may or may not be sourced from Realtek, and it'd be difficult 
for Realtek to provide documentation on their competition, wouldn't it?
Takashi Iwai April 16, 2021, 4:25 p.m. UTC | #4
On Fri, 16 Apr 2021 18:05:17 +0200,
Pierre-Louis Bossart wrote:
> 
> 
> 
> On 4/16/21 3:47 AM, Jaroslav Kysela wrote:
> > Dne 16. 04. 21 v 10:12 Takashi Iwai napsal(a):
> >> Lenovo Ideapad S740 requires quite a few COEF setups to make its
> >> speakers working.  The verb table was provided from Ryan Prescott as
> >> the result of investigation via qemu:
> >>    https://github.com/ryanprescott/realtek-verb-tools/wiki/How-to-sniff-verbs-from-a-Windows-sound-driver
> >
> > [Cc: to Kailang / Realtek]
> >
> > I believe that this sequence contains I2C writes to amplifier chips. It would
> > be really helpful, if Realtek can provide more information for the I2C master
> > interface for their codecs (describe basic I2C I/O).
> 
> The biggest problem is to figure what address/value pairs to write
> with I2C into the amplifiers, and here the catch is that those I2C/I2S
> amplifiers may or may not be sourced from Realtek, and it'd be
> difficult for Realtek to provide documentation on their competition,
> wouldn't it?

Sure, that's another problem.  But currently it's not clear even how
to communicate via I2C/whatever to the underlying chip, as it's done
via the vendor-specific COEF verb.  At least this could be opened, I
hope.


Takashi
Mark Pearson April 16, 2021, 4:35 p.m. UTC | #5
On 16/04/2021 12:05, Pierre-Louis Bossart wrote:
> 
> 
> On 4/16/21 3:47 AM, Jaroslav Kysela wrote:
>> Dne 16. 04. 21 v 10:12 Takashi Iwai napsal(a):
>>> Lenovo Ideapad S740 requires quite a few COEF setups to make its
>>> speakers working.  The verb table was provided from Ryan Prescott as
>>> the result of investigation via qemu:
>>>   
>>> https://github.com/ryanprescott/realtek-verb-tools/wiki/How-to-sniff-verbs-from-a-Windows-sound-driver
>>>
>>
>> [Cc: to Kailang / Realtek]
>>
>> I believe that this sequence contains I2C writes to amplifier chips.
>> It would
>> be really helpful, if Realtek can provide more information for the I2C
>> master
>> interface for their codecs (describe basic I2C I/O).
> 
> The biggest problem is to figure what address/value pairs to write with
> I2C into the amplifiers, and here the catch is that those I2C/I2S
> amplifiers may or may not be sourced from Realtek, and it'd be difficult
> for Realtek to provide documentation on their competition, wouldn't it?

Is this something, at least for our platforms, that we (Lenovo) should
be able to give guidance on more easily, perhaps working with the HW vendor?

I know I've had limited joy here previously on our non-Linux certified
platforms, but the more concise and targeted I make the request to the
HW/FW team the more likely I am to get success. Nothing is guaranteed
and if I go in with "audio doesn't work" they'll ignore me, but if I'm
asking for some specific information (which isn't proprietary) I'm more
likely to succeed, especially if it's details that they likely already
have documented. I'm definitely happy to at least try and do that - but
I've had trouble thus far knowing how to frame that request to get the
details needed.

It's been brilliant watching the debug of the S740 and I really want to
take advantage of this work to help out on our systems where we've been
stuck before.

As an aside (and probably this should be a different thread) if anybody
in the audio community would be interested in doing a training session
for the Lenovo Linux team so we can better understand how to make audio
better and contribute let me know. It's such a complicated subsystem and
knowing how everything hooks together, and what needs to be done where,
is something I haven't figured out yet. I believe we'd pay for your time
if that's required - I just need an expert who has the time and interest
to run a session :) The aim would be to get to the stage where we can
contribute and make audio better on our platforms generally - so it
would hopefully be a win-win. If that hit's anybodies interest let me know.

Mark
Jaroslav Kysela April 16, 2021, 5:21 p.m. UTC | #6
Dne 16. 04. 21 v 18:25 Takashi Iwai napsal(a):
> On Fri, 16 Apr 2021 18:05:17 +0200,
> Pierre-Louis Bossart wrote:
>>
>>
>>
>> On 4/16/21 3:47 AM, Jaroslav Kysela wrote:
>>> Dne 16. 04. 21 v 10:12 Takashi Iwai napsal(a):
>>>> Lenovo Ideapad S740 requires quite a few COEF setups to make its
>>>> speakers working.  The verb table was provided from Ryan Prescott as
>>>> the result of investigation via qemu:
>>>>    https://github.com/ryanprescott/realtek-verb-tools/wiki/How-to-sniff-verbs-from-a-Windows-sound-driver
>>>
>>> [Cc: to Kailang / Realtek]
>>>
>>> I believe that this sequence contains I2C writes to amplifier chips. It would
>>> be really helpful, if Realtek can provide more information for the I2C master
>>> interface for their codecs (describe basic I2C I/O).
>>
>> The biggest problem is to figure what address/value pairs to write
>> with I2C into the amplifiers, and here the catch is that those I2C/I2S
>> amplifiers may or may not be sourced from Realtek, and it'd be
>> difficult for Realtek to provide documentation on their competition,
>> wouldn't it?
> 
> Sure, that's another problem.  But currently it's not clear even how
> to communicate via I2C/whatever to the underlying chip, as it's done
> via the vendor-specific COEF verb.  At least this could be opened, I
> hope.

The nice thing if we know the I2C master communication is that we can create
I2C bus in the HDA driver and do run i2cdetect to detect the connected chips.
Yes, it's partial information, but it's far more better than this unreadable
coef implementation.

						Jaroslav
Pierre-Louis Bossart April 16, 2021, 6:30 p.m. UTC | #7
>>>> I believe that this sequence contains I2C writes to amplifier chips. It would
>>>> be really helpful, if Realtek can provide more information for the I2C master
>>>> interface for their codecs (describe basic I2C I/O).
>>>
>>> The biggest problem is to figure what address/value pairs to write
>>> with I2C into the amplifiers, and here the catch is that those I2C/I2S
>>> amplifiers may or may not be sourced from Realtek, and it'd be
>>> difficult for Realtek to provide documentation on their competition,
>>> wouldn't it?
>>
>> Sure, that's another problem.  But currently it's not clear even how
>> to communicate via I2C/whatever to the underlying chip, as it's done
>> via the vendor-specific COEF verb.  At least this could be opened, I
>> hope.
> 
> The nice thing if we know the I2C master communication is that we can create
> I2C bus in the HDA driver and do run i2cdetect to detect the connected chips.
> Yes, it's partial information, but it's far more better than this unreadable
> coef implementation.

Ah yes, now I see the idea. Very interesting indeed. It would help quite 
a bit if we can detect the devices and then go back to the OEMs to ask 
"can you give us the commands for device #42". In the absence of 
information, it would help filter the sequences extracted with scripts.
diff mbox series

Patch

diff --git a/sound/pci/hda/ideapad_s740_helper.c b/sound/pci/hda/ideapad_s740_helper.c
new file mode 100644
index 000000000000..564b9086e52d
--- /dev/null
+++ b/sound/pci/hda/ideapad_s740_helper.c
@@ -0,0 +1,492 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/* Fixes for Lenovo Ideapad S740, to be included from codec driver */
+
+static const struct hda_verb alc285_ideapad_s740_coefs[] = {
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x10 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0320 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
+{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
+{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+{}
+};
+
+static void alc285_fixup_ideapad_s740_coef(struct hda_codec *codec,
+					   const struct hda_fixup *fix,
+					   int action)
+{
+	switch (action) {
+	case HDA_FIXUP_ACT_PRE_PROBE:
+		snd_hda_add_verbs(codec, alc285_ideapad_s740_coefs);
+		break;
+	}
+}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 50437ec1b9af..1ef40f3ca259 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -6239,6 +6239,9 @@  static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
 /* for alc295_fixup_hp_top_speakers */
 #include "hp_x360_helper.c"
 
+/* for alc285_fixup_ideapad_s740_coef() */
+#include "ideapad_s740_helper.c"
+
 enum {
 	ALC269_FIXUP_GPIO2,
 	ALC269_FIXUP_SONY_VAIO,
@@ -6436,6 +6439,7 @@  enum {
 	ALC282_FIXUP_ACER_DISABLE_LINEOUT,
 	ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST,
 	ALC256_FIXUP_ACER_HEADSET_MIC,
+	ALC285_FIXUP_IDEAPAD_S740_COEF,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -7920,6 +7924,12 @@  static const struct hda_fixup alc269_fixups[] = {
 		.chained = true,
 		.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
 	},
+	[ALC285_FIXUP_IDEAPAD_S740_COEF] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc285_fixup_ideapad_s740_coef,
+		.chained = true,
+		.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
+	},
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -8263,6 +8273,7 @@  static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
 	SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
 	SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME),
+	SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF),
 	SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
 	SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
 	SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),