2021-03-12 18:48:29

by Vitaly Rodionov

[permalink] [raw]
Subject: [PATCH 0/4] ALSA: hda/cirrus: Make CS8409 driver more generic by using fixups

This series of patches will address comments by Pierre-Louis Bossart,
cleans up patch_cirrus.c source, reducing checkpatch.pl warnings from 19 to 0,
fixing an issue reported by Canonical: BugLink: https://bugs.launchpad.net/bugs/1918378,
and makes the CS8409 patch more generic by using fixups.

Stefan Binding (4):
ALSA: hda/cirrus: Add error handling into CS8409 I2C functions
ALSA: hda/cirrus: Cleanup patch_cirrus.c code.
ALSA: hda/cirrus: Fix CS42L42 Headset Mic volume control name
ALSA: hda/cirrus: Make CS8409 driver more generic by using fixups.

sound/pci/hda/patch_cirrus.c | 506 ++++++++++++++++-------------------
1 file changed, 228 insertions(+), 278 deletions(-)

--
2.25.1


2021-03-12 18:48:36

by Vitaly Rodionov

[permalink] [raw]
Subject: [PATCH 4/4] ALSA: hda/cirrus: Make CS8409 driver more generic by using fixups.

From: Stefan Binding <[email protected]>

CS8409/CS42L42 Driver currently does most of the platform specific
setup inside the main body of the code, however, this setup can be
moved into fixup functions, to make the driver more generic.

Making the driver more generic, allows the driver to use the
cs_parse_auto_config function in the patch function. This function
forces all of the ADCs to be permanently powered, which means the
cap_sync_hook function is no longer needed to restart the stream, when
the jack has been ejected.

Since the codec is re-initialized on every init/resume, there is no
need to add specific verbs to be run on init, and instead these can
be combined with the initialization verbs, which are run on init.

In addition, the extra fixup verbs are no longer required, since this
is taken care of elsewhere.

Tested on DELL Inspiron-3505, DELL Inspiron-3501, DELL Inspiron-3500

Signed-off-by: Stefan Binding <[email protected]>
Signed-off-by: Vitaly Rodionov <[email protected]>
---
sound/pci/hda/patch_cirrus.c | 304 ++++++++++++++---------------------
1 file changed, 118 insertions(+), 186 deletions(-)

diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 6495da523ea3..8cb91ca1720a 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -1292,9 +1292,14 @@ enum {
CS8409_BULLSEYE,
CS8409_WARLOCK,
CS8409_CYBORG,
- CS8409_VERBS,
+ CS8409_FIXUPS,
};

