Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp1970134pxf; Sat, 13 Mar 2021 03:39:48 -0800 (PST) X-Google-Smtp-Source: ABdhPJzS5hb+5rjdnfvv26TETOMjBDbnW//V1+yZC+1i6BSuUPTpbLh+voV/RjtsGzbcKtZyaY35 X-Received: by 2002:a17:906:ad4:: with SMTP id z20mr13254591ejf.496.1615635587952; Sat, 13 Mar 2021 03:39:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615635587; cv=none; d=google.com; s=arc-20160816; b=RpHSxuDi/PbqGvThYjDVwrP+ytkbhm+0xMJQtv2wFEsm8hdX21R6UhL2G9LWzG8Pll VSdEAWoVxver7EAYYePbSLnvNCMdnwHRUrjOjA9kjhAIh032rSwQsbOvFLstmPo44h1G 1EXC6/6IUQp4hxRGObC0tWu/1Q1Kl8aCgx+r8iOHdhtFBnrt9+pOkBeVNmoTD8Em5tQ2 c+rcProBVmvXBj94r5RvPELRXz0YRIpXu+ZuJYy2qHA88LSuXZQ0hPBOJvAOhiCQtmly nyocfbJqcQ5zD07tT8wtqPzPYTC4OcWx47w+OuZabqZwtKRXIhiIFPPLr7v9ywGASIu3 RiZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Qq8CAyHYdfIx8K6NAVSVv46EBWus1WC4THLo44yHYD8=; b=aO+BQvVqN/TZ+5tTKVzcXprmn02VCav/fzlPhPNwMfoP2NM1OGSwKIIlqZUgD4DLpk 9LztMU+WLF7824PbvxZnBI7NLXtuvFfWTqTGuU/XuT56lL11KBxtSDtye7SZF2ErPJPK tTmC97PqvFQZyepuASqaKtcepAbxGyEGSJM+p5ckhJu1DMmgh5GWnPAV4RqqG93vJ3ys gds/yfWe6gLrbR8OA+DmZFOXDTkbhBaMSqmHbnTPEWHj+5MSOEYwqLt/FAYjzpjswNrH /96ReTtqYra1dldPjEj16gOf6ZJ4RceZgxCzU2HS4Z96eXc69k8f/VkAzIzjSQ6sixUY YmMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cirrus.com header.s=PODMain02222019 header.b=osJJnWOJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=cirrus.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id da5si6909238edb.464.2021.03.13.03.39.24; Sat, 13 Mar 2021 03:39:47 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@cirrus.com header.s=PODMain02222019 header.b=osJJnWOJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=cirrus.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233530AbhCMLeu (ORCPT + 99 others); Sat, 13 Mar 2021 06:34:50 -0500 Received: from mx0a-001ae601.pphosted.com ([67.231.149.25]:19424 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S233103AbhCMLee (ORCPT ); Sat, 13 Mar 2021 06:34:34 -0500 Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 12DBW2m0023937; Sat, 13 Mar 2021 05:34:15 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=Qq8CAyHYdfIx8K6NAVSVv46EBWus1WC4THLo44yHYD8=; b=osJJnWOJm5MIsbdhvcr3q/8kfMcEhDGGc9NVlpBlgRWYMOZdQYXFZPW3TXwtdqPUny1x +/+f0bV5OAxT0ypKxxniXnAidYJXw+JL5suX12wAlmT1B2Lec57t/9JWwaM/XfT382sZ jDvYf4s3gZEO4tHPh+1quwOtaJre+CiSBNKXAPGv+kgcRbod6g2Zf6xwakhA59hpgute OLDq5P+B4joH4YrNWZUpP2XHNBW28zH9Hnb0C9uBgNmwH0Eoq4qsIuTmXI35siqFArao jqYMMiST1kqLnVVqi9bjn8T3Hjy5Dge5azKKHw2WzLKhcs7s0bvfTeUYQSdgZbvpcr7R ZA== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 378up782kb-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Sat, 13 Mar 2021 05:34:15 -0600 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Sat, 13 Mar 2021 11:34:12 +0000 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2176.2 via Frontend Transport; Sat, 13 Mar 2021 11:34:12 +0000 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.45]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id F250C11D7; Sat, 13 Mar 2021 11:34:11 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai CC: , , , Stefan Binding Subject: [PATCH v1 4/4] ALSA: hda/cirrus: Make CS8409 driver more generic by using fixups. Date: Sat, 13 Mar 2021 11:34:10 +0000 Message-ID: <20210313113410.90088-5-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210313113410.90088-1-vitalyr@opensource.cirrus.com> References: <20210313113410.90088-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 adultscore=0 impostorscore=0 bulkscore=0 priorityscore=1501 suspectscore=0 phishscore=0 lowpriorityscore=0 spamscore=0 clxscore=1015 mlxlogscore=999 mlxscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2103130084 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Stefan Binding 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 Signed-off-by: Vitaly Rodionov Changes in v1: - No changes --- 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 74ac758aa4d5..d0a3c3189d26 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; 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