+static void cs8409_cs42l42_fixups(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action);
+static int cs8409_cs42l42_exec_verb(struct hdac_device *dev,
+ unsigned int cmd, unsigned int flags, unsigned int *res);
+
/* Dell Inspiron models with cs8409/cs42l42 */
static const struct hda_model_fixup cs8409_models[] = {
{ .id = CS8409_BULLSEYE, .name = "bullseye" },
@@ -1357,6 +1362,22 @@ static const struct hda_verb cs8409_cs42l42_init_verbs[] = {
{ 0x47, AC_VERB_SET_PROC_COEF, 0x0080 }, /* I2C mode */
{ 0x47, AC_VERB_SET_COEF_INDEX, 0x005b }, /* Set I2C bus speed */
{ 0x47, AC_VERB_SET_PROC_COEF, 0x0200 }, /* 100kHz I2C_STO = 2 */
+ { 0x24, AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, 0xF0 }, /* Widget node ASP-1-TX */
+ { 0x24, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0x20 },
+ { 0x24, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x21 },
+ { 0x24, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x04 },
+ { 0x34, AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, 0x50 }, /* Widget node ASP-1-RX0 */
+ { 0x34, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0x20 },
+ { 0x34, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0xa1 },
+ { 0x34, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x04 },
+ { 0x2C, AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, 0xF0 }, /* Widget node ASP-2-TX */
+ { 0x2C, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0x00 },
+ { 0x2C, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x10 },
+ { 0x2C, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x90 },
+ { 0x44, AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, 0x90 }, /* Widget node DMIC-1 */
+ { 0x44, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0x00 },
+ { 0x44, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0xA0 },
+ { 0x44, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x90 },
{} /* terminator */
};

@@ -1368,48 +1389,28 @@ static const struct hda_pintbl cs8409_cs42l42_pincfgs[] = {
{} /* terminator */
};

-static const struct hda_verb cs8409_cs42l42_add_verbs[] = {
- { 0x24, 0x71c, 0xF0 }, /* Widget node ASP-1-TX */
- { 0x24, 0x71d, 0x20 },
- { 0x24, 0x71e, 0x21 },
- { 0x24, 0x71f, 0x04 },
- { 0x34, 0x71c, 0x50 }, /* Widget node ASP-1-RX0 */
- { 0x34, 0x71d, 0x20 },
- { 0x34, 0x71e, 0xa1 },
- { 0x34, 0x71f, 0x04 },
- { 0x2C, 0x71c, 0xF0 }, /* Widget node ASP-2-TX */
- { 0x2C, 0x71d, 0x00 },
- { 0x2C, 0x71e, 0x10 },
- { 0x2C, 0x71f, 0x90 },
- { 0x44, 0x71c, 0x90 }, /* Widget node DMIC-1 */
- { 0x44, 0x71d, 0x00 },
- { 0x44, 0x71e, 0xA0 },
- { 0x44, 0x71f, 0x90 },
- {} /* terminator */
-};
-
static const struct hda_fixup cs8409_fixups[] = {
[CS8409_BULLSEYE] = {
.type = HDA_FIXUP_PINS,
.v.pins = cs8409_cs42l42_pincfgs,
.chained = true,
- .chain_id = CS8409_VERBS,
+ .chain_id = CS8409_FIXUPS,
},
[CS8409_WARLOCK] = {
.type = HDA_FIXUP_PINS,
.v.pins = cs8409_cs42l42_pincfgs,
.chained = true,
- .chain_id = CS8409_VERBS,
+ .chain_id = CS8409_FIXUPS,
},
[CS8409_CYBORG] = {
.type = HDA_FIXUP_PINS,
.v.pins = cs8409_cs42l42_pincfgs,
.chained = true,
- .chain_id = CS8409_VERBS,
+ .chain_id = CS8409_FIXUPS,
},
- [CS8409_VERBS] = {
- .type = HDA_FIXUP_VERBS,
- .v.verbs = cs8409_cs42l42_add_verbs,
+ [CS8409_FIXUPS] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cs8409_cs42l42_fixups,
},
};

@@ -1975,26 +1976,6 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res)
}
}

-static int cs8409_cs42l42_build_controls(struct hda_codec *codec)
-{
- int err;
-
- err = snd_hda_gen_build_controls(codec);
- if (err < 0)
- return err;
-
- snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
-
- /* Run jack auto detect first time on boot
- * after controls have been added, to check if jack has
- * been already plugged in
- */
- cs8409_cs42l42_run_jack_detect(codec);
- usleep_range(100000, 150000);
-
- return 0;
-}
-
#ifdef CONFIG_PM
/* Manage PDREF, when transition to D3hot */
static int cs8409_suspend(struct hda_codec *codec)
@@ -2015,31 +1996,6 @@ static int cs8409_suspend(struct hda_codec *codec)
}
#endif

-static void cs8409_cs42l42_cap_sync_hook(struct hda_codec *codec,
- struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct cs_spec *spec = codec->spec;
- unsigned int curval, expval;
- /* CS8409 DMIC Pin only allows the setting of the Stream Parameters in
- * Power State D0. When a headset is unplugged, and the path is switched to
- * the DMIC, the Stream is restarted with the new ADC, but this is done in
- * Power State D3. Restart the Stream now DMIC is in D0.
- */
- if (spec->gen.cur_adc == CS8409_CS42L42_DMIC_ADC_PIN_NID) {
- curval = snd_hda_codec_read(codec, spec->gen.cur_adc,
- 0, AC_VERB_GET_CONV, 0);
- expval = (spec->gen.cur_adc_stream_tag << 4) | 0;
- if (curval != expval) {
- codec_dbg(codec, "%s Restarting Stream after DMIC switch\n", __func__);
- __snd_hda_codec_cleanup_stream(codec, spec->gen.cur_adc, 1);
- snd_hda_codec_setup_stream(codec, spec->gen.cur_adc,
- spec->gen.cur_adc_stream_tag, 0,
- spec->gen.cur_adc_format);
- }
- }
-}
-
/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */
static void cs8409_enable_ur(struct hda_codec *codec, int flag)
{
@@ -2123,25 +2079,14 @@ static int cs8409_cs42l42_init(struct hda_codec *codec)
{
int ret = snd_hda_gen_init(codec);

- if (!ret) {
- /* On Dell platforms with suspend D3 mode support we
- * have to re-initialise cs8409 bridge and companion
- * cs42l42 codec
- */
- snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs);
- snd_hda_sequence_write(codec, cs8409_cs42l42_add_verbs);
-
- cs8409_cs42l42_hw_init(codec);
-
- cs8409_cs42l42_run_jack_detect(codec);
- usleep_range(100000, 150000);
- }
+ if (!ret)
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);

return ret;
}

static const struct hda_codec_ops cs8409_cs42l42_patch_ops = {
- .build_controls = cs8409_cs42l42_build_controls,
+ .build_controls = cs_build_controls,
.build_pcms = snd_hda_gen_build_pcms,
.init = cs8409_cs42l42_init,
.free = cs_free,
@@ -2151,70 +2096,95 @@ static const struct hda_codec_ops cs8409_cs42l42_patch_ops = {
#endif
};

-static int cs8409_cs42l42_fixup(struct hda_codec *codec)
+static void cs8409_cs42l42_fixups(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
{
- int err;
struct cs_spec *spec = codec->spec;
unsigned int caps;

- /* Basic initial sequence for specific hw configuration */
- snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs);
-
- /* CS8409 is simple HDA bridge and intended to be used with a remote
- * companion codec. Most of input/output PIN(s) have only basic
- * capabilities. NID(s) 0x24 and 0x34 have only OUTC and INC
- * capabilities and no presence detect capable (PDC) and call to
- * snd_hda_gen_build_controls() will mark them as non detectable
- * phantom jacks. However, in this configuration companion codec
- * CS42L42 is connected to these pins and it has jack detect
- * capabilities. We have to override pin capabilities,
- * otherwise they will not be created as input devices.
- */
- caps = snd_hdac_read_parm(&codec->core, CS8409_CS42L42_HP_PIN_NID,
- AC_PAR_PIN_CAP);
- if (caps >= 0)
- snd_hdac_override_parm(&codec->core,
- CS8409_CS42L42_HP_PIN_NID, AC_PAR_PIN_CAP,
- (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT)));
-
- caps = snd_hdac_read_parm(&codec->core, CS8409_CS42L42_AMIC_PIN_NID,
- AC_PAR_PIN_CAP);
- if (caps >= 0)
- snd_hdac_override_parm(&codec->core,
- CS8409_CS42L42_AMIC_PIN_NID, AC_PAR_PIN_CAP,
- (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT)));
-
- caps = get_wcaps(codec, CS8409_CS42L42_HP_PIN_NID);
- if (caps >= 0)
- snd_hda_override_wcaps(codec, CS8409_CS42L42_HP_PIN_NID,
- (caps | AC_WCAP_UNSOL_CAP));
-
- caps = get_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID);
- if (caps >= 0)
- snd_hda_override_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID,
- (caps | AC_WCAP_UNSOL_CAP));
+ switch (action) {
+ case HDA_FIXUP_ACT_PRE_PROBE:
+ snd_hda_add_verbs(codec, cs8409_cs42l42_init_verbs);
+ /* verb exec op override */
+ spec->exec_verb = codec->core.exec_verb;
+ codec->core.exec_verb = cs8409_cs42l42_exec_verb;

- snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+ mutex_init(&spec->cs8409_i2c_mux);

- err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, 0, 0);
- if (err < 0)
- return err;
+ codec->patch_ops = cs8409_cs42l42_patch_ops;

- err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
- if (err < 0)
- return err;
+ spec->gen.suppress_auto_mute = 1;
+ spec->gen.no_primary_hp = 1;
+ spec->gen.suppress_vmaster = 1;

- if (!snd_hda_gen_add_kctl(
- &spec->gen, NULL, &cs8409_cs42l42_hp_volume_mixer))
- return -1;
+ /* GPIO 5 out, 3,4 in */
+ spec->gpio_dir = GPIO5_INT;
+ spec->gpio_data = 0;
+ spec->gpio_mask = 0x03f;

- if (!snd_hda_gen_add_kctl(
- &spec->gen, NULL, &cs8409_cs42l42_amic_volume_mixer))
- return -1;
+ spec->cs42l42_hp_jack_in = 0;
+ spec->cs42l42_mic_jack_in = 0;

- snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
+ /* Basic initial sequence for specific hw configuration */
+ snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs);

- return 0;
+ /* CS8409 is simple HDA bridge and intended to be used with a remote
+ * companion codec. Most of input/output PIN(s) have only basic
+ * capabilities. NID(s) 0x24 and 0x34 have only OUTC and INC
+ * capabilities and no presence detect capable (PDC) and call to
+ * snd_hda_gen_build_controls() will mark them as non detectable
+ * phantom jacks. However, in this configuration companion codec
+ * CS42L42 is connected to these pins and it has jack detect
+ * capabilities. We have to override pin capabilities,
+ * otherwise they will not be created as input devices.
+ */
+ caps = snd_hdac_read_parm(&codec->core, CS8409_CS42L42_HP_PIN_NID,
+ AC_PAR_PIN_CAP);
+ if (caps >= 0)
+ snd_hdac_override_parm(&codec->core,
+ CS8409_CS42L42_HP_PIN_NID, AC_PAR_PIN_CAP,
+ (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT)));
+
+ caps = snd_hdac_read_parm(&codec->core, CS8409_CS42L42_AMIC_PIN_NID,
+ AC_PAR_PIN_CAP);
+ if (caps >= 0)
+ snd_hdac_override_parm(&codec->core,
+ CS8409_CS42L42_AMIC_PIN_NID, AC_PAR_PIN_CAP,
+ (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT)));
+
+ caps = get_wcaps(codec, CS8409_CS42L42_HP_PIN_NID);
+ if (caps >= 0)
+ snd_hda_override_wcaps(codec, CS8409_CS42L42_HP_PIN_NID,
+ (caps | AC_WCAP_UNSOL_CAP));
+
+ caps = get_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID);
+ if (caps >= 0)
+ snd_hda_override_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID,
+ (caps | AC_WCAP_UNSOL_CAP));
+ break;
+ case HDA_FIXUP_ACT_PROBE:
+ snd_hda_gen_add_kctl(&spec->gen,
+ NULL, &cs8409_cs42l42_hp_volume_mixer);
+ snd_hda_gen_add_kctl(&spec->gen,
+ NULL, &cs8409_cs42l42_amic_volume_mixer);
+ cs8409_cs42l42_hw_init(codec);
+ snd_hda_codec_set_name(codec, "CS8409/CS42L42");
+ break;
+ case HDA_FIXUP_ACT_INIT:
+ cs8409_cs42l42_hw_init(codec);
+ // Fall through
+ case HDA_FIXUP_ACT_BUILD:
+ /* Run jack auto detect first time on boot
+ * after controls have been added, to check if jack has
+ * been already plugged in.
+ * Run immediately after init.
+ */
+ cs8409_cs42l42_run_jack_detect(codec);
+ usleep_range(100000, 150000);
+ break;
+ default:
+ break;
+ }
}

static int cs8409_cs42l42_exec_verb(struct hdac_device *dev,
@@ -2255,11 +2225,9 @@ static int cs8409_cs42l42_exec_verb(struct hdac_device *dev,

static int patch_cs8409(struct hda_codec *codec)
{
- struct cs_spec *spec;
- int err = -EINVAL;
+ int err;

- spec = cs_alloc_spec(codec, CS8409_VENDOR_NID);
- if (!spec)
+ if (!cs_alloc_spec(codec, CS8409_VENDOR_NID))
return -ENOMEM;

snd_hda_pick_fixup(codec,
@@ -2270,52 +2238,16 @@ static int patch_cs8409(struct hda_codec *codec)
codec->bus->pci->subsystem_vendor,
codec->bus->pci->subsystem_device);

- switch (codec->fixup_id) {
- /* Dell platforms with CS42L42 companion codec */
- case CS8409_BULLSEYE:
- case CS8409_WARLOCK:
- case CS8409_CYBORG:
-
- snd_hda_add_verbs(codec, cs8409_cs42l42_add_verbs);
-
- /* verb exec op override */
- spec->exec_verb = codec->core.exec_verb;
- codec->core.exec_verb = cs8409_cs42l42_exec_verb;
-
- mutex_init(&spec->cs8409_i2c_mux);
-
- codec->patch_ops = cs8409_cs42l42_patch_ops;
-
- spec->gen.cap_sync_hook = cs8409_cs42l42_cap_sync_hook;
-
- spec->gen.suppress_auto_mute = 1;
- spec->gen.no_primary_hp = 1;
- spec->gen.suppress_vmaster = 1;
- /* GPIO 5 out, 3,4 in */
- spec->gpio_dir = GPIO5_INT;
- spec->gpio_data = 0;
- spec->gpio_mask = 0x03f;
-
- spec->cs42l42_hp_jack_in = 0;
- spec->cs42l42_mic_jack_in = 0;
-
- err = cs8409_cs42l42_fixup(codec);
- break;
-
- default:
- codec_err(codec, "VID=%08x, DEV=%08x not supported\n",
- codec->bus->pci->subsystem_vendor,
- codec->bus->pci->subsystem_device);
- break;
- }
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);

- if (!err) {
- cs8409_cs42l42_hw_init(codec);
- snd_hda_codec_set_name(codec, "CS8409/CS42L42");
- } else
+ err = cs_parse_auto_config(codec);
+ if (err < 0) {
cs_free(codec);
+ return err;
+ }

- return err;
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
+ return 0;
}

/*
--
2.25.1

2021-03-12 22:02:23

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 4/4] ALSA: hda/cirrus: Make CS8409 driver more generic by using fixups.

Hi Vitaly,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on sound/for-next]
[also build test WARNING on next-20210312]
[cannot apply to v5.12-rc2]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Vitaly-Rodionov/ALSA-hda-cirrus-Make-CS8409-driver-more-generic-by-using-fixups/20210313-024937
base: https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git for-next
config: microblaze-randconfig-m031-20210312 (attached as .config)
compiler: microblaze-linux-gcc (GCC) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

New smatch warnings:
sound/pci/hda/patch_cirrus.c:2143 cs8409_cs42l42_fixups() warn: always true condition '(caps >= 0) => (0-u32max >= 0)'

Old smatch warnings:
sound/pci/hda/patch_cirrus.c:2150 cs8409_cs42l42_fixups() warn: always true condition '(caps >= 0) => (0-u32max >= 0)'
sound/pci/hda/patch_cirrus.c:2156 cs8409_cs42l42_fixups() warn: always true condition '(caps >= 0) => (0-u32max >= 0)'
sound/pci/hda/patch_cirrus.c:2161 cs8409_cs42l42_fixups() warn: always true condition '(caps >= 0) => (0-u32max >= 0)'

vim +2143 sound/pci/hda/patch_cirrus.c

6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2098
89b3eea4b1e18f Stefan Binding 2021-03-12 2099 static void cs8409_cs42l42_fixups(struct hda_codec *codec,
89b3eea4b1e18f Stefan Binding 2021-03-12 2100 const struct hda_fixup *fix, int action)
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2101 {
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2102 struct cs_spec *spec = codec->spec;
76e2b57d1d60d1 Stefan Binding 2021-03-12 2103 unsigned int caps;
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2104
89b3eea4b1e18f Stefan Binding 2021-03-12 2105 switch (action) {
89b3eea4b1e18f Stefan Binding 2021-03-12 2106 case HDA_FIXUP_ACT_PRE_PROBE:
89b3eea4b1e18f Stefan Binding 2021-03-12 2107 snd_hda_add_verbs(codec, cs8409_cs42l42_init_verbs);
89b3eea4b1e18f Stefan Binding 2021-03-12 2108 /* verb exec op override */
89b3eea4b1e18f Stefan Binding 2021-03-12 2109 spec->exec_verb = codec->core.exec_verb;
89b3eea4b1e18f Stefan Binding 2021-03-12 2110 codec->core.exec_verb = cs8409_cs42l42_exec_verb;
89b3eea4b1e18f Stefan Binding 2021-03-12 2111
89b3eea4b1e18f Stefan Binding 2021-03-12 2112 mutex_init(&spec->cs8409_i2c_mux);
89b3eea4b1e18f Stefan Binding 2021-03-12 2113
89b3eea4b1e18f Stefan Binding 2021-03-12 2114 codec->patch_ops = cs8409_cs42l42_patch_ops;
89b3eea4b1e18f Stefan Binding 2021-03-12 2115
89b3eea4b1e18f Stefan Binding 2021-03-12 2116 spec->gen.suppress_auto_mute = 1;
89b3eea4b1e18f Stefan Binding 2021-03-12 2117 spec->gen.no_primary_hp = 1;
89b3eea4b1e18f Stefan Binding 2021-03-12 2118 spec->gen.suppress_vmaster = 1;
89b3eea4b1e18f Stefan Binding 2021-03-12 2119
89b3eea4b1e18f Stefan Binding 2021-03-12 2120 /* GPIO 5 out, 3,4 in */
89b3eea4b1e18f Stefan Binding 2021-03-12 2121 spec->gpio_dir = GPIO5_INT;
89b3eea4b1e18f Stefan Binding 2021-03-12 2122 spec->gpio_data = 0;
89b3eea4b1e18f Stefan Binding 2021-03-12 2123 spec->gpio_mask = 0x03f;
89b3eea4b1e18f Stefan Binding 2021-03-12 2124
89b3eea4b1e18f Stefan Binding 2021-03-12 2125 spec->cs42l42_hp_jack_in = 0;
89b3eea4b1e18f Stefan Binding 2021-03-12 2126 spec->cs42l42_mic_jack_in = 0;
89b3eea4b1e18f Stefan Binding 2021-03-12 2127
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2128 /* Basic initial sequence for specific hw configuration */
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2129 snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs);
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2130
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2131 /* CS8409 is simple HDA bridge and intended to be used with a remote
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2132 * companion codec. Most of input/output PIN(s) have only basic
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2133 * capabilities. NID(s) 0x24 and 0x34 have only OUTC and INC
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2134 * capabilities and no presence detect capable (PDC) and call to
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2135 * snd_hda_gen_build_controls() will mark them as non detectable
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2136 * phantom jacks. However, in this configuration companion codec
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2137 * CS42L42 is connected to these pins and it has jack detect
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2138 * capabilities. We have to override pin capabilities,
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2139 * otherwise they will not be created as input devices.
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2140 */
76e2b57d1d60d1 Stefan Binding 2021-03-12 2141 caps = snd_hdac_read_parm(&codec->core, CS8409_CS42L42_HP_PIN_NID,
76e2b57d1d60d1 Stefan Binding 2021-03-12 2142 AC_PAR_PIN_CAP);
76e2b57d1d60d1 Stefan Binding 2021-03-12 @2143 if (caps >= 0)
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2144 snd_hdac_override_parm(&codec->core,
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2145 CS8409_CS42L42_HP_PIN_NID, AC_PAR_PIN_CAP,
76e2b57d1d60d1 Stefan Binding 2021-03-12 2146 (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT)));
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2147
76e2b57d1d60d1 Stefan Binding 2021-03-12 2148 caps = snd_hdac_read_parm(&codec->core, CS8409_CS42L42_AMIC_PIN_NID,
76e2b57d1d60d1 Stefan Binding 2021-03-12 2149 AC_PAR_PIN_CAP);
76e2b57d1d60d1 Stefan Binding 2021-03-12 2150 if (caps >= 0)
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2151 snd_hdac_override_parm(&codec->core,
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2152 CS8409_CS42L42_AMIC_PIN_NID, AC_PAR_PIN_CAP,
76e2b57d1d60d1 Stefan Binding 2021-03-12 2153 (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT)));
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2154
76e2b57d1d60d1 Stefan Binding 2021-03-12 2155 caps = get_wcaps(codec, CS8409_CS42L42_HP_PIN_NID);
76e2b57d1d60d1 Stefan Binding 2021-03-12 2156 if (caps >= 0)
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2157 snd_hda_override_wcaps(codec, CS8409_CS42L42_HP_PIN_NID,
76e2b57d1d60d1 Stefan Binding 2021-03-12 2158 (caps | AC_WCAP_UNSOL_CAP));
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2159
76e2b57d1d60d1 Stefan Binding 2021-03-12 2160 caps = get_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID);
76e2b57d1d60d1 Stefan Binding 2021-03-12 2161 if (caps >= 0)
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2162 snd_hda_override_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID,
76e2b57d1d60d1 Stefan Binding 2021-03-12 2163 (caps | AC_WCAP_UNSOL_CAP));
89b3eea4b1e18f Stefan Binding 2021-03-12 2164 break;
89b3eea4b1e18f Stefan Binding 2021-03-12 2165 case HDA_FIXUP_ACT_PROBE:
89b3eea4b1e18f Stefan Binding 2021-03-12 2166 snd_hda_gen_add_kctl(&spec->gen,
89b3eea4b1e18f Stefan Binding 2021-03-12 2167 NULL, &cs8409_cs42l42_hp_volume_mixer);
89b3eea4b1e18f Stefan Binding 2021-03-12 2168 snd_hda_gen_add_kctl(&spec->gen,
89b3eea4b1e18f Stefan Binding 2021-03-12 2169 NULL, &cs8409_cs42l42_amic_volume_mixer);
89b3eea4b1e18f Stefan Binding 2021-03-12 2170 cs8409_cs42l42_hw_init(codec);
89b3eea4b1e18f Stefan Binding 2021-03-12 2171 snd_hda_codec_set_name(codec, "CS8409/CS42L42");
89b3eea4b1e18f Stefan Binding 2021-03-12 2172 break;
89b3eea4b1e18f Stefan Binding 2021-03-12 2173 case HDA_FIXUP_ACT_INIT:
89b3eea4b1e18f Stefan Binding 2021-03-12 2174 cs8409_cs42l42_hw_init(codec);
89b3eea4b1e18f Stefan Binding 2021-03-12 2175 // Fall through
89b3eea4b1e18f Stefan Binding 2021-03-12 2176 case HDA_FIXUP_ACT_BUILD:
89b3eea4b1e18f Stefan Binding 2021-03-12 2177 /* Run jack auto detect first time on boot
89b3eea4b1e18f Stefan Binding 2021-03-12 2178 * after controls have been added, to check if jack has
89b3eea4b1e18f Stefan Binding 2021-03-12 2179 * been already plugged in.
89b3eea4b1e18f Stefan Binding 2021-03-12 2180 * Run immediately after init.
89b3eea4b1e18f Stefan Binding 2021-03-12 2181 */
89b3eea4b1e18f Stefan Binding 2021-03-12 2182 cs8409_cs42l42_run_jack_detect(codec);
89b3eea4b1e18f Stefan Binding 2021-03-12 2183 usleep_range(100000, 150000);
89b3eea4b1e18f Stefan Binding 2021-03-12 2184 break;
89b3eea4b1e18f Stefan Binding 2021-03-12 2185 default:
89b3eea4b1e18f Stefan Binding 2021-03-12 2186 break;
89b3eea4b1e18f Stefan Binding 2021-03-12 2187 }
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2188 }
6cc7e93f46a5ce Vitaly Rodionov 2021-03-06 2189

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (8.90 kB)
.config.gz (27.37 kB)
Download all attachments