From patchwork Wed Jul 28 13:43:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405877 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4DEFC4338F for ; Wed, 28 Jul 2021 13:50:55 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E977B60F5E for ; Wed, 28 Jul 2021 13:50:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org E977B60F5E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 6CA191AED; Wed, 28 Jul 2021 15:50:03 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 6CA191AED DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480253; bh=L+MtT0lnuKN1sBuym4eBC48BHOjUKOiyuzHRBzRNybA=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=JR7BAqz4fl+a4cWjWPgeUt9bF0HycovlIBpWwPSFO08g0g3wpkiKp2gwKSro7CZsQ JNtlRTsEH0rRH9QBUFQadzVpO78iTz7bSOTYhe2lRPHxIAEEDyFh/xTams4rH5hizV pl/TfQqICPxo2X/r3MSGPfp+AQ19CfkXGIc0NR2M= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 96C22F80558; Wed, 28 Jul 2021 15:45:13 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B3A62F8054A; Wed, 28 Jul 2021 15:45:08 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 31E68F802A9 for ; Wed, 28 Jul 2021 15:44:34 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 31E68F802A9 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="OmXvE7mf" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqg014335; Wed, 28 Jul 2021 08:44:32 -0500 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=ERerZNN/tht+5sYqMi1nYRmfQa0tZkJ5v5+yRrNCk7g=; b=OmXvE7mfgT3/pEvuf9dgKOiERUySKfEUnlwbLF0FZjOb7UcsHxYBC/TgJjPeIQWLlGxj 3QkzIkw3gaDC7svwt9YXgyRHJmcCh5Vew0NCl0K8J5OFL58Ud/7JbftWS51zTExycQ3T 6SlCzxIeJY5VEHYgrUHp1wBI5FDb1oEFVYr7rRs+qwnZtdzJZLwY+1TkvR/90AI/2isa qDb5VeFHvIpsj+R55A6bzoESRK36fZCJanJjxnssHQN7EGDTA3er8dQp0YcX8H6yGt4c ExxiWPpSlhTCHj7nftKAG0UIHJJU6bFD72/NLiQDFPR3VP+3E8jUpsN0F2r5tV0O630o 4g== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:31 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:30 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:30 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id E3A1246E; Wed, 28 Jul 2021 13:44:28 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 01/27] ALSA: hda/cirrus: Move CS8409 HDA bridge to separate module Date: Wed, 28 Jul 2021 14:43:42 +0100 Message-ID: <20210728134408.369396-2-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: ngVqwA6-zWe8WX6tRUiA-WLLlcsW6Mdq X-Proofpoint-GUID: ngVqwA6-zWe8WX6tRUiA-WLLlcsW6Mdq X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: Fixed reverse-selection, making modules individual. --- sound/pci/hda/Kconfig | 10 + sound/pci/hda/Makefile | 2 + sound/pci/hda/patch_cirrus.c | 1074 ---------------------------------- sound/pci/hda/patch_cs8409.c | 1060 +++++++++++++++++++++++++++++++++ sound/pci/hda/patch_cs8409.h | 91 +++ 5 files changed, 1163 insertions(+), 1074 deletions(-) create mode 100644 sound/pci/hda/patch_cs8409.c create mode 100644 sound/pci/hda/patch_cs8409.h diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index c4360cdbc728..ab9d2746e804 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -157,6 +157,16 @@ config SND_HDA_CODEC_CIRRUS comment "Set to Y if you want auto-loading the codec driver" depends on SND_HDA=y && SND_HDA_CODEC_CIRRUS=m +config SND_HDA_CODEC_CS8409 + tristate "Build Cirrus Logic HDA bridge support" + select SND_HDA_GENERIC + help + Say Y or M here to include Cirrus Logic HDA bridge support in + snd-hda-intel driver, such as CS8409. + +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA=y && SND_HDA_CODEC_CS8409=m + config SND_HDA_CODEC_CONEXANT tristate "Build Conexant HD-audio codec support" select SND_HDA_GENERIC diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index b57432f00056..1b73e08dc563 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -20,6 +20,7 @@ snd-hda-codec-analog-objs := patch_analog.o snd-hda-codec-idt-objs := patch_sigmatel.o snd-hda-codec-si3054-objs := patch_si3054.o snd-hda-codec-cirrus-objs := patch_cirrus.o +snd-hda-codec-cs8409-objs := patch_cs8409.o snd-hda-codec-ca0110-objs := patch_ca0110.o snd-hda-codec-ca0132-objs := patch_ca0132.o snd-hda-codec-conexant-objs := patch_conexant.o @@ -37,6 +38,7 @@ obj-$(CONFIG_SND_HDA_CODEC_ANALOG) += snd-hda-codec-analog.o obj-$(CONFIG_SND_HDA_CODEC_SIGMATEL) += snd-hda-codec-idt.o obj-$(CONFIG_SND_HDA_CODEC_SI3054) += snd-hda-codec-si3054.o obj-$(CONFIG_SND_HDA_CODEC_CIRRUS) += snd-hda-codec-cirrus.o +obj-$(CONFIG_SND_HDA_CODEC_CS8409) += snd-hda-codec-cs8409.o obj-$(CONFIG_SND_HDA_CODEC_CA0110) += snd-hda-codec-ca0110.o obj-$(CONFIG_SND_HDA_CODEC_CA0132) += snd-hda-codec-ca0132.o obj-$(CONFIG_SND_HDA_CODEC_CONEXANT) += snd-hda-codec-conexant.o diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 8629e84fef23..678fbcaf2a3b 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -21,9 +20,6 @@ /* */ -#define CS42L42_HP_CH (2U) -#define CS42L42_HS_MIC_CH (1U) - struct cs_spec { struct hda_gen_spec gen; @@ -42,18 +38,6 @@ struct cs_spec { /* for MBP SPDIF control */ int (*spdif_sw_put)(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); - - unsigned int cs42l42_hp_jack_in:1; - unsigned int cs42l42_mic_jack_in:1; - unsigned int cs42l42_volume_init:1; - char cs42l42_hp_volume[CS42L42_HP_CH]; - char cs42l42_hs_mic_volume[CS42L42_HS_MIC_CH]; - - struct mutex cs8409_i2c_mux; - - /* verb exec op override */ - int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, - unsigned int flags, unsigned int *res); }; /* available models with CS420x */ @@ -1239,1063 +1223,6 @@ static int patch_cs4213(struct hda_codec *codec) return err; } -/* Cirrus Logic CS8409 HDA bridge with - * companion codec CS42L42 - */ -#define CS8409_VENDOR_NID 0x47 - -#define CS8409_CS42L42_HP_PIN_NID 0x24 -#define CS8409_CS42L42_SPK_PIN_NID 0x2c -#define CS8409_CS42L42_AMIC_PIN_NID 0x34 -#define CS8409_CS42L42_DMIC_PIN_NID 0x44 -#define CS8409_CS42L42_DMIC_ADC_PIN_NID 0x22 - -#define CS42L42_HSDET_AUTO_DONE 0x02 -#define CS42L42_HSTYPE_MASK 0x03 - -#define CS42L42_JACK_INSERTED 0x0C -#define CS42L42_JACK_REMOVED 0x00 - -#define GPIO3_INT (1 << 3) -#define GPIO4_INT (1 << 4) -#define GPIO5_INT (1 << 5) - -#define CS42L42_I2C_ADDR (0x48 << 1) - -#define CIR_I2C_ADDR 0x0059 -#define CIR_I2C_DATA 0x005A -#define CIR_I2C_CTRL 0x005B -#define CIR_I2C_STATUS 0x005C -#define CIR_I2C_QWRITE 0x005D -#define CIR_I2C_QREAD 0x005E - -#define CS8409_CS42L42_HP_VOL_REAL_MIN (-63) -#define CS8409_CS42L42_HP_VOL_REAL_MAX (0) -#define CS8409_CS42L42_AMIC_VOL_REAL_MIN (-97) -#define CS8409_CS42L42_AMIC_VOL_REAL_MAX (12) -#define CS8409_CS42L42_REG_HS_VOLUME_CHA (0x2301) -#define CS8409_CS42L42_REG_HS_VOLUME_CHB (0x2303) -#define CS8409_CS42L42_REG_AMIC_VOLUME (0x1D03) - -struct cs8409_i2c_param { - unsigned int addr; - unsigned int reg; -}; - -struct cs8409_cir_param { - unsigned int nid; - unsigned int cir; - unsigned int coeff; -}; - -enum { - CS8409_BULLSEYE, - CS8409_WARLOCK, - CS8409_CYBORG, - 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" }, - { .id = CS8409_WARLOCK, .name = "warlock" }, - { .id = CS8409_CYBORG, .name = "cyborg" }, - {} -}; - -/* Dell Inspiron platforms - * with cs8409 bridge and cs42l42 codec - */ -static const struct snd_pci_quirk cs8409_fixup_tbl[] = { - SND_PCI_QUIRK(0x1028, 0x0A11, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A12, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A23, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A24, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A25, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A2B, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0AB0, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB5, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AD9, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0ADC, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0ADF, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE2, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE9, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEA, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEB, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEC, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AED, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), - {} /* terminator */ -}; - -static const struct hda_verb cs8409_cs42l42_init_verbs[] = { - { 0x01, AC_VERB_SET_GPIO_WAKE_MASK, 0x0018 }, /* WAKE from GPIO 3,4 */ - { 0x47, AC_VERB_SET_PROC_STATE, 0x0001 }, /* Enable VPW processing */ - { 0x47, AC_VERB_SET_COEF_INDEX, 0x0002 }, /* Configure GPIO 6,7 */ - { 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 */ - {} /* terminator */ -}; - -static const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { - { 0x24, 0x042120f0 }, /* ASP-1-TX */ - { 0x34, 0x04a12050 }, /* ASP-1-RX */ - { 0x2c, 0x901000f0 }, /* ASP-2-TX */ - { 0x44, 0x90a00090 }, /* DMIC-1 */ - {} /* terminator */ -}; - -static const struct hda_fixup cs8409_fixups[] = { - [CS8409_BULLSEYE] = { - .type = HDA_FIXUP_PINS, - .v.pins = cs8409_cs42l42_pincfgs, - .chained = true, - .chain_id = CS8409_FIXUPS, - }, - [CS8409_WARLOCK] = { - .type = HDA_FIXUP_PINS, - .v.pins = cs8409_cs42l42_pincfgs, - .chained = true, - .chain_id = CS8409_FIXUPS, - }, - [CS8409_CYBORG] = { - .type = HDA_FIXUP_PINS, - .v.pins = cs8409_cs42l42_pincfgs, - .chained = true, - .chain_id = CS8409_FIXUPS, - }, - [CS8409_FIXUPS] = { - .type = HDA_FIXUP_FUNC, - .v.func = cs8409_cs42l42_fixups, - }, -}; - -/* Vendor specific HW configuration for CS42L42 */ -static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { - { 0x1010, 0xB0 }, - { 0x1D01, 0x00 }, - { 0x1D02, 0x06 }, - { 0x1D03, 0x00 }, - { 0x1107, 0x01 }, - { 0x1009, 0x02 }, - { 0x1007, 0x03 }, - { 0x1201, 0x00 }, - { 0x1208, 0x13 }, - { 0x1205, 0xFF }, - { 0x1206, 0x00 }, - { 0x1207, 0x20 }, - { 0x1202, 0x0D }, - { 0x2A02, 0x02 }, - { 0x2A03, 0x00 }, - { 0x2A04, 0x00 }, - { 0x2A05, 0x02 }, - { 0x2A06, 0x00 }, - { 0x2A07, 0x20 }, - { 0x2A08, 0x02 }, - { 0x2A09, 0x00 }, - { 0x2A0A, 0x80 }, - { 0x2A0B, 0x02 }, - { 0x2A0C, 0x00 }, - { 0x2A0D, 0xA0 }, - { 0x2A01, 0x0C }, - { 0x2902, 0x01 }, - { 0x2903, 0x02 }, - { 0x2904, 0x00 }, - { 0x2905, 0x00 }, - { 0x2901, 0x01 }, - { 0x1101, 0x0A }, - { 0x1102, 0x84 }, - { 0x2301, 0x00 }, - { 0x2303, 0x00 }, - { 0x2302, 0x3f }, - { 0x2001, 0x03 }, - { 0x1B75, 0xB6 }, - { 0x1B73, 0xC2 }, - { 0x1129, 0x01 }, - { 0x1121, 0xF3 }, - { 0x1103, 0x20 }, - { 0x1105, 0x00 }, - { 0x1112, 0xC0 }, - { 0x1113, 0x80 }, - { 0x1C03, 0xC0 }, - { 0x1105, 0x00 }, - { 0x1112, 0xC0 }, - { 0x1101, 0x02 }, - {} /* Terminator */ -}; - -/* Vendor specific hw configuration for CS8409 */ -static const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[] = { - { 0x47, 0x00, 0xb008 }, /* +PLL1/2_EN, +I2C_EN */ - { 0x47, 0x01, 0x0002 }, /* ASP1/2_EN=0, ASP1_STP=1 */ - { 0x47, 0x02, 0x0a80 }, /* ASP1/2_BUS_IDLE=10, +GPIO_I2C */ - { 0x47, 0x19, 0x0800 }, /* ASP1.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ - { 0x47, 0x1a, 0x0820 }, /* ASP1.A: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=32 */ - { 0x47, 0x29, 0x0800 }, /* ASP2.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ - { 0x47, 0x2a, 0x2800 }, /* ASP2.A: TX.RAP=1, TX.RSZ=24 bits, TX.RCS=0 */ - { 0x47, 0x39, 0x0800 }, /* ASP1.A: RX.LAP=0, RX.LSZ=24 bits, RX.LCS=0 */ - { 0x47, 0x3a, 0x0800 }, /* ASP1.A: RX.RAP=0, RX.RSZ=24 bits, RX.RCS=0 */ - { 0x47, 0x03, 0x8000 }, /* ASP1: LCHI = 00h */ - { 0x47, 0x04, 0x28ff }, /* ASP1: MC/SC_SRCSEL=PLL1, LCPR=FFh */ - { 0x47, 0x05, 0x0062 }, /* ASP1: MCEN=0, FSD=011, SCPOL_IN/OUT=0, SCDIV=1:4 */ - { 0x47, 0x06, 0x801f }, /* ASP2: LCHI=1Fh */ - { 0x47, 0x07, 0x283f }, /* ASP2: MC/SC_SRCSEL=PLL1, LCPR=3Fh */ - { 0x47, 0x08, 0x805c }, /* ASP2: 5050=1, MCEN=0, FSD=010, SCPOL_IN/OUT=1, SCDIV=1:16 */ - { 0x47, 0x09, 0x0023 }, /* DMIC1_MO=10b, DMIC1/2_SR=1 */ - { 0x47, 0x0a, 0x0000 }, /* ASP1/2_BEEP=0 */ - { 0x47, 0x01, 0x0062 }, /* ASP1/2_EN=1, ASP1_STP=1 */ - { 0x47, 0x00, 0x9008 }, /* -PLL2_EN */ - { 0x47, 0x68, 0x0000 }, /* TX2.A: pre-scale att.=0 dB */ - { 0x47, 0x82, 0xfc03 }, /* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=1 */ - { 0x47, 0xc0, 0x9999 }, /* test mode on */ - { 0x47, 0xc5, 0x0000 }, /* GPIO hysteresis = 30 us */ - { 0x47, 0xc0, 0x0000 }, /* test mode off */ - {} /* Terminator */ -}; - -static const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[] = { - { 0x47, 0x65, 0x4000 }, /* EQ_SEL=1, EQ1/2_EN=0 */ - { 0x47, 0x64, 0x4000 }, /* +EQ_ACC */ - { 0x47, 0x65, 0x4010 }, /* +EQ2_EN */ - { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ - { 0x47, 0x64, 0xc0c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=0, EQ_DATA_LO=0x67 */ - { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ - { 0x47, 0x64, 0xc1c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=1, EQ_DATA_LO=0x67 */ - { 0x47, 0x63, 0xf370 }, /* EQ_DATA_HI=0xf370 */ - { 0x47, 0x64, 0xc271 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=2, EQ_DATA_LO=0x71 */ - { 0x47, 0x63, 0x1ef8 }, /* EQ_DATA_HI=0x1ef8 */ - { 0x47, 0x64, 0xc348 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=3, EQ_DATA_LO=0x48 */ - { 0x47, 0x63, 0xc110 }, /* EQ_DATA_HI=0xc110 */ - { 0x47, 0x64, 0xc45a }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=4, EQ_DATA_LO=0x5a */ - { 0x47, 0x63, 0x1f29 }, /* EQ_DATA_HI=0x1f29 */ - { 0x47, 0x64, 0xc574 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=5, EQ_DATA_LO=0x74 */ - { 0x47, 0x63, 0x1d7a }, /* EQ_DATA_HI=0x1d7a */ - { 0x47, 0x64, 0xc653 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=6, EQ_DATA_LO=0x53 */ - { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ - { 0x47, 0x64, 0xc714 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=7, EQ_DATA_LO=0x14 */ - { 0x47, 0x63, 0x1ca3 }, /* EQ_DATA_HI=0x1ca3 */ - { 0x47, 0x64, 0xc8c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=8, EQ_DATA_LO=0xc7 */ - { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ - { 0x47, 0x64, 0xc914 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=9, EQ_DATA_LO=0x14 */ - { 0x47, 0x64, 0x0000 }, /* -EQ_ACC, -EQ_WRT */ - {} /* Terminator */ -}; - -/** - * cs8409_enable_i2c_clock - Enable I2C clocks - * @codec: the codec instance - * @enable: Enable or disable I2C clocks - * - * Enable or Disable I2C clocks. - */ -static void cs8409_enable_i2c_clock(struct hda_codec *codec, unsigned int enable) -{ - unsigned int retval; - unsigned int newval; - - retval = cs_vendor_coef_get(codec, 0x0); - newval = (enable) ? (retval | 0x8) : (retval & 0xfffffff7); - cs_vendor_coef_set(codec, 0x0, newval); -} - -/** - * cs8409_i2c_wait_complete - Wait for I2C transaction - * @codec: the codec instance - * - * Wait for I2C transaction to complete. - * Return -1 if transaction wait times out. - */ -static int cs8409_i2c_wait_complete(struct hda_codec *codec) -{ - int repeat = 5; - unsigned int retval; - - do { - retval = cs_vendor_coef_get(codec, CIR_I2C_STATUS); - if ((retval & 0x18) != 0x18) { - usleep_range(2000, 4000); - --repeat; - } else - return 0; - - } while (repeat); - - return -1; -} - -/** - * cs8409_i2c_read - CS8409 I2C Read. - * @codec: the codec instance - * @i2c_address: I2C Address - * @i2c_reg: Register to read - * @paged: Is a paged transaction - * - * CS8409 I2C Read. - * Returns negative on error, otherwise returns read value in bits 0-7. - */ -static int cs8409_i2c_read(struct hda_codec *codec, - unsigned int i2c_address, - unsigned int i2c_reg, - unsigned int paged) -{ - unsigned int i2c_reg_data; - unsigned int read_data; - - cs8409_enable_i2c_clock(codec, 1); - cs_vendor_coef_set(codec, CIR_I2C_ADDR, i2c_address); - - if (paged) { - cs_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg >> 8); - if (cs8409_i2c_wait_complete(codec) < 0) { - codec_err(codec, - "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); - return -EIO; - } - } - - i2c_reg_data = (i2c_reg << 8) & 0x0ffff; - cs_vendor_coef_set(codec, CIR_I2C_QREAD, i2c_reg_data); - if (cs8409_i2c_wait_complete(codec) < 0) { - codec_err(codec, "%s() Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); - return -EIO; - } - - /* Register in bits 15-8 and the data in 7-0 */ - read_data = cs_vendor_coef_get(codec, CIR_I2C_QREAD); - - cs8409_enable_i2c_clock(codec, 0); - - return read_data & 0x0ff; -} - -/** - * cs8409_i2c_write - CS8409 I2C Write. - * @codec: the codec instance - * @i2c_address: I2C Address - * @i2c_reg: Register to write to - * @i2c_data: Data to write - * @paged: Is a paged transaction - * - * CS8409 I2C Write. - * Returns negative on error, otherwise returns 0. - */ -static int cs8409_i2c_write(struct hda_codec *codec, - unsigned int i2c_address, unsigned int i2c_reg, - unsigned int i2c_data, - unsigned int paged) -{ - unsigned int i2c_reg_data; - - cs8409_enable_i2c_clock(codec, 1); - cs_vendor_coef_set(codec, CIR_I2C_ADDR, i2c_address); - - if (paged) { - cs_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg >> 8); - if (cs8409_i2c_wait_complete(codec) < 0) { - codec_err(codec, - "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); - return -EIO; - } - } - - i2c_reg_data = ((i2c_reg << 8) & 0x0ff00) | (i2c_data & 0x0ff); - cs_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg_data); - - if (cs8409_i2c_wait_complete(codec) < 0) { - codec_err(codec, "%s() Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); - return -EIO; - } - - cs8409_enable_i2c_clock(codec, 0); - - return 0; -} - -static int cs8409_cs42l42_volume_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - u16 nid = get_amp_nid(kcontrol); - u8 chs = get_amp_channels(kcontrol); - - codec_dbg(codec, "%s() nid: %d\n", __func__, nid); - switch (nid) { - case CS8409_CS42L42_HP_PIN_NID: - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = chs == 3 ? 2 : 1; - uinfo->value.integer.min = CS8409_CS42L42_HP_VOL_REAL_MIN; - uinfo->value.integer.max = CS8409_CS42L42_HP_VOL_REAL_MAX; - break; - case CS8409_CS42L42_AMIC_PIN_NID: - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = chs == 3 ? 2 : 1; - uinfo->value.integer.min = CS8409_CS42L42_AMIC_VOL_REAL_MIN; - uinfo->value.integer.max = CS8409_CS42L42_AMIC_VOL_REAL_MAX; - break; - default: - break; - } - return 0; -} - -static void cs8409_cs42l42_update_volume(struct hda_codec *codec) -{ - struct cs_spec *spec = codec->spec; - int data; - - mutex_lock(&spec->cs8409_i2c_mux); - data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_HS_VOLUME_CHA, 1); - if (data >= 0) - spec->cs42l42_hp_volume[0] = -data; - else - spec->cs42l42_hp_volume[0] = CS8409_CS42L42_HP_VOL_REAL_MIN; - data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_HS_VOLUME_CHB, 1); - if (data >= 0) - spec->cs42l42_hp_volume[1] = -data; - else - spec->cs42l42_hp_volume[1] = CS8409_CS42L42_HP_VOL_REAL_MIN; - data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_AMIC_VOLUME, 1); - if (data >= 0) - spec->cs42l42_hs_mic_volume[0] = -data; - else - spec->cs42l42_hs_mic_volume[0] = CS8409_CS42L42_AMIC_VOL_REAL_MIN; - mutex_unlock(&spec->cs8409_i2c_mux); - spec->cs42l42_volume_init = 1; -} - -static int cs8409_cs42l42_volume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct cs_spec *spec = codec->spec; - hda_nid_t nid = get_amp_nid(kcontrol); - int chs = get_amp_channels(kcontrol); - long *valp = ucontrol->value.integer.value; - - if (!spec->cs42l42_volume_init) { - snd_hda_power_up(codec); - cs8409_cs42l42_update_volume(codec); - snd_hda_power_down(codec); - } - switch (nid) { - case CS8409_CS42L42_HP_PIN_NID: - if (chs & BIT(0)) - *valp++ = spec->cs42l42_hp_volume[0]; - if (chs & BIT(1)) - *valp++ = spec->cs42l42_hp_volume[1]; - break; - case CS8409_CS42L42_AMIC_PIN_NID: - if (chs & BIT(0)) - *valp++ = spec->cs42l42_hs_mic_volume[0]; - break; - default: - break; - } - return 0; -} - -static int cs8409_cs42l42_volume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct cs_spec *spec = codec->spec; - hda_nid_t nid = get_amp_nid(kcontrol); - int chs = get_amp_channels(kcontrol); - long *valp = ucontrol->value.integer.value; - int change = 0; - char vol; - - snd_hda_power_up(codec); - switch (nid) { - case CS8409_CS42L42_HP_PIN_NID: - mutex_lock(&spec->cs8409_i2c_mux); - if (chs & BIT(0)) { - vol = -(*valp); - change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_HS_VOLUME_CHA, vol, 1); - valp++; - } - if (chs & BIT(1)) { - vol = -(*valp); - change |= cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_HS_VOLUME_CHB, vol, 1); - } - mutex_unlock(&spec->cs8409_i2c_mux); - break; - case CS8409_CS42L42_AMIC_PIN_NID: - mutex_lock(&spec->cs8409_i2c_mux); - if (chs & BIT(0)) { - change = cs8409_i2c_write( - codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_AMIC_VOLUME, (char)*valp, 1); - valp++; - } - mutex_unlock(&spec->cs8409_i2c_mux); - break; - default: - break; - } - cs8409_cs42l42_update_volume(codec); - snd_hda_power_down(codec); - return change; -} - -static const DECLARE_TLV_DB_SCALE( - cs8409_cs42l42_hp_db_scale, - CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1); - -static const DECLARE_TLV_DB_SCALE( - cs8409_cs42l42_amic_db_scale, - CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1); - -static const struct snd_kcontrol_new cs8409_cs42l42_hp_volume_mixer = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .index = 0, - .name = "Headphone Playback Volume", - .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE - | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .info = cs8409_cs42l42_volume_info, - .get = cs8409_cs42l42_volume_get, - .put = cs8409_cs42l42_volume_put, - .tlv = { .p = cs8409_cs42l42_hp_db_scale }, - .private_value = HDA_COMPOSE_AMP_VAL( - CS8409_CS42L42_HP_PIN_NID, 3, 0, HDA_OUTPUT) - | HDA_AMP_VAL_MIN_MUTE -}; - -static const struct snd_kcontrol_new cs8409_cs42l42_amic_volume_mixer = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .index = 0, - .name = "Mic Capture Volume", - .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE - | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .info = cs8409_cs42l42_volume_info, - .get = cs8409_cs42l42_volume_get, - .put = cs8409_cs42l42_volume_put, - .tlv = { .p = cs8409_cs42l42_amic_db_scale }, - .private_value = HDA_COMPOSE_AMP_VAL( - CS8409_CS42L42_AMIC_PIN_NID, 1, 0, HDA_INPUT) - | HDA_AMP_VAL_MIN_MUTE -}; - -/* Assert/release RTS# line to CS42L42 */ -static void cs8409_cs42l42_reset(struct hda_codec *codec) -{ - struct cs_spec *spec = codec->spec; - - /* Assert RTS# line */ - snd_hda_codec_write(codec, - codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, 0); - /* wait ~10ms */ - usleep_range(10000, 15000); - /* Release RTS# line */ - snd_hda_codec_write(codec, - codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, GPIO5_INT); - /* wait ~10ms */ - usleep_range(10000, 15000); - - mutex_lock(&spec->cs8409_i2c_mux); - - /* Clear interrupts, by reading interrupt status registers */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1309, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130A, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130F, 1); - - mutex_unlock(&spec->cs8409_i2c_mux); - -} - -/* Configure CS42L42 slave codec for jack autodetect */ -static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) -{ - struct cs_spec *spec = codec->spec; - - mutex_lock(&spec->cs8409_i2c_mux); - - /* Set TIP_SENSE_EN for analog front-end of tip sense. */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020, 1); - /* Clear WAKE# */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x0001, 1); - /* Wait ~2.5ms */ - usleep_range(2500, 3000); - /* Set mode WAKE# output follows the combination logic directly */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x0020, 1); - /* Clear interrupts status */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b7b, 1); - /* Enable interrupt */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0x03, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b79, 0x00, 1); - - mutex_unlock(&spec->cs8409_i2c_mux); -} - -/* Enable and run CS42L42 slave codec jack auto detect */ -static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec) -{ - struct cs_spec *spec = codec->spec; - - mutex_lock(&spec->cs8409_i2c_mux); - - /* Clear interrupts */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77, 1); - - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0x01, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80, 1); - /* Wait ~110ms*/ - usleep_range(110000, 200000); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0, 1); - /* Wait ~10ms */ - usleep_range(10000, 25000); - - mutex_unlock(&spec->cs8409_i2c_mux); - -} - -static void cs8409_cs42l42_reg_setup(struct hda_codec *codec) -{ - const struct cs8409_i2c_param *seq = cs42l42_init_reg_seq; - struct cs_spec *spec = codec->spec; - - mutex_lock(&spec->cs8409_i2c_mux); - - for (; seq->addr; seq++) - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, seq->addr, seq->reg, 1); - - mutex_unlock(&spec->cs8409_i2c_mux); - -} - -/* - * In the case of CS8409 we do not have unsolicited events from NID's 0x24 - * and 0x34 where hs mic and hp are connected. Companion codec CS42L42 will - * generate interrupt via gpio 4 to notify jack events. We have to overwrite - * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers - * and then notify status via generic snd_hda_jack_unsol_event() call. - */ -static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) -{ - struct cs_spec *spec = codec->spec; - int status_changed = 0; - int reg_cdc_status; - int reg_hs_status; - int reg_ts_status; - int type; - struct hda_jack_tbl *jk; - - /* jack_unsol_event() will be called every time gpio line changing state. - * In this case gpio4 line goes up as a result of reading interrupt status - * registers in previous cs8409_jack_unsol_event() call. - * We don't need to handle this event, ignoring... - */ - if ((res & (1 << 4))) - return; - - mutex_lock(&spec->cs8409_i2c_mux); - - /* Read jack detect status registers */ - reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); - reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124, 1); - reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); - - /* Clear interrupts, by reading interrupt status registers */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b7b, 1); - - mutex_unlock(&spec->cs8409_i2c_mux); - - /* If status values are < 0, read error has occurred. */ - if (reg_cdc_status < 0 || reg_hs_status < 0 || reg_ts_status < 0) - return; - - /* HSDET_AUTO_DONE */ - if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) { - - type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1); - /* CS42L42 reports optical jack as type 4 - * We don't handle optical jack - */ - if (type != 4) { - if (!spec->cs42l42_hp_jack_in) { - status_changed = 1; - spec->cs42l42_hp_jack_in = 1; - } - /* type = 3 has no mic */ - if ((!spec->cs42l42_mic_jack_in) && (type != 3)) { - status_changed = 1; - spec->cs42l42_mic_jack_in = 1; - } - } else { - if (spec->cs42l42_hp_jack_in || spec->cs42l42_mic_jack_in) { - status_changed = 1; - spec->cs42l42_hp_jack_in = 0; - spec->cs42l42_mic_jack_in = 0; - } - } - - } else { - /* TIP_SENSE INSERT/REMOVE */ - switch (reg_ts_status) { - case CS42L42_JACK_INSERTED: - cs8409_cs42l42_run_jack_detect(codec); - break; - - case CS42L42_JACK_REMOVED: - if (spec->cs42l42_hp_jack_in || spec->cs42l42_mic_jack_in) { - status_changed = 1; - spec->cs42l42_hp_jack_in = 0; - spec->cs42l42_mic_jack_in = 0; - } - break; - - default: - /* jack in transition */ - status_changed = 0; - break; - } - } - - if (status_changed) { - - snd_hda_set_pin_ctl(codec, CS8409_CS42L42_SPK_PIN_NID, - spec->cs42l42_hp_jack_in ? 0 : PIN_OUT); - - /* Report jack*/ - jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_HP_PIN_NID, 0); - if (jk) { - snd_hda_jack_unsol_event(codec, - (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & AC_UNSOL_RES_TAG); - } - /* Report jack*/ - jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_AMIC_PIN_NID, 0); - if (jk) { - snd_hda_jack_unsol_event(codec, - (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & AC_UNSOL_RES_TAG); - } - } -} - -#ifdef CONFIG_PM -/* Manage PDREF, when transition to D3hot */ -static int cs8409_suspend(struct hda_codec *codec) -{ - struct cs_spec *spec = codec->spec; - - mutex_lock(&spec->cs8409_i2c_mux); - /* Power down CS42L42 ASP/EQ/MIX/HP */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe, 1); - mutex_unlock(&spec->cs8409_i2c_mux); - /* Assert CS42L42 RTS# line */ - snd_hda_codec_write(codec, - codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, 0); - - snd_hda_shutup_pins(codec); - - return 0; -} -#endif - -/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */ -static void cs8409_enable_ur(struct hda_codec *codec, int flag) -{ - /* GPIO4 INT# and GPIO3 WAKE# */ - snd_hda_codec_write(codec, codec->core.afg, - 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, - flag ? (GPIO3_INT | GPIO4_INT) : 0); - - snd_hda_codec_write(codec, codec->core.afg, - 0, AC_VERB_SET_UNSOLICITED_ENABLE, - flag ? AC_UNSOL_ENABLED : 0); - -} - -/* Vendor specific HW configuration - * PLL, ASP, I2C, SPI, GPIOs, DMIC etc... - */ -static void cs8409_cs42l42_hw_init(struct hda_codec *codec) -{ - const struct cs8409_cir_param *seq = cs8409_cs42l42_hw_cfg; - const struct cs8409_cir_param *seq_bullseye = cs8409_cs42l42_bullseye_atn; - struct cs_spec *spec = codec->spec; - - if (spec->gpio_mask) { - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, - spec->gpio_mask); - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, - spec->gpio_dir); - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, - spec->gpio_data); - } - - for (; seq->nid; seq++) - cs_vendor_coef_set(codec, seq->cir, seq->coeff); - - if (codec->fixup_id == CS8409_BULLSEYE) - for (; seq_bullseye->nid; seq_bullseye++) - cs_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff); - - /* Disable Unsolicited Response during boot */ - cs8409_enable_ur(codec, 0); - - /* Reset CS42L42 */ - cs8409_cs42l42_reset(codec); - - /* Initialise CS42L42 companion codec */ - cs8409_cs42l42_reg_setup(codec); - - if (codec->fixup_id == CS8409_WARLOCK || - codec->fixup_id == CS8409_CYBORG) { - /* FULL_SCALE_VOL = 0 for Warlock / Cyborg */ - mutex_lock(&spec->cs8409_i2c_mux); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01, 1); - mutex_unlock(&spec->cs8409_i2c_mux); - /* DMIC1_MO=00b, DMIC1/2_SR=1 */ - cs_vendor_coef_set(codec, 0x09, 0x0003); - } - - /* Restore Volumes after Resume */ - if (spec->cs42l42_volume_init) { - mutex_lock(&spec->cs8409_i2c_mux); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_HS_VOLUME_CHA, - -spec->cs42l42_hp_volume[0], - 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_HS_VOLUME_CHB, - -spec->cs42l42_hp_volume[1], - 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_AMIC_VOLUME, - spec->cs42l42_hs_mic_volume[0], - 1); - mutex_unlock(&spec->cs8409_i2c_mux); - } - - cs8409_cs42l42_update_volume(codec); - - cs8409_cs42l42_enable_jack_detect(codec); - - /* Enable Unsolicited Response */ - cs8409_enable_ur(codec, 1); -} - -static int cs8409_cs42l42_init(struct hda_codec *codec) -{ - int ret = snd_hda_gen_init(codec); - - 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 = cs_build_controls, - .build_pcms = snd_hda_gen_build_pcms, - .init = cs8409_cs42l42_init, - .free = cs_free, - .unsol_event = cs8409_jack_unsol_event, -#ifdef CONFIG_PM - .suspend = cs8409_suspend, -#endif -}; - -static void cs8409_cs42l42_fixups(struct hda_codec *codec, - const struct hda_fixup *fix, int action) -{ - struct cs_spec *spec = codec->spec; - int caps; - - 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; - - mutex_init(&spec->cs8409_i2c_mux); - - codec->patch_ops = cs8409_cs42l42_patch_ops; - - 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; - - /* 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))); - - snd_hda_override_wcaps(codec, CS8409_CS42L42_HP_PIN_NID, - (get_wcaps(codec, CS8409_CS42L42_HP_PIN_NID) | AC_WCAP_UNSOL_CAP)); - - snd_hda_override_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID, - (get_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID) | AC_WCAP_UNSOL_CAP)); - break; - case HDA_FIXUP_ACT_PROBE: - - /* Set initial DMIC volume to -26 dB */ - snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, - HDA_INPUT, 0, 0xff, 0x19); - 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); - fallthrough; - 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, - unsigned int cmd, unsigned int flags, unsigned int *res) -{ - struct hda_codec *codec = container_of(dev, struct hda_codec, core); - struct cs_spec *spec = codec->spec; - - unsigned int nid = ((cmd >> 20) & 0x07f); - unsigned int verb = ((cmd >> 8) & 0x0fff); - - /* CS8409 pins have no AC_PINSENSE_PRESENCE - * capabilities. We have to intercept 2 calls for pins 0x24 and 0x34 - * and return correct pin sense values for read_pin_sense() call from - * hda_jack based on CS42L42 jack detect status. - */ - switch (nid) { - case CS8409_CS42L42_HP_PIN_NID: - if (verb == AC_VERB_GET_PIN_SENSE) { - *res = (spec->cs42l42_hp_jack_in) ? AC_PINSENSE_PRESENCE : 0; - return 0; - } - break; - - case CS8409_CS42L42_AMIC_PIN_NID: - if (verb == AC_VERB_GET_PIN_SENSE) { - *res = (spec->cs42l42_mic_jack_in) ? AC_PINSENSE_PRESENCE : 0; - return 0; - } - break; - - default: - break; - } - - return spec->exec_verb(dev, cmd, flags, res); -} - -static int patch_cs8409(struct hda_codec *codec) -{ - int err; - - if (!cs_alloc_spec(codec, CS8409_VENDOR_NID)) - return -ENOMEM; - - snd_hda_pick_fixup(codec, - cs8409_models, cs8409_fixup_tbl, cs8409_fixups); - - codec_dbg(codec, "Picked ID=%d, VID=%08x, DEV=%08x\n", - codec->fixup_id, - codec->bus->pci->subsystem_vendor, - codec->bus->pci->subsystem_device); - - snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); - - err = cs_parse_auto_config(codec); - if (err < 0) { - cs_free(codec); - return err; - } - - snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); - return 0; -} - /* * patch entries */ @@ -2305,7 +1232,6 @@ static const struct hda_device_id snd_hda_id_cirrus[] = { HDA_CODEC_ENTRY(0x10134208, "CS4208", patch_cs4208), HDA_CODEC_ENTRY(0x10134210, "CS4210", patch_cs4210), HDA_CODEC_ENTRY(0x10134213, "CS4213", patch_cs4213), - HDA_CODEC_ENTRY(0x10138409, "CS8409", patch_cs8409), {} /* terminator */ }; MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_cirrus); diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c new file mode 100644 index 000000000000..9b16f1b5b828 --- /dev/null +++ b/sound/pci/hda/patch_cs8409.c @@ -0,0 +1,1060 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * HD audio interface patch for Cirrus Logic CS8409 HDA bridge chip + * + * Copyright (C) 2021 Cirrus Logic, Inc. and + * Cirrus Logic International Semiconductor Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "hda_local.h" +#include "hda_auto_parser.h" +#include "hda_jack.h" +#include "hda_generic.h" + +#include "patch_cs8409.h" + +static int cs8409_parse_auto_config(struct hda_codec *codec) +{ + struct cs8409_spec *spec = codec->spec; + int err; + int i; + + err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); + if (err < 0) + return err; + + err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); + if (err < 0) + return err; + + /* keep the ADCs powered up when it's dynamically switchable */ + if (spec->gen.dyn_adc_switch) { + unsigned int done = 0; + + for (i = 0; i < spec->gen.input_mux.num_items; i++) { + int idx = spec->gen.dyn_adc_idx[i]; + + if (done & (1 << idx)) + continue; + snd_hda_gen_fix_pin_power(codec, spec->gen.adc_nids[idx]); + done |= 1 << idx; + } + } + + return 0; +} + +/* Dell Inspiron models with cs8409/cs42l42 */ +static const struct hda_model_fixup cs8409_models[] = { + { .id = CS8409_BULLSEYE, .name = "bullseye" }, + { .id = CS8409_WARLOCK, .name = "warlock" }, + { .id = CS8409_CYBORG, .name = "cyborg" }, + {} +}; + +/* Dell Inspiron platforms + * with cs8409 bridge and cs42l42 codec + */ +static const struct snd_pci_quirk cs8409_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0A11, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A12, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A23, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A24, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A25, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A2B, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0AB0, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB5, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AD9, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADC, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0ADF, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE2, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE9, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEA, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEB, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEC, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AED, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), + {} /* terminator */ +}; + +static const struct hda_verb cs8409_cs42l42_init_verbs[] = { + { 0x01, AC_VERB_SET_GPIO_WAKE_MASK, 0x0018 }, /* WAKE from GPIO 3,4 */ + { 0x47, AC_VERB_SET_PROC_STATE, 0x0001 }, /* Enable VPW processing */ + { 0x47, AC_VERB_SET_COEF_INDEX, 0x0002 }, /* Configure GPIO 6,7 */ + { 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 */ + {} /* terminator */ +}; + +static const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { + { 0x24, 0x042120f0 }, /* ASP-1-TX */ + { 0x34, 0x04a12050 }, /* ASP-1-RX */ + { 0x2c, 0x901000f0 }, /* ASP-2-TX */ + { 0x44, 0x90a00090 }, /* DMIC-1 */ + {} /* terminator */ +}; + +static struct cs8409_spec *cs8409_alloc_spec(struct hda_codec *codec) +{ + struct cs8409_spec *spec; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return NULL; + codec->spec = spec; + codec->power_save_node = 1; + snd_hda_gen_spec_init(&spec->gen); + + return spec; +} + +/* Vendor specific HW configuration for CS42L42 */ +static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { + { 0x1010, 0xB0 }, + { 0x1D01, 0x00 }, + { 0x1D02, 0x06 }, + { 0x1D03, 0x00 }, + { 0x1107, 0x01 }, + { 0x1009, 0x02 }, + { 0x1007, 0x03 }, + { 0x1201, 0x00 }, + { 0x1208, 0x13 }, + { 0x1205, 0xFF }, + { 0x1206, 0x00 }, + { 0x1207, 0x20 }, + { 0x1202, 0x0D }, + { 0x2A02, 0x02 }, + { 0x2A03, 0x00 }, + { 0x2A04, 0x00 }, + { 0x2A05, 0x02 }, + { 0x2A06, 0x00 }, + { 0x2A07, 0x20 }, + { 0x2A08, 0x02 }, + { 0x2A09, 0x00 }, + { 0x2A0A, 0x80 }, + { 0x2A0B, 0x02 }, + { 0x2A0C, 0x00 }, + { 0x2A0D, 0xA0 }, + { 0x2A01, 0x0C }, + { 0x2902, 0x01 }, + { 0x2903, 0x02 }, + { 0x2904, 0x00 }, + { 0x2905, 0x00 }, + { 0x2901, 0x01 }, + { 0x1101, 0x0A }, + { 0x1102, 0x84 }, + { 0x2301, 0x00 }, + { 0x2303, 0x00 }, + { 0x2302, 0x3f }, + { 0x2001, 0x03 }, + { 0x1B75, 0xB6 }, + { 0x1B73, 0xC2 }, + { 0x1129, 0x01 }, + { 0x1121, 0xF3 }, + { 0x1103, 0x20 }, + { 0x1105, 0x00 }, + { 0x1112, 0xC0 }, + { 0x1113, 0x80 }, + { 0x1C03, 0xC0 }, + { 0x1105, 0x00 }, + { 0x1112, 0xC0 }, + { 0x1101, 0x02 }, + {} /* Terminator */ +}; + +/* Vendor specific hw configuration for CS8409 */ +static const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[] = { + { 0x47, 0x00, 0xb008 }, /* +PLL1/2_EN, +I2C_EN */ + { 0x47, 0x01, 0x0002 }, /* ASP1/2_EN=0, ASP1_STP=1 */ + { 0x47, 0x02, 0x0a80 }, /* ASP1/2_BUS_IDLE=10, +GPIO_I2C */ + { 0x47, 0x19, 0x0800 }, /* ASP1.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ + { 0x47, 0x1a, 0x0820 }, /* ASP1.A: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=32 */ + { 0x47, 0x29, 0x0800 }, /* ASP2.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ + { 0x47, 0x2a, 0x2800 }, /* ASP2.A: TX.RAP=1, TX.RSZ=24 bits, TX.RCS=0 */ + { 0x47, 0x39, 0x0800 }, /* ASP1.A: RX.LAP=0, RX.LSZ=24 bits, RX.LCS=0 */ + { 0x47, 0x3a, 0x0800 }, /* ASP1.A: RX.RAP=0, RX.RSZ=24 bits, RX.RCS=0 */ + { 0x47, 0x03, 0x8000 }, /* ASP1: LCHI = 00h */ + { 0x47, 0x04, 0x28ff }, /* ASP1: MC/SC_SRCSEL=PLL1, LCPR=FFh */ + { 0x47, 0x05, 0x0062 }, /* ASP1: MCEN=0, FSD=011, SCPOL_IN/OUT=0, SCDIV=1:4 */ + { 0x47, 0x06, 0x801f }, /* ASP2: LCHI=1Fh */ + { 0x47, 0x07, 0x283f }, /* ASP2: MC/SC_SRCSEL=PLL1, LCPR=3Fh */ + { 0x47, 0x08, 0x805c }, /* ASP2: 5050=1, MCEN=0, FSD=010, SCPOL_IN/OUT=1, SCDIV=1:16 */ + { 0x47, 0x09, 0x0023 }, /* DMIC1_MO=10b, DMIC1/2_SR=1 */ + { 0x47, 0x0a, 0x0000 }, /* ASP1/2_BEEP=0 */ + { 0x47, 0x01, 0x0062 }, /* ASP1/2_EN=1, ASP1_STP=1 */ + { 0x47, 0x00, 0x9008 }, /* -PLL2_EN */ + { 0x47, 0x68, 0x0000 }, /* TX2.A: pre-scale att.=0 dB */ + { 0x47, 0x82, 0xfc03 }, /* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=1 */ + { 0x47, 0xc0, 0x9999 }, /* test mode on */ + { 0x47, 0xc5, 0x0000 }, /* GPIO hysteresis = 30 us */ + { 0x47, 0xc0, 0x0000 }, /* test mode off */ + {} /* Terminator */ +}; + +static const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[] = { + { 0x47, 0x65, 0x4000 }, /* EQ_SEL=1, EQ1/2_EN=0 */ + { 0x47, 0x64, 0x4000 }, /* +EQ_ACC */ + { 0x47, 0x65, 0x4010 }, /* +EQ2_EN */ + { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ + { 0x47, 0x64, 0xc0c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=0, EQ_DATA_LO=0x67 */ + { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ + { 0x47, 0x64, 0xc1c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=1, EQ_DATA_LO=0x67 */ + { 0x47, 0x63, 0xf370 }, /* EQ_DATA_HI=0xf370 */ + { 0x47, 0x64, 0xc271 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=2, EQ_DATA_LO=0x71 */ + { 0x47, 0x63, 0x1ef8 }, /* EQ_DATA_HI=0x1ef8 */ + { 0x47, 0x64, 0xc348 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=3, EQ_DATA_LO=0x48 */ + { 0x47, 0x63, 0xc110 }, /* EQ_DATA_HI=0xc110 */ + { 0x47, 0x64, 0xc45a }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=4, EQ_DATA_LO=0x5a */ + { 0x47, 0x63, 0x1f29 }, /* EQ_DATA_HI=0x1f29 */ + { 0x47, 0x64, 0xc574 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=5, EQ_DATA_LO=0x74 */ + { 0x47, 0x63, 0x1d7a }, /* EQ_DATA_HI=0x1d7a */ + { 0x47, 0x64, 0xc653 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=6, EQ_DATA_LO=0x53 */ + { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ + { 0x47, 0x64, 0xc714 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=7, EQ_DATA_LO=0x14 */ + { 0x47, 0x63, 0x1ca3 }, /* EQ_DATA_HI=0x1ca3 */ + { 0x47, 0x64, 0xc8c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=8, EQ_DATA_LO=0xc7 */ + { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ + { 0x47, 0x64, 0xc914 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=9, EQ_DATA_LO=0x14 */ + { 0x47, 0x64, 0x0000 }, /* -EQ_ACC, -EQ_WRT */ + {} /* Terminator */ +}; + +static inline int cs8409_vendor_coef_get(struct hda_codec *codec, unsigned int idx) +{ + snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0, AC_VERB_SET_COEF_INDEX, idx); + return snd_hda_codec_read(codec, CS8409_VENDOR_NID, 0, AC_VERB_GET_PROC_COEF, 0); +} + +static inline void cs8409_vendor_coef_set(struct hda_codec *codec, unsigned int idx, + unsigned int coef) +{ + snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0, AC_VERB_SET_COEF_INDEX, idx); + snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0, AC_VERB_SET_PROC_COEF, coef); +} + +/** + * cs8409_enable_i2c_clock - Enable I2C clocks + * @codec: the codec instance + * @enable: Enable or disable I2C clocks + * + * Enable or Disable I2C clocks. + */ +static void cs8409_enable_i2c_clock(struct hda_codec *codec, unsigned int enable) +{ + unsigned int retval; + unsigned int newval; + + retval = cs8409_vendor_coef_get(codec, 0x0); + newval = (enable) ? (retval | 0x8) : (retval & 0xfffffff7); + cs8409_vendor_coef_set(codec, 0x0, newval); +} + +/** + * cs8409_i2c_wait_complete - Wait for I2C transaction + * @codec: the codec instance + * + * Wait for I2C transaction to complete. + * Return -1 if transaction wait times out. + */ +static int cs8409_i2c_wait_complete(struct hda_codec *codec) +{ + int repeat = 5; + unsigned int retval; + + do { + retval = cs8409_vendor_coef_get(codec, CIR_I2C_STATUS); + if ((retval & 0x18) != 0x18) { + usleep_range(2000, 4000); + --repeat; + } else + return 0; + + } while (repeat); + + return -1; +} + +/** + * cs8409_i2c_read - CS8409 I2C Read. + * @codec: the codec instance + * @i2c_address: I2C Address + * @i2c_reg: Register to read + * @paged: Is a paged transaction + * + * CS8409 I2C Read. + * Returns negative on error, otherwise returns read value in bits 0-7. + */ +static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg, + unsigned int paged) +{ + unsigned int i2c_reg_data; + unsigned int read_data; + + cs8409_enable_i2c_clock(codec, 1); + cs8409_vendor_coef_set(codec, CIR_I2C_ADDR, i2c_address); + + if (paged) { + cs8409_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg >> 8); + if (cs8409_i2c_wait_complete(codec) < 0) { + codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; + } + } + + i2c_reg_data = (i2c_reg << 8) & 0x0ffff; + cs8409_vendor_coef_set(codec, CIR_I2C_QREAD, i2c_reg_data); + if (cs8409_i2c_wait_complete(codec) < 0) { + codec_err(codec, "%s() Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; + } + + /* Register in bits 15-8 and the data in 7-0 */ + read_data = cs8409_vendor_coef_get(codec, CIR_I2C_QREAD); + + cs8409_enable_i2c_clock(codec, 0); + + return read_data & 0x0ff; +} + +/** + * cs8409_i2c_write - CS8409 I2C Write. + * @codec: the codec instance + * @i2c_address: I2C Address + * @i2c_reg: Register to write to + * @i2c_data: Data to write + * @paged: Is a paged transaction + * + * CS8409 I2C Write. + * Returns negative on error, otherwise returns 0. + */ +static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg, + unsigned int i2c_data, unsigned int paged) +{ + unsigned int i2c_reg_data; + + cs8409_enable_i2c_clock(codec, 1); + cs8409_vendor_coef_set(codec, CIR_I2C_ADDR, i2c_address); + + if (paged) { + cs8409_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg >> 8); + if (cs8409_i2c_wait_complete(codec) < 0) { + codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; + } + } + + i2c_reg_data = ((i2c_reg << 8) & 0x0ff00) | (i2c_data & 0x0ff); + cs8409_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg_data); + + if (cs8409_i2c_wait_complete(codec) < 0) { + codec_err(codec, "%s() Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; + } + + cs8409_enable_i2c_clock(codec, 0); + + return 0; +} + +static int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) +{ + u16 nid = get_amp_nid(kctrl); + u8 chs = get_amp_channels(kctrl); + + switch (nid) { + case CS8409_CS42L42_HP_PIN_NID: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = chs == 3 ? 2 : 1; + uinfo->value.integer.min = CS8409_CS42L42_HP_VOL_REAL_MIN; + uinfo->value.integer.max = CS8409_CS42L42_HP_VOL_REAL_MAX; + break; + case CS8409_CS42L42_AMIC_PIN_NID: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = chs == 3 ? 2 : 1; + uinfo->value.integer.min = CS8409_CS42L42_AMIC_VOL_REAL_MIN; + uinfo->value.integer.max = CS8409_CS42L42_AMIC_VOL_REAL_MAX; + break; + default: + break; + } + return 0; +} + +static void cs8409_cs42l42_update_volume(struct hda_codec *codec) +{ + struct cs8409_spec *spec = codec->spec; + int data; + + mutex_lock(&spec->cs8409_i2c_mux); + data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHA, 1); + if (data >= 0) + spec->cs42l42_hp_volume[0] = -data; + else + spec->cs42l42_hp_volume[0] = CS8409_CS42L42_HP_VOL_REAL_MIN; + data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHB, 1); + if (data >= 0) + spec->cs42l42_hp_volume[1] = -data; + else + spec->cs42l42_hp_volume[1] = CS8409_CS42L42_HP_VOL_REAL_MIN; + data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOLUME, 1); + if (data >= 0) + spec->cs42l42_hs_mic_volume[0] = -data; + else + spec->cs42l42_hs_mic_volume[0] = CS8409_CS42L42_AMIC_VOL_REAL_MIN; + mutex_unlock(&spec->cs8409_i2c_mux); + spec->cs42l42_volume_init = 1; +} + +static int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) +{ + struct hda_codec *codec = snd_kcontrol_chip(kctrl); + struct cs8409_spec *spec = codec->spec; + hda_nid_t nid = get_amp_nid(kctrl); + int chs = get_amp_channels(kctrl); + long *valp = uctrl->value.integer.value; + + if (!spec->cs42l42_volume_init) { + snd_hda_power_up(codec); + cs8409_cs42l42_update_volume(codec); + snd_hda_power_down(codec); + } + switch (nid) { + case CS8409_CS42L42_HP_PIN_NID: + if (chs & BIT(0)) + *valp++ = spec->cs42l42_hp_volume[0]; + if (chs & BIT(1)) + *valp++ = spec->cs42l42_hp_volume[1]; + break; + case CS8409_CS42L42_AMIC_PIN_NID: + if (chs & BIT(0)) + *valp++ = spec->cs42l42_hs_mic_volume[0]; + break; + default: + break; + } + return 0; +} + +static int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) +{ + struct hda_codec *codec = snd_kcontrol_chip(kctrl); + struct cs8409_spec *spec = codec->spec; + hda_nid_t nid = get_amp_nid(kctrl); + int chs = get_amp_channels(kctrl); + long *valp = uctrl->value.integer.value; + int change = 0; + char vol; + + snd_hda_power_up(codec); + switch (nid) { + case CS8409_CS42L42_HP_PIN_NID: + mutex_lock(&spec->cs8409_i2c_mux); + if (chs & BIT(0)) { + vol = -(*valp); + change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_HS_VOLUME_CHA, vol, 1); + valp++; + } + if (chs & BIT(1)) { + vol = -(*valp); + change |= cs8409_i2c_write(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_HS_VOLUME_CHB, vol, 1); + } + mutex_unlock(&spec->cs8409_i2c_mux); + break; + case CS8409_CS42L42_AMIC_PIN_NID: + mutex_lock(&spec->cs8409_i2c_mux); + if (chs & BIT(0)) { + change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_AMIC_VOLUME, (char)*valp, 1); + valp++; + } + mutex_unlock(&spec->cs8409_i2c_mux); + break; + default: + break; + } + cs8409_cs42l42_update_volume(codec); + snd_hda_power_down(codec); + return change; +} + +static const DECLARE_TLV_DB_SCALE(cs8409_cs42l42_hp_db_scale, + CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1); + +static const DECLARE_TLV_DB_SCALE(cs8409_cs42l42_amic_db_scale, + CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1); + +static const struct snd_kcontrol_new cs8409_cs42l42_hp_volume_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .index = 0, + .name = "Headphone Playback Volume", + .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .info = cs8409_cs42l42_volume_info, + .get = cs8409_cs42l42_volume_get, + .put = cs8409_cs42l42_volume_put, + .tlv = { .p = cs8409_cs42l42_hp_db_scale }, + .private_value = HDA_COMPOSE_AMP_VAL(CS8409_CS42L42_HP_PIN_NID, 3, 0, HDA_OUTPUT) | + HDA_AMP_VAL_MIN_MUTE +}; + +static const struct snd_kcontrol_new cs8409_cs42l42_amic_volume_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .index = 0, + .name = "Mic Capture Volume", + .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .info = cs8409_cs42l42_volume_info, + .get = cs8409_cs42l42_volume_get, + .put = cs8409_cs42l42_volume_put, + .tlv = { .p = cs8409_cs42l42_amic_db_scale }, + .private_value = HDA_COMPOSE_AMP_VAL(CS8409_CS42L42_AMIC_PIN_NID, 1, 0, HDA_INPUT) | + HDA_AMP_VAL_MIN_MUTE +}; + +/* Assert/release RTS# line to CS42L42 */ +static void cs8409_cs42l42_reset(struct hda_codec *codec) +{ + struct cs8409_spec *spec = codec->spec; + + /* Assert RTS# line */ + snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, 0); + /* wait ~10ms */ + usleep_range(10000, 15000); + /* Release RTS# line */ + snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, GPIO5_INT); + /* wait ~10ms */ + usleep_range(10000, 15000); + + mutex_lock(&spec->cs8409_i2c_mux); + + /* Clear interrupts, by reading interrupt status registers */ + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1309, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130A, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130F, 1); + + mutex_unlock(&spec->cs8409_i2c_mux); + +} + +/* Configure CS42L42 slave codec for jack autodetect */ +static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) +{ + struct cs8409_spec *spec = codec->spec; + + mutex_lock(&spec->cs8409_i2c_mux); + + /* Set TIP_SENSE_EN for analog front-end of tip sense. */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020, 1); + /* Clear WAKE# */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x0001, 1); + /* Wait ~2.5ms */ + usleep_range(2500, 3000); + /* Set mode WAKE# output follows the combination logic directly */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x0020, 1); + /* Clear interrupts status */ + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b7b, 1); + /* Enable interrupt */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0x03, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b79, 0x00, 1); + + mutex_unlock(&spec->cs8409_i2c_mux); +} + +/* Enable and run CS42L42 slave codec jack auto detect */ +static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec) +{ + struct cs8409_spec *spec = codec->spec; + + mutex_lock(&spec->cs8409_i2c_mux); + + /* Clear interrupts */ + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77, 1); + + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0x01, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80, 1); + /* Wait ~110ms*/ + usleep_range(110000, 200000); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0, 1); + /* Wait ~10ms */ + usleep_range(10000, 25000); + + mutex_unlock(&spec->cs8409_i2c_mux); + +} + +static void cs8409_cs42l42_reg_setup(struct hda_codec *codec) +{ + const struct cs8409_i2c_param *seq = cs42l42_init_reg_seq; + struct cs8409_spec *spec = codec->spec; + + mutex_lock(&spec->cs8409_i2c_mux); + + for (; seq->addr; seq++) + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, seq->addr, seq->reg, 1); + + mutex_unlock(&spec->cs8409_i2c_mux); + +} + +/* + * In the case of CS8409 we do not have unsolicited events from NID's 0x24 + * and 0x34 where hs mic and hp are connected. Companion codec CS42L42 will + * generate interrupt via gpio 4 to notify jack events. We have to overwrite + * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers + * and then notify status via generic snd_hda_jack_unsol_event() call. + */ +static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) +{ + struct cs8409_spec *spec = codec->spec; + int status_changed = 0; + int reg_cdc_status; + int reg_hs_status; + int reg_ts_status; + int type; + struct hda_jack_tbl *jk; + + /* jack_unsol_event() will be called every time gpio line changing state. + * In this case gpio4 line goes up as a result of reading interrupt status + * registers in previous cs8409_jack_unsol_event() call. + * We don't need to handle this event, ignoring... + */ + if ((res & (1 << 4))) + return; + + mutex_lock(&spec->cs8409_i2c_mux); + + /* Read jack detect status registers */ + reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); + reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124, 1); + reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); + + /* Clear interrupts, by reading interrupt status registers */ + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b7b, 1); + + mutex_unlock(&spec->cs8409_i2c_mux); + + /* If status values are < 0, read error has occurred. */ + if (reg_cdc_status < 0 || reg_hs_status < 0 || reg_ts_status < 0) + return; + + /* HSDET_AUTO_DONE */ + if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) { + + type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1); + /* CS42L42 reports optical jack as type 4 + * We don't handle optical jack + */ + if (type != 4) { + if (!spec->cs42l42_hp_jack_in) { + status_changed = 1; + spec->cs42l42_hp_jack_in = 1; + } + /* type = 3 has no mic */ + if ((!spec->cs42l42_mic_jack_in) && (type != 3)) { + status_changed = 1; + spec->cs42l42_mic_jack_in = 1; + } + } else { + if (spec->cs42l42_hp_jack_in || spec->cs42l42_mic_jack_in) { + status_changed = 1; + spec->cs42l42_hp_jack_in = 0; + spec->cs42l42_mic_jack_in = 0; + } + } + + } else { + /* TIP_SENSE INSERT/REMOVE */ + switch (reg_ts_status) { + case CS42L42_JACK_INSERTED: + cs8409_cs42l42_run_jack_detect(codec); + break; + + case CS42L42_JACK_REMOVED: + if (spec->cs42l42_hp_jack_in || spec->cs42l42_mic_jack_in) { + status_changed = 1; + spec->cs42l42_hp_jack_in = 0; + spec->cs42l42_mic_jack_in = 0; + } + break; + + default: + /* jack in transition */ + status_changed = 0; + break; + } + } + + if (status_changed) { + + snd_hda_set_pin_ctl(codec, CS8409_CS42L42_SPK_PIN_NID, + spec->cs42l42_hp_jack_in ? 0 : PIN_OUT); + + /* Report jack*/ + jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_HP_PIN_NID, 0); + if (jk) { + snd_hda_jack_unsol_event(codec, (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & + AC_UNSOL_RES_TAG); + } + /* Report jack*/ + jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_AMIC_PIN_NID, 0); + if (jk) { + snd_hda_jack_unsol_event(codec, (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & + AC_UNSOL_RES_TAG); + } + } +} + +#ifdef CONFIG_PM +/* Manage PDREF, when transition to D3hot */ +static int cs8409_suspend(struct hda_codec *codec) +{ + struct cs8409_spec *spec = codec->spec; + + mutex_lock(&spec->cs8409_i2c_mux); + /* Power down CS42L42 ASP/EQ/MIX/HP */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe, 1); + mutex_unlock(&spec->cs8409_i2c_mux); + /* Assert CS42L42 RTS# line */ + snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, 0); + + snd_hda_shutup_pins(codec); + + return 0; +} +#endif + +/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */ +static void cs8409_enable_ur(struct hda_codec *codec, int flag) +{ + /* GPIO4 INT# and GPIO3 WAKE# */ + snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, + flag ? (GPIO3_INT | GPIO4_INT) : 0); + + snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_UNSOLICITED_ENABLE, + flag ? AC_UNSOL_ENABLED : 0); + +} + +/* Vendor specific HW configuration + * PLL, ASP, I2C, SPI, GPIOs, DMIC etc... + */ +static void cs8409_cs42l42_hw_init(struct hda_codec *codec) +{ + const struct cs8409_cir_param *seq = cs8409_cs42l42_hw_cfg; + const struct cs8409_cir_param *seq_bullseye = cs8409_cs42l42_bullseye_atn; + struct cs8409_spec *spec = codec->spec; + + if (spec->gpio_mask) { + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, spec->gpio_mask); + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir); + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_data); + } + + for (; seq->nid; seq++) + cs8409_vendor_coef_set(codec, seq->cir, seq->coeff); + + if (codec->fixup_id == CS8409_BULLSEYE) + for (; seq_bullseye->nid; seq_bullseye++) + cs8409_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff); + + /* Disable Unsolicited Response during boot */ + cs8409_enable_ur(codec, 0); + + /* Reset CS42L42 */ + cs8409_cs42l42_reset(codec); + + /* Initialise CS42L42 companion codec */ + cs8409_cs42l42_reg_setup(codec); + + if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) { + /* FULL_SCALE_VOL = 0 for Warlock / Cyborg */ + mutex_lock(&spec->cs8409_i2c_mux); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01, 1); + mutex_unlock(&spec->cs8409_i2c_mux); + /* DMIC1_MO=00b, DMIC1/2_SR=1 */ + cs8409_vendor_coef_set(codec, 0x09, 0x0003); + } + + /* Restore Volumes after Resume */ + if (spec->cs42l42_volume_init) { + mutex_lock(&spec->cs8409_i2c_mux); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHA, + -spec->cs42l42_hp_volume[0], 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHB, + -spec->cs42l42_hp_volume[1], 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOLUME, + spec->cs42l42_hs_mic_volume[0], 1); + mutex_unlock(&spec->cs8409_i2c_mux); + } + + cs8409_cs42l42_update_volume(codec); + + cs8409_cs42l42_enable_jack_detect(codec); + + /* Enable Unsolicited Response */ + cs8409_enable_ur(codec, 1); +} + +static int cs8409_cs42l42_init(struct hda_codec *codec) +{ + int ret = snd_hda_gen_init(codec); + + if (!ret) + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); + + return ret; +} + +static int cs8409_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); + + return 0; +} + +static const struct hda_codec_ops cs8409_cs42l42_patch_ops = { + .build_controls = cs8409_build_controls, + .build_pcms = snd_hda_gen_build_pcms, + .init = cs8409_cs42l42_init, + .free = snd_hda_gen_free, + .unsol_event = cs8409_jack_unsol_event, +#ifdef CONFIG_PM + .suspend = cs8409_suspend, +#endif +}; + +static int cs8409_cs42l42_exec_verb(struct hdac_device *dev, unsigned int cmd, unsigned int flags, + unsigned int *res) +{ + struct hda_codec *codec = container_of(dev, struct hda_codec, core); + struct cs8409_spec *spec = codec->spec; + + unsigned int nid = ((cmd >> 20) & 0x07f); + unsigned int verb = ((cmd >> 8) & 0x0fff); + + /* CS8409 pins have no AC_PINSENSE_PRESENCE + * capabilities. We have to intercept 2 calls for pins 0x24 and 0x34 + * and return correct pin sense values for read_pin_sense() call from + * hda_jack based on CS42L42 jack detect status. + */ + switch (nid) { + case CS8409_CS42L42_HP_PIN_NID: + if (verb == AC_VERB_GET_PIN_SENSE) { + *res = (spec->cs42l42_hp_jack_in) ? AC_PINSENSE_PRESENCE : 0; + return 0; + } + break; + + case CS8409_CS42L42_AMIC_PIN_NID: + if (verb == AC_VERB_GET_PIN_SENSE) { + *res = (spec->cs42l42_mic_jack_in) ? AC_PINSENSE_PRESENCE : 0; + return 0; + } + break; + + default: + break; + } + + return spec->exec_verb(dev, cmd, flags, res); +} + +static void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action) +{ + struct cs8409_spec *spec = codec->spec; + int caps; + + 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; + + mutex_init(&spec->cs8409_i2c_mux); + + codec->patch_ops = cs8409_cs42l42_patch_ops; + + 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; + + /* 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))); + + snd_hda_override_wcaps(codec, CS8409_CS42L42_HP_PIN_NID, + (get_wcaps(codec, CS8409_CS42L42_HP_PIN_NID) | AC_WCAP_UNSOL_CAP)); + + snd_hda_override_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID, + (get_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID) | AC_WCAP_UNSOL_CAP)); + break; + case HDA_FIXUP_ACT_PROBE: + /* Set initial DMIC volume to -26 dB */ + snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, + HDA_INPUT, 0, 0xff, 0x19); + 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); + fallthrough; + 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 const struct hda_fixup cs8409_fixups[] = { + [CS8409_BULLSEYE] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_WARLOCK] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_CYBORG] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_FIXUPS] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs8409_cs42l42_fixups, + }, +}; + +static int patch_cs8409(struct hda_codec *codec) +{ + int err; + + if (!cs8409_alloc_spec(codec)) + return -ENOMEM; + + snd_hda_pick_fixup(codec, cs8409_models, cs8409_fixup_tbl, cs8409_fixups); + + codec_dbg(codec, "Picked ID=%d, VID=%08x, DEV=%08x\n", codec->fixup_id, + codec->bus->pci->subsystem_vendor, + codec->bus->pci->subsystem_device); + + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); + + err = cs8409_parse_auto_config(codec); + if (err < 0) { + snd_hda_gen_free(codec); + return err; + } + + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); + return 0; +} + +static const struct hda_device_id snd_hda_id_cs8409[] = { + HDA_CODEC_ENTRY(0x10138409, "CS8409", patch_cs8409), + {} /* terminator */ +}; +MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_cs8409); + +static struct hda_codec_driver cs8409_driver = { + .id = snd_hda_id_cs8409, +}; +module_hda_codec_driver(cs8409_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cirrus Logic HDA bridge"); diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h new file mode 100644 index 000000000000..2ab02a520f5a --- /dev/null +++ b/sound/pci/hda/patch_cs8409.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * HD audio interface patch for Cirrus Logic CS8409 HDA bridge chip + * + * Copyright (C) 2021 Cirrus Logic, Inc. and + * Cirrus Logic International Semiconductor Ltd. + */ + +#ifndef __CS8409_PATCH_H +#define __CS8409_PATCH_H + +/* Cirrus Logic CS8409 HDA bridge with + * companion codec CS42L42 + */ +#define CS42L42_HP_CH (2U) +#define CS42L42_HS_MIC_CH (1U) + +#define CS8409_VENDOR_NID 0x47 + +#define CS8409_CS42L42_HP_PIN_NID 0x24 +#define CS8409_CS42L42_SPK_PIN_NID 0x2c +#define CS8409_CS42L42_AMIC_PIN_NID 0x34 +#define CS8409_CS42L42_DMIC_PIN_NID 0x44 +#define CS8409_CS42L42_DMIC_ADC_PIN_NID 0x22 + +#define CS42L42_HSDET_AUTO_DONE 0x02 +#define CS42L42_HSTYPE_MASK 0x03 + +#define CS42L42_JACK_INSERTED 0x0C +#define CS42L42_JACK_REMOVED 0x00 + +#define GPIO3_INT (1 << 3) +#define GPIO4_INT (1 << 4) +#define GPIO5_INT (1 << 5) + +#define CS42L42_I2C_ADDR (0x48 << 1) + +#define CIR_I2C_ADDR 0x0059 +#define CIR_I2C_DATA 0x005A +#define CIR_I2C_CTRL 0x005B +#define CIR_I2C_STATUS 0x005C +#define CIR_I2C_QWRITE 0x005D +#define CIR_I2C_QREAD 0x005E + +#define CS8409_CS42L42_HP_VOL_REAL_MIN (-63) +#define CS8409_CS42L42_HP_VOL_REAL_MAX (0) +#define CS8409_CS42L42_AMIC_VOL_REAL_MIN (-97) +#define CS8409_CS42L42_AMIC_VOL_REAL_MAX (12) +#define CS8409_CS42L42_REG_HS_VOLUME_CHA (0x2301) +#define CS8409_CS42L42_REG_HS_VOLUME_CHB (0x2303) +#define CS8409_CS42L42_REG_AMIC_VOLUME (0x1D03) + +enum { + CS8409_BULLSEYE, + CS8409_WARLOCK, + CS8409_CYBORG, + CS8409_FIXUPS, +}; + +struct cs8409_i2c_param { + unsigned int addr; + unsigned int reg; +}; + +struct cs8409_cir_param { + unsigned int nid; + unsigned int cir; + unsigned int coeff; +}; + +struct cs8409_spec { + struct hda_gen_spec gen; + + unsigned int gpio_mask; + unsigned int gpio_dir; + unsigned int gpio_data; + + unsigned int cs42l42_hp_jack_in:1; + unsigned int cs42l42_mic_jack_in:1; + unsigned int cs42l42_volume_init:1; + char cs42l42_hp_volume[CS42L42_HP_CH]; + char cs42l42_hs_mic_volume[CS42L42_HS_MIC_CH]; + + struct mutex cs8409_i2c_mux; + + /* verb exec op override */ + int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, unsigned int flags, + unsigned int *res); +}; + +#endif From patchwork Wed Jul 28 13:43:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405881 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 65ED4C4338F for ; Wed, 28 Jul 2021 13:51:37 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DC4906023E for ; Wed, 28 Jul 2021 13:51:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org DC4906023E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 8AB7B1ED5; Wed, 28 Jul 2021 15:50:45 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 8AB7B1ED5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480295; bh=036X0gZ+QFJgkfac3ZDux1yKVHPtuc6riCWgOXg0xOQ=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=EvaUyHp4Ct8BSdx6AntLR3Ue+jR1M7fq88rzH7aCWGsBvIzjglNW9cPIPwhE1N3XR adJ2PfGeN6zp7FUJO4a+1HYo52Z+1ZmHQBt458z/GPyYKdu+wVHrZ3hQqf57W5/cZy Kx2idU+KE6okchORSiYzjeTZuuyKzOAj31BqKEqg= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 23396F8056F; Wed, 28 Jul 2021 15:45:15 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id CE5B6F80553; Wed, 28 Jul 2021 15:45:09 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id A9BC6F804E2 for ; Wed, 28 Jul 2021 15:44:39 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz A9BC6F804E2 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="KP98WmRq" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqh014335; Wed, 28 Jul 2021 08:44:33 -0500 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=Zia0kjdORR/kh1suTZbOoDQmikI0+TDOu1rJDVLknQc=; b=KP98WmRqiLhdw+bHOMmC+xePVhFehdCG2iKEQ5PVPMJuWiQ8pl8ITbDoyQ4XMiFfcJuu wXEo/dfAu5AUsUc1n+g3tlSGLQl2BC5zfuc3pUtN68VgXL6QDcr82IxHJpk1kFQXiTPG sJOL3Liv8XCt6bZJt4USYR0G94w8VimRmmRLpU4L9nXGbJFPcBUTPskRBWJgrypjdDJH 5kx3Z8xwgn0G+o0N2MQ8T/HI0/Iqko4/tZPgPHopZGmtfbEBGVyoXeNJ0AgaagnIo3Z8 hlsx2JY5d7Pm14A/msgmHKBXlm/gQ7rsWff5eQuPNAXiEtTfBRD/anV/hz9D+652Ieek 1w== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:32 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:30 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:30 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 16B132BA; Wed, 28 Jul 2021 13:44:30 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 02/27] ALSA: hda/cs8409: Move arrays of configuration to a new file Date: Wed, 28 Jul 2021 14:43:43 +0100 Message-ID: <20210728134408.369396-3-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: TM_Ehtm2KBO1D0pmV4RAmbYLcD2aB_M0 X-Proofpoint-GUID: TM_Ehtm2KBO1D0pmV4RAmbYLcD2aB_M0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/Makefile | 2 +- sound/pci/hda/patch_cs8409-tables.c | 220 ++++++++++++++++++++++++++++ sound/pci/hda/patch_cs8409.c | 218 +-------------------------- sound/pci/hda/patch_cs8409.h | 19 +++ 4 files changed, 241 insertions(+), 218 deletions(-) create mode 100644 sound/pci/hda/patch_cs8409-tables.c diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 1b73e08dc563..b8fa682ce66a 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -20,7 +20,7 @@ snd-hda-codec-analog-objs := patch_analog.o snd-hda-codec-idt-objs := patch_sigmatel.o snd-hda-codec-si3054-objs := patch_si3054.o snd-hda-codec-cirrus-objs := patch_cirrus.o -snd-hda-codec-cs8409-objs := patch_cs8409.o +snd-hda-codec-cs8409-objs := patch_cs8409.o patch_cs8409-tables.o snd-hda-codec-ca0110-objs := patch_ca0110.o snd-hda-codec-ca0132-objs := patch_ca0132.o snd-hda-codec-conexant-objs := patch_conexant.o diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c new file mode 100644 index 000000000000..4adc7a4c4a25 --- /dev/null +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * patch_cs8409-tables.c -- HD audio interface patch for Cirrus Logic CS8409 HDA bridge chip + * + * Copyright (C) 2021 Cirrus Logic, Inc. and + * Cirrus Logic International Semiconductor Ltd. + * + * Author: Lucas Tanure + */ + +#include "patch_cs8409.h" + +/* Dell Inspiron platforms + * with cs8409 bridge and cs42l42 codec + */ +const struct snd_pci_quirk cs8409_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0A11, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A12, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A23, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A24, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A25, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A2B, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0AB0, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB5, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AD9, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADC, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0ADF, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE2, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE9, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEA, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEB, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEC, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AED, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), + {} /* terminator */ +}; + +/* Dell Inspiron models with cs8409/cs42l42 */ +const struct hda_model_fixup cs8409_models[] = { + { .id = CS8409_BULLSEYE, .name = "bullseye" }, + { .id = CS8409_WARLOCK, .name = "warlock" }, + { .id = CS8409_CYBORG, .name = "cyborg" }, + {} +}; + +const struct hda_fixup cs8409_fixups[] = { + [CS8409_BULLSEYE] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_WARLOCK] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_CYBORG] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_FIXUPS] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs8409_cs42l42_fixups, + }, +}; + +const struct hda_verb cs8409_cs42l42_init_verbs[] = { + { 0x01, AC_VERB_SET_GPIO_WAKE_MASK, 0x0018 }, /* WAKE from GPIO 3,4 */ + { 0x47, AC_VERB_SET_PROC_STATE, 0x0001 }, /* Enable VPW processing */ + { 0x47, AC_VERB_SET_COEF_INDEX, 0x0002 }, /* Configure GPIO 6,7 */ + { 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 */ + {} /* terminator */ +}; + +const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { + { 0x24, 0x042120f0 }, /* ASP-1-TX */ + { 0x34, 0x04a12050 }, /* ASP-1-RX */ + { 0x2c, 0x901000f0 }, /* ASP-2-TX */ + { 0x44, 0x90a00090 }, /* DMIC-1 */ + {} /* terminator */ +}; + +/* Vendor specific HW configuration for CS42L42 */ +const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { + { 0x1010, 0xB0 }, + { 0x1D01, 0x00 }, + { 0x1D02, 0x06 }, + { 0x1D03, 0x00 }, + { 0x1107, 0x01 }, + { 0x1009, 0x02 }, + { 0x1007, 0x03 }, + { 0x1201, 0x00 }, + { 0x1208, 0x13 }, + { 0x1205, 0xFF }, + { 0x1206, 0x00 }, + { 0x1207, 0x20 }, + { 0x1202, 0x0D }, + { 0x2A02, 0x02 }, + { 0x2A03, 0x00 }, + { 0x2A04, 0x00 }, + { 0x2A05, 0x02 }, + { 0x2A06, 0x00 }, + { 0x2A07, 0x20 }, + { 0x2A08, 0x02 }, + { 0x2A09, 0x00 }, + { 0x2A0A, 0x80 }, + { 0x2A0B, 0x02 }, + { 0x2A0C, 0x00 }, + { 0x2A0D, 0xA0 }, + { 0x2A01, 0x0C }, + { 0x2902, 0x01 }, + { 0x2903, 0x02 }, + { 0x2904, 0x00 }, + { 0x2905, 0x00 }, + { 0x2901, 0x01 }, + { 0x1101, 0x0A }, + { 0x1102, 0x84 }, + { 0x2301, 0x00 }, + { 0x2303, 0x00 }, + { 0x2302, 0x3f }, + { 0x2001, 0x03 }, + { 0x1B75, 0xB6 }, + { 0x1B73, 0xC2 }, + { 0x1129, 0x01 }, + { 0x1121, 0xF3 }, + { 0x1103, 0x20 }, + { 0x1105, 0x00 }, + { 0x1112, 0xC0 }, + { 0x1113, 0x80 }, + { 0x1C03, 0xC0 }, + { 0x1105, 0x00 }, + { 0x1112, 0xC0 }, + { 0x1101, 0x02 }, + {} /* Terminator */ +}; + +/* Vendor specific hw configuration for CS8409 */ +const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[] = { + { 0x47, 0x00, 0xb008 }, /* +PLL1/2_EN, +I2C_EN */ + { 0x47, 0x01, 0x0002 }, /* ASP1/2_EN=0, ASP1_STP=1 */ + { 0x47, 0x02, 0x0a80 }, /* ASP1/2_BUS_IDLE=10, +GPIO_I2C */ + { 0x47, 0x19, 0x0800 }, /* ASP1.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ + { 0x47, 0x1a, 0x0820 }, /* ASP1.A: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=32 */ + { 0x47, 0x29, 0x0800 }, /* ASP2.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ + { 0x47, 0x2a, 0x2800 }, /* ASP2.A: TX.RAP=1, TX.RSZ=24 bits, TX.RCS=0 */ + { 0x47, 0x39, 0x0800 }, /* ASP1.A: RX.LAP=0, RX.LSZ=24 bits, RX.LCS=0 */ + { 0x47, 0x3a, 0x0800 }, /* ASP1.A: RX.RAP=0, RX.RSZ=24 bits, RX.RCS=0 */ + { 0x47, 0x03, 0x8000 }, /* ASP1: LCHI = 00h */ + { 0x47, 0x04, 0x28ff }, /* ASP1: MC/SC_SRCSEL=PLL1, LCPR=FFh */ + { 0x47, 0x05, 0x0062 }, /* ASP1: MCEN=0, FSD=011, SCPOL_IN/OUT=0, SCDIV=1:4 */ + { 0x47, 0x06, 0x801f }, /* ASP2: LCHI=1Fh */ + { 0x47, 0x07, 0x283f }, /* ASP2: MC/SC_SRCSEL=PLL1, LCPR=3Fh */ + { 0x47, 0x08, 0x805c }, /* ASP2: 5050=1, MCEN=0, FSD=010, SCPOL_IN/OUT=1, SCDIV=1:16 */ + { 0x47, 0x09, 0x0023 }, /* DMIC1_MO=10b, DMIC1/2_SR=1 */ + { 0x47, 0x0a, 0x0000 }, /* ASP1/2_BEEP=0 */ + { 0x47, 0x01, 0x0062 }, /* ASP1/2_EN=1, ASP1_STP=1 */ + { 0x47, 0x00, 0x9008 }, /* -PLL2_EN */ + { 0x47, 0x68, 0x0000 }, /* TX2.A: pre-scale att.=0 dB */ + { 0x47, 0x82, 0xfc03 }, /* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=1 */ + { 0x47, 0xc0, 0x9999 }, /* test mode on */ + { 0x47, 0xc5, 0x0000 }, /* GPIO hysteresis = 30 us */ + { 0x47, 0xc0, 0x0000 }, /* test mode off */ + {} /* Terminator */ +}; + +const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[] = { + { 0x47, 0x65, 0x4000 }, /* EQ_SEL=1, EQ1/2_EN=0 */ + { 0x47, 0x64, 0x4000 }, /* +EQ_ACC */ + { 0x47, 0x65, 0x4010 }, /* +EQ2_EN */ + { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ + { 0x47, 0x64, 0xc0c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=0, EQ_DATA_LO=0x67 */ + { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ + { 0x47, 0x64, 0xc1c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=1, EQ_DATA_LO=0x67 */ + { 0x47, 0x63, 0xf370 }, /* EQ_DATA_HI=0xf370 */ + { 0x47, 0x64, 0xc271 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=2, EQ_DATA_LO=0x71 */ + { 0x47, 0x63, 0x1ef8 }, /* EQ_DATA_HI=0x1ef8 */ + { 0x47, 0x64, 0xc348 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=3, EQ_DATA_LO=0x48 */ + { 0x47, 0x63, 0xc110 }, /* EQ_DATA_HI=0xc110 */ + { 0x47, 0x64, 0xc45a }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=4, EQ_DATA_LO=0x5a */ + { 0x47, 0x63, 0x1f29 }, /* EQ_DATA_HI=0x1f29 */ + { 0x47, 0x64, 0xc574 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=5, EQ_DATA_LO=0x74 */ + { 0x47, 0x63, 0x1d7a }, /* EQ_DATA_HI=0x1d7a */ + { 0x47, 0x64, 0xc653 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=6, EQ_DATA_LO=0x53 */ + { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ + { 0x47, 0x64, 0xc714 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=7, EQ_DATA_LO=0x14 */ + { 0x47, 0x63, 0x1ca3 }, /* EQ_DATA_HI=0x1ca3 */ + { 0x47, 0x64, 0xc8c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=8, EQ_DATA_LO=0xc7 */ + { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ + { 0x47, 0x64, 0xc914 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=9, EQ_DATA_LO=0x14 */ + { 0x47, 0x64, 0x0000 }, /* -EQ_ACC, -EQ_WRT */ + {} /* Terminator */ +}; diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 9b16f1b5b828..b56fc89ad2cd 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -11,13 +11,6 @@ #include #include #include -#include -#include -#include -#include "hda_local.h" -#include "hda_auto_parser.h" -#include "hda_jack.h" -#include "hda_generic.h" #include "patch_cs8409.h" @@ -52,79 +45,6 @@ static int cs8409_parse_auto_config(struct hda_codec *codec) return 0; } -/* Dell Inspiron models with cs8409/cs42l42 */ -static const struct hda_model_fixup cs8409_models[] = { - { .id = CS8409_BULLSEYE, .name = "bullseye" }, - { .id = CS8409_WARLOCK, .name = "warlock" }, - { .id = CS8409_CYBORG, .name = "cyborg" }, - {} -}; - -/* Dell Inspiron platforms - * with cs8409 bridge and cs42l42 codec - */ -static const struct snd_pci_quirk cs8409_fixup_tbl[] = { - SND_PCI_QUIRK(0x1028, 0x0A11, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A12, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A23, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A24, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A25, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A2B, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0AB0, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB5, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AD9, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0ADC, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0ADF, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE2, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE9, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEA, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEB, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEC, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AED, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), - {} /* terminator */ -}; - -static const struct hda_verb cs8409_cs42l42_init_verbs[] = { - { 0x01, AC_VERB_SET_GPIO_WAKE_MASK, 0x0018 }, /* WAKE from GPIO 3,4 */ - { 0x47, AC_VERB_SET_PROC_STATE, 0x0001 }, /* Enable VPW processing */ - { 0x47, AC_VERB_SET_COEF_INDEX, 0x0002 }, /* Configure GPIO 6,7 */ - { 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 */ - {} /* terminator */ -}; - -static const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { - { 0x24, 0x042120f0 }, /* ASP-1-TX */ - { 0x34, 0x04a12050 }, /* ASP-1-RX */ - { 0x2c, 0x901000f0 }, /* ASP-2-TX */ - { 0x44, 0x90a00090 }, /* DMIC-1 */ - {} /* terminator */ -}; - static struct cs8409_spec *cs8409_alloc_spec(struct hda_codec *codec) { struct cs8409_spec *spec; @@ -139,117 +59,6 @@ static struct cs8409_spec *cs8409_alloc_spec(struct hda_codec *codec) return spec; } -/* Vendor specific HW configuration for CS42L42 */ -static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { - { 0x1010, 0xB0 }, - { 0x1D01, 0x00 }, - { 0x1D02, 0x06 }, - { 0x1D03, 0x00 }, - { 0x1107, 0x01 }, - { 0x1009, 0x02 }, - { 0x1007, 0x03 }, - { 0x1201, 0x00 }, - { 0x1208, 0x13 }, - { 0x1205, 0xFF }, - { 0x1206, 0x00 }, - { 0x1207, 0x20 }, - { 0x1202, 0x0D }, - { 0x2A02, 0x02 }, - { 0x2A03, 0x00 }, - { 0x2A04, 0x00 }, - { 0x2A05, 0x02 }, - { 0x2A06, 0x00 }, - { 0x2A07, 0x20 }, - { 0x2A08, 0x02 }, - { 0x2A09, 0x00 }, - { 0x2A0A, 0x80 }, - { 0x2A0B, 0x02 }, - { 0x2A0C, 0x00 }, - { 0x2A0D, 0xA0 }, - { 0x2A01, 0x0C }, - { 0x2902, 0x01 }, - { 0x2903, 0x02 }, - { 0x2904, 0x00 }, - { 0x2905, 0x00 }, - { 0x2901, 0x01 }, - { 0x1101, 0x0A }, - { 0x1102, 0x84 }, - { 0x2301, 0x00 }, - { 0x2303, 0x00 }, - { 0x2302, 0x3f }, - { 0x2001, 0x03 }, - { 0x1B75, 0xB6 }, - { 0x1B73, 0xC2 }, - { 0x1129, 0x01 }, - { 0x1121, 0xF3 }, - { 0x1103, 0x20 }, - { 0x1105, 0x00 }, - { 0x1112, 0xC0 }, - { 0x1113, 0x80 }, - { 0x1C03, 0xC0 }, - { 0x1105, 0x00 }, - { 0x1112, 0xC0 }, - { 0x1101, 0x02 }, - {} /* Terminator */ -}; - -/* Vendor specific hw configuration for CS8409 */ -static const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[] = { - { 0x47, 0x00, 0xb008 }, /* +PLL1/2_EN, +I2C_EN */ - { 0x47, 0x01, 0x0002 }, /* ASP1/2_EN=0, ASP1_STP=1 */ - { 0x47, 0x02, 0x0a80 }, /* ASP1/2_BUS_IDLE=10, +GPIO_I2C */ - { 0x47, 0x19, 0x0800 }, /* ASP1.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ - { 0x47, 0x1a, 0x0820 }, /* ASP1.A: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=32 */ - { 0x47, 0x29, 0x0800 }, /* ASP2.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ - { 0x47, 0x2a, 0x2800 }, /* ASP2.A: TX.RAP=1, TX.RSZ=24 bits, TX.RCS=0 */ - { 0x47, 0x39, 0x0800 }, /* ASP1.A: RX.LAP=0, RX.LSZ=24 bits, RX.LCS=0 */ - { 0x47, 0x3a, 0x0800 }, /* ASP1.A: RX.RAP=0, RX.RSZ=24 bits, RX.RCS=0 */ - { 0x47, 0x03, 0x8000 }, /* ASP1: LCHI = 00h */ - { 0x47, 0x04, 0x28ff }, /* ASP1: MC/SC_SRCSEL=PLL1, LCPR=FFh */ - { 0x47, 0x05, 0x0062 }, /* ASP1: MCEN=0, FSD=011, SCPOL_IN/OUT=0, SCDIV=1:4 */ - { 0x47, 0x06, 0x801f }, /* ASP2: LCHI=1Fh */ - { 0x47, 0x07, 0x283f }, /* ASP2: MC/SC_SRCSEL=PLL1, LCPR=3Fh */ - { 0x47, 0x08, 0x805c }, /* ASP2: 5050=1, MCEN=0, FSD=010, SCPOL_IN/OUT=1, SCDIV=1:16 */ - { 0x47, 0x09, 0x0023 }, /* DMIC1_MO=10b, DMIC1/2_SR=1 */ - { 0x47, 0x0a, 0x0000 }, /* ASP1/2_BEEP=0 */ - { 0x47, 0x01, 0x0062 }, /* ASP1/2_EN=1, ASP1_STP=1 */ - { 0x47, 0x00, 0x9008 }, /* -PLL2_EN */ - { 0x47, 0x68, 0x0000 }, /* TX2.A: pre-scale att.=0 dB */ - { 0x47, 0x82, 0xfc03 }, /* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=1 */ - { 0x47, 0xc0, 0x9999 }, /* test mode on */ - { 0x47, 0xc5, 0x0000 }, /* GPIO hysteresis = 30 us */ - { 0x47, 0xc0, 0x0000 }, /* test mode off */ - {} /* Terminator */ -}; - -static const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[] = { - { 0x47, 0x65, 0x4000 }, /* EQ_SEL=1, EQ1/2_EN=0 */ - { 0x47, 0x64, 0x4000 }, /* +EQ_ACC */ - { 0x47, 0x65, 0x4010 }, /* +EQ2_EN */ - { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ - { 0x47, 0x64, 0xc0c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=0, EQ_DATA_LO=0x67 */ - { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ - { 0x47, 0x64, 0xc1c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=1, EQ_DATA_LO=0x67 */ - { 0x47, 0x63, 0xf370 }, /* EQ_DATA_HI=0xf370 */ - { 0x47, 0x64, 0xc271 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=2, EQ_DATA_LO=0x71 */ - { 0x47, 0x63, 0x1ef8 }, /* EQ_DATA_HI=0x1ef8 */ - { 0x47, 0x64, 0xc348 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=3, EQ_DATA_LO=0x48 */ - { 0x47, 0x63, 0xc110 }, /* EQ_DATA_HI=0xc110 */ - { 0x47, 0x64, 0xc45a }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=4, EQ_DATA_LO=0x5a */ - { 0x47, 0x63, 0x1f29 }, /* EQ_DATA_HI=0x1f29 */ - { 0x47, 0x64, 0xc574 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=5, EQ_DATA_LO=0x74 */ - { 0x47, 0x63, 0x1d7a }, /* EQ_DATA_HI=0x1d7a */ - { 0x47, 0x64, 0xc653 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=6, EQ_DATA_LO=0x53 */ - { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ - { 0x47, 0x64, 0xc714 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=7, EQ_DATA_LO=0x14 */ - { 0x47, 0x63, 0x1ca3 }, /* EQ_DATA_HI=0x1ca3 */ - { 0x47, 0x64, 0xc8c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=8, EQ_DATA_LO=0xc7 */ - { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ - { 0x47, 0x64, 0xc914 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=9, EQ_DATA_LO=0x14 */ - { 0x47, 0x64, 0x0000 }, /* -EQ_ACC, -EQ_WRT */ - {} /* Terminator */ -}; - static inline int cs8409_vendor_coef_get(struct hda_codec *codec, unsigned int idx) { snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0, AC_VERB_SET_COEF_INDEX, idx); @@ -908,7 +717,7 @@ static int cs8409_cs42l42_exec_verb(struct hdac_device *dev, unsigned int cmd, u return spec->exec_verb(dev, cmd, flags, res); } -static void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action) +void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct cs8409_spec *spec = codec->spec; int caps; @@ -995,31 +804,6 @@ static void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixu } } -static const struct hda_fixup cs8409_fixups[] = { - [CS8409_BULLSEYE] = { - .type = HDA_FIXUP_PINS, - .v.pins = cs8409_cs42l42_pincfgs, - .chained = true, - .chain_id = CS8409_FIXUPS, - }, - [CS8409_WARLOCK] = { - .type = HDA_FIXUP_PINS, - .v.pins = cs8409_cs42l42_pincfgs, - .chained = true, - .chain_id = CS8409_FIXUPS, - }, - [CS8409_CYBORG] = { - .type = HDA_FIXUP_PINS, - .v.pins = cs8409_cs42l42_pincfgs, - .chained = true, - .chain_id = CS8409_FIXUPS, - }, - [CS8409_FIXUPS] = { - .type = HDA_FIXUP_FUNC, - .v.func = cs8409_cs42l42_fixups, - }, -}; - static int patch_cs8409(struct hda_codec *codec) { int err; diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 2ab02a520f5a..516123a411db 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -9,6 +9,14 @@ #ifndef __CS8409_PATCH_H #define __CS8409_PATCH_H +#include +#include +#include +#include "hda_local.h" +#include "hda_auto_parser.h" +#include "hda_jack.h" +#include "hda_generic.h" + /* Cirrus Logic CS8409 HDA bridge with * companion codec CS42L42 */ @@ -88,4 +96,15 @@ struct cs8409_spec { unsigned int *res); }; +extern const struct snd_pci_quirk cs8409_fixup_tbl[]; +extern const struct hda_model_fixup cs8409_models[]; +extern const struct hda_fixup cs8409_fixups[]; +extern const struct hda_verb cs8409_cs42l42_init_verbs[]; +extern const struct hda_pintbl cs8409_cs42l42_pincfgs[]; +extern const struct cs8409_i2c_param cs42l42_init_reg_seq[]; +extern const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[]; +extern const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[]; + +void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action); + #endif From patchwork Wed Jul 28 13:43:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405843 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD34BC4338F for ; Wed, 28 Jul 2021 13:47:11 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3029860EC0 for ; Wed, 28 Jul 2021 13:47:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 3029860EC0 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id CCAAB1891; Wed, 28 Jul 2021 15:46:18 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz CCAAB1891 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480028; bh=ju7mtQ+f5XXBm6nlHlI8UthWrkdzY1EZooOhfITBwAw=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=k2W3PnAXmHt0gN5GhSP3rUKkJ1lwhBOIQx/K5N2JqG2SN3jMChHNrJLdv/8+Ps0aF IEHtMSFR6YUzkJwD35bmvFRyMeZIaozslDJUYQxad48tvNAHvdfxf6S+4lqQM0+Tfk HyDv8t8v0fKoaMKXzuLQrhEYaVRzeJH76HGCG0xs= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 7CD69F80516; Wed, 28 Jul 2021 15:44:54 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 3624BF804FE; Wed, 28 Jul 2021 15:44:48 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 2A270F8028B for ; Wed, 28 Jul 2021 15:44:35 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 2A270F8028B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="ROGcWoDA" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqj014335; Wed, 28 Jul 2021 08:44:33 -0500 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=wVV/OUH4z1fxh9RJfnBhJiSILPDU3Vt5WtVWO+Cqu5w=; b=ROGcWoDAbNfysktkIgx1lzudVbe5m8n5D/2OvbLCwexWlIaoU1d2TX+LZdQaqiK3TwXq E1oXzZ9PVOqUBZS1dm25Xls6YmEHfIkd1mITXLcjWta+fHTLer/j2PFUJBQgygOM3DmX T8Yj84jk0ov5RVJihZCHtaBNaOIeeA+HKVL+X/J/X5cDlFOoKu/EpVsQo1GUJXk8SX0t iYi03B8wXgFPEVmYW4xinx1CnI8F3kL66S0NKuwFaUdl2qIzZ3/ZDoOE3/RU1AwZfp93 QwxRTroa5QhPOY8w+gGNGmef2mVoduiwlZtlNj3HzUc3WL5WUymLYsJjlXoLECyRgFcb 6Q== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:33 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:30 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:30 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 6544445D; Wed, 28 Jul 2021 13:44:30 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 03/27] ALSA: hda/cs8409: Use enums for register names and coefficients Date: Wed, 28 Jul 2021 14:43:44 +0100 Message-ID: <20210728134408.369396-4-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: a1JetvF2aFTOvP7Ahml7hGPDVCOA927B X-Proofpoint-GUID: a1JetvF2aFTOvP7Ahml7hGPDVCOA927B X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 164 ++++++++++++------- sound/pci/hda/patch_cs8409.c | 49 +++--- sound/pci/hda/patch_cs8409.h | 239 ++++++++++++++++++++++++---- 3 files changed, 343 insertions(+), 109 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index 4adc7a4c4a25..5766433325a9 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -91,20 +91,20 @@ const struct hda_fixup cs8409_fixups[] = { }; const struct hda_verb cs8409_cs42l42_init_verbs[] = { - { 0x01, AC_VERB_SET_GPIO_WAKE_MASK, 0x0018 }, /* WAKE from GPIO 3,4 */ - { 0x47, AC_VERB_SET_PROC_STATE, 0x0001 }, /* Enable VPW processing */ - { 0x47, AC_VERB_SET_COEF_INDEX, 0x0002 }, /* Configure GPIO 6,7 */ - { 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 */ + { CS8409_PIN_AFG, AC_VERB_SET_GPIO_WAKE_MASK, 0x0018 }, /* WAKE from GPIO 3,4 */ + { CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_STATE, 0x0001 }, /* Enable VPW processing */ + { CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_COEF_INDEX, 0x0002 }, /* Configure GPIO 6,7 */ + { CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_COEF, 0x0080 }, /* I2C mode */ + { CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_COEF_INDEX, 0x005b }, /* Set I2C bus speed */ + { CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_COEF, 0x0200 }, /* 100kHz I2C_STO = 2 */ {} /* terminator */ }; const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { - { 0x24, 0x042120f0 }, /* ASP-1-TX */ - { 0x34, 0x04a12050 }, /* ASP-1-RX */ - { 0x2c, 0x901000f0 }, /* ASP-2-TX */ - { 0x44, 0x90a00090 }, /* DMIC-1 */ + { CS8409_PIN_ASP1_TRANSMITTER_A, 0x042120f0 }, /* ASP-1-TX */ + { CS8409_PIN_ASP1_RECEIVER_A, 0x04a12050 }, /* ASP-1-RX */ + { CS8409_PIN_ASP2_TRANSMITTER_A, 0x901000f0 }, /* ASP-2-TX */ + { CS8409_PIN_DMIC1_IN, 0x90a00090 }, /* DMIC-1 */ {} /* terminator */ }; @@ -164,57 +164,105 @@ const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { /* Vendor specific hw configuration for CS8409 */ const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[] = { - { 0x47, 0x00, 0xb008 }, /* +PLL1/2_EN, +I2C_EN */ - { 0x47, 0x01, 0x0002 }, /* ASP1/2_EN=0, ASP1_STP=1 */ - { 0x47, 0x02, 0x0a80 }, /* ASP1/2_BUS_IDLE=10, +GPIO_I2C */ - { 0x47, 0x19, 0x0800 }, /* ASP1.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ - { 0x47, 0x1a, 0x0820 }, /* ASP1.A: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=32 */ - { 0x47, 0x29, 0x0800 }, /* ASP2.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ - { 0x47, 0x2a, 0x2800 }, /* ASP2.A: TX.RAP=1, TX.RSZ=24 bits, TX.RCS=0 */ - { 0x47, 0x39, 0x0800 }, /* ASP1.A: RX.LAP=0, RX.LSZ=24 bits, RX.LCS=0 */ - { 0x47, 0x3a, 0x0800 }, /* ASP1.A: RX.RAP=0, RX.RSZ=24 bits, RX.RCS=0 */ - { 0x47, 0x03, 0x8000 }, /* ASP1: LCHI = 00h */ - { 0x47, 0x04, 0x28ff }, /* ASP1: MC/SC_SRCSEL=PLL1, LCPR=FFh */ - { 0x47, 0x05, 0x0062 }, /* ASP1: MCEN=0, FSD=011, SCPOL_IN/OUT=0, SCDIV=1:4 */ - { 0x47, 0x06, 0x801f }, /* ASP2: LCHI=1Fh */ - { 0x47, 0x07, 0x283f }, /* ASP2: MC/SC_SRCSEL=PLL1, LCPR=3Fh */ - { 0x47, 0x08, 0x805c }, /* ASP2: 5050=1, MCEN=0, FSD=010, SCPOL_IN/OUT=1, SCDIV=1:16 */ - { 0x47, 0x09, 0x0023 }, /* DMIC1_MO=10b, DMIC1/2_SR=1 */ - { 0x47, 0x0a, 0x0000 }, /* ASP1/2_BEEP=0 */ - { 0x47, 0x01, 0x0062 }, /* ASP1/2_EN=1, ASP1_STP=1 */ - { 0x47, 0x00, 0x9008 }, /* -PLL2_EN */ - { 0x47, 0x68, 0x0000 }, /* TX2.A: pre-scale att.=0 dB */ - { 0x47, 0x82, 0xfc03 }, /* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=1 */ - { 0x47, 0xc0, 0x9999 }, /* test mode on */ - { 0x47, 0xc5, 0x0000 }, /* GPIO hysteresis = 30 us */ - { 0x47, 0xc0, 0x0000 }, /* test mode off */ + /* +PLL1/2_EN, +I2C_EN */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG1, 0xb008 }, + /* ASP1/2_EN=0, ASP1_STP=1 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG2, 0x0002 }, + /* ASP1/2_BUS_IDLE=10, +GPIO_I2C */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG3, 0x0a80 }, + /* ASP1.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ + { CS8409_PIN_VENDOR_WIDGET, ASP1_A_TX_CTRL1, 0x0800 }, + /* ASP1.A: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=32 */ + { CS8409_PIN_VENDOR_WIDGET, ASP1_A_TX_CTRL2, 0x0820 }, + /* ASP2.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ + { CS8409_PIN_VENDOR_WIDGET, ASP2_A_TX_CTRL1, 0x0800 }, + /* ASP2.A: TX.RAP=1, TX.RSZ=24 bits, TX.RCS=0 */ + { CS8409_PIN_VENDOR_WIDGET, ASP2_A_TX_CTRL2, 0x2800 }, + /* ASP1.A: RX.LAP=0, RX.LSZ=24 bits, RX.LCS=0 */ + { CS8409_PIN_VENDOR_WIDGET, ASP1_A_RX_CTRL1, 0x0800 }, + /* ASP1.A: RX.RAP=0, RX.RSZ=24 bits, RX.RCS=0 */ + { CS8409_PIN_VENDOR_WIDGET, ASP1_A_RX_CTRL2, 0x0800 }, + /* ASP1: LCHI = 00h */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL1, 0x8000 }, + /* ASP1: MC/SC_SRCSEL=PLL1, LCPR=FFh */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL2, 0x28ff }, + /* ASP1: MCEN=0, FSD=011, SCPOL_IN/OUT=0, SCDIV=1:4 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL3, 0x0062 }, + /* ASP2: LCHI=1Fh */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_ASP2_CLK_CTRL1, 0x801f }, + /* ASP2: MC/SC_SRCSEL=PLL1, LCPR=3Fh */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_ASP2_CLK_CTRL2, 0x283f }, + /* ASP2: 5050=1, MCEN=0, FSD=010, SCPOL_IN/OUT=1, SCDIV=1:16 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_ASP2_CLK_CTRL3, 0x805c }, + /* DMIC1_MO=10b, DMIC1/2_SR=1 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DMIC_CFG, 0x0023 }, + /* ASP1/2_BEEP=0 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_BEEP_CFG, 0x0000 }, + /* ASP1/2_EN=1, ASP1_STP=1 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG2, 0x0062 }, + /* -PLL2_EN */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG1, 0x9008 }, + /* TX2.A: pre-scale att.=0 dB */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PRE_SCALE_ATTN2, 0x0000 }, + /* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=1 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PAD_CFG_SLW_RATE_CTRL, 0xfc03 }, + /* test mode on */ + { CS8409_PIN_VENDOR_WIDGET, 0xc0, 0x9999 }, + /* GPIO hysteresis = 30 us */ + { CS8409_PIN_VENDOR_WIDGET, 0xc5, 0x0000 }, + /* test mode off */ + { CS8409_PIN_VENDOR_WIDGET, 0xc0, 0x0000 }, {} /* Terminator */ }; const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[] = { - { 0x47, 0x65, 0x4000 }, /* EQ_SEL=1, EQ1/2_EN=0 */ - { 0x47, 0x64, 0x4000 }, /* +EQ_ACC */ - { 0x47, 0x65, 0x4010 }, /* +EQ2_EN */ - { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ - { 0x47, 0x64, 0xc0c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=0, EQ_DATA_LO=0x67 */ - { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ - { 0x47, 0x64, 0xc1c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=1, EQ_DATA_LO=0x67 */ - { 0x47, 0x63, 0xf370 }, /* EQ_DATA_HI=0xf370 */ - { 0x47, 0x64, 0xc271 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=2, EQ_DATA_LO=0x71 */ - { 0x47, 0x63, 0x1ef8 }, /* EQ_DATA_HI=0x1ef8 */ - { 0x47, 0x64, 0xc348 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=3, EQ_DATA_LO=0x48 */ - { 0x47, 0x63, 0xc110 }, /* EQ_DATA_HI=0xc110 */ - { 0x47, 0x64, 0xc45a }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=4, EQ_DATA_LO=0x5a */ - { 0x47, 0x63, 0x1f29 }, /* EQ_DATA_HI=0x1f29 */ - { 0x47, 0x64, 0xc574 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=5, EQ_DATA_LO=0x74 */ - { 0x47, 0x63, 0x1d7a }, /* EQ_DATA_HI=0x1d7a */ - { 0x47, 0x64, 0xc653 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=6, EQ_DATA_LO=0x53 */ - { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ - { 0x47, 0x64, 0xc714 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=7, EQ_DATA_LO=0x14 */ - { 0x47, 0x63, 0x1ca3 }, /* EQ_DATA_HI=0x1ca3 */ - { 0x47, 0x64, 0xc8c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=8, EQ_DATA_LO=0xc7 */ - { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ - { 0x47, 0x64, 0xc914 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=9, EQ_DATA_LO=0x14 */ - { 0x47, 0x64, 0x0000 }, /* -EQ_ACC, -EQ_WRT */ + /* EQ_SEL=1, EQ1/2_EN=0 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_CTRL1, 0x4000 }, + /* +EQ_ACC */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0x4000 }, + /* +EQ2_EN */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_CTRL1, 0x4010 }, + /* EQ_DATA_HI=0x0647 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x0647 }, + /* +EQ_WRT, +EQ_ACC, EQ_ADR=0, EQ_DATA_LO=0x67 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc0c7 }, + /* EQ_DATA_HI=0x0647 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x0647 }, + /* +EQ_WRT, +EQ_ACC, EQ_ADR=1, EQ_DATA_LO=0x67 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc1c7 }, + /* EQ_DATA_HI=0xf370 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0xf370 }, + /* +EQ_WRT, +EQ_ACC, EQ_ADR=2, EQ_DATA_LO=0x71 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc271 }, + /* EQ_DATA_HI=0x1ef8 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x1ef8 }, + /* +EQ_WRT, +EQ_ACC, EQ_ADR=3, EQ_DATA_LO=0x48 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc348 }, + /* EQ_DATA_HI=0xc110 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0xc110 }, + /* +EQ_WRT, +EQ_ACC, EQ_ADR=4, EQ_DATA_LO=0x5a */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc45a }, + /* EQ_DATA_HI=0x1f29 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x1f29 }, + /* +EQ_WRT, +EQ_ACC, EQ_ADR=5, EQ_DATA_LO=0x74 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc574 }, + /* EQ_DATA_HI=0x1d7a */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x1d7a }, + /* +EQ_WRT, +EQ_ACC, EQ_ADR=6, EQ_DATA_LO=0x53 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc653 }, + /* EQ_DATA_HI=0xc38c */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0xc38c }, + /* +EQ_WRT, +EQ_ACC, EQ_ADR=7, EQ_DATA_LO=0x14 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc714 }, + /* EQ_DATA_HI=0x1ca3 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x1ca3 }, + /* +EQ_WRT, +EQ_ACC, EQ_ADR=8, EQ_DATA_LO=0xc7 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc8c7 }, + /* EQ_DATA_HI=0xc38c */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0xc38c }, + /* +EQ_WRT, +EQ_ACC, EQ_ADR=9, EQ_DATA_LO=0x14 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc914 }, + /* -EQ_ACC, -EQ_WRT */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0x0000 }, {} /* Terminator */ }; diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index b56fc89ad2cd..e4319a0b9cf6 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -61,15 +61,15 @@ static struct cs8409_spec *cs8409_alloc_spec(struct hda_codec *codec) static inline int cs8409_vendor_coef_get(struct hda_codec *codec, unsigned int idx) { - snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0, AC_VERB_SET_COEF_INDEX, idx); - return snd_hda_codec_read(codec, CS8409_VENDOR_NID, 0, AC_VERB_GET_PROC_COEF, 0); + snd_hda_codec_write(codec, CS8409_PIN_VENDOR_WIDGET, 0, AC_VERB_SET_COEF_INDEX, idx); + return snd_hda_codec_read(codec, CS8409_PIN_VENDOR_WIDGET, 0, AC_VERB_GET_PROC_COEF, 0); } static inline void cs8409_vendor_coef_set(struct hda_codec *codec, unsigned int idx, unsigned int coef) { - snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0, AC_VERB_SET_COEF_INDEX, idx); - snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0, AC_VERB_SET_PROC_COEF, coef); + snd_hda_codec_write(codec, CS8409_PIN_VENDOR_WIDGET, 0, AC_VERB_SET_COEF_INDEX, idx); + snd_hda_codec_write(codec, CS8409_PIN_VENDOR_WIDGET, 0, AC_VERB_SET_PROC_COEF, coef); } /** @@ -102,7 +102,7 @@ static int cs8409_i2c_wait_complete(struct hda_codec *codec) unsigned int retval; do { - retval = cs8409_vendor_coef_get(codec, CIR_I2C_STATUS); + retval = cs8409_vendor_coef_get(codec, CS8409_I2C_STS); if ((retval & 0x18) != 0x18) { usleep_range(2000, 4000); --repeat; @@ -131,10 +131,10 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un unsigned int read_data; cs8409_enable_i2c_clock(codec, 1); - cs8409_vendor_coef_set(codec, CIR_I2C_ADDR, i2c_address); + cs8409_vendor_coef_set(codec, CS8409_I2C_ADDR, i2c_address); if (paged) { - cs8409_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg >> 8); + cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); if (cs8409_i2c_wait_complete(codec) < 0) { codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", __func__, i2c_address, i2c_reg); @@ -143,7 +143,7 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un } i2c_reg_data = (i2c_reg << 8) & 0x0ffff; - cs8409_vendor_coef_set(codec, CIR_I2C_QREAD, i2c_reg_data); + cs8409_vendor_coef_set(codec, CS8409_I2C_QREAD, i2c_reg_data); if (cs8409_i2c_wait_complete(codec) < 0) { codec_err(codec, "%s() Transaction Failed 0x%02x : 0x%04x\n", __func__, i2c_address, i2c_reg); @@ -151,7 +151,7 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un } /* Register in bits 15-8 and the data in 7-0 */ - read_data = cs8409_vendor_coef_get(codec, CIR_I2C_QREAD); + read_data = cs8409_vendor_coef_get(codec, CS8409_I2C_QREAD); cs8409_enable_i2c_clock(codec, 0); @@ -175,10 +175,10 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u unsigned int i2c_reg_data; cs8409_enable_i2c_clock(codec, 1); - cs8409_vendor_coef_set(codec, CIR_I2C_ADDR, i2c_address); + cs8409_vendor_coef_set(codec, CS8409_I2C_ADDR, i2c_address); if (paged) { - cs8409_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg >> 8); + cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); if (cs8409_i2c_wait_complete(codec) < 0) { codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", __func__, i2c_address, i2c_reg); @@ -187,7 +187,7 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u } i2c_reg_data = ((i2c_reg << 8) & 0x0ff00) | (i2c_data & 0x0ff); - cs8409_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg_data); + cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg_data); if (cs8409_i2c_wait_complete(codec) < 0) { codec_err(codec, "%s() Transaction Failed 0x%02x : 0x%04x\n", @@ -363,11 +363,11 @@ static void cs8409_cs42l42_reset(struct hda_codec *codec) struct cs8409_spec *spec = codec->spec; /* Assert RTS# line */ - snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, 0); + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0); /* wait ~10ms */ usleep_range(10000, 15000); /* Release RTS# line */ - snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, GPIO5_INT); + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, CS8409_CS42L42_RESET); /* wait ~10ms */ usleep_range(10000, 15000); @@ -471,7 +471,7 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) * registers in previous cs8409_jack_unsol_event() call. * We don't need to handle this event, ignoring... */ - if ((res & (1 << 4))) + if (res & CS8409_CS42L42_INT) return; mutex_lock(&spec->cs8409_i2c_mux); @@ -568,7 +568,7 @@ static int cs8409_suspend(struct hda_codec *codec) cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe, 1); mutex_unlock(&spec->cs8409_i2c_mux); /* Assert CS42L42 RTS# line */ - snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, 0); + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0); snd_hda_shutup_pins(codec); @@ -580,10 +580,10 @@ static int cs8409_suspend(struct hda_codec *codec) static void cs8409_enable_ur(struct hda_codec *codec, int flag) { /* GPIO4 INT# and GPIO3 WAKE# */ - snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, - flag ? (GPIO3_INT | GPIO4_INT) : 0); + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, + flag ? CS8409_CS42L42_INT : 0); - snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_UNSOLICITED_ENABLE, + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_UNSOLICITED_ENABLE, flag ? AC_UNSOL_ENABLED : 0); } @@ -598,9 +598,12 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) struct cs8409_spec *spec = codec->spec; if (spec->gpio_mask) { - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, spec->gpio_mask); - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir); - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_data); + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_MASK, + spec->gpio_mask); + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DIRECTION, + spec->gpio_dir); + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, + spec->gpio_data); } for (; seq->nid; seq++) @@ -738,7 +741,7 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, spec->gen.suppress_vmaster = 1; /* GPIO 5 out, 3,4 in */ - spec->gpio_dir = GPIO5_INT; + spec->gpio_dir = CS8409_CS42L42_RESET; spec->gpio_data = 0; spec->gpio_mask = 0x03f; diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 516123a411db..1d3ce28415fa 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -17,38 +17,206 @@ #include "hda_jack.h" #include "hda_generic.h" -/* Cirrus Logic CS8409 HDA bridge with - * companion codec CS42L42 - */ -#define CS42L42_HP_CH (2U) -#define CS42L42_HS_MIC_CH (1U) - -#define CS8409_VENDOR_NID 0x47 +/* CS8409 Specific Definitions */ -#define CS8409_CS42L42_HP_PIN_NID 0x24 -#define CS8409_CS42L42_SPK_PIN_NID 0x2c -#define CS8409_CS42L42_AMIC_PIN_NID 0x34 -#define CS8409_CS42L42_DMIC_PIN_NID 0x44 -#define CS8409_CS42L42_DMIC_ADC_PIN_NID 0x22 - -#define CS42L42_HSDET_AUTO_DONE 0x02 -#define CS42L42_HSTYPE_MASK 0x03 - -#define CS42L42_JACK_INSERTED 0x0C -#define CS42L42_JACK_REMOVED 0x00 +enum cs8409_pins { + CS8409_PIN_ROOT, + CS8409_PIN_AFG, + CS8409_PIN_ASP1_OUT_A, + CS8409_PIN_ASP1_OUT_B, + CS8409_PIN_ASP1_OUT_C, + CS8409_PIN_ASP1_OUT_D, + CS8409_PIN_ASP1_OUT_E, + CS8409_PIN_ASP1_OUT_F, + CS8409_PIN_ASP1_OUT_G, + CS8409_PIN_ASP1_OUT_H, + CS8409_PIN_ASP2_OUT_A, + CS8409_PIN_ASP2_OUT_B, + CS8409_PIN_ASP2_OUT_C, + CS8409_PIN_ASP2_OUT_D, + CS8409_PIN_ASP2_OUT_E, + CS8409_PIN_ASP2_OUT_F, + CS8409_PIN_ASP2_OUT_G, + CS8409_PIN_ASP2_OUT_H, + CS8409_PIN_ASP1_IN_A, + CS8409_PIN_ASP1_IN_B, + CS8409_PIN_ASP1_IN_C, + CS8409_PIN_ASP1_IN_D, + CS8409_PIN_ASP1_IN_E, + CS8409_PIN_ASP1_IN_F, + CS8409_PIN_ASP1_IN_G, + CS8409_PIN_ASP1_IN_H, + CS8409_PIN_ASP2_IN_A, + CS8409_PIN_ASP2_IN_B, + CS8409_PIN_ASP2_IN_C, + CS8409_PIN_ASP2_IN_D, + CS8409_PIN_ASP2_IN_E, + CS8409_PIN_ASP2_IN_F, + CS8409_PIN_ASP2_IN_G, + CS8409_PIN_ASP2_IN_H, + CS8409_PIN_DMIC1, + CS8409_PIN_DMIC2, + CS8409_PIN_ASP1_TRANSMITTER_A, + CS8409_PIN_ASP1_TRANSMITTER_B, + CS8409_PIN_ASP1_TRANSMITTER_C, + CS8409_PIN_ASP1_TRANSMITTER_D, + CS8409_PIN_ASP1_TRANSMITTER_E, + CS8409_PIN_ASP1_TRANSMITTER_F, + CS8409_PIN_ASP1_TRANSMITTER_G, + CS8409_PIN_ASP1_TRANSMITTER_H, + CS8409_PIN_ASP2_TRANSMITTER_A, + CS8409_PIN_ASP2_TRANSMITTER_B, + CS8409_PIN_ASP2_TRANSMITTER_C, + CS8409_PIN_ASP2_TRANSMITTER_D, + CS8409_PIN_ASP2_TRANSMITTER_E, + CS8409_PIN_ASP2_TRANSMITTER_F, + CS8409_PIN_ASP2_TRANSMITTER_G, + CS8409_PIN_ASP2_TRANSMITTER_H, + CS8409_PIN_ASP1_RECEIVER_A, + CS8409_PIN_ASP1_RECEIVER_B, + CS8409_PIN_ASP1_RECEIVER_C, + CS8409_PIN_ASP1_RECEIVER_D, + CS8409_PIN_ASP1_RECEIVER_E, + CS8409_PIN_ASP1_RECEIVER_F, + CS8409_PIN_ASP1_RECEIVER_G, + CS8409_PIN_ASP1_RECEIVER_H, + CS8409_PIN_ASP2_RECEIVER_A, + CS8409_PIN_ASP2_RECEIVER_B, + CS8409_PIN_ASP2_RECEIVER_C, + CS8409_PIN_ASP2_RECEIVER_D, + CS8409_PIN_ASP2_RECEIVER_E, + CS8409_PIN_ASP2_RECEIVER_F, + CS8409_PIN_ASP2_RECEIVER_G, + CS8409_PIN_ASP2_RECEIVER_H, + CS8409_PIN_DMIC1_IN, + CS8409_PIN_DMIC2_IN, + CS8409_PIN_BEEP_GEN, + CS8409_PIN_VENDOR_WIDGET +}; -#define GPIO3_INT (1 << 3) -#define GPIO4_INT (1 << 4) -#define GPIO5_INT (1 << 5) +enum cs8409_coefficient_index_registers { + CS8409_DEV_CFG1, + CS8409_DEV_CFG2, + CS8409_DEV_CFG3, + CS8409_ASP1_CLK_CTRL1, + CS8409_ASP1_CLK_CTRL2, + CS8409_ASP1_CLK_CTRL3, + CS8409_ASP2_CLK_CTRL1, + CS8409_ASP2_CLK_CTRL2, + CS8409_ASP2_CLK_CTRL3, + CS8409_DMIC_CFG, + CS8409_BEEP_CFG, + ASP1_RX_NULL_INS_RMV, + ASP1_Rx_RATE1, + ASP1_Rx_RATE2, + ASP1_Tx_NULL_INS_RMV, + ASP1_Tx_RATE1, + ASP1_Tx_RATE2, + ASP2_Rx_NULL_INS_RMV, + ASP2_Rx_RATE1, + ASP2_Rx_RATE2, + ASP2_Tx_NULL_INS_RMV, + ASP2_Tx_RATE1, + ASP2_Tx_RATE2, + ASP1_SYNC_CTRL, + ASP2_SYNC_CTRL, + ASP1_A_TX_CTRL1, + ASP1_A_TX_CTRL2, + ASP1_B_TX_CTRL1, + ASP1_B_TX_CTRL2, + ASP1_C_TX_CTRL1, + ASP1_C_TX_CTRL2, + ASP1_D_TX_CTRL1, + ASP1_D_TX_CTRL2, + ASP1_E_TX_CTRL1, + ASP1_E_TX_CTRL2, + ASP1_F_TX_CTRL1, + ASP1_F_TX_CTRL2, + ASP1_G_TX_CTRL1, + ASP1_G_TX_CTRL2, + ASP1_H_TX_CTRL1, + ASP1_H_TX_CTRL2, + ASP2_A_TX_CTRL1, + ASP2_A_TX_CTRL2, + ASP2_B_TX_CTRL1, + ASP2_B_TX_CTRL2, + ASP2_C_TX_CTRL1, + ASP2_C_TX_CTRL2, + ASP2_D_TX_CTRL1, + ASP2_D_TX_CTRL2, + ASP2_E_TX_CTRL1, + ASP2_E_TX_CTRL2, + ASP2_F_TX_CTRL1, + ASP2_F_TX_CTRL2, + ASP2_G_TX_CTRL1, + ASP2_G_TX_CTRL2, + ASP2_H_TX_CTRL1, + ASP2_H_TX_CTRL2, + ASP1_A_RX_CTRL1, + ASP1_A_RX_CTRL2, + ASP1_B_RX_CTRL1, + ASP1_B_RX_CTRL2, + ASP1_C_RX_CTRL1, + ASP1_C_RX_CTRL2, + ASP1_D_RX_CTRL1, + ASP1_D_RX_CTRL2, + ASP1_E_RX_CTRL1, + ASP1_E_RX_CTRL2, + ASP1_F_RX_CTRL1, + ASP1_F_RX_CTRL2, + ASP1_G_RX_CTRL1, + ASP1_G_RX_CTRL2, + ASP1_H_RX_CTRL1, + ASP1_H_RX_CTRL2, + ASP2_A_RX_CTRL1, + ASP2_A_RX_CTRL2, + ASP2_B_RX_CTRL1, + ASP2_B_RX_CTRL2, + ASP2_C_RX_CTRL1, + ASP2_C_RX_CTRL2, + ASP2_D_RX_CTRL1, + ASP2_D_RX_CTRL2, + ASP2_E_RX_CTRL1, + ASP2_E_RX_CTRL2, + ASP2_F_RX_CTRL1, + ASP2_F_RX_CTRL2, + ASP2_G_RX_CTRL1, + ASP2_G_RX_CTRL2, + ASP2_H_RX_CTRL1, + ASP2_H_RX_CTRL2, + CS8409_I2C_ADDR, + CS8409_I2C_DATA, + CS8409_I2C_CTRL, + CS8409_I2C_STS, + CS8409_I2C_QWRITE, + CS8409_I2C_QREAD, + CS8409_SPI_CTRL, + CS8409_SPI_TX_DATA, + CS8409_SPI_RX_DATA, + CS8409_SPI_STS, + CS8409_PFE_COEF_W1, /* Parametric filter engine coefficient write 1*/ + CS8409_PFE_COEF_W2, + CS8409_PFE_CTRL1, + CS8409_PFE_CTRL2, + CS8409_PRE_SCALE_ATTN1, + CS8409_PRE_SCALE_ATTN2, + CS8409_PFE_COEF_MON1, /* Parametric filter engine coefficient monitor 1*/ + CS8409_PFE_COEF_MON2, + CS8409_ASP1_INTRN_STS, + CS8409_ASP2_INTRN_STS, + CS8409_ASP1_RX_SCLK_COUNT, + CS8409_ASP1_TX_SCLK_COUNT, + CS8409_ASP2_RX_SCLK_COUNT, + CS8409_ASP2_TX_SCLK_COUNT, + CS8409_ASP_UNS_RESP_MASK, + CS8409_LOOPBACK_CTRL = 0x80, + CS8409_PAD_CFG_SLW_RATE_CTRL = 0x82, /* Pad Config and Slew Rate Control (CIR = 0x0082) */ +}; -#define CS42L42_I2C_ADDR (0x48 << 1) +/* CS42L42 Specific Definitions */ -#define CIR_I2C_ADDR 0x0059 -#define CIR_I2C_DATA 0x005A -#define CIR_I2C_CTRL 0x005B -#define CIR_I2C_STATUS 0x005C -#define CIR_I2C_QWRITE 0x005D -#define CIR_I2C_QREAD 0x005E +#define CS42L42_HP_CH (2U) +#define CS42L42_HS_MIC_CH (1U) #define CS8409_CS42L42_HP_VOL_REAL_MIN (-63) #define CS8409_CS42L42_HP_VOL_REAL_MAX (0) @@ -57,6 +225,21 @@ #define CS8409_CS42L42_REG_HS_VOLUME_CHA (0x2301) #define CS8409_CS42L42_REG_HS_VOLUME_CHB (0x2303) #define CS8409_CS42L42_REG_AMIC_VOLUME (0x1D03) +#define CS42L42_HSDET_AUTO_DONE (0x02) +#define CS42L42_HSTYPE_MASK (0x03) +#define CS42L42_JACK_INSERTED (0x0C) +#define CS42L42_JACK_REMOVED (0x00) + +/* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */ + +#define CS42L42_I2C_ADDR (0x48 << 1) +#define CS8409_CS42L42_RESET GENMASK(5, 5) /* CS8409_GPIO5 */ +#define CS8409_CS42L42_INT GENMASK(4, 4) /* CS8409_GPIO4 */ +#define CS8409_CS42L42_HP_PIN_NID CS8409_PIN_ASP1_TRANSMITTER_A +#define CS8409_CS42L42_SPK_PIN_NID CS8409_PIN_ASP2_TRANSMITTER_A +#define CS8409_CS42L42_AMIC_PIN_NID CS8409_PIN_ASP1_RECEIVER_A +#define CS8409_CS42L42_DMIC_PIN_NID CS8409_PIN_DMIC1_IN +#define CS8409_CS42L42_DMIC_ADC_PIN_NID CS8409_PIN_DMIC1 enum { CS8409_BULLSEYE, From patchwork Wed Jul 28 13:43:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405845 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8ED56C4338F for ; Wed, 28 Jul 2021 13:47:22 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B212460EC0 for ; Wed, 28 Jul 2021 13:47:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org B212460EC0 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 599B218A6; Wed, 28 Jul 2021 15:46:30 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 599B218A6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480040; bh=Z1irmq4q5G5vjS64pklMlsVZHEtAiirWsPISQ/SIvQg=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=NZlgXgAp132OH16vGcfy5r3NI2D2CoIv/DeMproB34DU4WHYyZqD0EXMapoJi+FM1 VklWsEzzyGG4pAdCJB0BASR8uZO/16sMgoJVwuFhkHxmhT8+C6UrA9Wth4Bra5lN6L pIeEYcr2qEM7wTf2y7PpLuf+wcs87SfyFMK02qgw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 5F675F804DA; Wed, 28 Jul 2021 15:44:56 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 78C23F80253; Wed, 28 Jul 2021 15:44:48 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 3951BF8025A for ; Wed, 28 Jul 2021 15:44:35 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 3951BF8025A Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="d9pnkH+7" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUql014335; Wed, 28 Jul 2021 08:44:34 -0500 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=7vkQIoBquMVVKjTnWMLcfqhODSdY1nfkUHZ8S3dlJNU=; b=d9pnkH+7ffix3IWdWH010Ic8bKdngFB2dA+SCbqaeTvLP6NkyBQo6wyGilY4jibb0aYC vh9B5hnM0RUAfofGWA4+HnV+SFMIhhez0FBD+UC7yk8ce7uFCqin04tljGkCQoANOoQm ZnujysMtaxHE6BZ1wvmUqvdP1pFzZeskXpVnw7FSwkajM5DkTxb1+kuTooRopYI3Dnvi OjkZCwxiWgLbBRiSPbMIVNp3APcaAZcxy0AvjgwpENpRkdQI3YO2OGWUCFJjyUuAeKDA nT7xF4SJOE4jg15oAJoprXuj0OBNb+NVpm1JrSBMSdbTxneyQEbglcsGQ494MICSbPeI 8A== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:34 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:31 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:31 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id B64482BA; Wed, 28 Jul 2021 13:44:30 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 04/27] ALSA: hda/cs8409: Mask all CS42L42 interrupts on initialization Date: Wed, 28 Jul 2021 14:43:45 +0100 Message-ID: <20210728134408.369396-5-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: Zcjs7wkf_Pl7XmigpfZXZF_1GOEyjkCJ X-Proofpoint-GUID: Zcjs7wkf_Pl7XmigpfZXZF_1GOEyjkCJ X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index 5766433325a9..91b6a5b2824a 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -159,6 +159,18 @@ const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { { 0x1105, 0x00 }, { 0x1112, 0xC0 }, { 0x1101, 0x02 }, + { 0x1316, 0xff }, + { 0x1317, 0xff }, + { 0x1318, 0xff }, + { 0x1319, 0xff }, + { 0x131a, 0xff }, + { 0x131b, 0xff }, + { 0x131c, 0xff }, + { 0x131e, 0xff }, + { 0x131f, 0xff }, + { 0x1320, 0xff }, + { 0x1b79, 0xff }, + { 0x1b7a, 0xff }, {} /* Terminator */ }; From patchwork Wed Jul 28 13:43:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405841 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98FF2C4338F for ; Wed, 28 Jul 2021 13:46:29 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C73EF60EC0 for ; Wed, 28 Jul 2021 13:46:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org C73EF60EC0 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 630201838; Wed, 28 Jul 2021 15:45:37 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 630201838 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627479987; bh=TBmi5g44tLyqOp6cNat/wTvwHVUdSrkCMeEb1sZAQZ4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=qRgPYwVu1ICa217HNaBbmOmXWsz1+VfY/Ekmav0gOYmCldO638RDWSMyq6tYgsEkP N74V296L7T/DCjOeILMaVFtB43nSBfr4O91+uL5bQYhT0x9G91Kcyz4GKYHrwtCqG1 0O3x8mJl3uz2lsOtuc3nvskrhFzkVf8QkY1U+oAA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 58BCAF804FF; Wed, 28 Jul 2021 15:44:51 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 554DEF80253; Wed, 28 Jul 2021 15:44:47 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 1C040F80253 for ; Wed, 28 Jul 2021 15:44:34 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 1C040F80253 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="IrQEGJ5y" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqi014335; Wed, 28 Jul 2021 08:44:33 -0500 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=i4REo5301mPGc2B6d399nXL2kSmD25xO2mx4FFL4BOs=; b=IrQEGJ5yM6BlvlPIqJQxUkyyP0QV+62kEtStMTp7AwOnqFyl0qimREaVfrc/TuIFeLgG kMD3R1UaVinLeNpqW+P2zz3rRrYhshEknELwVrVpEUIOP6qHE7GFPozoScKppgCPKqVN njOMfNQGf5nHw1vBDL4WGjCKwVQY7QajEQS0Fa7LSYDY0oaDGgNUQ10Qpl6kG0DhZ7eM GWp2uAWuV+RWqwCn2yIC32B/6FK+k2kxuMVxmYy171M6BQhWHu57rfBylrRhaKqkjUox mZBaRmREAXk/MPTCk+fdpF7AKWcz0L2bsdv/oI60c6di/7U6jJwCl0DAvgs367eQl5x5 Rw== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fxa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:32 -0500 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.2242.4; Wed, 28 Jul 2021 14:44:31 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:31 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 17F3046E; Wed, 28 Jul 2021 13:44:31 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 05/27] ALSA: hda/cs8409: Reduce HS pops/clicks for Cyborg Date: Wed, 28 Jul 2021 14:43:46 +0100 Message-ID: <20210728134408.369396-6-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: QNDrlpy1X4csPBuyfwwXU6oX_lzIWr70 X-Proofpoint-GUID: QNDrlpy1X4csPBuyfwwXU6oX_lzIWr70 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=956 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Enable HSBIAS_SENSE_EN for Cyborg during jack detect to reduce pops and clicks. Do not enable this for Warlock/Bullseye, as it causes ESD issues. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index e4319a0b9cf6..1745f8b188c6 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -390,8 +390,14 @@ static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) mutex_lock(&spec->cs8409_i2c_mux); - /* Set TIP_SENSE_EN for analog front-end of tip sense. */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020, 1); + /* Set TIP_SENSE_EN for analog front-end of tip sense. + * Additionally set HSBIAS_SENSE_EN for some variants. + */ + if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_BULLSEYE) + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020, 1); + else + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0, 1); + /* Clear WAKE# */ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x0001, 1); /* Wait ~2.5ms */ From patchwork Wed Jul 28 13:43:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405847 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EAADBC4338F for ; Wed, 28 Jul 2021 13:47:53 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7AD1360EC0 for ; Wed, 28 Jul 2021 13:47:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7AD1360EC0 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 281BA18C3; Wed, 28 Jul 2021 15:47:02 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 281BA18C3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480072; bh=c9m5B9zMyTqw8MxxtOqej+/kkLDLu6qZrwguGPejrP0=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Vza8ckhPJk5GcG2Pjzq3UVK6Vb3ys6/NVLP9oXepjpjVUtQR58ENzLpZoUaC4WR8a I7YMZ3Lp5C8ADZ2wZ1ROzatwP0qjcguiNbC0Z87eYWP1g+Saue87UKV7/Mmkh+zVrM 1tV/UnTUEw2Zet17Qnzv1S3Yt9atbJbhwLzft6Cg= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id D926AF8051D; Wed, 28 Jul 2021 15:44:58 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id BDEFEF804FF; Wed, 28 Jul 2021 15:44:48 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 23F3EF8025E for ; Wed, 28 Jul 2021 15:44:35 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 23F3EF8025E Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="A301stn4" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqk014335; Wed, 28 Jul 2021 08:44:34 -0500 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=/bHZiPhZYlMPqxLNMuV2yaLHw8mxlxJDo0FwPDN8wLc=; b=A301stn4qNsZDTzrapUU13nSKLvyUeo1/Wy8XN9/d3xdV7ro8l+Fpx4PdGy+LfYlqwRb N5k/fPnCUrlvax/v7F0dMtx87MRTx63dcwAEld60LnuTKhjG4dGwoIyeEsBl/ZiYAS4D G9fPacKfTId8JgOckhQzYeUYoCSmAMcbjpchImCmnOpmkSLb5gPUSfySl0ES9n8jpG0g wksYDxLqrzE/eF8bXf8EtB/GkiawTbTotdDzTblaytlm1MMq0i7fA5ReYwIlnRjrHkJ5 x9QBLtj5wYvoOWA3q5SQVHi5jkw+35wcetZDnZoeBm76AfpZpVW4jY/tafrwyI8JRWMv bw== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fxa-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:33 -0500 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.2242.4; Wed, 28 Jul 2021 14:44:31 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:31 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 6514845D; Wed, 28 Jul 2021 13:44:31 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 06/27] ALSA: hda/cs8409: Disable unnecessary Ring Sense for Cyborg/Warlock/Bullseye Date: Wed, 28 Jul 2021 14:43:47 +0100 Message-ID: <20210728134408.369396-7-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: 7uSNYk1ptsPOWHMKE0iJJ0KEb-pJq3rq X-Proofpoint-GUID: 7uSNYk1ptsPOWHMKE0iJJ0KEb-pJq3rq X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Also remove unnecessary repeated register writes. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index 91b6a5b2824a..07d3ae28c105 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -153,11 +153,9 @@ const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { { 0x1121, 0xF3 }, { 0x1103, 0x20 }, { 0x1105, 0x00 }, - { 0x1112, 0xC0 }, + { 0x1112, 0x00 }, { 0x1113, 0x80 }, { 0x1C03, 0xC0 }, - { 0x1105, 0x00 }, - { 0x1112, 0xC0 }, { 0x1101, 0x02 }, { 0x1316, 0xff }, { 0x1317, 0xff }, From patchwork Wed Jul 28 13:43:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405849 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CBAA7C4320A for ; Wed, 28 Jul 2021 13:48:27 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4DB6C60EC0 for ; Wed, 28 Jul 2021 13:48:27 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 4DB6C60EC0 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id A9B9618A0; Wed, 28 Jul 2021 15:47:35 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz A9B9618A0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480106; bh=E037M/5/jccnEoNKcfUdjUaLkRJzoloc4UIYgdEeu4g=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=gA2JAeayU0F1t3+5BuECUXd/cI39/SZnnecfhAnqHkSMXMTe/C994ea17EOHtKIx4 l6MEWwXEE7IXtvYxKiXQIAol94UvcWlmxOWdOawV1i/VRypw4lo3qNatKIPYAJDdp1 /uxmYbcMlhz06FQkoI0YLjwi4d/NDXumd57SqyvY= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 09AA3F80525; Wed, 28 Jul 2021 15:45:01 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B2665F80508; Wed, 28 Jul 2021 15:44:51 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 5F11EF804B1 for ; Wed, 28 Jul 2021 15:44:36 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 5F11EF804B1 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="Vp3l57Vk" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqn014335; Wed, 28 Jul 2021 08:44:35 -0500 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=nnbA+U3b8rR5d/LrvSt+v/g6PVXbhpxfzvK69+37YnI=; b=Vp3l57VkIx95pySkiaCcXvi77kev1atUylaH7cNwg+sudnw5dgyMkWj+QpsOCkfFFMkA 1Qz750hc8jeWvBmCkwvXg6kYO0Z40Ae3OqX0FakT85Sgd6Gc/sqBMzCREVM8inI76jwg 9IJ74gDypXBGOrC91uCCIGw2R+Mb3i6H2rs6eCx6rGG2wqsOGbr6GnozMokW+vS3kgm4 xjBgMdTm1mX7eI9n9FZJVU0sz7xRYAgJmJSqCSSGWfO0IL/LkTUZTWVukwhFNhMmoCyg t5jXxQXNCV7g8wDEEImPDujCt8keq6one8FyYcCsXMnXQiv/wUnvFjjfM/ojTaUJ7m1b yQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:35 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:32 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:32 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id BB7752BA; Wed, 28 Jul 2021 13:44:31 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 07/27] ALSA: hda/cs8409: Disable unsolicited responses during suspend Date: Wed, 28 Jul 2021 14:43:48 +0100 Message-ID: <20210728134408.369396-8-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: LNjZhZfQ13IpgpO-x4-FNSjCYYvWUdcO X-Proofpoint-GUID: LNjZhZfQ13IpgpO-x4-FNSjCYYvWUdcO X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Ensure unsolicited responses cannot occur whilst the sub codecs are being disabled. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 1745f8b188c6..4906d2913603 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -563,12 +563,26 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) } } +/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */ +static void cs8409_enable_ur(struct hda_codec *codec, int flag) +{ + /* GPIO4 INT# and GPIO3 WAKE# */ + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, + flag ? CS8409_CS42L42_INT : 0); + + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_UNSOLICITED_ENABLE, + flag ? AC_UNSOL_ENABLED : 0); + +} + #ifdef CONFIG_PM /* Manage PDREF, when transition to D3hot */ static int cs8409_suspend(struct hda_codec *codec) { struct cs8409_spec *spec = codec->spec; + cs8409_enable_ur(codec, 0); + mutex_lock(&spec->cs8409_i2c_mux); /* Power down CS42L42 ASP/EQ/MIX/HP */ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe, 1); @@ -582,18 +596,6 @@ static int cs8409_suspend(struct hda_codec *codec) } #endif -/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */ -static void cs8409_enable_ur(struct hda_codec *codec, int flag) -{ - /* GPIO4 INT# and GPIO3 WAKE# */ - snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, - flag ? CS8409_CS42L42_INT : 0); - - snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_UNSOLICITED_ENABLE, - flag ? AC_UNSOL_ENABLED : 0); - -} - /* Vendor specific HW configuration * PLL, ASP, I2C, SPI, GPIOs, DMIC etc... */ From patchwork Wed Jul 28 13:43:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405853 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9BDF1C432BE for ; Wed, 28 Jul 2021 13:49:03 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2164C60F45 for ; Wed, 28 Jul 2021 13:49:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2164C60F45 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id C65BC18FA; Wed, 28 Jul 2021 15:48:11 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C65BC18FA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480141; bh=T4+DhwsJr2Ei7QYmngj+WouzEwGq9Dm/iFUUH+jpdOI=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=rJThjo/flpBncp6Ld78V15qPAxCYPc7ofO8Jj6OuVrq0FlTOCCndEG+O5c2qkTPHU NT4yg8cjrEuJ3ju77bOBusN5gzhv2mqi7MrwLptW/wqRQqoO70LcmZHP0GT4v56sQe s/6Xv6tkzKABYPCyC7ehTs73aBbq0UFxfdIilN6Y= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id D43FAF80537; Wed, 28 Jul 2021 15:45:03 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id D2B5DF8051A; Wed, 28 Jul 2021 15:44:55 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 6A0D0F804DA for ; Wed, 28 Jul 2021 15:44:37 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 6A0D0F804DA Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="RDB0ZsMl" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqp014335; Wed, 28 Jul 2021 08:44:36 -0500 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=gZBfdzKCf7MimQj8s86TOtGPJRjEk+L7pnGb15Pkchs=; b=RDB0ZsMl7426umHD7UvwCKQd0rWb7el3C8zHvZMHigqcf31ZVmdRjE5mOGJjPzISmRnX Tceo1pt/3XRC1GSQhBF2ClrrRu6Rzb/E7offcS2vQk9z1pCKRdWuNPQ4AwjYUR2okRCb lMmBXRVDnU4/Y8SnS+PdGGvuEqEV5uSVYyEDLAPthhzUAkibLimrmawK9uwORFdBwTEy 7vFzwp75d8sF9Z8u9Pqgtbzgp1KhRCb09CHaB7wHX3iiBHAjUE6sKSRno/1Oz7EwXGmk owc7b4Mc+rGkyQnjBBeY9BK0zUTp1ac+EwaOQVIiRpqNP8/XUgbzbr6gfCjRUTCWvl2l KQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:35 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:32 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:32 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 1499B46E; Wed, 28 Jul 2021 13:44:32 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 08/27] ALSA: hda/cs8409: Disable unsolicited response for the first boot Date: Wed, 28 Jul 2021 14:43:49 +0100 Message-ID: <20210728134408.369396-9-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: nYVt8qQbqRWkeIHUfynX9EBHxd9gCisE X-Proofpoint-GUID: nYVt8qQbqRWkeIHUfynX9EBHxd9gCisE X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure The subsequence suspend and remuse have their enable/disable unsolicited responses at the correct place already Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 4906d2913603..2ed07ab3f47e 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -621,9 +621,6 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) for (; seq_bullseye->nid; seq_bullseye++) cs8409_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff); - /* Disable Unsolicited Response during boot */ - cs8409_enable_ur(codec, 0); - /* Reset CS42L42 */ cs8409_cs42l42_reset(codec); @@ -795,6 +792,8 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, HDA_INPUT, 0, 0xff, 0x19); 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); + /* Disable Unsolicited Response during boot */ + cs8409_enable_ur(codec, 0); cs8409_cs42l42_hw_init(codec); snd_hda_codec_set_name(codec, "CS8409/CS42L42"); break; From patchwork Wed Jul 28 13:43:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405857 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 049FFC4338F for ; Wed, 28 Jul 2021 13:49:41 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7800060F5E for ; Wed, 28 Jul 2021 13:49:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7800060F5E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 1FE901A3B; Wed, 28 Jul 2021 15:48:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 1FE901A3B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480179; bh=/aw8/5Spi7aQIpJuAawFzqoH3F5HfB5NKUPTVqt0f5E=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=sJWr2cQoTan2Zz1+FfUlHAYJF/0OC+Qj1POF+YSaFK5ot8b1zSfDfgLwzg0N/iVKr Fcs7LCdENkmM66UO+0fFx8GXCKJTqBz6o34pBanuvp5i8j1hUrIWO1TbDvLM3gHDGI D75B+pGFo/KJre5z5CGaX1d+nICRBK64zMb0iMlA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 89B15F8053D; Wed, 28 Jul 2021 15:45:07 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 3F989F8051A; Wed, 28 Jul 2021 15:44:58 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 717AAF8049E for ; Wed, 28 Jul 2021 15:44:37 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 717AAF8049E Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="ncckKk32" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqr014335; Wed, 28 Jul 2021 08:44:36 -0500 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=/DrhRLL4/bGYv3v1PfKrsPp9oTw0k4T6r1RIzNb4ly8=; b=ncckKk32Tat1Ac6Oam0VUxLXddH+d1MUNPP9mM1NsqYLOcuQr+Yf7ODDHtheo6exi9gU kRfNI/BmWeoV0T6BM3Sdf6eBwvl/5gLWs2M63hOTslQ3AjOBmFd46Jm8MmKpbhko5rKv yHzOoLuEIrZ5EGfKVejn9aeaS56Ube1AyoET2WTp9nMLlgdFAa40iEe95Ae042yDCVw5 rVUTyawDmCqUz2/dBUbiRuWB4oUm68cnjj6pmPIN9SQw/47wryvcrKRwxKNcmuJfEAYC FFuQ6vOYGYLT1tOQb4pKP1gQtzxvz9FgbWUn79YFpkNiJ5XSNEd8Duu33C4bRxe7QZw0 3g== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:36 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:32 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:32 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 67A9F45D; Wed, 28 Jul 2021 13:44:32 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 09/27] ALSA: hda/cs8409: Mask CS42L42 wake events Date: Wed, 28 Jul 2021 14:43:50 +0100 Message-ID: <20210728134408.369396-10-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: V7yPL7qUiS9QTH1SH3S3JSsPKD_6vvWy X-Proofpoint-GUID: V7yPL7qUiS9QTH1SH3S3JSsPKD_6vvWy X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Wake events are not needed for jack detect. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 2ed07ab3f47e..f4401c1e8572 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -399,11 +399,11 @@ static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0, 1); /* Clear WAKE# */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x0001, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C1, 1); /* Wait ~2.5ms */ usleep_range(2500, 3000); /* Set mode WAKE# output follows the combination logic directly */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x0020, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0, 1); /* Clear interrupts status */ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b7b, 1); From patchwork Wed Jul 28 13:43:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405859 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DFABC4338F for ; Wed, 28 Jul 2021 13:50:15 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9454060F5E for ; Wed, 28 Jul 2021 13:50:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 9454060F5E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 36C5A1AC7; Wed, 28 Jul 2021 15:49:23 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 36C5A1AC7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480213; bh=JXPPTb0aExzgKqmi+MXGjQH3X8/yeSLrbzNSSSZe5Vo=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=nO5sLL2jUT1TH7/qU0QBstAVcQ96mlZ8RBLyXoDp27/X7n12HcMh2LkEUPo8iLhMb qyiiV0r0D7AFwxaqTeqYjUcodFionTAuQbeK7BqQiwER00FXUvYgSLqBXmdtP7CAng X6qm0CKbsDSye1i3nPDtkyAYtSfJoufdeS15Jj0s= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id BB341F80543; Wed, 28 Jul 2021 15:45:09 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id AE9CEF8053B; Wed, 28 Jul 2021 15:45:04 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id A66EDF804DF for ; Wed, 28 Jul 2021 15:44:38 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz A66EDF804DF Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="KDk9Ykq7" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqs014335; Wed, 28 Jul 2021 08:44:37 -0500 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=Wu5RHG+z4CrcbTD0wN2+615+GsLX2gZo7DeNNwOtopk=; b=KDk9Ykq7SJec2Jlvdz5/j9AUGeHmWdecClr6EuinujKYDEfjHzeBrlJZ1iAK5BehNKC7 u5nDp+IVafmggN+U2NtCWaOM6Z1fKZnixgdxQ/k2DoI8tx0jiLV/rZPZWJ4N0HjYQBig B00sRNMehEiAg51ogABGwy2Q5UXKylbFpC5wjnJQC0Wpd94RWTrPvMw4j5SE8wWI5MoX HdWtzwNyxpH+Ev3eOC0jWq7pcKKrDxuM/gQt01ye06ZCSYIZUraS3JMc6aQc1IsECa/B Lu+CmmpfcopOD4wnBMhaRzPzptL0DoCUPN6Rw1ZAHqusckjMLRjCXi32tIqS1ssR7Ule TQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-8 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:37 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:33 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:33 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id BDB6B2BA; Wed, 28 Jul 2021 13:44:32 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 10/27] ALSA: hda/cs8409: Simplify CS42L42 jack detect. Date: Wed, 28 Jul 2021 14:43:51 +0100 Message-ID: <20210728134408.369396-11-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: tQYMHJdNmkJ-aDtGRIWRN4LFVve5s1ru X-Proofpoint-GUID: tQYMHJdNmkJ-aDtGRIWRN4LFVve5s1ru X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=857 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Cleanup interrupt masks. Remove unnecessary read/writes. Ensure Tip Sense/Type Detection interrupts are enabled/disabled when needed. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index f4401c1e8572..4ad832f5c4ba 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -406,10 +406,8 @@ static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0, 1); /* Clear interrupts status */ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b7b, 1); /* Enable interrupt */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0x03, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b79, 0x00, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3, 1); mutex_unlock(&spec->cs8409_i2c_mux); } @@ -424,11 +422,13 @@ static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec) /* Clear interrupts */ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xFF, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87, 1); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86, 1); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0x01, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFD, 1); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80, 1); /* Wait ~110ms*/ usleep_range(110000, 200000); @@ -487,9 +487,6 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124, 1); reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); - /* Clear interrupts, by reading interrupt status registers */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b7b, 1); - mutex_unlock(&spec->cs8409_i2c_mux); /* If status values are < 0, read error has occurred. */ @@ -499,6 +496,11 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) /* HSDET_AUTO_DONE */ if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) { + mutex_lock(&spec->cs8409_i2c_mux); + /* Disable HSDET_AUTO_DONE */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF, 1); + mutex_unlock(&spec->cs8409_i2c_mux); + type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1); /* CS42L42 reports optical jack as type 4 * We don't handle optical jack @@ -521,6 +523,11 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) } } + mutex_lock(&spec->cs8409_i2c_mux); + /* Re-Enable Tip Sense Interrupt */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3, 1); + mutex_unlock(&spec->cs8409_i2c_mux); + } else { /* TIP_SENSE INSERT/REMOVE */ switch (reg_ts_status) { From patchwork Wed Jul 28 13:43:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405875 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8B19C4338F for ; Wed, 28 Jul 2021 13:50:33 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2B8B360F45 for ; Wed, 28 Jul 2021 13:50:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2B8B360F45 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id BF6091ADE; Wed, 28 Jul 2021 15:49:41 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz BF6091ADE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480231; bh=Zmid88JsFI+TF+OfF8Lkr7wSVktG9WbDAfLyfZGJDLc=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=fwxzXegFqp4l0edzF4ceSUr/9Zbryi/lHSJJZHl9KsVjQ7mPEZ3nvbEuMaxFGRQ1Q orZ9fMcImsPitdWRdsFFgNJssP+AW6f5N/k1C4hYUF+Hpo4natoGrL1tT+3dxTyK79 5bJjs4vqRdu4/D8rDWuvkmTkHFNS+0w81obKSj70= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id BF51BF80553; Wed, 28 Jul 2021 15:45:12 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6B775F8053A; Wed, 28 Jul 2021 15:45:05 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 4DC1CF804E1 for ; Wed, 28 Jul 2021 15:44:39 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 4DC1CF804E1 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="o+J1TN2x" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqt014335; Wed, 28 Jul 2021 08:44:38 -0500 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=sv9CoWslopRHQ8T0qp6pGNCCUwN+J2by6FZSrV1vKrc=; b=o+J1TN2xFvjt+hBLy53nDZfZ8J471x4JEr22brCbb+TlJqOchaZv+cFwvwovAueN3Q09 evZLP6KcPdRk4J+zpj9JjwP8V0IQp9AgkSPUiqGa3PGAbHjYqFKYxoU55x96Bc5EFpPO QlKDFTognGcPWo+qcVtmtCQFZhxZd4bVj6dxQWZ3tNe9PS+zDZgw42UtdWcLRDj4VZw/ ZNvqaF2hZm83cp9LCBJGhCJYszwrttbFYNzoXvxcFNzdV96E/sP3s4QpoAYwMHMA1uCF nQJ7R6IHHv02X2cmI35y34EHBpEc5h9F6VPxmjfDt2yZzrtb7dwzPjmGPFhFVABV0VgP HQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-9 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:37 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:33 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:33 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 21D6945D; Wed, 28 Jul 2021 13:44:33 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 11/27] ALSA: hda/cs8409: Prevent I2C access during suspend time Date: Wed, 28 Jul 2021 14:43:52 +0100 Message-ID: <20210728134408.369396-12-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: uE1LOUpQ29KdW-ha1-lLzpswiEYP0En4 X-Proofpoint-GUID: uE1LOUpQ29KdW-ha1-lLzpswiEYP0En4 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 14 ++++++++++++++ sound/pci/hda/patch_cs8409.h | 1 + 2 files changed, 15 insertions(+) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 4ad832f5c4ba..0b13bcecd778 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -127,9 +127,13 @@ static int cs8409_i2c_wait_complete(struct hda_codec *codec) static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg, unsigned int paged) { + struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; unsigned int read_data; + if (spec->cs42l42_suspended) + return -EPERM; + cs8409_enable_i2c_clock(codec, 1); cs8409_vendor_coef_set(codec, CS8409_I2C_ADDR, i2c_address); @@ -172,8 +176,12 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg, unsigned int i2c_data, unsigned int paged) { + struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; + if (spec->cs42l42_suspended) + return -EPERM; + cs8409_enable_i2c_clock(codec, 1); cs8409_vendor_coef_set(codec, CS8409_I2C_ADDR, i2c_address); @@ -371,6 +379,8 @@ static void cs8409_cs42l42_reset(struct hda_codec *codec) /* wait ~10ms */ usleep_range(10000, 15000); + spec->cs42l42_suspended = 0; + mutex_lock(&spec->cs8409_i2c_mux); /* Clear interrupts, by reading interrupt status registers */ @@ -594,6 +604,9 @@ static int cs8409_suspend(struct hda_codec *codec) /* Power down CS42L42 ASP/EQ/MIX/HP */ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe, 1); mutex_unlock(&spec->cs8409_i2c_mux); + + spec->cs42l42_suspended = 1; + /* Assert CS42L42 RTS# line */ snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0); @@ -759,6 +772,7 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, spec->cs42l42_hp_jack_in = 0; spec->cs42l42_mic_jack_in = 0; + spec->cs42l42_suspended = 1; /* Basic initial sequence for specific hw configuration */ snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs); diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 1d3ce28415fa..0f2084b6ec8e 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -269,6 +269,7 @@ struct cs8409_spec { unsigned int cs42l42_hp_jack_in:1; unsigned int cs42l42_mic_jack_in:1; unsigned int cs42l42_volume_init:1; + unsigned int cs42l42_suspended:1; char cs42l42_hp_volume[CS42L42_HP_CH]; char cs42l42_hs_mic_volume[CS42L42_HS_MIC_CH]; From patchwork Wed Jul 28 13:43:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405839 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BDF93C4338F for ; Wed, 28 Jul 2021 13:46:25 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1100B60F45 for ; Wed, 28 Jul 2021 13:46:24 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 1100B60F45 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 23E6217F5; Wed, 28 Jul 2021 15:45:33 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 23E6217F5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627479983; bh=32Yg2JJOvjhtb7grimnTwd4lFjZRSr7oymbWaBnNwkg=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=LSZv1UcfUDzJO+hOThLSXlswKtxlI4FmYUd/AGl572npOiMEmV/vy0jhd/r8CzH+Y /7nb4/x97Tq5jfPm5sXZ01OiCTgn5vRn+aWJUPIvkMYaRhshRqHeI6K5OVxlN/HLjR NaYM3wnCgzuPKAX0fPmcdRW5RcmtvXrqFXSlSH7o= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id DB1CCF8025E; Wed, 28 Jul 2021 15:44:48 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id BD5D5F8020D; Wed, 28 Jul 2021 15:44:46 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 20099F8020D for ; Wed, 28 Jul 2021 15:44:36 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 20099F8020D Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="jmfZqAIu" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqm014335; Wed, 28 Jul 2021 08:44:34 -0500 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=Lu7TV9wCG8k0Hn3fxIizUed92dsnr8JS+aHAqFGwf58=; b=jmfZqAIudl/VW4UQtwFqvG8c84e+OULnLrQlaYkCX89swEkRTCynSA2O8gjFP38HnuL2 F9O+uaggnlHVXsRvR+vksWp0SXaqnoSb940ef6DVjp3D++7+K2OWM9PxcsueczNSr9ba 3LwRWU6Wb7UxHTsjkoe3QCXR7zoWCtRgjb2b+Qy6/Jt1TtWs/hSOf0E6EUIoTBZk3Bvn UW65y9dt2JVXBYTVJkb4xFoMk4Iyw2ov0snKTs5J+FotwU11mn8d4KgRvgJOl1G8Z35O jhsCwEQlBuQaS6JkJyk2YgqrR49qjPq1O3ZKkeqnojHyY9Ue4xn8y7Xq//hR/jkgTkrW uA== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fxa-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:34 -0500 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.2242.4; Wed, 28 Jul 2021 14:44:33 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:33 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 79A6246E; Wed, 28 Jul 2021 13:44:33 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 12/27] ALSA: hda/cs8409: Generalize volume controls Date: Wed, 28 Jul 2021 14:43:53 +0100 Message-ID: <20210728134408.369396-13-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: UW19VzvhRscKn3QjCHCo16ezbe259Au5 X-Proofpoint-GUID: UW19VzvhRscKn3QjCHCo16ezbe259Au5 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure Use amp offsets as indexes for saved volumes. Remove dependencies on NID inside volume control functions. Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 37 +++++++ sound/pci/hda/patch_cs8409.c | 165 +++++++++------------------- sound/pci/hda/patch_cs8409.h | 27 +++-- 3 files changed, 105 insertions(+), 124 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index 07d3ae28c105..b03ddef2a25f 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -10,6 +10,43 @@ #include "patch_cs8409.h" +/****************************************************************************** + * CS42L42 Specific Data + * + ******************************************************************************/ + +static const DECLARE_TLV_DB_SCALE(cs42l42_dac_db_scale, + CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1); + +static const DECLARE_TLV_DB_SCALE(cs42l42_adc_db_scale, + CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1); + +const struct snd_kcontrol_new cs42l42_dac_volume_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .index = 0, + .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .info = cs8409_cs42l42_volume_info, + .get = cs8409_cs42l42_volume_get, + .put = cs8409_cs42l42_volume_put, + .tlv = { .p = cs42l42_dac_db_scale }, + .private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_TRANSMITTER_A, 3, 0, + HDA_OUTPUT, CS42L42_VOL_DAC) | HDA_AMP_VAL_MIN_MUTE +}; + +const struct snd_kcontrol_new cs42l42_adc_volume_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .index = 0, + .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .info = cs8409_cs42l42_volume_info, + .get = cs8409_cs42l42_volume_get, + .put = cs8409_cs42l42_volume_put, + .tlv = { .p = cs42l42_adc_db_scale }, + .private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_RECEIVER_A, 1, 0, + HDA_INPUT, CS42L42_VOL_ADC) | HDA_AMP_VAL_MIN_MUTE +}; + /* Dell Inspiron platforms * with cs8409 bridge and cs42l42 codec */ diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 0b13bcecd778..08205c19698c 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -208,162 +208,97 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u return 0; } -static int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) +int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) { - u16 nid = get_amp_nid(kctrl); + unsigned int ofs = get_amp_offset(kctrl); u8 chs = get_amp_channels(kctrl); - switch (nid) { - case CS8409_CS42L42_HP_PIN_NID: - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = chs == 3 ? 2 : 1; + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.step = 1; + uinfo->count = chs == 3 ? 2 : 1; + + switch (ofs) { + case CS42L42_VOL_DAC: uinfo->value.integer.min = CS8409_CS42L42_HP_VOL_REAL_MIN; uinfo->value.integer.max = CS8409_CS42L42_HP_VOL_REAL_MAX; break; - case CS8409_CS42L42_AMIC_PIN_NID: - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = chs == 3 ? 2 : 1; + case CS42L42_VOL_ADC: uinfo->value.integer.min = CS8409_CS42L42_AMIC_VOL_REAL_MIN; uinfo->value.integer.max = CS8409_CS42L42_AMIC_VOL_REAL_MAX; break; default: break; } - return 0; -} -static void cs8409_cs42l42_update_volume(struct hda_codec *codec) -{ - struct cs8409_spec *spec = codec->spec; - int data; - - mutex_lock(&spec->cs8409_i2c_mux); - data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHA, 1); - if (data >= 0) - spec->cs42l42_hp_volume[0] = -data; - else - spec->cs42l42_hp_volume[0] = CS8409_CS42L42_HP_VOL_REAL_MIN; - data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHB, 1); - if (data >= 0) - spec->cs42l42_hp_volume[1] = -data; - else - spec->cs42l42_hp_volume[1] = CS8409_CS42L42_HP_VOL_REAL_MIN; - data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOLUME, 1); - if (data >= 0) - spec->cs42l42_hs_mic_volume[0] = -data; - else - spec->cs42l42_hs_mic_volume[0] = CS8409_CS42L42_AMIC_VOL_REAL_MIN; - mutex_unlock(&spec->cs8409_i2c_mux); - spec->cs42l42_volume_init = 1; + return 0; } -static int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) +int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) { struct hda_codec *codec = snd_kcontrol_chip(kctrl); struct cs8409_spec *spec = codec->spec; - hda_nid_t nid = get_amp_nid(kctrl); int chs = get_amp_channels(kctrl); + unsigned int ofs = get_amp_offset(kctrl); long *valp = uctrl->value.integer.value; - if (!spec->cs42l42_volume_init) { - snd_hda_power_up(codec); - cs8409_cs42l42_update_volume(codec); - snd_hda_power_down(codec); - } - switch (nid) { - case CS8409_CS42L42_HP_PIN_NID: + switch (ofs) { + case CS42L42_VOL_DAC: if (chs & BIT(0)) - *valp++ = spec->cs42l42_hp_volume[0]; + *valp++ = spec->vol[ofs]; if (chs & BIT(1)) - *valp++ = spec->cs42l42_hp_volume[1]; + *valp = spec->vol[ofs+1]; break; - case CS8409_CS42L42_AMIC_PIN_NID: + case CS42L42_VOL_ADC: if (chs & BIT(0)) - *valp++ = spec->cs42l42_hs_mic_volume[0]; + *valp = spec->vol[ofs]; break; default: break; } + return 0; } -static int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) +int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) { struct hda_codec *codec = snd_kcontrol_chip(kctrl); struct cs8409_spec *spec = codec->spec; - hda_nid_t nid = get_amp_nid(kctrl); int chs = get_amp_channels(kctrl); + unsigned int ofs = get_amp_offset(kctrl); long *valp = uctrl->value.integer.value; - int change = 0; - char vol; - snd_hda_power_up(codec); - switch (nid) { - case CS8409_CS42L42_HP_PIN_NID: + switch (ofs) { + case CS42L42_VOL_DAC: mutex_lock(&spec->cs8409_i2c_mux); if (chs & BIT(0)) { - vol = -(*valp); - change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_HS_VOLUME_CHA, vol, 1); - valp++; + spec->vol[ofs] = *valp; + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA, + -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); } if (chs & BIT(1)) { - vol = -(*valp); - change |= cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_HS_VOLUME_CHB, vol, 1); + ofs++; + valp++; + spec->vol[ofs] = *valp; + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, + -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); } mutex_unlock(&spec->cs8409_i2c_mux); break; - case CS8409_CS42L42_AMIC_PIN_NID: + case CS42L42_VOL_ADC: mutex_lock(&spec->cs8409_i2c_mux); if (chs & BIT(0)) { - change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_AMIC_VOLUME, (char)*valp, 1); - valp++; + spec->vol[ofs] = *valp; + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, + spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1); } mutex_unlock(&spec->cs8409_i2c_mux); break; default: break; } - cs8409_cs42l42_update_volume(codec); - snd_hda_power_down(codec); - return change; -} - -static const DECLARE_TLV_DB_SCALE(cs8409_cs42l42_hp_db_scale, - CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1); - -static const DECLARE_TLV_DB_SCALE(cs8409_cs42l42_amic_db_scale, - CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1); - -static const struct snd_kcontrol_new cs8409_cs42l42_hp_volume_mixer = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .index = 0, - .name = "Headphone Playback Volume", - .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .info = cs8409_cs42l42_volume_info, - .get = cs8409_cs42l42_volume_get, - .put = cs8409_cs42l42_volume_put, - .tlv = { .p = cs8409_cs42l42_hp_db_scale }, - .private_value = HDA_COMPOSE_AMP_VAL(CS8409_CS42L42_HP_PIN_NID, 3, 0, HDA_OUTPUT) | - HDA_AMP_VAL_MIN_MUTE -}; -static const struct snd_kcontrol_new cs8409_cs42l42_amic_volume_mixer = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .index = 0, - .name = "Mic Capture Volume", - .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .info = cs8409_cs42l42_volume_info, - .get = cs8409_cs42l42_volume_get, - .put = cs8409_cs42l42_volume_put, - .tlv = { .p = cs8409_cs42l42_amic_db_scale }, - .private_value = HDA_COMPOSE_AMP_VAL(CS8409_CS42L42_AMIC_PIN_NID, 1, 0, HDA_INPUT) | - HDA_AMP_VAL_MIN_MUTE -}; + return 0; +} /* Assert/release RTS# line to CS42L42 */ static void cs8409_cs42l42_reset(struct hda_codec *codec) @@ -657,18 +592,14 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) } /* Restore Volumes after Resume */ - if (spec->cs42l42_volume_init) { - mutex_lock(&spec->cs8409_i2c_mux); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHA, - -spec->cs42l42_hp_volume[0], 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHB, - -spec->cs42l42_hp_volume[1], 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOLUME, - spec->cs42l42_hs_mic_volume[0], 1); - mutex_unlock(&spec->cs8409_i2c_mux); - } - - cs8409_cs42l42_update_volume(codec); + mutex_lock(&spec->cs8409_i2c_mux); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA, + -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, + -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, + spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1); + mutex_unlock(&spec->cs8409_i2c_mux); cs8409_cs42l42_enable_jack_detect(codec); @@ -811,8 +742,10 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, /* Set initial DMIC volume to -26 dB */ snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, HDA_INPUT, 0, 0xff, 0x19); - 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); + snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume", + &cs42l42_dac_volume_mixer); + snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume", + &cs42l42_adc_volume_mixer); /* Disable Unsolicited Response during boot */ cs8409_enable_ur(codec, 0); cs8409_cs42l42_hw_init(codec); diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 0f2084b6ec8e..bf0e8a4cc4cc 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -215,16 +215,17 @@ enum cs8409_coefficient_index_registers { /* CS42L42 Specific Definitions */ -#define CS42L42_HP_CH (2U) -#define CS42L42_HS_MIC_CH (1U) +#define CS42L42_VOLUMES (4U) #define CS8409_CS42L42_HP_VOL_REAL_MIN (-63) #define CS8409_CS42L42_HP_VOL_REAL_MAX (0) #define CS8409_CS42L42_AMIC_VOL_REAL_MIN (-97) #define CS8409_CS42L42_AMIC_VOL_REAL_MAX (12) -#define CS8409_CS42L42_REG_HS_VOLUME_CHA (0x2301) -#define CS8409_CS42L42_REG_HS_VOLUME_CHB (0x2303) -#define CS8409_CS42L42_REG_AMIC_VOLUME (0x1D03) +#define CS8409_CS42L42_REG_HS_VOL_CHA (0x2301) +#define CS8409_CS42L42_REG_HS_VOL_CHB (0x2303) +#define CS8409_CS42L42_REG_HS_VOL_MASK (0x003F) +#define CS8409_CS42L42_REG_AMIC_VOL (0x1D03) +#define CS8409_CS42L42_REG_AMIC_VOL_MASK (0x00FF) #define CS42L42_HSDET_AUTO_DONE (0x02) #define CS42L42_HSTYPE_MASK (0x03) #define CS42L42_JACK_INSERTED (0x0C) @@ -248,6 +249,11 @@ enum { CS8409_FIXUPS, }; +enum { + CS42L42_VOL_ADC, + CS42L42_VOL_DAC, +}; + struct cs8409_i2c_param { unsigned int addr; unsigned int reg; @@ -268,10 +274,8 @@ struct cs8409_spec { unsigned int cs42l42_hp_jack_in:1; unsigned int cs42l42_mic_jack_in:1; - unsigned int cs42l42_volume_init:1; unsigned int cs42l42_suspended:1; - char cs42l42_hp_volume[CS42L42_HP_CH]; - char cs42l42_hs_mic_volume[CS42L42_HS_MIC_CH]; + s8 vol[CS42L42_VOLUMES]; struct mutex cs8409_i2c_mux; @@ -280,6 +284,13 @@ struct cs8409_spec { unsigned int *res); }; +extern const struct snd_kcontrol_new cs42l42_dac_volume_mixer; +extern const struct snd_kcontrol_new cs42l42_adc_volume_mixer; + +int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo); +int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl); +int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl); + extern const struct snd_pci_quirk cs8409_fixup_tbl[]; extern const struct hda_model_fixup cs8409_models[]; extern const struct hda_fixup cs8409_fixups[]; From patchwork Wed Jul 28 13:43:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405883 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE654C4338F for ; Wed, 28 Jul 2021 13:52:15 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5078760F45 for ; Wed, 28 Jul 2021 13:52:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 5078760F45 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id DDA181F08; Wed, 28 Jul 2021 15:51:23 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz DDA181F08 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480334; bh=8bzORQcOq3DKOftt48qSpQutZ42VxsK1dCRTlM0L1OM=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=uzt+mWXaw8vGkLQg3yxfYas+iaA7cn4MuZTyMWym3B+rrOERJEObEpjidOwbNvopy AdXiP3NBZIZzkdqlvDw+WjEbrh7FzyCTUjQJHgLM6ixQ1dmwvfhh+deN59IeLXlzFB gQUPzAn2eberczmqCXRm9HxI8VNZ6bveN2IEzytE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B5A20F80588; Wed, 28 Jul 2021 15:45:20 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 7D89AF80212; Wed, 28 Jul 2021 15:45:14 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id E4F24F80212 for ; Wed, 28 Jul 2021 15:44:39 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz E4F24F80212 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="V+kh9DVI" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqu014335; Wed, 28 Jul 2021 08:44:38 -0500 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=5QbIZt2MuxfZlycdKGc6Hz8Fn1X7GVx8fCAT6vrva70=; b=V+kh9DVIUYBkiDk6pg7o5KEkKSvuK9DdvjgsOdwld5WzL5wjrqIdb3e1dIRBif6RvL4s rN+1X0C07H1rjsSb+vFGkFtgb+IgUsA/L0WDUrmJXYmfIJpmLNhohrMxeqrgGrvr7YFi yoO8Ljxv0h2IZ76vS+u/GBttFuBQTbUjHAbVUO4c7mrJYvKEZywVZoP4gfHI/JBgQLcc twMzxVA0Uuxybe7tkh5O+ebWA5lHKwXZO0V0VUd8ckNLFEYZeJCyRs0LiMIBEum4SqbS AJm/UgWkCIuJuYORoxm5R3pIQcjEEPQlYnUr2NjzQryWLHF3jZgndGHXs/uTfInSYW2B 3Q== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-10 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:38 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:34 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:34 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id CE7242BA; Wed, 28 Jul 2021 13:44:33 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 13/27] ALSA: hda/cs8409: Dont disable I2C clock between consecutive accesses Date: Wed, 28 Jul 2021 14:43:54 +0100 Message-ID: <20210728134408.369396-14-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: 7AFf1gLaLEvJjTRfvW2V29nZv25xJmLv X-Proofpoint-GUID: 7AFf1gLaLEvJjTRfvW2V29nZv25xJmLv X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure , Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure Only disable I2C clock 25 ms after not being used. The current implementation enables and disables the I2C clock for each I2C transaction. Each enable/disable call requires two verb transactions. This means each I2C transaction requires a total of four verb transactions to enable and disable the clock. However, if there are multiple consecutive I2C transactions, it is not necessary to enable and disable the clock each time, instead it is more efficient to enable the clock for the first transaction, and disable it after the final transaction, which would improve performance. This is achieved by using a timeout which disables the clock if no request to enable the clock has occurred for 25 ms. Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Signed-off-by: Stefan Binding Changes in v2: Improved delayed work start/cancel implementation, and re-worked commit message adding more explanation why this was required. --- sound/pci/hda/patch_cs8409.c | 56 +++++++++++++++++++++++++----------- sound/pci/hda/patch_cs8409.h | 4 +++ 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 08205c19698c..fafc0f309e70 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -53,7 +53,9 @@ static struct cs8409_spec *cs8409_alloc_spec(struct hda_codec *codec) if (!spec) return NULL; codec->spec = spec; + spec->codec = codec; codec->power_save_node = 1; + INIT_DELAYED_WORK(&spec->i2c_clk_work, cs8409_disable_i2c_clock); snd_hda_gen_spec_init(&spec->gen); return spec; @@ -72,21 +74,37 @@ static inline void cs8409_vendor_coef_set(struct hda_codec *codec, unsigned int snd_hda_codec_write(codec, CS8409_PIN_VENDOR_WIDGET, 0, AC_VERB_SET_PROC_COEF, coef); } -/** +/* + * cs8409_disable_i2c_clock - Worker that disable the I2C Clock after 25ms without use + */ +static void cs8409_disable_i2c_clock(struct work_struct *work) +{ + struct cs8409_spec *spec = container_of(work, struct cs8409_spec, i2c_clk_work.work); + + mutex_lock(&spec->cs8409_i2c_mux); + cs8409_vendor_coef_set(spec->codec, 0x0, + cs8409_vendor_coef_get(spec->codec, 0x0) & 0xfffffff7); + spec->i2c_clck_enabled = 0; + mutex_unlock(&spec->cs8409_i2c_mux); +} + +/* * cs8409_enable_i2c_clock - Enable I2C clocks * @codec: the codec instance - * @enable: Enable or disable I2C clocks - * * Enable or Disable I2C clocks. + * This must be called when the i2c mutex is locked. */ -static void cs8409_enable_i2c_clock(struct hda_codec *codec, unsigned int enable) +static void cs8409_enable_i2c_clock(struct hda_codec *codec) { - unsigned int retval; - unsigned int newval; + struct cs8409_spec *spec = codec->spec; + + cancel_delayed_work_sync(&spec->i2c_clk_work); - retval = cs8409_vendor_coef_get(codec, 0x0); - newval = (enable) ? (retval | 0x8) : (retval & 0xfffffff7); - cs8409_vendor_coef_set(codec, 0x0, newval); + if (!spec->i2c_clck_enabled) { + cs8409_vendor_coef_set(codec, 0x0, cs8409_vendor_coef_get(codec, 0x0) | 0x8); + spec->i2c_clck_enabled = 1; + } + queue_delayed_work(system_power_efficient_wq, &spec->i2c_clk_work, msecs_to_jiffies(25)); } /** @@ -134,7 +152,7 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un if (spec->cs42l42_suspended) return -EPERM; - cs8409_enable_i2c_clock(codec, 1); + cs8409_enable_i2c_clock(codec); cs8409_vendor_coef_set(codec, CS8409_I2C_ADDR, i2c_address); if (paged) { @@ -157,8 +175,6 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un /* Register in bits 15-8 and the data in 7-0 */ read_data = cs8409_vendor_coef_get(codec, CS8409_I2C_QREAD); - cs8409_enable_i2c_clock(codec, 0); - return read_data & 0x0ff; } @@ -182,7 +198,7 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u if (spec->cs42l42_suspended) return -EPERM; - cs8409_enable_i2c_clock(codec, 1); + cs8409_enable_i2c_clock(codec); cs8409_vendor_coef_set(codec, CS8409_I2C_ADDR, i2c_address); if (paged) { @@ -203,8 +219,6 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u return -EIO; } - cs8409_enable_i2c_clock(codec, 0); - return 0; } @@ -551,6 +565,14 @@ static int cs8409_suspend(struct hda_codec *codec) } #endif +static void cs8409_free(struct hda_codec *codec) +{ + struct cs8409_spec *spec = codec->spec; + + cancel_delayed_work_sync(&spec->i2c_clk_work); + snd_hda_gen_free(codec); +} + /* Vendor specific HW configuration * PLL, ASP, I2C, SPI, GPIOs, DMIC etc... */ @@ -633,7 +655,7 @@ static const struct hda_codec_ops cs8409_cs42l42_patch_ops = { .build_controls = cs8409_build_controls, .build_pcms = snd_hda_gen_build_pcms, .init = cs8409_cs42l42_init, - .free = snd_hda_gen_free, + .free = cs8409_free, .unsol_event = cs8409_jack_unsol_event, #ifdef CONFIG_PM .suspend = cs8409_suspend, @@ -785,7 +807,7 @@ static int patch_cs8409(struct hda_codec *codec) err = cs8409_parse_auto_config(codec); if (err < 0) { - snd_hda_gen_free(codec); + cs8409_free(codec); return err; } diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index bf0e8a4cc4cc..542582c213d2 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -11,6 +11,7 @@ #include #include +#include #include #include "hda_local.h" #include "hda_auto_parser.h" @@ -267,6 +268,7 @@ struct cs8409_cir_param { struct cs8409_spec { struct hda_gen_spec gen; + struct hda_codec *codec; unsigned int gpio_mask; unsigned int gpio_dir; @@ -278,6 +280,8 @@ struct cs8409_spec { s8 vol[CS42L42_VOLUMES]; struct mutex cs8409_i2c_mux; + unsigned int i2c_clck_enabled; + struct delayed_work i2c_clk_work; /* verb exec op override */ int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, unsigned int flags, From patchwork Wed Jul 28 13:43:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405851 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 649A2C4338F for ; Wed, 28 Jul 2021 13:48:44 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DF30560F45 for ; Wed, 28 Jul 2021 13:48:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org DF30560F45 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 8E3A618F8; Wed, 28 Jul 2021 15:47:52 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 8E3A618F8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480122; bh=Qtx13gGv2wCvBCe2VvGz9EbhOm52TgN8TYbO6R6iXS8=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=JopRttQLByKvc0cEcATs0h9/Sp0lM0O+remRkv3h8S3LiOkIO+dyz3ohjIhCz9WvZ JN5CUXsW3EwH+1PXOwX8Pt+v2TYPGsTM3GGp7adQLGK2WKpATxBFMzF9l9hSvsPuPX hC7ktfQfA8QVs8KOZjeXV0FuRjZ1vwDBbQiJsoMM= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 76FC1F8052E; Wed, 28 Jul 2021 15:45:02 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6DE8AF8051B; Wed, 28 Jul 2021 15:44:55 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 68051F804CF for ; Wed, 28 Jul 2021 15:44:36 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 68051F804CF Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="cmnmoIGH" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqo014335; Wed, 28 Jul 2021 08:44:35 -0500 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=YdllO4dOaVEcV4spblJnXSctk/p1jkPBosuasafeUk0=; b=cmnmoIGHz09eBEXeRrWGh6XLI8tyY2J0DYBIHJXPTlglWh3sQ6XR2A01r7oPT2uDZJ7c V9Xt4Y+xX/P5JiMRxkJZpTpc7NJOhXJ1eStQfpThsNwU1iCfWYbC7WvB5EG2WkMyFplz eYBXgotr0NTaY5wArXtSW9FRLM+hRejwEfl/bq0USWruZ7u65aNp0Uz/EM44Qb/fN/3J NwA4VCNWx0FR7mnofr4+sUjnjfu0HYyPvboatVyrtGQOKwNj9WVd+m3vQoGGTWWjO5jN fx+VLypXmve2cztbNkrRDCismIf5sBzd0Tpfl7zJCUo0iSBegFrJbz30jA8SXS1URYBY pA== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fxa-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:35 -0500 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.2242.4; Wed, 28 Jul 2021 14:44:34 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:34 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 332EE46E; Wed, 28 Jul 2021 13:44:34 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 14/27] ALSA: hda/cs8409: Avoid setting the same I2C address for every access Date: Wed, 28 Jul 2021 14:43:55 +0100 Message-ID: <20210728134408.369396-15-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: dvLHFuyTpjtZeHLHgaoGObBWE5-mHP0t X-Proofpoint-GUID: dvLHFuyTpjtZeHLHgaoGObBWE5-mHP0t X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=996 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 19 +++++++++++++++++-- sound/pci/hda/patch_cs8409.h | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index fafc0f309e70..bd43c42d5c74 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -132,6 +132,21 @@ static int cs8409_i2c_wait_complete(struct hda_codec *codec) return -1; } +/** + * cs8409_set_i2c_dev_addr - Set i2c address for transaction + * @codec: the codec instance + * @addr: I2C Address + */ +static void cs8409_set_i2c_dev_addr(struct hda_codec *codec, unsigned int addr) +{ + struct cs8409_spec *spec = codec->spec; + + if (spec->dev_addr != addr) { + cs8409_vendor_coef_set(codec, CS8409_I2C_ADDR, addr); + spec->dev_addr = addr; + } +} + /** * cs8409_i2c_read - CS8409 I2C Read. * @codec: the codec instance @@ -153,7 +168,7 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un return -EPERM; cs8409_enable_i2c_clock(codec); - cs8409_vendor_coef_set(codec, CS8409_I2C_ADDR, i2c_address); + cs8409_set_i2c_dev_addr(codec, i2c_address); if (paged) { cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); @@ -199,7 +214,7 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u return -EPERM; cs8409_enable_i2c_clock(codec); - cs8409_vendor_coef_set(codec, CS8409_I2C_ADDR, i2c_address); + cs8409_set_i2c_dev_addr(codec, i2c_address); if (paged) { cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 542582c213d2..c2c208218e34 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -281,6 +281,7 @@ struct cs8409_spec { struct mutex cs8409_i2c_mux; unsigned int i2c_clck_enabled; + unsigned int dev_addr; struct delayed_work i2c_clk_work; /* verb exec op override */ From patchwork Wed Jul 28 13:43:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405879 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C3B8EC4338F for ; Wed, 28 Jul 2021 13:51:13 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 43191604DB for ; Wed, 28 Jul 2021 13:51:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 43191604DB Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id E19881B02; Wed, 28 Jul 2021 15:50:21 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz E19881B02 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480271; bh=eZH5AP6S/H/cCGdz1e2CB1v0k0cQwCk8OqbcJ6GmUfA=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=K7wlsTlM4xo1jOS5gnChn85zxRR1j6I8AdTIk5vgUPfeugFCv/SIpOiVQfXNmOLoh 8xXb/+3eFxwP8MbDbQTFm8KUHZe1yyNvcH7SpWXC2eKJbfN3oU0g03o6mz14h7qpKQ GPpMRKbZZS4ZQPccVAX0Vu9L5lrwgNKRCUcJLK7Q= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 27C21F80566; Wed, 28 Jul 2021 15:45:14 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id DF7A4F80543; Wed, 28 Jul 2021 15:45:08 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id E4E5BF804E7 for ; Wed, 28 Jul 2021 15:44:40 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz E4E5BF804E7 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="C8pYZX7K" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqv014335; Wed, 28 Jul 2021 08:44:39 -0500 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=Izz3irDLw9ridFa0yxcyJ6oQcr6PnOZtkxVd2bTNjHg=; b=C8pYZX7KjY8GGool9Vvx+62uhmpgefc/1o1biSoyEnNZs8TIvvvb3m/iaNdEMXfiPdPM zOzriK4BMjjq/5fasTC/cpWTehGMx8UPaOOkQPiCd5eHuD2ePRX65Uu7H98f8YpGlzZ9 U6tlRZx5bFBpWigIuTV6znLGsnx42RwZn5yGyvLGEIdLoEQNyZMmmwUu/rdrxGQ/ysj0 ombXh8bTU1mqABKxMCCUnzJYEROlno8JspSYFbAjKUx1qWCqPFmHF8qfhqtzVBQfD2Vf 0tOfj4T+LeL+P0zTI1k1qCezOUy0g9bOG08lIqet5cDQO+bd9LqgJQWVKfKVekz1589/ ow== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-11 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:39 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:34 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:34 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 856AF45D; Wed, 28 Jul 2021 13:44:34 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 15/27] ALSA: hda/cs8409: Avoid re-setting the same page as the last access Date: Wed, 28 Jul 2021 14:43:56 +0100 Message-ID: <20210728134408.369396-16-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: 8imKXchv3ZHRFLggP38sUx_7PxIzOdL2 X-Proofpoint-GUID: 8imKXchv3ZHRFLggP38sUx_7PxIzOdL2 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 124 +++++++++++++++++++---------------- sound/pci/hda/patch_cs8409.h | 2 + 2 files changed, 71 insertions(+), 55 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index bd43c42d5c74..31c9f1a3aeaa 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -147,18 +147,37 @@ static void cs8409_set_i2c_dev_addr(struct hda_codec *codec, unsigned int addr) } } +/** + * cs8409_i2c_set_page - CS8409 I2C set page register. + * @codec: the codec instance + * @i2c_reg: Page register + * + * Returns negative on error. + */ +static int cs8409_i2c_set_page(struct hda_codec *codec, unsigned int i2c_reg) +{ + struct cs8409_spec *spec = codec->spec; + + if (spec->paged && (spec->last_page != (i2c_reg >> 8))) { + cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); + if (cs8409_i2c_wait_complete(codec) < 0) + return -EIO; + spec->last_page = i2c_reg >> 8; + } + + return 0; +} + /** * cs8409_i2c_read - CS8409 I2C Read. * @codec: the codec instance * @i2c_address: I2C Address * @i2c_reg: Register to read - * @paged: Is a paged transaction * * CS8409 I2C Read. * Returns negative on error, otherwise returns read value in bits 0-7. */ -static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg, - unsigned int paged) +static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg) { struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; @@ -170,13 +189,10 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un cs8409_enable_i2c_clock(codec); cs8409_set_i2c_dev_addr(codec, i2c_address); - if (paged) { - cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); - if (cs8409_i2c_wait_complete(codec) < 0) { - codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); - return -EIO; - } + if (cs8409_i2c_set_page(codec, i2c_reg)) { + codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; } i2c_reg_data = (i2c_reg << 8) & 0x0ffff; @@ -199,13 +215,12 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un * @i2c_address: I2C Address * @i2c_reg: Register to write to * @i2c_data: Data to write - * @paged: Is a paged transaction * * CS8409 I2C Write. * Returns negative on error, otherwise returns 0. */ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg, - unsigned int i2c_data, unsigned int paged) + unsigned int i2c_data) { struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; @@ -216,13 +231,10 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u cs8409_enable_i2c_clock(codec); cs8409_set_i2c_dev_addr(codec, i2c_address); - if (paged) { - cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); - if (cs8409_i2c_wait_complete(codec) < 0) { - codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); - return -EIO; - } + if (cs8409_i2c_set_page(codec, i2c_reg)) { + codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; } i2c_reg_data = ((i2c_reg << 8) & 0x0ff00) | (i2c_data & 0x0ff); @@ -302,14 +314,14 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va if (chs & BIT(0)) { spec->vol[ofs] = *valp; cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA, - -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); + -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK); } if (chs & BIT(1)) { ofs++; valp++; spec->vol[ofs] = *valp; cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, - -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); + -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK); } mutex_unlock(&spec->cs8409_i2c_mux); break; @@ -318,7 +330,7 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va if (chs & BIT(0)) { spec->vol[ofs] = *valp; cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, - spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1); + spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK); } mutex_unlock(&spec->cs8409_i2c_mux); break; @@ -344,14 +356,15 @@ static void cs8409_cs42l42_reset(struct hda_codec *codec) usleep_range(10000, 15000); spec->cs42l42_suspended = 0; + spec->last_page = 0; mutex_lock(&spec->cs8409_i2c_mux); /* Clear interrupts, by reading interrupt status registers */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1309, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130A, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130F, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1309); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130A); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130F); mutex_unlock(&spec->cs8409_i2c_mux); @@ -368,20 +381,20 @@ static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) * Additionally set HSBIAS_SENSE_EN for some variants. */ if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_BULLSEYE) - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020); else - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0); /* Clear WAKE# */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C1, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C1); /* Wait ~2.5ms */ usleep_range(2500, 3000); /* Set mode WAKE# output follows the combination logic directly */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0); /* Clear interrupts status */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); /* Enable interrupt */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3); mutex_unlock(&spec->cs8409_i2c_mux); } @@ -394,20 +407,20 @@ static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec) mutex_lock(&spec->cs8409_i2c_mux); /* Clear interrupts */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xFF, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); - - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFD, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xFF); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); + + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFD); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80); /* Wait ~110ms*/ usleep_range(110000, 200000); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0); /* Wait ~10ms */ usleep_range(10000, 25000); @@ -423,7 +436,7 @@ static void cs8409_cs42l42_reg_setup(struct hda_codec *codec) mutex_lock(&spec->cs8409_i2c_mux); for (; seq->addr; seq++) - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, seq->addr, seq->reg, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, seq->addr, seq->reg); mutex_unlock(&spec->cs8409_i2c_mux); @@ -457,9 +470,9 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) mutex_lock(&spec->cs8409_i2c_mux); /* Read jack detect status registers */ - reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); - reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124, 1); - reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); + reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); + reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124); + reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); mutex_unlock(&spec->cs8409_i2c_mux); @@ -472,7 +485,7 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) mutex_lock(&spec->cs8409_i2c_mux); /* Disable HSDET_AUTO_DONE */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF); mutex_unlock(&spec->cs8409_i2c_mux); type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1); @@ -499,7 +512,7 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) mutex_lock(&spec->cs8409_i2c_mux); /* Re-Enable Tip Sense Interrupt */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3); mutex_unlock(&spec->cs8409_i2c_mux); } else { @@ -566,7 +579,7 @@ static int cs8409_suspend(struct hda_codec *codec) mutex_lock(&spec->cs8409_i2c_mux); /* Power down CS42L42 ASP/EQ/MIX/HP */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe); mutex_unlock(&spec->cs8409_i2c_mux); spec->cs42l42_suspended = 1; @@ -622,7 +635,7 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) { /* FULL_SCALE_VOL = 0 for Warlock / Cyborg */ mutex_lock(&spec->cs8409_i2c_mux); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01); mutex_unlock(&spec->cs8409_i2c_mux); /* DMIC1_MO=00b, DMIC1/2_SR=1 */ cs8409_vendor_coef_set(codec, 0x09, 0x0003); @@ -631,11 +644,11 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) /* Restore Volumes after Resume */ mutex_lock(&spec->cs8409_i2c_mux); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA, - -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); + -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, - -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); + -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, - spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1); + spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK); mutex_unlock(&spec->cs8409_i2c_mux); cs8409_cs42l42_enable_jack_detect(codec); @@ -741,6 +754,7 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, spec->cs42l42_hp_jack_in = 0; spec->cs42l42_mic_jack_in = 0; spec->cs42l42_suspended = 1; + spec->paged = 1; /* Basic initial sequence for specific hw configuration */ snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs); diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index c2c208218e34..ee66fd0c01dc 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -283,6 +283,8 @@ struct cs8409_spec { unsigned int i2c_clck_enabled; unsigned int dev_addr; struct delayed_work i2c_clk_work; + unsigned int paged; + unsigned int last_page; /* verb exec op override */ int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, unsigned int flags, From patchwork Wed Jul 28 13:43:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90A02C4338F for ; Wed, 28 Jul 2021 13:53:36 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1D3B260F5E for ; Wed, 28 Jul 2021 13:53:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 1D3B260F5E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id ADCF71F43; Wed, 28 Jul 2021 15:52:44 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz ADCF71F43 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480414; bh=EJyiK1OLFdSLjPVbzOWCW7r9rpP4js68tHEzJl4jUOs=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=noe9u+R1kj0DR7Z6aTvbgOFUTGrI1fjlZCma/TSOb2QysAEIK6ilMZADZ6LMHzZE5 WhGZrUpnPpSD2p7IQ2mrRk/aMFF/5I9pCzTrLkYXB7zo5pEQNwOFygdS/Nr0i6ejD8 pO9PVBsaNxmJObWwsn4QBBsYGgxJziIy08RDBFKI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 4F9F7F805AD; Wed, 28 Jul 2021 15:45:28 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id C0ACAF804F1; Wed, 28 Jul 2021 15:45:16 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id BC48EF804F1 for ; Wed, 28 Jul 2021 15:44:41 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BC48EF804F1 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="DVtcXOQw" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqw014335; Wed, 28 Jul 2021 08:44:40 -0500 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=rRA5Z6IIIDMrXPw1HXC90paYF1ELT1IDE1t39NuCcLs=; b=DVtcXOQw9IYymbbRZw7XBJBDZy4KirkBG35XZRMjf/GnracHo9cwFkiSCxpwzwn7o+C1 dqXL4ePmmOb9h5qFpJRuNaF/F+exTuI0DNjt8MWy5FxFCcIgZ0gRI4F0sdAd9uAx74eA Rb0Rci0Oar1FaIR/XqEcj00x5//rZ7BJ6OcNfOF00+H+dc/IRJXPH/0Py/JmBx1YN8wG Yr5ZIKddfAJjBfyXj3ghhcrDLV/3OaBj1K9mucw8WE8gCaRC1eecgcLzry7cb9Rytoji 95Nq5Q6HyP2M8ycGoeokbbslQdHIK5x8Vx5LuyAVuGG4no1TpoBhXNXszOjwn1Kd0evC aw== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-12 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:40 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:35 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:35 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id D5AA52BA; Wed, 28 Jul 2021 13:44:34 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 16/27] ALSA: hda/cs8409: Support i2c bulk read/write functions Date: Wed, 28 Jul 2021 14:43:57 +0100 Message-ID: <20210728134408.369396-17-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: xVFV6fxWo2GmuU7zPUhKJlwIjRmvxC1S X-Proofpoint-GUID: xVFV6fxWo2GmuU7zPUhKJlwIjRmvxC1S X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure This allows mutex locks to be moved into i2c functions, as the bulk read/write functions can lock/unlock themselves to prevent interruption of sequence reads/writes. Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 3 +- sound/pci/hda/patch_cs8409.c | 208 +++++++++++++++++----------- sound/pci/hda/patch_cs8409.h | 8 +- 3 files changed, 136 insertions(+), 83 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index b03ddef2a25f..0f2fd8bb92bf 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -146,7 +146,7 @@ const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { }; /* Vendor specific HW configuration for CS42L42 */ -const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { +const struct cs8409_i2c_param cs42l42_init_reg_seq[CS42L42_INIT_REG_SEQ_SIZE] = { { 0x1010, 0xB0 }, { 0x1D01, 0x00 }, { 0x1D02, 0x06 }, @@ -206,7 +206,6 @@ const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { { 0x1320, 0xff }, { 0x1b79, 0xff }, { 0x1b7a, 0xff }, - {} /* Terminator */ }; /* Vendor specific hw configuration for CS8409 */ diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 31c9f1a3aeaa..d88b32816769 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -81,11 +81,11 @@ static void cs8409_disable_i2c_clock(struct work_struct *work) { struct cs8409_spec *spec = container_of(work, struct cs8409_spec, i2c_clk_work.work); - mutex_lock(&spec->cs8409_i2c_mux); + mutex_lock(&spec->i2c_mux); cs8409_vendor_coef_set(spec->codec, 0x0, cs8409_vendor_coef_get(spec->codec, 0x0) & 0xfffffff7); spec->i2c_clck_enabled = 0; - mutex_unlock(&spec->cs8409_i2c_mux); + mutex_unlock(&spec->i2c_mux); } /* @@ -172,12 +172,12 @@ static int cs8409_i2c_set_page(struct hda_codec *codec, unsigned int i2c_reg) * cs8409_i2c_read - CS8409 I2C Read. * @codec: the codec instance * @i2c_address: I2C Address - * @i2c_reg: Register to read + * @addr: Register to read * * CS8409 I2C Read. * Returns negative on error, otherwise returns read value in bits 0-7. */ -static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg) +static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int addr) { struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; @@ -186,41 +186,90 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un if (spec->cs42l42_suspended) return -EPERM; + mutex_lock(&spec->i2c_mux); cs8409_enable_i2c_clock(codec); cs8409_set_i2c_dev_addr(codec, i2c_address); - if (cs8409_i2c_set_page(codec, i2c_reg)) { + if (cs8409_i2c_set_page(codec, addr)) { codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); + __func__, i2c_address, addr); return -EIO; } - i2c_reg_data = (i2c_reg << 8) & 0x0ffff; + i2c_reg_data = (addr << 8) & 0x0ffff; cs8409_vendor_coef_set(codec, CS8409_I2C_QREAD, i2c_reg_data); - if (cs8409_i2c_wait_complete(codec) < 0) { - codec_err(codec, "%s() Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); - return -EIO; - } + if (cs8409_i2c_wait_complete(codec) < 0) + goto error; /* Register in bits 15-8 and the data in 7-0 */ read_data = cs8409_vendor_coef_get(codec, CS8409_I2C_QREAD); + mutex_unlock(&spec->i2c_mux); return read_data & 0x0ff; + +error: + mutex_unlock(&spec->i2c_mux); + codec_err(codec, "%s() Failed 0x%02x : 0x%04x\n", __func__, i2c_address, addr); + return -EIO; +} + +/** + * cs8409_i2c_bulk_read - CS8409 I2C Read Sequence. + * @codec: the codec instance + * @seq: Register Sequence to read + * @count: Number of registeres to read + * + * Returns negative on error, values are read into value element of cs8409_i2c_param sequence. + */ +static int cs8409_i2c_bulk_read(struct hda_codec *codec, unsigned int i2c_address, + struct cs8409_i2c_param *seq, int count) +{ + struct cs8409_spec *spec = codec->spec; + unsigned int i2c_reg_data; + int i; + + if (spec->cs42l42_suspended) + return -EPERM; + + mutex_lock(&spec->i2c_mux); + cs8409_set_i2c_dev_addr(codec, i2c_address); + + for (i = 0; i < count; i++) { + cs8409_enable_i2c_clock(codec); + if (cs8409_i2c_set_page(codec, seq[i].addr)) + goto error; + + i2c_reg_data = (seq[i].addr << 8) & 0x0ffff; + cs8409_vendor_coef_set(codec, CS8409_I2C_QREAD, i2c_reg_data); + + if (cs8409_i2c_wait_complete(codec) < 0) + goto error; + + seq[i].value = cs8409_vendor_coef_get(codec, CS8409_I2C_QREAD) & 0xff; + } + + mutex_unlock(&spec->i2c_mux); + + return 0; + +error: + mutex_unlock(&spec->i2c_mux); + codec_err(codec, "I2C Bulk Write Failed 0x%02x\n", i2c_address); + return -EIO; } /** * cs8409_i2c_write - CS8409 I2C Write. * @codec: the codec instance * @i2c_address: I2C Address - * @i2c_reg: Register to write to - * @i2c_data: Data to write + * @addr: Register to write to + * @value: Data to write * * CS8409 I2C Write. * Returns negative on error, otherwise returns 0. */ -static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg, - unsigned int i2c_data) +static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, unsigned int addr, + unsigned int value) { struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; @@ -228,25 +277,73 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u if (spec->cs42l42_suspended) return -EPERM; + mutex_lock(&spec->i2c_mux); + cs8409_enable_i2c_clock(codec); cs8409_set_i2c_dev_addr(codec, i2c_address); - if (cs8409_i2c_set_page(codec, i2c_reg)) { + if (cs8409_i2c_set_page(codec, addr)) { codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); + __func__, i2c_address, addr); return -EIO; } - i2c_reg_data = ((i2c_reg << 8) & 0x0ff00) | (i2c_data & 0x0ff); + i2c_reg_data = ((addr << 8) & 0x0ff00) | (value & 0x0ff); cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg_data); - if (cs8409_i2c_wait_complete(codec) < 0) { - codec_err(codec, "%s() Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); - return -EIO; + if (cs8409_i2c_wait_complete(codec) < 0) + goto error; + + mutex_unlock(&spec->i2c_mux); + return 0; + +error: + mutex_unlock(&spec->i2c_mux); + codec_err(codec, "%s() Failed 0x%02x : 0x%04x\n", __func__, i2c_address, addr); + return -EIO; +} + +/** + * cs8409_i2c_bulk_write - CS8409 I2C Write Sequence. + * @codec: the codec instance + * @seq: Register Sequence to write + * @count: Number of registeres to write + * + * Returns negative on error. + */ +static int cs8409_i2c_bulk_write(struct hda_codec *codec, unsigned int i2c_address, + const struct cs8409_i2c_param *seq, int count) +{ + struct cs8409_spec *spec = codec->spec; + unsigned int i2c_reg_data; + int i; + + if (spec->cs42l42_suspended) + return -EPERM; + + mutex_lock(&spec->i2c_mux); + cs8409_set_i2c_dev_addr(codec, i2c_address); + + for (i = 0; i < count; i++) { + cs8409_enable_i2c_clock(codec); + if (cs8409_i2c_set_page(codec, seq[i].addr)) + goto error; + + i2c_reg_data = ((seq[i].addr << 8) & 0x0ff00) | (seq[i].value & 0x0ff); + cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg_data); + + if (cs8409_i2c_wait_complete(codec) < 0) + goto error; } + mutex_unlock(&spec->i2c_mux); + return 0; + +error: + mutex_unlock(&spec->i2c_mux); + codec_err(codec, "I2C Bulk Write Failed 0x%02x\n", i2c_address); + return -EIO; } int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) @@ -310,7 +407,6 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va switch (ofs) { case CS42L42_VOL_DAC: - mutex_lock(&spec->cs8409_i2c_mux); if (chs & BIT(0)) { spec->vol[ofs] = *valp; cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA, @@ -323,16 +419,13 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK); } - mutex_unlock(&spec->cs8409_i2c_mux); break; case CS42L42_VOL_ADC: - mutex_lock(&spec->cs8409_i2c_mux); if (chs & BIT(0)) { spec->vol[ofs] = *valp; cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK); } - mutex_unlock(&spec->cs8409_i2c_mux); break; default: break; @@ -345,6 +438,12 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va static void cs8409_cs42l42_reset(struct hda_codec *codec) { struct cs8409_spec *spec = codec->spec; + struct cs8409_i2c_param irq_regs[] = { + { 0x1308, 0x00 }, + { 0x1309, 0x00 }, + { 0x130A, 0x00 }, + { 0x130F, 0x00 }, + }; /* Assert RTS# line */ snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0); @@ -358,25 +457,13 @@ static void cs8409_cs42l42_reset(struct hda_codec *codec) spec->cs42l42_suspended = 0; spec->last_page = 0; - mutex_lock(&spec->cs8409_i2c_mux); - /* Clear interrupts, by reading interrupt status registers */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1309); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130A); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130F); - - mutex_unlock(&spec->cs8409_i2c_mux); - + cs8409_i2c_bulk_read(codec, CS42L42_I2C_ADDR, irq_regs, ARRAY_SIZE(irq_regs)); } /* Configure CS42L42 slave codec for jack autodetect */ static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) { - struct cs8409_spec *spec = codec->spec; - - mutex_lock(&spec->cs8409_i2c_mux); - /* Set TIP_SENSE_EN for analog front-end of tip sense. * Additionally set HSBIAS_SENSE_EN for some variants. */ @@ -395,17 +482,11 @@ static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); /* Enable interrupt */ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3); - - mutex_unlock(&spec->cs8409_i2c_mux); } /* Enable and run CS42L42 slave codec jack auto detect */ static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec) { - struct cs8409_spec *spec = codec->spec; - - mutex_lock(&spec->cs8409_i2c_mux); - /* Clear interrupts */ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77); @@ -424,22 +505,6 @@ static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec) /* Wait ~10ms */ usleep_range(10000, 25000); - mutex_unlock(&spec->cs8409_i2c_mux); - -} - -static void cs8409_cs42l42_reg_setup(struct hda_codec *codec) -{ - const struct cs8409_i2c_param *seq = cs42l42_init_reg_seq; - struct cs8409_spec *spec = codec->spec; - - mutex_lock(&spec->cs8409_i2c_mux); - - for (; seq->addr; seq++) - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, seq->addr, seq->reg); - - mutex_unlock(&spec->cs8409_i2c_mux); - } /* @@ -467,15 +532,11 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) if (res & CS8409_CS42L42_INT) return; - mutex_lock(&spec->cs8409_i2c_mux); - /* Read jack detect status registers */ reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124); reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); - mutex_unlock(&spec->cs8409_i2c_mux); - /* If status values are < 0, read error has occurred. */ if (reg_cdc_status < 0 || reg_hs_status < 0 || reg_ts_status < 0) return; @@ -483,10 +544,8 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) /* HSDET_AUTO_DONE */ if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) { - mutex_lock(&spec->cs8409_i2c_mux); /* Disable HSDET_AUTO_DONE */ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF); - mutex_unlock(&spec->cs8409_i2c_mux); type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1); /* CS42L42 reports optical jack as type 4 @@ -510,10 +569,8 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) } } - mutex_lock(&spec->cs8409_i2c_mux); /* Re-Enable Tip Sense Interrupt */ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3); - mutex_unlock(&spec->cs8409_i2c_mux); } else { /* TIP_SENSE INSERT/REMOVE */ @@ -577,10 +634,8 @@ static int cs8409_suspend(struct hda_codec *codec) cs8409_enable_ur(codec, 0); - mutex_lock(&spec->cs8409_i2c_mux); /* Power down CS42L42 ASP/EQ/MIX/HP */ cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe); - mutex_unlock(&spec->cs8409_i2c_mux); spec->cs42l42_suspended = 1; @@ -630,26 +685,23 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) cs8409_cs42l42_reset(codec); /* Initialise CS42L42 companion codec */ - cs8409_cs42l42_reg_setup(codec); + cs8409_i2c_bulk_write(codec, CS42L42_I2C_ADDR, cs42l42_init_reg_seq, + CS42L42_INIT_REG_SEQ_SIZE); if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) { /* FULL_SCALE_VOL = 0 for Warlock / Cyborg */ - mutex_lock(&spec->cs8409_i2c_mux); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01); - mutex_unlock(&spec->cs8409_i2c_mux); /* DMIC1_MO=00b, DMIC1/2_SR=1 */ cs8409_vendor_coef_set(codec, 0x09, 0x0003); } /* Restore Volumes after Resume */ - mutex_lock(&spec->cs8409_i2c_mux); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA, -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK); - mutex_unlock(&spec->cs8409_i2c_mux); cs8409_cs42l42_enable_jack_detect(codec); @@ -738,7 +790,7 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, spec->exec_verb = codec->core.exec_verb; codec->core.exec_verb = cs8409_cs42l42_exec_verb; - mutex_init(&spec->cs8409_i2c_mux); + mutex_init(&spec->i2c_mux); codec->patch_ops = cs8409_cs42l42_patch_ops; diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index ee66fd0c01dc..d84cda94dfb9 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -243,6 +243,8 @@ enum cs8409_coefficient_index_registers { #define CS8409_CS42L42_DMIC_PIN_NID CS8409_PIN_DMIC1_IN #define CS8409_CS42L42_DMIC_ADC_PIN_NID CS8409_PIN_DMIC1 +#define CS42L42_INIT_REG_SEQ_SIZE 59 + enum { CS8409_BULLSEYE, CS8409_WARLOCK, @@ -257,7 +259,7 @@ enum { struct cs8409_i2c_param { unsigned int addr; - unsigned int reg; + unsigned int value; }; struct cs8409_cir_param { @@ -279,7 +281,7 @@ struct cs8409_spec { unsigned int cs42l42_suspended:1; s8 vol[CS42L42_VOLUMES]; - struct mutex cs8409_i2c_mux; + struct mutex i2c_mux; unsigned int i2c_clck_enabled; unsigned int dev_addr; struct delayed_work i2c_clk_work; @@ -303,7 +305,7 @@ extern const struct hda_model_fixup cs8409_models[]; extern const struct hda_fixup cs8409_fixups[]; extern const struct hda_verb cs8409_cs42l42_init_verbs[]; extern const struct hda_pintbl cs8409_cs42l42_pincfgs[]; -extern const struct cs8409_i2c_param cs42l42_init_reg_seq[]; +extern const struct cs8409_i2c_param cs42l42_init_reg_seq[CS42L42_INIT_REG_SEQ_SIZE]; extern const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[]; extern const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[]; From patchwork Wed Jul 28 13:43:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405855 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0DE81C4338F for ; Wed, 28 Jul 2021 13:49:22 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8A97C60F5E for ; Wed, 28 Jul 2021 13:49:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 8A97C60F5E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 2F070192B; Wed, 28 Jul 2021 15:48:30 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 2F070192B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480160; bh=iL91QqbRcH8rwLEWZc+5YGKWy1SS7SKOIqJt3oN7uvg=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=jjneidCTpcp8loRQLQhIp0OYeuzR5KsNCM2mqEQvQAcgkh9Nr4c3YIUijzBAV0EnE U3PvsOTnL9AzNnmj6N3fThWcx3hx3MfuSb7gJ8gIzdp8GGi8Ivst0V+vcXUNtmet3x ekCSIc7LoWHs5qRlJ1Dyww1WHRLZ1CDmuzaQufy4= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id E7086F804E1; Wed, 28 Jul 2021 15:45:05 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6FC82F8051C; Wed, 28 Jul 2021 15:44:58 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 71850F804E0 for ; Wed, 28 Jul 2021 15:44:37 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 71850F804E0 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="cPp/XAc5" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqq014335; Wed, 28 Jul 2021 08:44:36 -0500 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=rccI2fZXbyE5Nn4pacHeTa5WebXke0XDJeBiH+OpYUs=; b=cPp/XAc5XtFSX5E0LDSnb9gCDWN/WMbc1ZyGq/WtNSBEMZHA988Iq5yO99OQ64+r3VM6 F3lrOIUY9ns+Ph+pZc4jZUq76ocEnSeyFDnfwM3CmIb5ia0Pf/RHblfWd2Hmkra9WyLV iqxiK7wKroXSVE+IVZy0MIbIjFGzsLXuJ61XsjxZcog5nk/52ScxMqZJjmUMBA9Ke06t +SISOCkXE0Lxz0clbgxXe/ww/bDi1dYYoAha66MjbTngsdg7DWWxjtSUkvg++XugE92n wsqoajsizmqsh7TZoCMNag1hUuSMzh3c+uX74lXyonLiA1gHjbf7wwwoG0ty7LRVjrPB BQ== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fxa-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:35 -0500 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.2242.4; Wed, 28 Jul 2021 14:44:35 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:35 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 30D8E46E; Wed, 28 Jul 2021 13:44:35 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 17/27] ALSA: hda/cs8409: Separate CS8409, CS42L42 and project functions Date: Wed, 28 Jul 2021 14:43:58 +0100 Message-ID: <20210728134408.369396-18-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: TlCiRg3vxqB_R3w8l-_eEyvyHcowXZct X-Proofpoint-GUID: TlCiRg3vxqB_R3w8l-_eEyvyHcowXZct X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 18 +- sound/pci/hda/patch_cs8409.c | 329 +++++++++++++++------------- sound/pci/hda/patch_cs8409.h | 24 +- 3 files changed, 194 insertions(+), 177 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index 0f2fd8bb92bf..77a7b2f42128 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -15,20 +15,18 @@ * ******************************************************************************/ -static const DECLARE_TLV_DB_SCALE(cs42l42_dac_db_scale, - CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1); +static const DECLARE_TLV_DB_SCALE(cs42l42_dac_db_scale, CS42L42_HP_VOL_REAL_MIN * 100, 100, 1); -static const DECLARE_TLV_DB_SCALE(cs42l42_adc_db_scale, - CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1); +static const DECLARE_TLV_DB_SCALE(cs42l42_adc_db_scale, CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1); const struct snd_kcontrol_new cs42l42_dac_volume_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .index = 0, .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .info = cs8409_cs42l42_volume_info, - .get = cs8409_cs42l42_volume_get, - .put = cs8409_cs42l42_volume_put, + .info = cs42l42_volume_info, + .get = cs42l42_volume_get, + .put = cs42l42_volume_put, .tlv = { .p = cs42l42_dac_db_scale }, .private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_TRANSMITTER_A, 3, 0, HDA_OUTPUT, CS42L42_VOL_DAC) | HDA_AMP_VAL_MIN_MUTE @@ -39,9 +37,9 @@ const struct snd_kcontrol_new cs42l42_adc_volume_mixer = { .index = 0, .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .info = cs8409_cs42l42_volume_info, - .get = cs8409_cs42l42_volume_get, - .put = cs8409_cs42l42_volume_put, + .info = cs42l42_volume_info, + .get = cs42l42_volume_get, + .put = cs42l42_volume_put, .tlv = { .p = cs42l42_adc_db_scale }, .private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_RECEIVER_A, 1, 0, HDA_INPUT, CS42L42_VOL_ADC) | HDA_AMP_VAL_MIN_MUTE diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index d88b32816769..59cecbf1b54d 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -14,6 +14,10 @@ #include "patch_cs8409.h" +/****************************************************************************** + * CS8409 Specific Functions + ******************************************************************************/ + static int cs8409_parse_auto_config(struct hda_codec *codec) { struct cs8409_spec *spec = codec->spec; @@ -45,6 +49,8 @@ static int cs8409_parse_auto_config(struct hda_codec *codec) return 0; } +static void cs8409_disable_i2c_clock(struct work_struct *work); + static struct cs8409_spec *cs8409_alloc_spec(struct hda_codec *codec) { struct cs8409_spec *spec; @@ -55,6 +61,7 @@ static struct cs8409_spec *cs8409_alloc_spec(struct hda_codec *codec) codec->spec = spec; spec->codec = codec; codec->power_save_node = 1; + mutex_init(&spec->i2c_mux); INIT_DELAYED_WORK(&spec->i2c_clk_work, cs8409_disable_i2c_clock); snd_hda_gen_spec_init(&spec->gen); @@ -346,7 +353,67 @@ static int cs8409_i2c_bulk_write(struct hda_codec *codec, unsigned int i2c_addre return -EIO; } -int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) +static int cs8409_init(struct hda_codec *codec) +{ + int ret = snd_hda_gen_init(codec); + + if (!ret) + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); + + return ret; +} + +static int cs8409_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); + + return 0; +} + +/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */ +static void cs8409_enable_ur(struct hda_codec *codec, int flag) +{ + /* GPIO4 INT# and GPIO3 WAKE# */ + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, + flag ? CS8409_CS42L42_INT : 0); + + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_UNSOLICITED_ENABLE, + flag ? AC_UNSOL_ENABLED : 0); + +} + +static void cs8409_fix_caps(struct hda_codec *codec, unsigned int nid) +{ + int caps; + + /* 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. Receive and Transmit NID(s) 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, a companion codec may be + * connected to these pins which supports 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, nid, AC_PAR_PIN_CAP); + if (caps >= 0) + snd_hdac_override_parm(&codec->core, nid, AC_PAR_PIN_CAP, + (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT))); + + snd_hda_override_wcaps(codec, nid, (get_wcaps(codec, nid) | AC_WCAP_UNSOL_CAP)); +} + +/****************************************************************************** + * CS42L42 Specific Functions + ******************************************************************************/ + +int cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) { unsigned int ofs = get_amp_offset(kctrl); u8 chs = get_amp_channels(kctrl); @@ -357,12 +424,12 @@ int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_i switch (ofs) { case CS42L42_VOL_DAC: - uinfo->value.integer.min = CS8409_CS42L42_HP_VOL_REAL_MIN; - uinfo->value.integer.max = CS8409_CS42L42_HP_VOL_REAL_MAX; + uinfo->value.integer.min = CS42L42_HP_VOL_REAL_MIN; + uinfo->value.integer.max = CS42L42_HP_VOL_REAL_MAX; break; case CS42L42_VOL_ADC: - uinfo->value.integer.min = CS8409_CS42L42_AMIC_VOL_REAL_MIN; - uinfo->value.integer.max = CS8409_CS42L42_AMIC_VOL_REAL_MAX; + uinfo->value.integer.min = CS42L42_AMIC_VOL_REAL_MIN; + uinfo->value.integer.max = CS42L42_AMIC_VOL_REAL_MAX; break; default: break; @@ -371,7 +438,7 @@ int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_i return 0; } -int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) +int cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) { struct hda_codec *codec = snd_kcontrol_chip(kctrl); struct cs8409_spec *spec = codec->spec; @@ -397,7 +464,7 @@ int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va return 0; } -int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) +int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) { struct hda_codec *codec = snd_kcontrol_chip(kctrl); struct cs8409_spec *spec = codec->spec; @@ -409,22 +476,22 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va case CS42L42_VOL_DAC: if (chs & BIT(0)) { spec->vol[ofs] = *valp; - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA, - -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHA, + -(spec->vol[ofs]) & CS42L42_REG_HS_VOL_MASK); } if (chs & BIT(1)) { ofs++; valp++; spec->vol[ofs] = *valp; - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, - -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHB, + -(spec->vol[ofs]) & CS42L42_REG_HS_VOL_MASK); } break; case CS42L42_VOL_ADC: if (chs & BIT(0)) { spec->vol[ofs] = *valp; - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, - spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_AMIC_VOL, + spec->vol[ofs] & CS42L42_REG_AMIC_VOL_MASK); } break; default: @@ -434,35 +501,8 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va return 0; } -/* Assert/release RTS# line to CS42L42 */ -static void cs8409_cs42l42_reset(struct hda_codec *codec) -{ - struct cs8409_spec *spec = codec->spec; - struct cs8409_i2c_param irq_regs[] = { - { 0x1308, 0x00 }, - { 0x1309, 0x00 }, - { 0x130A, 0x00 }, - { 0x130F, 0x00 }, - }; - - /* Assert RTS# line */ - snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0); - /* wait ~10ms */ - usleep_range(10000, 15000); - /* Release RTS# line */ - snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, CS8409_CS42L42_RESET); - /* wait ~10ms */ - usleep_range(10000, 15000); - - spec->cs42l42_suspended = 0; - spec->last_page = 0; - - /* Clear interrupts, by reading interrupt status registers */ - cs8409_i2c_bulk_read(codec, CS42L42_I2C_ADDR, irq_regs, ARRAY_SIZE(irq_regs)); -} - /* Configure CS42L42 slave codec for jack autodetect */ -static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) +static void cs42l42_enable_jack_detect(struct hda_codec *codec) { /* Set TIP_SENSE_EN for analog front-end of tip sense. * Additionally set HSBIAS_SENSE_EN for some variants. @@ -485,7 +525,7 @@ static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) } /* Enable and run CS42L42 slave codec jack auto detect */ -static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec) +static void cs42l42_run_jack_detect(struct hda_codec *codec) { /* Clear interrupts */ cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); @@ -507,14 +547,7 @@ static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec) } -/* - * In the case of CS8409 we do not have unsolicited events from NID's 0x24 - * and 0x34 where hs mic and hp are connected. Companion codec CS42L42 will - * generate interrupt via gpio 4 to notify jack events. We have to overwrite - * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers - * and then notify status via generic snd_hda_jack_unsol_event() call. - */ -static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) +static int cs42l42_jack_unsol_event(struct hda_codec *codec) { struct cs8409_spec *spec = codec->spec; int status_changed = 0; @@ -522,15 +555,6 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) int reg_hs_status; int reg_ts_status; int type; - struct hda_jack_tbl *jk; - - /* jack_unsol_event() will be called every time gpio line changing state. - * In this case gpio4 line goes up as a result of reading interrupt status - * registers in previous cs8409_jack_unsol_event() call. - * We don't need to handle this event, ignoring... - */ - if (res & CS8409_CS42L42_INT) - return; /* Read jack detect status registers */ reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); @@ -539,7 +563,7 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) /* If status values are < 0, read error has occurred. */ if (reg_cdc_status < 0 || reg_hs_status < 0 || reg_ts_status < 0) - return; + return -EIO; /* HSDET_AUTO_DONE */ if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) { @@ -576,7 +600,7 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) /* TIP_SENSE INSERT/REMOVE */ switch (reg_ts_status) { case CS42L42_JACK_INSERTED: - cs8409_cs42l42_run_jack_detect(codec); + cs42l42_run_jack_detect(codec); break; case CS42L42_JACK_REMOVED: @@ -594,48 +618,102 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) } } - if (status_changed) { + return status_changed; +} +/* Assert/release RTS# line to CS42L42 */ +static void cs42l42_reset(struct hda_codec *codec) +{ + struct cs8409_spec *spec = codec->spec; + struct cs8409_i2c_param irq_regs[] = { + { 0x1308, 0x00 }, + { 0x1309, 0x00 }, + { 0x130A, 0x00 }, + { 0x130F, 0x00 }, + }; + + /* Assert RTS# line */ + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0); + /* wait ~10ms */ + usleep_range(10000, 15000); + /* Release RTS# line */ + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, CS8409_CS42L42_RESET); + /* wait ~10ms */ + usleep_range(10000, 15000); + + spec->cs42l42_suspended = 0; + spec->last_page = 0; + + /* Clear interrupts, by reading interrupt status registers */ + cs8409_i2c_bulk_read(codec, CS42L42_I2C_ADDR, irq_regs, ARRAY_SIZE(irq_regs)); +} + +#ifdef CONFIG_PM +static void cs42l42_suspend(struct hda_codec *codec) +{ + /* Power down CS42L42 ASP/EQ/MIX/HP */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe); +} +#endif + +static void cs8409_free(struct hda_codec *codec) +{ + struct cs8409_spec *spec = codec->spec; + + cancel_delayed_work_sync(&spec->i2c_clk_work); + snd_hda_gen_free(codec); +} + +/****************************************************************************** + * BULLSEYE / WARLOCK / CYBORG Specific Functions + * CS8409/CS42L42 + ******************************************************************************/ + +/* + * In the case of CS8409 we do not have unsolicited events from NID's 0x24 + * and 0x34 where hs mic and hp are connected. Companion codec CS42L42 will + * generate interrupt via gpio 4 to notify jack events. We have to overwrite + * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers + * and then notify status via generic snd_hda_jack_unsol_event() call. + */ +static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) +{ + struct cs8409_spec *spec = codec->spec; + struct hda_jack_tbl *jk; + + /* jack_unsol_event() will be called every time gpio line changing state. + * In this case gpio4 line goes up as a result of reading interrupt status + * registers in previous cs8409_jack_unsol_event() call. + * We don't need to handle this event, ignoring... + */ + if (res & CS8409_CS42L42_INT) + return; + + if (cs42l42_jack_unsol_event(codec)) { snd_hda_set_pin_ctl(codec, CS8409_CS42L42_SPK_PIN_NID, spec->cs42l42_hp_jack_in ? 0 : PIN_OUT); - /* Report jack*/ jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_HP_PIN_NID, 0); - if (jk) { + if (jk) snd_hda_jack_unsol_event(codec, (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & AC_UNSOL_RES_TAG); - } /* Report jack*/ jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_AMIC_PIN_NID, 0); - if (jk) { + if (jk) snd_hda_jack_unsol_event(codec, (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & AC_UNSOL_RES_TAG); - } } } -/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */ -static void cs8409_enable_ur(struct hda_codec *codec, int flag) -{ - /* GPIO4 INT# and GPIO3 WAKE# */ - snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, - flag ? CS8409_CS42L42_INT : 0); - - snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_UNSOLICITED_ENABLE, - flag ? AC_UNSOL_ENABLED : 0); - -} - #ifdef CONFIG_PM /* Manage PDREF, when transition to D3hot */ -static int cs8409_suspend(struct hda_codec *codec) +static int cs8409_cs42l42_suspend(struct hda_codec *codec) { struct cs8409_spec *spec = codec->spec; cs8409_enable_ur(codec, 0); - /* Power down CS42L42 ASP/EQ/MIX/HP */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe); + cs42l42_suspend(codec); spec->cs42l42_suspended = 1; @@ -648,14 +726,6 @@ static int cs8409_suspend(struct hda_codec *codec) } #endif -static void cs8409_free(struct hda_codec *codec) -{ - struct cs8409_spec *spec = codec->spec; - - cancel_delayed_work_sync(&spec->i2c_clk_work); - snd_hda_gen_free(codec); -} - /* Vendor specific HW configuration * PLL, ASP, I2C, SPI, GPIOs, DMIC etc... */ @@ -682,7 +752,7 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) cs8409_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff); /* Reset CS42L42 */ - cs8409_cs42l42_reset(codec); + cs42l42_reset(codec); /* Initialise CS42L42 companion codec */ cs8409_i2c_bulk_write(codec, CS42L42_I2C_ADDR, cs42l42_init_reg_seq, @@ -696,49 +766,27 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) } /* Restore Volumes after Resume */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA, - -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, - -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, - spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHA, + -(spec->vol[1]) & CS42L42_REG_HS_VOL_MASK); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHB, + -(spec->vol[2]) & CS42L42_REG_HS_VOL_MASK); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_AMIC_VOL, + spec->vol[0] & CS42L42_REG_AMIC_VOL_MASK); - cs8409_cs42l42_enable_jack_detect(codec); + cs42l42_enable_jack_detect(codec); /* Enable Unsolicited Response */ cs8409_enable_ur(codec, 1); } -static int cs8409_cs42l42_init(struct hda_codec *codec) -{ - int ret = snd_hda_gen_init(codec); - - if (!ret) - snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); - - return ret; -} - -static int cs8409_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); - - return 0; -} - static const struct hda_codec_ops cs8409_cs42l42_patch_ops = { .build_controls = cs8409_build_controls, .build_pcms = snd_hda_gen_build_pcms, - .init = cs8409_cs42l42_init, + .init = cs8409_init, .free = cs8409_free, .unsol_event = cs8409_jack_unsol_event, #ifdef CONFIG_PM - .suspend = cs8409_suspend, + .suspend = cs8409_cs42l42_suspend, #endif }; @@ -781,7 +829,6 @@ static int cs8409_cs42l42_exec_verb(struct hdac_device *dev, unsigned int cmd, u void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct cs8409_spec *spec = codec->spec; - int caps; switch (action) { case HDA_FIXUP_ACT_PRE_PROBE: @@ -790,8 +837,6 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, spec->exec_verb = codec->core.exec_verb; codec->core.exec_verb = cs8409_cs42l42_exec_verb; - mutex_init(&spec->i2c_mux); - codec->patch_ops = cs8409_cs42l42_patch_ops; spec->gen.suppress_auto_mute = 1; @@ -811,35 +856,9 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, /* 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))); - - snd_hda_override_wcaps(codec, CS8409_CS42L42_HP_PIN_NID, - (get_wcaps(codec, CS8409_CS42L42_HP_PIN_NID) | AC_WCAP_UNSOL_CAP)); - - snd_hda_override_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID, - (get_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID) | AC_WCAP_UNSOL_CAP)); + cs8409_fix_caps(codec, CS8409_CS42L42_HP_PIN_NID); + cs8409_fix_caps(codec, CS8409_CS42L42_AMIC_PIN_NID); + break; case HDA_FIXUP_ACT_PROBE: /* Set initial DMIC volume to -26 dB */ @@ -863,7 +882,7 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, * been already plugged in. * Run immediately after init. */ - cs8409_cs42l42_run_jack_detect(codec); + cs42l42_run_jack_detect(codec); usleep_range(100000, 150000); break; default: diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index d84cda94dfb9..ac68cca2bc11 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -218,15 +218,15 @@ enum cs8409_coefficient_index_registers { #define CS42L42_VOLUMES (4U) -#define CS8409_CS42L42_HP_VOL_REAL_MIN (-63) -#define CS8409_CS42L42_HP_VOL_REAL_MAX (0) -#define CS8409_CS42L42_AMIC_VOL_REAL_MIN (-97) -#define CS8409_CS42L42_AMIC_VOL_REAL_MAX (12) -#define CS8409_CS42L42_REG_HS_VOL_CHA (0x2301) -#define CS8409_CS42L42_REG_HS_VOL_CHB (0x2303) -#define CS8409_CS42L42_REG_HS_VOL_MASK (0x003F) -#define CS8409_CS42L42_REG_AMIC_VOL (0x1D03) -#define CS8409_CS42L42_REG_AMIC_VOL_MASK (0x00FF) +#define CS42L42_HP_VOL_REAL_MIN (-63) +#define CS42L42_HP_VOL_REAL_MAX (0) +#define CS42L42_AMIC_VOL_REAL_MIN (-97) +#define CS42L42_AMIC_VOL_REAL_MAX (12) +#define CS42L42_REG_HS_VOL_CHA (0x2301) +#define CS42L42_REG_HS_VOL_CHB (0x2303) +#define CS42L42_REG_HS_VOL_MASK (0x003F) +#define CS42L42_REG_AMIC_VOL (0x1D03) +#define CS42L42_REG_AMIC_VOL_MASK (0x00FF) #define CS42L42_HSDET_AUTO_DONE (0x02) #define CS42L42_HSTYPE_MASK (0x03) #define CS42L42_JACK_INSERTED (0x0C) @@ -296,9 +296,9 @@ struct cs8409_spec { extern const struct snd_kcontrol_new cs42l42_dac_volume_mixer; extern const struct snd_kcontrol_new cs42l42_adc_volume_mixer; -int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo); -int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl); -int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl); +int cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo); +int cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl); +int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl); extern const struct snd_pci_quirk cs8409_fixup_tbl[]; extern const struct hda_model_fixup cs8409_models[]; From patchwork Wed Jul 28 13:43:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405897 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5FF8EC4338F for ; Wed, 28 Jul 2021 13:54:51 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B181E60F45 for ; Wed, 28 Jul 2021 13:54:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org B181E60F45 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 48D4C1F82; Wed, 28 Jul 2021 15:53:57 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 48D4C1F82 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480487; bh=lDi8dHs9U1Ca84xfoQiQ5rwfbUiXrJq/nKD4shSDqf4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=uQg+5DVHmu2jpIJdzyE5cFmHTKpn7T5NGeEZ/o8xi7r/x01AeeXRdDC6PY2OaiiOh uiPRYbe9y02cv1XRmbCEVPdkTdWNkeRQ7g4pyKVZvU83IoeNj0xO1wKpfjGowVzJpN OXOJIpgrW2auGotmMR/qEIFrK1Xa4AO35oIW7TFY= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 47F75F805C6; Wed, 28 Jul 2021 15:45:31 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0E1EFF805A0; Wed, 28 Jul 2021 15:45:23 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 7C64FF804EC for ; Wed, 28 Jul 2021 15:44:44 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 7C64FF804EC Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="kW5XEJD+" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUqx014335; Wed, 28 Jul 2021 08:44:41 -0500 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=ZOWUOKnQFysaN1azhoqT8ZXXKYcf2w1vfZAHPA2rXow=; b=kW5XEJD+og9wu1DUfxyHZ4KxOrgIIZT991n2o+8bdd4khiZrF9SNifD0thNDyx+eDYyc 8UEuauzXgNgp10pdEkyX2DkHi1eiHiayX7fGEH/E6YK47gC/2H+f937PGWCsxARBaHfZ aHYn+48R3AN5gE4GjDe0Sb23Jo3nAV7qE67SGMYYs1NpHh5uJ5UH8iLmEhM1M3Rbpsmk gc8EZkZ0QKievm6LpyirtQ9oGZzQscFESU/FBcEOe+IMok6wyPuYPdOLkBt+hFp/aN1L brqQYWYgv/YDNqW1XUVg48i++AVlw2WjFBo3qQfpgFbrjYcEZp8G26el6Sn/drCijcx1 Xg== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-13 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:40 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:35 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:35 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 829612BA; Wed, 28 Jul 2021 13:44:35 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 18/27] ALSA: hda/cs8409: Move codec properties to its own struct Date: Wed, 28 Jul 2021 14:43:59 +0100 Message-ID: <20210728134408.369396-19-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: 5LQC5vcd3RcHR0h9KR63NceZGkVCCuzJ X-Proofpoint-GUID: 5LQC5vcd3RcHR0h9KR63NceZGkVCCuzJ X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure To accommodate move, cs42l42_resume has been added to mirror the existing function cs42l42_suspend. Function cs42l42_reset is no longer required, since cs42l42_resume and cs42l42_suspend perform the same operations. Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 183 ++++++++-------- sound/pci/hda/patch_cs8409.c | 312 ++++++++++++++-------------- sound/pci/hda/patch_cs8409.h | 39 +++- 3 files changed, 284 insertions(+), 250 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index 77a7b2f42128..117c70536ff0 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -28,7 +28,7 @@ const struct snd_kcontrol_new cs42l42_dac_volume_mixer = { .get = cs42l42_volume_get, .put = cs42l42_volume_put, .tlv = { .p = cs42l42_dac_db_scale }, - .private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_TRANSMITTER_A, 3, 0, + .private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_TRANSMITTER_A, 3, CS8409_CODEC0, HDA_OUTPUT, CS42L42_VOL_DAC) | HDA_AMP_VAL_MIN_MUTE }; @@ -41,89 +41,14 @@ const struct snd_kcontrol_new cs42l42_adc_volume_mixer = { .get = cs42l42_volume_get, .put = cs42l42_volume_put, .tlv = { .p = cs42l42_adc_db_scale }, - .private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_RECEIVER_A, 1, 0, + .private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_RECEIVER_A, 1, CS8409_CODEC0, HDA_INPUT, CS42L42_VOL_ADC) | HDA_AMP_VAL_MIN_MUTE }; -/* Dell Inspiron platforms - * with cs8409 bridge and cs42l42 codec - */ -const struct snd_pci_quirk cs8409_fixup_tbl[] = { - SND_PCI_QUIRK(0x1028, 0x0A11, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A12, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A23, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A24, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A25, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0A2B, "Bullseye", CS8409_BULLSEYE), - SND_PCI_QUIRK(0x1028, 0x0AB0, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AB5, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AD9, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0ADC, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK), - SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0ADF, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE2, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AE9, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEA, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEB, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEC, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AED, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG), - SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), - {} /* terminator */ -}; - -/* Dell Inspiron models with cs8409/cs42l42 */ -const struct hda_model_fixup cs8409_models[] = { - { .id = CS8409_BULLSEYE, .name = "bullseye" }, - { .id = CS8409_WARLOCK, .name = "warlock" }, - { .id = CS8409_CYBORG, .name = "cyborg" }, - {} -}; - -const struct hda_fixup cs8409_fixups[] = { - [CS8409_BULLSEYE] = { - .type = HDA_FIXUP_PINS, - .v.pins = cs8409_cs42l42_pincfgs, - .chained = true, - .chain_id = CS8409_FIXUPS, - }, - [CS8409_WARLOCK] = { - .type = HDA_FIXUP_PINS, - .v.pins = cs8409_cs42l42_pincfgs, - .chained = true, - .chain_id = CS8409_FIXUPS, - }, - [CS8409_CYBORG] = { - .type = HDA_FIXUP_PINS, - .v.pins = cs8409_cs42l42_pincfgs, - .chained = true, - .chain_id = CS8409_FIXUPS, - }, - [CS8409_FIXUPS] = { - .type = HDA_FIXUP_FUNC, - .v.func = cs8409_cs42l42_fixups, - }, -}; +/****************************************************************************** + * BULLSEYE / WARLOCK / CYBORG Specific Arrays + * CS8409/CS42L42 + ******************************************************************************/ const struct hda_verb cs8409_cs42l42_init_verbs[] = { { CS8409_PIN_AFG, AC_VERB_SET_GPIO_WAKE_MASK, 0x0018 }, /* WAKE from GPIO 3,4 */ @@ -144,7 +69,7 @@ const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { }; /* Vendor specific HW configuration for CS42L42 */ -const struct cs8409_i2c_param cs42l42_init_reg_seq[CS42L42_INIT_REG_SEQ_SIZE] = { +static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { { 0x1010, 0xB0 }, { 0x1D01, 0x00 }, { 0x1D02, 0x06 }, @@ -310,3 +235,97 @@ const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[] = { { CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0x0000 }, {} /* Terminator */ }; + +struct sub_codec cs8409_cs42l42_codec = { + .addr = CS42L42_I2C_ADDR, + .reset_gpio = CS8409_CS42L42_RESET, + .irq_mask = CS8409_CS42L42_INT, + .init_seq = cs42l42_init_reg_seq, + .init_seq_num = ARRAY_SIZE(cs42l42_init_reg_seq), + .hp_jack_in = 0, + .mic_jack_in = 0, + .paged = 1, + .suspended = 1, +}; + +/****************************************************************************** + * CS8409 Patch Driver Structs + * Arrays Used for all projects using CS8409 + ******************************************************************************/ + +const struct snd_pci_quirk cs8409_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0A11, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A12, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A23, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A24, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A25, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A2B, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0AB0, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB5, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AD9, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADC, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0ADF, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE2, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE9, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEA, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEB, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEC, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AED, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), + {} /* terminator */ +}; + +/* Dell Inspiron models with cs8409/cs42l42 */ +const struct hda_model_fixup cs8409_models[] = { + { .id = CS8409_BULLSEYE, .name = "bullseye" }, + { .id = CS8409_WARLOCK, .name = "warlock" }, + { .id = CS8409_CYBORG, .name = "cyborg" }, + {} +}; + +const struct hda_fixup cs8409_fixups[] = { + [CS8409_BULLSEYE] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_WARLOCK] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_CYBORG] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_FIXUPS] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs8409_cs42l42_fixups, + }, +}; diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 59cecbf1b54d..9d10eaa5d486 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -156,20 +156,20 @@ static void cs8409_set_i2c_dev_addr(struct hda_codec *codec, unsigned int addr) /** * cs8409_i2c_set_page - CS8409 I2C set page register. - * @codec: the codec instance + * @scodec: the codec instance * @i2c_reg: Page register * * Returns negative on error. */ -static int cs8409_i2c_set_page(struct hda_codec *codec, unsigned int i2c_reg) +static int cs8409_i2c_set_page(struct sub_codec *scodec, unsigned int i2c_reg) { - struct cs8409_spec *spec = codec->spec; + struct hda_codec *codec = scodec->codec; - if (spec->paged && (spec->last_page != (i2c_reg >> 8))) { + if (scodec->paged && (scodec->last_page != (i2c_reg >> 8))) { cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); if (cs8409_i2c_wait_complete(codec) < 0) return -EIO; - spec->last_page = i2c_reg >> 8; + scodec->last_page = i2c_reg >> 8; } return 0; @@ -177,31 +177,27 @@ static int cs8409_i2c_set_page(struct hda_codec *codec, unsigned int i2c_reg) /** * cs8409_i2c_read - CS8409 I2C Read. - * @codec: the codec instance - * @i2c_address: I2C Address + * @scodec: the codec instance * @addr: Register to read * - * CS8409 I2C Read. * Returns negative on error, otherwise returns read value in bits 0-7. */ -static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int addr) +static int cs8409_i2c_read(struct sub_codec *scodec, unsigned int addr) { + struct hda_codec *codec = scodec->codec; struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; unsigned int read_data; - if (spec->cs42l42_suspended) + if (scodec->suspended) return -EPERM; mutex_lock(&spec->i2c_mux); cs8409_enable_i2c_clock(codec); - cs8409_set_i2c_dev_addr(codec, i2c_address); + cs8409_set_i2c_dev_addr(codec, scodec->addr); - if (cs8409_i2c_set_page(codec, addr)) { - codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, addr); - return -EIO; - } + if (cs8409_i2c_set_page(scodec, addr)) + goto error; i2c_reg_data = (addr << 8) & 0x0ffff; cs8409_vendor_coef_set(codec, CS8409_I2C_QREAD, i2c_reg_data); @@ -216,34 +212,34 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un error: mutex_unlock(&spec->i2c_mux); - codec_err(codec, "%s() Failed 0x%02x : 0x%04x\n", __func__, i2c_address, addr); + codec_err(codec, "%s() Failed 0x%02x : 0x%04x\n", __func__, scodec->addr, addr); return -EIO; } /** * cs8409_i2c_bulk_read - CS8409 I2C Read Sequence. - * @codec: the codec instance + * @scodec: the codec instance * @seq: Register Sequence to read * @count: Number of registeres to read * * Returns negative on error, values are read into value element of cs8409_i2c_param sequence. */ -static int cs8409_i2c_bulk_read(struct hda_codec *codec, unsigned int i2c_address, - struct cs8409_i2c_param *seq, int count) +static int cs8409_i2c_bulk_read(struct sub_codec *scodec, struct cs8409_i2c_param *seq, int count) { + struct hda_codec *codec = scodec->codec; struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; int i; - if (spec->cs42l42_suspended) + if (scodec->suspended) return -EPERM; mutex_lock(&spec->i2c_mux); - cs8409_set_i2c_dev_addr(codec, i2c_address); + cs8409_set_i2c_dev_addr(codec, scodec->addr); for (i = 0; i < count; i++) { cs8409_enable_i2c_clock(codec); - if (cs8409_i2c_set_page(codec, seq[i].addr)) + if (cs8409_i2c_set_page(scodec, seq[i].addr)) goto error; i2c_reg_data = (seq[i].addr << 8) & 0x0ffff; @@ -261,39 +257,34 @@ static int cs8409_i2c_bulk_read(struct hda_codec *codec, unsigned int i2c_addres error: mutex_unlock(&spec->i2c_mux); - codec_err(codec, "I2C Bulk Write Failed 0x%02x\n", i2c_address); + codec_err(codec, "I2C Bulk Write Failed 0x%02x\n", scodec->addr); return -EIO; } /** * cs8409_i2c_write - CS8409 I2C Write. - * @codec: the codec instance - * @i2c_address: I2C Address + * @scodec: the codec instance * @addr: Register to write to * @value: Data to write * - * CS8409 I2C Write. * Returns negative on error, otherwise returns 0. */ -static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, unsigned int addr, - unsigned int value) +static int cs8409_i2c_write(struct sub_codec *scodec, unsigned int addr, unsigned int value) { + struct hda_codec *codec = scodec->codec; struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; - if (spec->cs42l42_suspended) + if (scodec->suspended) return -EPERM; mutex_lock(&spec->i2c_mux); cs8409_enable_i2c_clock(codec); - cs8409_set_i2c_dev_addr(codec, i2c_address); + cs8409_set_i2c_dev_addr(codec, scodec->addr); - if (cs8409_i2c_set_page(codec, addr)) { - codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, addr); - return -EIO; - } + if (cs8409_i2c_set_page(scodec, addr)) + goto error; i2c_reg_data = ((addr << 8) & 0x0ff00) | (value & 0x0ff); cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg_data); @@ -306,34 +297,35 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u error: mutex_unlock(&spec->i2c_mux); - codec_err(codec, "%s() Failed 0x%02x : 0x%04x\n", __func__, i2c_address, addr); + codec_err(codec, "%s() Failed 0x%02x : 0x%04x\n", __func__, scodec->addr, addr); return -EIO; } /** * cs8409_i2c_bulk_write - CS8409 I2C Write Sequence. - * @codec: the codec instance + * @scodec: the codec instance * @seq: Register Sequence to write * @count: Number of registeres to write * * Returns negative on error. */ -static int cs8409_i2c_bulk_write(struct hda_codec *codec, unsigned int i2c_address, - const struct cs8409_i2c_param *seq, int count) +static int cs8409_i2c_bulk_write(struct sub_codec *scodec, const struct cs8409_i2c_param *seq, + int count) { + struct hda_codec *codec = scodec->codec; struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; int i; - if (spec->cs42l42_suspended) + if (scodec->suspended) return -EPERM; mutex_lock(&spec->i2c_mux); - cs8409_set_i2c_dev_addr(codec, i2c_address); + cs8409_set_i2c_dev_addr(codec, scodec->addr); for (i = 0; i < count; i++) { cs8409_enable_i2c_clock(codec); - if (cs8409_i2c_set_page(codec, seq[i].addr)) + if (cs8409_i2c_set_page(scodec, seq[i].addr)) goto error; i2c_reg_data = ((seq[i].addr << 8) & 0x0ff00) | (seq[i].value & 0x0ff); @@ -349,7 +341,7 @@ static int cs8409_i2c_bulk_write(struct hda_codec *codec, unsigned int i2c_addre error: mutex_unlock(&spec->i2c_mux); - codec_err(codec, "I2C Bulk Write Failed 0x%02x\n", i2c_address); + codec_err(codec, "I2C Bulk Write Failed 0x%02x\n", scodec->addr); return -EIO; } @@ -442,6 +434,7 @@ int cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc { struct hda_codec *codec = snd_kcontrol_chip(kctrl); struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42 = spec->scodecs[get_amp_index(kctrl)]; int chs = get_amp_channels(kctrl); unsigned int ofs = get_amp_offset(kctrl); long *valp = uctrl->value.integer.value; @@ -449,13 +442,13 @@ int cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc switch (ofs) { case CS42L42_VOL_DAC: if (chs & BIT(0)) - *valp++ = spec->vol[ofs]; + *valp++ = cs42l42->vol[ofs]; if (chs & BIT(1)) - *valp = spec->vol[ofs+1]; + *valp = cs42l42->vol[ofs+1]; break; case CS42L42_VOL_ADC: if (chs & BIT(0)) - *valp = spec->vol[ofs]; + *valp = cs42l42->vol[ofs]; break; default: break; @@ -468,6 +461,7 @@ int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc { struct hda_codec *codec = snd_kcontrol_chip(kctrl); struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42 = spec->scodecs[get_amp_index(kctrl)]; int chs = get_amp_channels(kctrl); unsigned int ofs = get_amp_offset(kctrl); long *valp = uctrl->value.integer.value; @@ -475,23 +469,23 @@ int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc switch (ofs) { case CS42L42_VOL_DAC: if (chs & BIT(0)) { - spec->vol[ofs] = *valp; - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHA, - -(spec->vol[ofs]) & CS42L42_REG_HS_VOL_MASK); + cs42l42->vol[ofs] = *valp; + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, + -(cs42l42->vol[ofs]) & CS42L42_REG_HS_VOL_MASK); } if (chs & BIT(1)) { ofs++; valp++; - spec->vol[ofs] = *valp; - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHB, - -(spec->vol[ofs]) & CS42L42_REG_HS_VOL_MASK); + cs42l42->vol[ofs] = *valp; + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, + -(cs42l42->vol[ofs]) & CS42L42_REG_HS_VOL_MASK); } break; case CS42L42_VOL_ADC: if (chs & BIT(0)) { - spec->vol[ofs] = *valp; - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_AMIC_VOL, - spec->vol[ofs] & CS42L42_REG_AMIC_VOL_MASK); + cs42l42->vol[ofs] = *valp; + cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, + cs42l42->vol[ofs] & CS42L42_REG_AMIC_VOL_MASK); } break; default: @@ -502,54 +496,45 @@ int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc } /* Configure CS42L42 slave codec for jack autodetect */ -static void cs42l42_enable_jack_detect(struct hda_codec *codec) +static void cs42l42_enable_jack_detect(struct sub_codec *cs42l42) { - /* Set TIP_SENSE_EN for analog front-end of tip sense. - * Additionally set HSBIAS_SENSE_EN for some variants. - */ - if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_BULLSEYE) - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020); - else - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0); - + cs8409_i2c_write(cs42l42, 0x1b70, cs42l42->hsbias_hiz); /* Clear WAKE# */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C1); + cs8409_i2c_write(cs42l42, 0x1b71, 0x00C1); /* Wait ~2.5ms */ usleep_range(2500, 3000); /* Set mode WAKE# output follows the combination logic directly */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0); + cs8409_i2c_write(cs42l42, 0x1b71, 0x00C0); /* Clear interrupts status */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); + cs8409_i2c_read(cs42l42, 0x130f); /* Enable interrupt */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3); + cs8409_i2c_write(cs42l42, 0x1320, 0xF3); } /* Enable and run CS42L42 slave codec jack auto detect */ -static void cs42l42_run_jack_detect(struct hda_codec *codec) +static void cs42l42_run_jack_detect(struct sub_codec *cs42l42) { /* Clear interrupts */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xFF); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); - - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFD); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80); + cs8409_i2c_read(cs42l42, 0x1308); + cs8409_i2c_read(cs42l42, 0x1b77); + cs8409_i2c_write(cs42l42, 0x1320, 0xFF); + cs8409_i2c_read(cs42l42, 0x130f); + + cs8409_i2c_write(cs42l42, 0x1102, 0x87); + cs8409_i2c_write(cs42l42, 0x1f06, 0x86); + cs8409_i2c_write(cs42l42, 0x1b74, 0x07); + cs8409_i2c_write(cs42l42, 0x131b, 0xFD); + cs8409_i2c_write(cs42l42, 0x1120, 0x80); /* Wait ~110ms*/ usleep_range(110000, 200000); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0); + cs8409_i2c_write(cs42l42, 0x111f, 0x77); + cs8409_i2c_write(cs42l42, 0x1120, 0xc0); /* Wait ~10ms */ usleep_range(10000, 25000); - } -static int cs42l42_jack_unsol_event(struct hda_codec *codec) +static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42) { - struct cs8409_spec *spec = codec->spec; int status_changed = 0; int reg_cdc_status; int reg_hs_status; @@ -557,9 +542,9 @@ static int cs42l42_jack_unsol_event(struct hda_codec *codec) int type; /* Read jack detect status registers */ - reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); - reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124); - reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); + reg_cdc_status = cs8409_i2c_read(cs42l42, 0x1308); + reg_hs_status = cs8409_i2c_read(cs42l42, 0x1124); + reg_ts_status = cs8409_i2c_read(cs42l42, 0x130f); /* If status values are < 0, read error has occurred. */ if (reg_cdc_status < 0 || reg_hs_status < 0 || reg_ts_status < 0) @@ -569,45 +554,45 @@ static int cs42l42_jack_unsol_event(struct hda_codec *codec) if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) { /* Disable HSDET_AUTO_DONE */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF); + cs8409_i2c_write(cs42l42, 0x131b, 0xFF); type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1); /* CS42L42 reports optical jack as type 4 * We don't handle optical jack */ if (type != 4) { - if (!spec->cs42l42_hp_jack_in) { + if (!cs42l42->hp_jack_in) { status_changed = 1; - spec->cs42l42_hp_jack_in = 1; + cs42l42->hp_jack_in = 1; } /* type = 3 has no mic */ - if ((!spec->cs42l42_mic_jack_in) && (type != 3)) { + if ((!cs42l42->mic_jack_in) && (type != 3)) { status_changed = 1; - spec->cs42l42_mic_jack_in = 1; + cs42l42->mic_jack_in = 1; } } else { - if (spec->cs42l42_hp_jack_in || spec->cs42l42_mic_jack_in) { + if (cs42l42->hp_jack_in || cs42l42->mic_jack_in) { status_changed = 1; - spec->cs42l42_hp_jack_in = 0; - spec->cs42l42_mic_jack_in = 0; + cs42l42->hp_jack_in = 0; + cs42l42->mic_jack_in = 0; } } /* Re-Enable Tip Sense Interrupt */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3); + cs8409_i2c_write(cs42l42, 0x1320, 0xF3); } else { /* TIP_SENSE INSERT/REMOVE */ switch (reg_ts_status) { case CS42L42_JACK_INSERTED: - cs42l42_run_jack_detect(codec); + cs42l42_run_jack_detect(cs42l42); break; case CS42L42_JACK_REMOVED: - if (spec->cs42l42_hp_jack_in || spec->cs42l42_mic_jack_in) { + if (cs42l42->hp_jack_in || cs42l42->mic_jack_in) { status_changed = 1; - spec->cs42l42_hp_jack_in = 0; - spec->cs42l42_mic_jack_in = 0; + cs42l42->hp_jack_in = 0; + cs42l42->mic_jack_in = 0; } break; @@ -621,10 +606,8 @@ static int cs42l42_jack_unsol_event(struct hda_codec *codec) return status_changed; } -/* Assert/release RTS# line to CS42L42 */ -static void cs42l42_reset(struct hda_codec *codec) +static void cs42l42_resume(struct sub_codec *cs42l42) { - struct cs8409_spec *spec = codec->spec; struct cs8409_i2c_param irq_regs[] = { { 0x1308, 0x00 }, { 0x1309, 0x00 }, @@ -632,27 +615,35 @@ static void cs42l42_reset(struct hda_codec *codec) { 0x130F, 0x00 }, }; - /* Assert RTS# line */ - snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0); - /* wait ~10ms */ - usleep_range(10000, 15000); - /* Release RTS# line */ - snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, CS8409_CS42L42_RESET); - /* wait ~10ms */ - usleep_range(10000, 15000); + cs42l42->suspended = 0; - spec->cs42l42_suspended = 0; - spec->last_page = 0; + /* Initialize CS42L42 companion codec */ + cs8409_i2c_bulk_write(cs42l42, cs42l42->init_seq, cs42l42->init_seq_num); /* Clear interrupts, by reading interrupt status registers */ - cs8409_i2c_bulk_read(codec, CS42L42_I2C_ADDR, irq_regs, ARRAY_SIZE(irq_regs)); + cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs)); + + /* Restore Volumes after Resume */ + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, + -(cs42l42->vol[1]) & CS42L42_REG_HS_VOL_MASK); + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, + -(cs42l42->vol[2]) & CS42L42_REG_HS_VOL_MASK); + cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, + cs42l42->vol[0] & CS42L42_REG_AMIC_VOL_MASK); + + if (cs42l42->full_scale_vol) + cs8409_i2c_write(cs42l42, 0x2001, 0x01); + + cs42l42_enable_jack_detect(cs42l42); } #ifdef CONFIG_PM -static void cs42l42_suspend(struct hda_codec *codec) +static void cs42l42_suspend(struct sub_codec *cs42l42) { /* Power down CS42L42 ASP/EQ/MIX/HP */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe); + cs8409_i2c_write(cs42l42, 0x1101, 0xfe); + cs42l42->suspended = 1; + cs42l42->last_page = 0; } #endif @@ -676,9 +667,10 @@ static void cs8409_free(struct hda_codec *codec) * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers * and then notify status via generic snd_hda_jack_unsol_event() call. */ -static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) +static void cs8409_cs42l42_jack_unsol_event(struct hda_codec *codec, unsigned int res) { struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42 = spec->scodecs[CS8409_CODEC0]; struct hda_jack_tbl *jk; /* jack_unsol_event() will be called every time gpio line changing state. @@ -686,12 +678,12 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) * registers in previous cs8409_jack_unsol_event() call. * We don't need to handle this event, ignoring... */ - if (res & CS8409_CS42L42_INT) + if (res & cs42l42->irq_mask) return; - if (cs42l42_jack_unsol_event(codec)) { + if (cs42l42_jack_unsol_event(cs42l42)) { snd_hda_set_pin_ctl(codec, CS8409_CS42L42_SPK_PIN_NID, - spec->cs42l42_hp_jack_in ? 0 : PIN_OUT); + cs42l42->hp_jack_in ? 0 : PIN_OUT); /* Report jack*/ jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_HP_PIN_NID, 0); if (jk) @@ -713,9 +705,7 @@ static int cs8409_cs42l42_suspend(struct hda_codec *codec) cs8409_enable_ur(codec, 0); - cs42l42_suspend(codec); - - spec->cs42l42_suspended = 1; + cs42l42_suspend(spec->scodecs[CS8409_CODEC0]); /* Assert CS42L42 RTS# line */ snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0); @@ -734,6 +724,7 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) const struct cs8409_cir_param *seq = cs8409_cs42l42_hw_cfg; const struct cs8409_cir_param *seq_bullseye = cs8409_cs42l42_bullseye_atn; struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42 = spec->scodecs[CS8409_CODEC0]; if (spec->gpio_mask) { snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_MASK, @@ -747,33 +738,21 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) for (; seq->nid; seq++) cs8409_vendor_coef_set(codec, seq->cir, seq->coeff); - if (codec->fixup_id == CS8409_BULLSEYE) + if (codec->fixup_id == CS8409_BULLSEYE) { for (; seq_bullseye->nid; seq_bullseye++) cs8409_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff); + } - /* Reset CS42L42 */ - cs42l42_reset(codec); - - /* Initialise CS42L42 companion codec */ - cs8409_i2c_bulk_write(codec, CS42L42_I2C_ADDR, cs42l42_init_reg_seq, - CS42L42_INIT_REG_SEQ_SIZE); - - if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) { - /* FULL_SCALE_VOL = 0 for Warlock / Cyborg */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01); - /* DMIC1_MO=00b, DMIC1/2_SR=1 */ + /* DMIC1_MO=00b, DMIC1/2_SR=1 */ + if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) cs8409_vendor_coef_set(codec, 0x09, 0x0003); - } - /* Restore Volumes after Resume */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHA, - -(spec->vol[1]) & CS42L42_REG_HS_VOL_MASK); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_HS_VOL_CHB, - -(spec->vol[2]) & CS42L42_REG_HS_VOL_MASK); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS42L42_REG_AMIC_VOL, - spec->vol[0] & CS42L42_REG_AMIC_VOL_MASK); + /* Release RTS# line */ + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, CS8409_CS42L42_RESET); + /* wait ~10ms */ + usleep_range(10000, 15000); - cs42l42_enable_jack_detect(codec); + cs42l42_resume(cs42l42); /* Enable Unsolicited Response */ cs8409_enable_ur(codec, 1); @@ -784,7 +763,7 @@ static const struct hda_codec_ops cs8409_cs42l42_patch_ops = { .build_pcms = snd_hda_gen_build_pcms, .init = cs8409_init, .free = cs8409_free, - .unsol_event = cs8409_jack_unsol_event, + .unsol_event = cs8409_cs42l42_jack_unsol_event, #ifdef CONFIG_PM .suspend = cs8409_cs42l42_suspend, #endif @@ -795,6 +774,7 @@ static int cs8409_cs42l42_exec_verb(struct hdac_device *dev, unsigned int cmd, u { struct hda_codec *codec = container_of(dev, struct hda_codec, core); struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42 = spec->scodecs[CS8409_CODEC0]; unsigned int nid = ((cmd >> 20) & 0x07f); unsigned int verb = ((cmd >> 8) & 0x0fff); @@ -807,18 +787,16 @@ static int cs8409_cs42l42_exec_verb(struct hdac_device *dev, unsigned int cmd, u switch (nid) { case CS8409_CS42L42_HP_PIN_NID: if (verb == AC_VERB_GET_PIN_SENSE) { - *res = (spec->cs42l42_hp_jack_in) ? AC_PINSENSE_PRESENCE : 0; + *res = (cs42l42->hp_jack_in) ? AC_PINSENSE_PRESENCE : 0; return 0; } break; - case CS8409_CS42L42_AMIC_PIN_NID: if (verb == AC_VERB_GET_PIN_SENSE) { - *res = (spec->cs42l42_mic_jack_in) ? AC_PINSENSE_PRESENCE : 0; + *res = (cs42l42->mic_jack_in) ? AC_PINSENSE_PRESENCE : 0; return 0; } break; - default: break; } @@ -837,6 +815,9 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, spec->exec_verb = codec->core.exec_verb; codec->core.exec_verb = cs8409_cs42l42_exec_verb; + spec->scodecs[CS8409_CODEC0] = &cs8409_cs42l42_codec; + spec->num_scodecs = 1; + spec->scodecs[CS8409_CODEC0]->codec = codec; codec->patch_ops = cs8409_cs42l42_patch_ops; spec->gen.suppress_auto_mute = 1; @@ -844,21 +825,38 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, spec->gen.suppress_vmaster = 1; /* GPIO 5 out, 3,4 in */ - spec->gpio_dir = CS8409_CS42L42_RESET; + spec->gpio_dir = spec->scodecs[CS8409_CODEC0]->reset_gpio; spec->gpio_data = 0; spec->gpio_mask = 0x03f; - spec->cs42l42_hp_jack_in = 0; - spec->cs42l42_mic_jack_in = 0; - spec->cs42l42_suspended = 1; - spec->paged = 1; - /* Basic initial sequence for specific hw configuration */ snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs); cs8409_fix_caps(codec, CS8409_CS42L42_HP_PIN_NID); cs8409_fix_caps(codec, CS8409_CS42L42_AMIC_PIN_NID); + /* Set TIP_SENSE_EN for analog front-end of tip sense. + * Additionally set HSBIAS_SENSE_EN and Full Scale volume for some variants. + */ + switch (codec->fixup_id) { + case CS8409_WARLOCK: + spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; + spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1; + break; + case CS8409_BULLSEYE: + spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0020; + spec->scodecs[CS8409_CODEC0]->full_scale_vol = 0; + break; + case CS8409_CYBORG: + spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x00a0; + spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1; + break; + default: + spec->scodecs[CS8409_CODEC0]->hsbias_hiz = 0x0003; + spec->scodecs[CS8409_CODEC0]->full_scale_vol = 1; + break; + } + break; case HDA_FIXUP_ACT_PROBE: /* Set initial DMIC volume to -26 dB */ @@ -882,7 +880,7 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, * been already plugged in. * Run immediately after init. */ - cs42l42_run_jack_detect(codec); + cs42l42_run_jack_detect(spec->scodecs[CS8409_CODEC0]); usleep_range(100000, 150000); break; default: diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index ac68cca2bc11..817df295d594 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -216,8 +216,8 @@ enum cs8409_coefficient_index_registers { /* CS42L42 Specific Definitions */ +#define CS8409_MAX_CODECS 8 #define CS42L42_VOLUMES (4U) - #define CS42L42_HP_VOL_REAL_MIN (-63) #define CS42L42_HP_VOL_REAL_MAX (0) #define CS42L42_AMIC_VOL_REAL_MIN (-97) @@ -243,8 +243,6 @@ enum cs8409_coefficient_index_registers { #define CS8409_CS42L42_DMIC_PIN_NID CS8409_PIN_DMIC1_IN #define CS8409_CS42L42_DMIC_ADC_PIN_NID CS8409_PIN_DMIC1 -#define CS42L42_INIT_REG_SEQ_SIZE 59 - enum { CS8409_BULLSEYE, CS8409_WARLOCK, @@ -252,6 +250,10 @@ enum { CS8409_FIXUPS, }; +enum { + CS8409_CODEC0, +}; + enum { CS42L42_VOL_ADC, CS42L42_VOL_DAC, @@ -268,25 +270,40 @@ struct cs8409_cir_param { unsigned int coeff; }; +struct sub_codec { + struct hda_codec *codec; + unsigned int addr; + unsigned int reset_gpio; + unsigned int irq_mask; + const struct cs8409_i2c_param *init_seq; + unsigned int init_seq_num; + + unsigned int hp_jack_in:1; + unsigned int mic_jack_in:1; + unsigned int suspended:1; + unsigned int paged:1; + unsigned int last_page; + unsigned int hsbias_hiz; + unsigned int full_scale_vol:1; + + s8 vol[CS42L42_VOLUMES]; +}; + struct cs8409_spec { struct hda_gen_spec gen; struct hda_codec *codec; + struct sub_codec *scodecs[CS8409_MAX_CODECS]; + unsigned int num_scodecs; + unsigned int gpio_mask; unsigned int gpio_dir; unsigned int gpio_data; - unsigned int cs42l42_hp_jack_in:1; - unsigned int cs42l42_mic_jack_in:1; - unsigned int cs42l42_suspended:1; - s8 vol[CS42L42_VOLUMES]; - struct mutex i2c_mux; unsigned int i2c_clck_enabled; unsigned int dev_addr; struct delayed_work i2c_clk_work; - unsigned int paged; - unsigned int last_page; /* verb exec op override */ int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, unsigned int flags, @@ -305,9 +322,9 @@ extern const struct hda_model_fixup cs8409_models[]; extern const struct hda_fixup cs8409_fixups[]; extern const struct hda_verb cs8409_cs42l42_init_verbs[]; extern const struct hda_pintbl cs8409_cs42l42_pincfgs[]; -extern const struct cs8409_i2c_param cs42l42_init_reg_seq[CS42L42_INIT_REG_SEQ_SIZE]; extern const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[]; extern const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[]; +extern struct sub_codec cs8409_cs42l42_codec; void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action); From patchwork Wed Jul 28 13:44:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405899 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05F38C4338F for ; Wed, 28 Jul 2021 13:55:08 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8115560F5E for ; Wed, 28 Jul 2021 13:55:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 8115560F5E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 2E87F1F91; Wed, 28 Jul 2021 15:54:16 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 2E87F1F91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480506; bh=+tCVyoWtkeiliUC3S6ZH+4u1Kds86Wy29VjmdZJP3ME=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=AxWxCEQlP/77FFh/HVwTBgTpB/nVCRLvnfRnCFhisi5zC/hO04+U9d3k/Nnp0W28Q FJUjyubRB5KFzbRLTMOZ+1Q1a0Zaht8Xwa0ww9iXq7AnQuCTCIZ/HTbA92sxXTxHXm inqvlPDdc3C73TWqmrML5LNaoDsciZ86T6srRX+4= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 014F8F805C8; Wed, 28 Jul 2021 15:45:32 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 35380F805A1; Wed, 28 Jul 2021 15:45:24 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id BF014F804E4 for ; Wed, 28 Jul 2021 15:44:44 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BF014F804E4 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="ima5V2sX" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUr0014335; Wed, 28 Jul 2021 08:44:42 -0500 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=PNdg/iTwvrhGZ8Mzw2a+J04qei/z4cW0yJCNNtld2Oc=; b=ima5V2sXyyaDuEAYzNd2zC09gcguHWf5UMxNic6Q85LtiGPMopDm4rJCY1hPo5N1t27T ire+HROor63myCe50ywKzZ9RGYDxJgMKCEoWZvPMNjEaaGzb52zZdY5xmuUTgNSloR7Y 2JFr/pCLXbvdWrftKDrVwUspGYFSPlhEJ4ZYopMy7ae+UqjvgG7JBM3Z5AVt6KvrP817 pez+3rxvwur80EzUHWa7BmRy9sHfpJlk3BQkkAOuVMNPSTXGk6Ncv1ftZBoYnyCkEVA6 JpxzgEdPxHzYAU4kJ7+sm7XWvcs+TmmiM0grQv7YeljGNDCK4rDNnaqdEmAbAoSL2+3U lQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-14 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:42 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:36 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:36 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id D38D0478; Wed, 28 Jul 2021 13:44:35 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 19/27] ALSA: hda/cs8409: Support multiple sub_codecs for Suspend/Resume/Unsol events Date: Wed, 28 Jul 2021 14:44:00 +0100 Message-ID: <20210728134408.369396-20-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: 59ei803UaRgttdQpLIToxYryrn8o8Tse X-Proofpoint-GUID: 59ei803UaRgttdQpLIToxYryrn8o8Tse X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 41 ++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 9d10eaa5d486..d5001f46224f 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -367,16 +367,21 @@ static int cs8409_build_controls(struct hda_codec *codec) return 0; } -/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */ +/* Enable/Disable Unsolicited Response */ static void cs8409_enable_ur(struct hda_codec *codec, int flag) { - /* GPIO4 INT# and GPIO3 WAKE# */ + struct cs8409_spec *spec = codec->spec; + unsigned int ur_gpios = 0; + int i; + + for (i = 0; i < spec->num_scodecs; i++) + ur_gpios |= spec->scodecs[i]->irq_mask; + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, - flag ? CS8409_CS42L42_INT : 0); + flag ? ur_gpios : 0); snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_UNSOLICITED_ENABLE, flag ? AC_UNSOL_ENABLED : 0); - } static void cs8409_fix_caps(struct hda_codec *codec, unsigned int nid) @@ -608,6 +613,8 @@ static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42) static void cs42l42_resume(struct sub_codec *cs42l42) { + struct hda_codec *codec = cs42l42->codec; + unsigned int gpio_data; struct cs8409_i2c_param irq_regs[] = { { 0x1308, 0x00 }, { 0x1309, 0x00 }, @@ -615,6 +622,12 @@ static void cs42l42_resume(struct sub_codec *cs42l42) { 0x130F, 0x00 }, }; + /* Bring CS42L42 out of Reset */ + gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); + gpio_data |= cs42l42->reset_gpio; + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, gpio_data); + usleep_range(10000, 15000); + cs42l42->suspended = 0; /* Initialize CS42L42 companion codec */ @@ -640,10 +653,18 @@ static void cs42l42_resume(struct sub_codec *cs42l42) #ifdef CONFIG_PM static void cs42l42_suspend(struct sub_codec *cs42l42) { + struct hda_codec *codec = cs42l42->codec; + unsigned int gpio_data; + /* Power down CS42L42 ASP/EQ/MIX/HP */ cs8409_i2c_write(cs42l42, 0x1101, 0xfe); cs42l42->suspended = 1; cs42l42->last_page = 0; + + /* Put CS42L42 into Reset */ + gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); + gpio_data &= ~cs42l42->reset_gpio; + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, gpio_data); } #endif @@ -702,13 +723,12 @@ static void cs8409_cs42l42_jack_unsol_event(struct hda_codec *codec, unsigned in static int cs8409_cs42l42_suspend(struct hda_codec *codec) { struct cs8409_spec *spec = codec->spec; + int i; cs8409_enable_ur(codec, 0); - cs42l42_suspend(spec->scodecs[CS8409_CODEC0]); - - /* Assert CS42L42 RTS# line */ - snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, 0); + for (i = 0; i < spec->num_scodecs; i++) + cs42l42_suspend(spec->scodecs[i]); snd_hda_shutup_pins(codec); @@ -747,11 +767,6 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) cs8409_vendor_coef_set(codec, 0x09, 0x0003); - /* Release RTS# line */ - snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, CS8409_CS42L42_RESET); - /* wait ~10ms */ - usleep_range(10000, 15000); - cs42l42_resume(cs42l42); /* Enable Unsolicited Response */ From patchwork Wed Jul 28 13:44:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405885 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A5B9C4320A for ; Wed, 28 Jul 2021 13:52:34 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D7B4760F45 for ; Wed, 28 Jul 2021 13:52:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org D7B4760F45 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 771101F1C; Wed, 28 Jul 2021 15:51:42 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 771101F1C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480352; bh=ZYQcw9X1U/m716CkebWUKFWVwXgqBfH+ZRj4GoqJqf0=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=PUnWfi4LOe3Hp19MIXPtmooWBlnbrnkIkujHDodcjLWaUHQOoxP11m7KN9wcuKA8k macJzCJ1qmdQVYbQhqwQ7wHKEqqij4Ii0yYEuWhM0GvNmazWVNdRKNz0hzY0LukLVf nIClllchudt5beU2Rbhm/JD/VMWjyDoEREsTEA64= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 17253F804FB; Wed, 28 Jul 2021 15:45:24 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 499D1F80571; Wed, 28 Jul 2021 15:45:15 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 3E1C3F804E6 for ; Wed, 28 Jul 2021 15:44:40 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 3E1C3F804E6 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="HVzM35D/" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S674iT029982; Wed, 28 Jul 2021 08:44:38 -0500 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=ZGgnWVNrqqnhEmNf6UFCsoATb7uvc3qFnlWIgEoQFRI=; b=HVzM35D/8mLfVfHObIJK4m21MmWiAV49dBPi1iUNI7w9hF0bmpyZSp93+zL3DjFr2o7b tJtOLsGCoDn8IMk3Zzlid8jtyPRIkcL5KzeNsiBM5+Kut3FtVXf+TAIDKNAPOKYR7KuC 7eRiOmoOkN+bZDDzJinBWxQpXnEoODOZFgxsWYzP+LlckOxC5sR8lH/NB9SFqH5IKj0+ cQWSmSTelLSPcUS2lIHVGJb6oXwQjZulIXZqvEP3iNsZTFZRu7Iq3z1M5oYQeJeRuY2P hxbj/fQVlQ/BHhriY0AnKhs/Wpl1T80xD84oLD/Y7fw4mLTyAaGMe3rxyMCafJDLvHwo 6A== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a31m2resc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:38 -0500 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.2242.4; Wed, 28 Jul 2021 14:44:36 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:36 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 2F51845D; Wed, 28 Jul 2021 13:44:36 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 20/27] ALSA: hda/cs8409: Add Support to disable jack type detection for CS42L42 Date: Wed, 28 Jul 2021 14:44:01 +0100 Message-ID: <20210728134408.369396-21-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: 9NHHw5W_5nrs7lrDUYXYSgBTwXOrkyAv X-Proofpoint-ORIG-GUID: 9NHHw5W_5nrs7lrDUYXYSgBTwXOrkyAv X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 suspectscore=0 lowpriorityscore=0 mlxlogscore=999 phishscore=0 spamscore=0 clxscore=1015 mlxscore=0 adultscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Some hardware configurations do not support jack type detection. Instead, for those configurations, only tip detection is supported. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 1 + sound/pci/hda/patch_cs8409.c | 72 ++++++++++++++++------------- sound/pci/hda/patch_cs8409.h | 1 + 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index 117c70536ff0..be9feb84aaa2 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -246,6 +246,7 @@ struct sub_codec cs8409_cs42l42_codec = { .mic_jack_in = 0, .paged = 1, .suspended = 1, + .no_type_dect = 0, }; /****************************************************************************** diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index d5001f46224f..cee9d5c506ed 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -538,6 +538,39 @@ static void cs42l42_run_jack_detect(struct sub_codec *cs42l42) usleep_range(10000, 25000); } +static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ts_status) +{ + int status_changed = 0; + + /* TIP_SENSE INSERT/REMOVE */ + switch (reg_ts_status) { + case CS42L42_JACK_INSERTED: + if (!cs42l42->hp_jack_in) { + if (cs42l42->no_type_dect) { + status_changed = 1; + cs42l42->hp_jack_in = 1; + cs42l42->mic_jack_in = 0; + } else { + cs42l42_run_jack_detect(cs42l42); + } + } + break; + + case CS42L42_JACK_REMOVED: + if (cs42l42->hp_jack_in || cs42l42->mic_jack_in) { + status_changed = 1; + cs42l42->hp_jack_in = 0; + cs42l42->mic_jack_in = 0; + } + break; + default: + /* jack in transition */ + break; + } + + return status_changed; +} + static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42) { int status_changed = 0; @@ -562,10 +595,13 @@ static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42) cs8409_i2c_write(cs42l42, 0x131b, 0xFF); type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1); - /* CS42L42 reports optical jack as type 4 - * We don't handle optical jack - */ - if (type != 4) { + + if (cs42l42->no_type_dect) { + status_changed = cs42l42_handle_tip_sense(cs42l42, reg_ts_status); + } else if (type == 4) { + /* Type 4 not supported */ + status_changed = cs42l42_handle_tip_sense(cs42l42, CS42L42_JACK_REMOVED); + } else { if (!cs42l42->hp_jack_in) { status_changed = 1; cs42l42->hp_jack_in = 1; @@ -575,37 +611,11 @@ static int cs42l42_jack_unsol_event(struct sub_codec *cs42l42) status_changed = 1; cs42l42->mic_jack_in = 1; } - } else { - if (cs42l42->hp_jack_in || cs42l42->mic_jack_in) { - status_changed = 1; - cs42l42->hp_jack_in = 0; - cs42l42->mic_jack_in = 0; - } } - /* Re-Enable Tip Sense Interrupt */ cs8409_i2c_write(cs42l42, 0x1320, 0xF3); - } else { - /* TIP_SENSE INSERT/REMOVE */ - switch (reg_ts_status) { - case CS42L42_JACK_INSERTED: - cs42l42_run_jack_detect(cs42l42); - break; - - case CS42L42_JACK_REMOVED: - if (cs42l42->hp_jack_in || cs42l42->mic_jack_in) { - status_changed = 1; - cs42l42->hp_jack_in = 0; - cs42l42->mic_jack_in = 0; - } - break; - - default: - /* jack in transition */ - status_changed = 0; - break; - } + status_changed = cs42l42_handle_tip_sense(cs42l42, reg_ts_status); } return status_changed; diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 817df295d594..a105c3c9023d 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -285,6 +285,7 @@ struct sub_codec { unsigned int last_page; unsigned int hsbias_hiz; unsigned int full_scale_vol:1; + unsigned int no_type_dect:1; s8 vol[CS42L42_VOLUMES]; }; From patchwork Wed Jul 28 13:44:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405901 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A36F3C4338F for ; Wed, 28 Jul 2021 13:55:26 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2438D6023E for ; Wed, 28 Jul 2021 13:55:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2438D6023E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id C07C31FA1; Wed, 28 Jul 2021 15:54:34 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C07C31FA1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480524; bh=ar5ZMNIKleoNxJhQZ5XG5SunDiZrB9J5E2XQ2EDK1RQ=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=WE5rIxQ0ZmQrVhPnjnHO0SRFqBSZvsINFeMXlY8Q3Ux49RMPfDtks5y/o1BMjDf8w Q545igRjK1Tvj+oWBJTfTqKQWUu1hOdu/15eQ40Vw+qOdjACyFWuSymMlqtGOtsxtH y3u0ZWwg6Wre79EkEJZSDZVl4M6LwhUjffheMzLk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B90BEF805D6; Wed, 28 Jul 2021 15:45:32 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id ACB7EF805A0; Wed, 28 Jul 2021 15:45:24 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 17801F804F3 for ; Wed, 28 Jul 2021 15:44:44 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 17801F804F3 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="in4ujsNs" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUr1014335; Wed, 28 Jul 2021 08:44:43 -0500 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=ypyIuCtU5UUfnesJBDrJd7erQjABNEEIgMqprdvZ4gU=; b=in4ujsNsUAy1XVbefCluQhBU0o/gXKELHJxSpf4sJ+BzQuTiZf4UQbCOKwUNGMDt/nrk OsPtKkew4eGoW6ucGDSbFJwHEtG+FifMTv2DCSp5hrwDW9eRp4DXAvbocxHgxSOkGvk2 BSvX1e1qCu4yW1Z+U/Xc2vl7yLdrclAMWYUwyaZU67sH+tm5iyhcDRg2l2jPX6jHmQXE slhNVyFmjOMPTAIpOb/bOuzDoZJZPQyn8ntfqxVimmeRnjFlMD0tGON3qmZuCdWKnd2e 8JsxOvIigBL6hE0ncxVq1JOCeidMWhVLx6jM7kqvoV9OrIt6C4OHiYmW2/+rTxO6uDp/ Aw== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-15 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:42 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:36 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:36 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 81C452BA; Wed, 28 Jul 2021 13:44:36 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 21/27] ALSA: hda/cs8409: Add support for dolphin Date: Wed, 28 Jul 2021 14:44:02 +0100 Message-ID: <20210728134408.369396-22-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: DbxsdzgIRGys4a2XWQZ8vIbtjzHEH-v2 X-Proofpoint-GUID: DbxsdzgIRGys4a2XWQZ8vIbtjzHEH-v2 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Lucas Tanure , Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Lucas Tanure Dolphin devices have CS8409 HDA Bridge connected to two CS42L42 codecs. Codec 1 supports Headphone and Headset Mic. Codec 2 supports Line Out. Features: - Front and Read Jacks appear as separate jacks; Removal or connection of on jack should not affect the connection of the other. - Front Jack only shows up on jack detection. - Rear Jack is Phantom Jack. - Separate Volume Controls for each Jack Signed-off-by: Stefan Binding Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Changes in v2: Fixed sparse warnings : Reported-by: kernel test robot sound/pci/hda/patch_cs8409.c:1061:59: sparse: sparse: Using plain integer as NULL pointer --- sound/pci/hda/patch_cs8409-tables.c | 220 ++++++++++++++++++++++++++++ sound/pci/hda/patch_cs8409.c | 196 +++++++++++++++++++++++++ sound/pci/hda/patch_cs8409.h | 24 +++ 3 files changed, 440 insertions(+) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index be9feb84aaa2..6453a7ec3856 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -249,6 +249,210 @@ struct sub_codec cs8409_cs42l42_codec = { .no_type_dect = 0, }; +/****************************************************************************** + * Dolphin Specific Arrays + * CS8409/ 2 X CS42L42 + ******************************************************************************/ + +const struct hda_verb dolphin_init_verbs[] = { + { 0x01, AC_VERB_SET_GPIO_WAKE_MASK, DOLPHIN_WAKE }, /* WAKE from GPIO 0,4 */ + { CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_STATE, 0x0001 }, /* Enable VPW processing */ + { CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_COEF_INDEX, 0x0002 }, /* Configure GPIO 6,7 */ + { CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_COEF, 0x0080 }, /* I2C mode */ + { CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_COEF_INDEX, 0x005b }, /* Set I2C bus speed */ + { CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_COEF, 0x0200 }, /* 100kHz I2C_STO = 2 */ + {} /* terminator */ +}; + +const struct hda_pintbl dolphin_pincfgs[] = { + { 0x24, 0x022210f0 }, /* ASP-1-TX-A */ + { 0x25, 0x010240f0 }, /* ASP-1-TX-B */ + { 0x34, 0x02a21050 }, /* ASP-1-RX */ + {} /* terminator */ +}; + +/* Vendor specific HW configuration for CS42L42 */ +static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = { + { 0x1010, 0xB0 }, + { 0x1D01, 0x00 }, + { 0x1D02, 0x06 }, + { 0x1D03, 0x00 }, + { 0x1107, 0x01 }, + { 0x1009, 0x02 }, + { 0x1007, 0x03 }, + { 0x1201, 0x00 }, + { 0x1208, 0x13 }, + { 0x1205, 0xFF }, + { 0x1206, 0x00 }, + { 0x1207, 0x20 }, + { 0x1202, 0x0D }, + { 0x2A02, 0x02 }, + { 0x2A03, 0x00 }, + { 0x2A04, 0x00 }, + { 0x2A05, 0x02 }, + { 0x2A06, 0x00 }, + { 0x2A07, 0x20 }, + { 0x2A01, 0x0C }, + { 0x2902, 0x01 }, + { 0x2903, 0x02 }, + { 0x2904, 0x00 }, + { 0x2905, 0x00 }, + { 0x2901, 0x01 }, + { 0x1101, 0x0A }, + { 0x1102, 0x84 }, + { 0x2301, 0x00 }, + { 0x2303, 0x00 }, + { 0x2302, 0x3f }, + { 0x2001, 0x03 }, + { 0x1B75, 0xB6 }, + { 0x1B73, 0xC2 }, + { 0x1129, 0x01 }, + { 0x1121, 0xF3 }, + { 0x1103, 0x20 }, + { 0x1105, 0x00 }, + { 0x1112, 0x00 }, + { 0x1113, 0x80 }, + { 0x1C03, 0xC0 }, + { 0x1101, 0x02 }, + { 0x1316, 0xff }, + { 0x1317, 0xff }, + { 0x1318, 0xff }, + { 0x1319, 0xff }, + { 0x131a, 0xff }, + { 0x131b, 0xff }, + { 0x131c, 0xff }, + { 0x131e, 0xff }, + { 0x131f, 0xff }, + { 0x1320, 0xff }, + { 0x1b79, 0xff }, + { 0x1b7a, 0xff } +}; + +static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { + { 0x1010, 0xB0 }, + { 0x1D01, 0x00 }, + { 0x1D02, 0x06 }, + { 0x1D03, 0x00 }, + { 0x1107, 0x01 }, + { 0x1009, 0x02 }, + { 0x1007, 0x03 }, + { 0x1201, 0x00 }, + { 0x1208, 0x13 }, + { 0x1205, 0xFF }, + { 0x1206, 0x00 }, + { 0x1207, 0x20 }, + { 0x1202, 0x0D }, + { 0x2A02, 0x02 }, + { 0x2A03, 0x00 }, + { 0x2A04, 0x80 }, + { 0x2A05, 0x02 }, + { 0x2A06, 0x00 }, + { 0x2A07, 0xA0 }, + { 0x2A01, 0x0C }, + { 0x2902, 0x00 }, + { 0x2903, 0x02 }, + { 0x2904, 0x00 }, + { 0x2905, 0x00 }, + { 0x2901, 0x00 }, + { 0x1101, 0x0E }, + { 0x1102, 0x84 }, + { 0x2301, 0x00 }, + { 0x2303, 0x00 }, + { 0x2302, 0x3f }, + { 0x2001, 0x03 }, + { 0x1B75, 0xB6 }, + { 0x1B73, 0xC2 }, + { 0x1129, 0x01 }, + { 0x1121, 0xF3 }, + { 0x1103, 0x20 }, + { 0x1105, 0x00 }, + { 0x1112, 0x00 }, + { 0x1113, 0x80 }, + { 0x1C03, 0xC0 }, + { 0x1101, 0x02 }, + { 0x1316, 0xff }, + { 0x1317, 0xff }, + { 0x1318, 0xff }, + { 0x1319, 0xff }, + { 0x131a, 0xff }, + { 0x131b, 0xff }, + { 0x131c, 0xff }, + { 0x131e, 0xff }, + { 0x131f, 0xff }, + { 0x1320, 0xff }, + { 0x1b79, 0xff }, + { 0x1b7a, 0xff } +}; + +/* Vendor specific hw configuration for CS8409 */ +const struct cs8409_cir_param dolphin_hw_cfg[] = { + /* +PLL1/2_EN, +I2C_EN */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG1, 0xb008 }, + /* ASP1_EN=0, ASP1_STP=1 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG2, 0x0002 }, + /* ASP1/2_BUS_IDLE=10, +GPIO_I2C */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG3, 0x0a80 }, + /* ASP1.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ + { CS8409_PIN_VENDOR_WIDGET, ASP1_A_TX_CTRL1, 0x0800 }, + /* ASP1.A: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=32 */ + { CS8409_PIN_VENDOR_WIDGET, ASP1_A_TX_CTRL2, 0x0820 }, + /* ASP1.B: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=128 */ + { CS8409_PIN_VENDOR_WIDGET, ASP1_B_TX_CTRL1, 0x0880 }, + /* ASP1.B: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=160 */ + { CS8409_PIN_VENDOR_WIDGET, ASP1_B_TX_CTRL2, 0x08a0 }, + /* ASP1.A: RX.LAP=0, RX.LSZ=24 bits, RX.LCS=0 */ + { CS8409_PIN_VENDOR_WIDGET, ASP1_A_RX_CTRL1, 0x0800 }, + /* ASP1.A: RX.RAP=0, RX.RSZ=24 bits, RX.RCS=0 */ + { CS8409_PIN_VENDOR_WIDGET, ASP1_A_RX_CTRL2, 0x0800 }, + /* ASP1: LCHI = 00h */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL1, 0x8000 }, + /* ASP1: MC/SC_SRCSEL=PLL1, LCPR=FFh */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL2, 0x28ff }, + /* ASP1: MCEN=0, FSD=011, SCPOL_IN/OUT=0, SCDIV=1:4 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL3, 0x0062 }, + /* ASP1/2_BEEP=0 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_BEEP_CFG, 0x0000 }, + /* ASP1_EN=1, ASP1_STP=1 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG2, 0x0022 }, + /* -PLL2_EN */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG1, 0x9008 }, + /* ASP1_xxx_EN=1, ASP1_MCLK_EN=0 */ + { CS8409_PIN_VENDOR_WIDGET, CS8409_PAD_CFG_SLW_RATE_CTRL, 0x5400 }, + /* test mode on */ + { CS8409_PIN_VENDOR_WIDGET, 0xc0, 0x9999 }, + /* GPIO hysteresis = 30 us */ + { CS8409_PIN_VENDOR_WIDGET, 0xc5, 0x0000 }, + /* test mode off */ + { CS8409_PIN_VENDOR_WIDGET, 0xc0, 0x0000 }, + {} /* Terminator */ +}; + +struct sub_codec dolphin_cs42l42_0 = { + .addr = DOLPHIN_C0_I2C_ADDR, + .reset_gpio = DOLPHIN_C0_RESET, + .irq_mask = DOLPHIN_C0_INT, + .init_seq = dolphin_c0_init_reg_seq, + .init_seq_num = ARRAY_SIZE(dolphin_c0_init_reg_seq), + .hp_jack_in = 0, + .mic_jack_in = 0, + .paged = 1, + .suspended = 1, + .no_type_dect = 0, +}; + +struct sub_codec dolphin_cs42l42_1 = { + .addr = DOLPHIN_C1_I2C_ADDR, + .reset_gpio = DOLPHIN_C1_RESET, + .irq_mask = DOLPHIN_C1_INT, + .init_seq = dolphin_c1_init_reg_seq, + .init_seq_num = ARRAY_SIZE(dolphin_c1_init_reg_seq), + .hp_jack_in = 0, + .mic_jack_in = 0, + .paged = 1, + .suspended = 1, + .no_type_dect = 1, +}; + /****************************************************************************** * CS8409 Patch Driver Structs * Arrays Used for all projects using CS8409 @@ -295,6 +499,11 @@ const struct snd_pci_quirk cs8409_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG), SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG), SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AD0, "Dolphin", CS8409_DOLPHIN), + SND_PCI_QUIRK(0x1028, 0x0AD1, "Dolphin", CS8409_DOLPHIN), + SND_PCI_QUIRK(0x1028, 0x0AD2, "Dolphin", CS8409_DOLPHIN), + SND_PCI_QUIRK(0x1028, 0x0AD3, "Dolphin", CS8409_DOLPHIN), + SND_PCI_QUIRK(0x1028, 0x0ACF, "Dolphin", CS8409_DOLPHIN), {} /* terminator */ }; @@ -303,6 +512,7 @@ const struct hda_model_fixup cs8409_models[] = { { .id = CS8409_BULLSEYE, .name = "bullseye" }, { .id = CS8409_WARLOCK, .name = "warlock" }, { .id = CS8409_CYBORG, .name = "cyborg" }, + { .id = CS8409_DOLPHIN, .name = "dolphin" }, {} }; @@ -329,4 +539,14 @@ const struct hda_fixup cs8409_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = cs8409_cs42l42_fixups, }, + [CS8409_DOLPHIN] = { + .type = HDA_FIXUP_PINS, + .v.pins = dolphin_pincfgs, + .chained = true, + .chain_id = CS8409_DOLPHIN_FIXUPS, + }, + [CS8409_DOLPHIN_FIXUPS] = { + .type = HDA_FIXUP_FUNC, + .v.func = dolphin_fixups, + }, }; diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index cee9d5c506ed..97649d35aefb 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -913,6 +913,202 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, } } +/****************************************************************************** + * Dolphin Specific Functions + * CS8409/ 2 X CS42L42 + ******************************************************************************/ + +/* + * In the case of CS8409 we do not have unsolicited events when + * hs mic and hp are connected. Companion codec CS42L42 will + * generate interrupt via irq_mask to notify jack events. We have to overwrite + * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers + * and then notify status via generic snd_hda_jack_unsol_event() call. + */ +static void dolphin_jack_unsol_event(struct hda_codec *codec, unsigned int res) +{ + struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42; + struct hda_jack_tbl *jk; + + cs42l42 = spec->scodecs[CS8409_CODEC0]; + if (!cs42l42->suspended && (~res & cs42l42->irq_mask) && + cs42l42_jack_unsol_event(cs42l42)) { + jk = snd_hda_jack_tbl_get_mst(codec, DOLPHIN_HP_PIN_NID, 0); + if (jk) + snd_hda_jack_unsol_event(codec, + (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & + AC_UNSOL_RES_TAG); + + jk = snd_hda_jack_tbl_get_mst(codec, DOLPHIN_AMIC_PIN_NID, 0); + if (jk) + snd_hda_jack_unsol_event(codec, + (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & + AC_UNSOL_RES_TAG); + } + + cs42l42 = spec->scodecs[CS8409_CODEC1]; + if (!cs42l42->suspended && (~res & cs42l42->irq_mask) && + cs42l42_jack_unsol_event(cs42l42)) { + jk = snd_hda_jack_tbl_get_mst(codec, DOLPHIN_LO_PIN_NID, 0); + if (jk) + snd_hda_jack_unsol_event(codec, + (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & + AC_UNSOL_RES_TAG); + } +} + +/* Vendor specific HW configuration + * PLL, ASP, I2C, SPI, GPIOs, DMIC etc... + */ +static void dolphin_hw_init(struct hda_codec *codec) +{ + const struct cs8409_cir_param *seq = dolphin_hw_cfg; + struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42; + int i; + + if (spec->gpio_mask) { + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_MASK, + spec->gpio_mask); + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DIRECTION, + spec->gpio_dir); + snd_hda_codec_write(codec, CS8409_PIN_AFG, 0, AC_VERB_SET_GPIO_DATA, + spec->gpio_data); + } + + for (; seq->nid; seq++) + cs8409_vendor_coef_set(codec, seq->cir, seq->coeff); + + for (i = 0; i < spec->num_scodecs; i++) { + cs42l42 = spec->scodecs[i]; + cs42l42_resume(cs42l42); + } + + /* Enable Unsolicited Response */ + cs8409_enable_ur(codec, 1); +} + +static const struct hda_codec_ops cs8409_dolphin_patch_ops = { + .build_controls = cs8409_build_controls, + .build_pcms = snd_hda_gen_build_pcms, + .init = cs8409_init, + .free = snd_hda_gen_free, + .unsol_event = dolphin_jack_unsol_event, +#ifdef CONFIG_PM + .suspend = cs8409_cs42l42_suspend, +#endif +}; + +static int dolphin_exec_verb(struct hdac_device *dev, unsigned int cmd, unsigned int flags, + unsigned int *res) +{ + struct hda_codec *codec = container_of(dev, struct hda_codec, core); + struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42 = spec->scodecs[CS8409_CODEC0]; + + unsigned int nid = ((cmd >> 20) & 0x07f); + unsigned int verb = ((cmd >> 8) & 0x0fff); + + /* CS8409 pins have no AC_PINSENSE_PRESENCE + * capabilities. We have to intercept calls for CS42L42 pins + * and return correct pin sense values for read_pin_sense() call from + * hda_jack based on CS42L42 jack detect status. + */ + switch (nid) { + case DOLPHIN_HP_PIN_NID: + case DOLPHIN_LO_PIN_NID: + if (nid == DOLPHIN_LO_PIN_NID) + cs42l42 = spec->scodecs[CS8409_CODEC1]; + if (verb == AC_VERB_GET_PIN_SENSE) { + *res = (cs42l42->hp_jack_in) ? AC_PINSENSE_PRESENCE : 0; + return 0; + } + break; + case DOLPHIN_AMIC_PIN_NID: + if (verb == AC_VERB_GET_PIN_SENSE) { + *res = (cs42l42->mic_jack_in) ? AC_PINSENSE_PRESENCE : 0; + return 0; + } + break; + default: + break; + } + + return spec->exec_verb(dev, cmd, flags, res); +} + +void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action) +{ + struct cs8409_spec *spec = codec->spec; + struct snd_kcontrol_new *kctrl; + int i; + + switch (action) { + case HDA_FIXUP_ACT_PRE_PROBE: + snd_hda_add_verbs(codec, dolphin_init_verbs); + /* verb exec op override */ + spec->exec_verb = codec->core.exec_verb; + codec->core.exec_verb = dolphin_exec_verb; + + spec->scodecs[CS8409_CODEC0] = &dolphin_cs42l42_0; + spec->scodecs[CS8409_CODEC0]->codec = codec; + spec->scodecs[CS8409_CODEC1] = &dolphin_cs42l42_1; + spec->scodecs[CS8409_CODEC1]->codec = codec; + spec->num_scodecs = 2; + + codec->patch_ops = cs8409_dolphin_patch_ops; + + /* GPIO 1,5 out, 0,4 in */ + spec->gpio_dir = spec->scodecs[CS8409_CODEC0]->reset_gpio | + spec->scodecs[CS8409_CODEC1]->reset_gpio; + spec->gpio_data = 0; + spec->gpio_mask = 0x03f; + + /* Basic initial sequence for specific hw configuration */ + snd_hda_sequence_write(codec, dolphin_init_verbs); + + snd_hda_jack_add_kctl(codec, DOLPHIN_LO_PIN_NID, "Line Out", true, + SND_JACK_HEADPHONE, NULL); + + cs8409_fix_caps(codec, DOLPHIN_HP_PIN_NID); + cs8409_fix_caps(codec, DOLPHIN_LO_PIN_NID); + cs8409_fix_caps(codec, DOLPHIN_AMIC_PIN_NID); + + break; + case HDA_FIXUP_ACT_PROBE: + snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume", + &cs42l42_dac_volume_mixer); + snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume", &cs42l42_adc_volume_mixer); + kctrl = snd_hda_gen_add_kctl(&spec->gen, "Line Out Playback Volume", + &cs42l42_dac_volume_mixer); + /* Update Line Out kcontrol template */ + kctrl->private_value = HDA_COMPOSE_AMP_VAL_OFS(DOLPHIN_HP_PIN_NID, 3, CS8409_CODEC1, + HDA_OUTPUT, CS42L42_VOL_DAC) | HDA_AMP_VAL_MIN_MUTE; + cs8409_enable_ur(codec, 0); + dolphin_hw_init(codec); + snd_hda_codec_set_name(codec, "CS8409/CS42L42"); + break; + case HDA_FIXUP_ACT_INIT: + dolphin_hw_init(codec); + fallthrough; + 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. + */ + for (i = 0; i < spec->num_scodecs; i++) { + cs42l42_run_jack_detect(spec->scodecs[i]); + usleep_range(100000, 150000); + } + + break; + default: + break; + } +} + static int patch_cs8409(struct hda_codec *codec) { int err; diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index a105c3c9023d..1b5a8d04ba0f 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -243,15 +243,32 @@ enum cs8409_coefficient_index_registers { #define CS8409_CS42L42_DMIC_PIN_NID CS8409_PIN_DMIC1_IN #define CS8409_CS42L42_DMIC_ADC_PIN_NID CS8409_PIN_DMIC1 +/* Dolphin */ + +#define DOLPHIN_C0_I2C_ADDR (0x48 << 1) +#define DOLPHIN_C1_I2C_ADDR (0x49 << 1) +#define DOLPHIN_HP_PIN_NID CS8409_PIN_ASP1_TRANSMITTER_A +#define DOLPHIN_LO_PIN_NID CS8409_PIN_ASP1_TRANSMITTER_B +#define DOLPHIN_AMIC_PIN_NID CS8409_PIN_ASP1_RECEIVER_A + +#define DOLPHIN_C0_INT GENMASK(4, 4) +#define DOLPHIN_C1_INT GENMASK(0, 0) +#define DOLPHIN_C0_RESET GENMASK(5, 5) +#define DOLPHIN_C1_RESET GENMASK(1, 1) +#define DOLPHIN_WAKE (DOLPHIN_C0_INT | DOLPHIN_C1_INT) + enum { CS8409_BULLSEYE, CS8409_WARLOCK, CS8409_CYBORG, CS8409_FIXUPS, + CS8409_DOLPHIN, + CS8409_DOLPHIN_FIXUPS, }; enum { CS8409_CODEC0, + CS8409_CODEC1 }; enum { @@ -327,6 +344,13 @@ extern const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[]; extern const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[]; extern struct sub_codec cs8409_cs42l42_codec; +extern const struct hda_verb dolphin_init_verbs[]; +extern const struct hda_pintbl dolphin_pincfgs[]; +extern const struct cs8409_cir_param dolphin_hw_cfg[]; +extern struct sub_codec dolphin_cs42l42_0; +extern struct sub_codec dolphin_cs42l42_1; + void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action); +void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action); #endif From patchwork Wed Jul 28 13:44:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405895 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D4E03C4338F for ; Wed, 28 Jul 2021 13:54:29 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5B29060F45 for ; Wed, 28 Jul 2021 13:54:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 5B29060F45 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 9AB211F72; Wed, 28 Jul 2021 15:53:37 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9AB211F72 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480467; bh=EMgCcOa6l2LVnOtwyeiJsNQ5qjhh1j7h9ylWi5R4L1o=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=DFVOMvtKAC8XEUrnrAYZ5M9U3Uup3dFwIx2FOId7thWDM/vE8Le0mBHKWtI0SbHRq CswQbsEwUbvB9yxoE3+0xKhW5YFexYQnVZyuoHY7CdRDlzCrRDNbSavgL2oK27slxZ E0kwo4Cepwjjr61hBtGuQoo7WzFQ7JSd9v6qAnnk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 60B93F805BB; Wed, 28 Jul 2021 15:45:30 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 8F5A6F805A1; Wed, 28 Jul 2021 15:45:22 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 790B6F804FB for ; Wed, 28 Jul 2021 15:44:45 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 790B6F804FB Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="ZZiB5pV9" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUr2014335; Wed, 28 Jul 2021 08:44:43 -0500 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=zYqzRWTxUJuaEiFkrwIy5RZBXmZV8qi+Ef/364pMMpU=; b=ZZiB5pV9l74VfDEhU98bNq0t+++BPKeFvT18ov1/oe1j183Q7INJyLeKVTKUDRiI1iCi g0npLzXdi6/ygpDsIQC35ZZ/WxuTHUknHEuoRAv777JtW8ON0hE4Zfy4nHyRqQw3H4ZB DFQLGyEcFVIDJyJ/bve5f7LDS8JkQ/IEdYUgtzFPwKWwYLF+BskC+xhCaVZMs/MsnW08 wB20t92eRnXl5E46S44TBFr4vYuwprJQyZvt5+yJofSOv1HqcYCcSg0F50vu81facskQ 17L4ARt3uAGBMwrHVH6GFXJcfUEE3rjCYMvDv2LZXZSlJD8MhM4CPoxiG77Mg8lRQYdx 3g== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-16 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:43 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:37 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:37 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id DEEC445D; Wed, 28 Jul 2021 13:44:36 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 22/27] ALSA: hda/cs8409: Enable Full Scale Volume for Line Out Codec on Dolphin Date: Wed, 28 Jul 2021 14:44:03 +0100 Message-ID: <20210728134408.369396-23-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: n6jDMYegU_eaHDOIcR052O6-aMHok-dC X-Proofpoint-GUID: n6jDMYegU_eaHDOIcR052O6-aMHok-dC X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Headphones codec will keep reduced maximum volume. Line Out codec will have increased maximum volume. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index 6453a7ec3856..a39b2c20f61c 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -300,10 +300,10 @@ static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = { { 0x2901, 0x01 }, { 0x1101, 0x0A }, { 0x1102, 0x84 }, + { 0x2001, 0x03 }, { 0x2301, 0x00 }, { 0x2303, 0x00 }, { 0x2302, 0x3f }, - { 0x2001, 0x03 }, { 0x1B75, 0xB6 }, { 0x1B73, 0xC2 }, { 0x1129, 0x01 }, @@ -356,10 +356,10 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { { 0x2901, 0x00 }, { 0x1101, 0x0E }, { 0x1102, 0x84 }, + { 0x2001, 0x01 }, { 0x2301, 0x00 }, { 0x2303, 0x00 }, { 0x2302, 0x3f }, - { 0x2001, 0x03 }, { 0x1B75, 0xB6 }, { 0x1B73, 0xC2 }, { 0x1129, 0x01 }, From patchwork Wed Jul 28 13:44:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405887 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA53EC4338F for ; Wed, 28 Jul 2021 13:52:55 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 661B06101D for ; Wed, 28 Jul 2021 13:52:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 661B06101D Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 057831EDD; Wed, 28 Jul 2021 15:52:04 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 057831EDD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480374; bh=edU4LwCxIXEXJshG73Ycmz2zvI71RkezCRfDNXDdkHc=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Ak7XYXps86/7A1WAQQh5vYYr6WwL/AayDyXVqJT8aOrg2e7uMZzfs+rDEmS21xAHx opDtPozYA40xqCTJKVAshrEcRccRlfZhgUesu6DY92T1BMFBx3n0dsM8LbI1SRzszx ES9yGQ5QPAwMWRNx+jW9tgauiCzY9MOatETyWuB8= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id F16DFF805A0; Wed, 28 Jul 2021 15:45:26 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 2200BF804E6; Wed, 28 Jul 2021 15:45:16 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 4F947F804ED for ; Wed, 28 Jul 2021 15:44:41 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 4F947F804ED Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="HQZqNmtr" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S674iU029982; Wed, 28 Jul 2021 08:44:39 -0500 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=Cd8sZsyPFjub9SNh+fp/si6i8IHWZ4PqUCYMaY7jOhU=; b=HQZqNmtrDYlRd5DVtaKekkNw1rxiJ0jD8avcx11n6ShamRGE3ym2vAqXTsvkZLXjAuLN 2J9AZkHURJlfpUD5OH2FZJqyhsfEWsAlkymnbe9oYJDSfAlNquRU415cgfFR+kcaRXH8 VMQgE8cXWFG0OG8zjwSxW5XgK3hedaNdUW5jii3cQHZZaDMjW94tOTjyX1BoLXNz8xTL T99tyTbcZ74y1akmZFaBW3jIQroW6GsYvuHEWg4VhvJzN+4aP/onFcSMj46DOI/Ac/pT OCfLFuRXup3UwABD1X0s3Hu2VmAKKAs0rDeWf+L7NNVewtdFeO9tzis4YXHUAYpVLSD4 zA== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a31m2resc-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:39 -0500 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.2242.4; Wed, 28 Jul 2021 14:44:37 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:37 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 42FB92BA; Wed, 28 Jul 2021 13:44:37 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 23/27] ALSA: hda/cs8409: Set fixed sample rate of 48kHz for CS42L42 Date: Wed, 28 Jul 2021 14:44:04 +0100 Message-ID: <20210728134408.369396-24-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: 7M38jdXwygA7qXgKEnmLkLkz4Krc7-HL X-Proofpoint-ORIG-GUID: 7M38jdXwygA7qXgKEnmLkLkz4Krc7-HL X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 suspectscore=0 lowpriorityscore=0 mlxlogscore=999 phishscore=0 spamscore=0 clxscore=1015 mlxscore=0 adultscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding CS42L42 is configured to use a fixed sample rate of 48kHz. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 8 ++++++++ sound/pci/hda/patch_cs8409.c | 6 ++++++ sound/pci/hda/patch_cs8409.h | 2 ++ 3 files changed, 16 insertions(+) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index a39b2c20f61c..a9a0b8e3b2a9 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -45,6 +45,14 @@ const struct snd_kcontrol_new cs42l42_adc_volume_mixer = { HDA_INPUT, CS42L42_VOL_ADC) | HDA_AMP_VAL_MIN_MUTE }; +const struct hda_pcm_stream cs42l42_48k_pcm_analog_playback = { + .rates = SNDRV_PCM_RATE_48000, /* fixed rate */ +}; + +const struct hda_pcm_stream cs42l42_48k_pcm_analog_capture = { + .rates = SNDRV_PCM_RATE_48000, /* fixed rate */ +}; + /****************************************************************************** * BULLSEYE / WARLOCK / CYBORG Specific Arrays * CS8409/CS42L42 diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 97649d35aefb..5b6d843ab7fb 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -884,6 +884,9 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, break; case HDA_FIXUP_ACT_PROBE: + /* Fix Sample Rate to 48kHz */ + spec->gen.stream_analog_playback = &cs42l42_48k_pcm_analog_playback; + spec->gen.stream_analog_capture = &cs42l42_48k_pcm_analog_capture; /* Set initial DMIC volume to -26 dB */ snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, HDA_INPUT, 0, 0xff, 0x19); @@ -1077,6 +1080,9 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac break; case HDA_FIXUP_ACT_PROBE: + /* Fix Sample Rate to 48kHz */ + spec->gen.stream_analog_playback = &cs42l42_48k_pcm_analog_playback; + spec->gen.stream_analog_capture = &cs42l42_48k_pcm_analog_capture; snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume", &cs42l42_dac_volume_mixer); snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume", &cs42l42_adc_volume_mixer); diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 1b5a8d04ba0f..2208be2ffad1 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -335,6 +335,8 @@ int cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *ui int cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl); int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl); +extern const struct hda_pcm_stream cs42l42_48k_pcm_analog_playback; +extern const struct hda_pcm_stream cs42l42_48k_pcm_analog_capture; extern const struct snd_pci_quirk cs8409_fixup_tbl[]; extern const struct hda_model_fixup cs8409_models[]; extern const struct hda_fixup cs8409_fixups[]; From patchwork Wed Jul 28 13:44:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405889 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 591C7C4338F for ; Wed, 28 Jul 2021 13:53:14 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CF2B660F45 for ; Wed, 28 Jul 2021 13:53:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org CF2B660F45 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 7F87E1EF2; Wed, 28 Jul 2021 15:52:22 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 7F87E1EF2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480392; bh=F+c5uECCzCtVoFGEOrKitAsQka0SXCs7wRoynSZUAaM=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Jr3qCnUnCnjvHKbyidG8sjKXYFF3l03jB1YsqwN1Ygnb84myS9gbO3zztHGcCtUS+ PnVSSG6AZ0m1IUZ9wXewl9/ZpmCH88DCkXnCBA49iKgfF+l9n1fYLyC9RUiW1tjrZo cTnhL+WadlOs/BDmGnjPQDnWH+EdbSkv1yF/Zy0Q= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B4489F805A9; Wed, 28 Jul 2021 15:45:27 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 31A6CF80212; Wed, 28 Jul 2021 15:45:16 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id F15CFF804F2 for ; Wed, 28 Jul 2021 15:44:41 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz F15CFF804F2 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="PvWHwOyj" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S674iV029982; Wed, 28 Jul 2021 08:44:40 -0500 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=XmFBZUirrBMcbd0VfLaCCvQVi7P6F/EIdfjs1jk50/k=; b=PvWHwOyjAwQe0MivKd/ONFxwCLs/AYbFjXBZVb/m/fuRDrWyIzVU9OI/pRlUkGUcUWE0 7a2SLNPUGuAYUqroOB/QJUhzxN5z0OgIHsv3wwxqS2jYTqDOlhNgraf37Aw8l1sTy4aK mctrxAfvHm0BqSvY3SpRskeG9nZyurayaXj/KQ/kPnM+d9UZgOouPuAkM7//NixSomZv 4XhlMes7/pcZgeVyd6Fx20k6m/G2XYXXw7BBlzZkrDgmghetcQuI+tofxO3IWLQXH4vp FH37ZssGbovzyR5MzjZLxWC44byjJ+dhObf2VftPOhq/0qvKATZyFmLpugazUsEODsR5 Vg== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a31m2resc-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:40 -0500 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.2242.4; Wed, 28 Jul 2021 14:44:37 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:37 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 93BC545D; Wed, 28 Jul 2021 13:44:37 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 24/27] ALSA: hda/cs8409: Use timeout rather than retries for I2C transaction waits Date: Wed, 28 Jul 2021 14:44:05 +0100 Message-ID: <20210728134408.369396-25-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: CslibmsU6zfbB4ExL7oNDjsjJlg28kNJ X-Proofpoint-ORIG-GUID: CslibmsU6zfbB4ExL7oNDjsjJlg28kNJ X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 suspectscore=0 lowpriorityscore=0 mlxlogscore=999 phishscore=0 spamscore=0 clxscore=1015 mlxscore=0 adultscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 16 +++------------- sound/pci/hda/patch_cs8409.h | 2 ++ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 5b6d843ab7fb..422381913bc6 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -119,24 +119,14 @@ static void cs8409_enable_i2c_clock(struct hda_codec *codec) * @codec: the codec instance * * Wait for I2C transaction to complete. - * Return -1 if transaction wait times out. + * Return -ETIMEDOUT if transaction wait times out. */ static int cs8409_i2c_wait_complete(struct hda_codec *codec) { - int repeat = 5; unsigned int retval; - do { - retval = cs8409_vendor_coef_get(codec, CS8409_I2C_STS); - if ((retval & 0x18) != 0x18) { - usleep_range(2000, 4000); - --repeat; - } else - return 0; - - } while (repeat); - - return -1; + return read_poll_timeout(cs8409_vendor_coef_get, retval, retval & 0x18, + CS42L42_I2C_SLEEP_US, CS42L42_I2C_TIMEOUT_US, false, codec, CS8409_I2C_STS); } /** diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 2208be2ffad1..71dbbd8e2f3b 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -231,6 +231,8 @@ enum cs8409_coefficient_index_registers { #define CS42L42_HSTYPE_MASK (0x03) #define CS42L42_JACK_INSERTED (0x0C) #define CS42L42_JACK_REMOVED (0x00) +#define CS42L42_I2C_TIMEOUT_US (20000) +#define CS42L42_I2C_SLEEP_US (2000) /* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */ From patchwork Wed Jul 28 13:44:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405931 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E4A4C41537 for ; Wed, 28 Jul 2021 13:56:01 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9E09A6023E for ; Wed, 28 Jul 2021 13:56:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 9E09A6023E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 18F441FBF; Wed, 28 Jul 2021 15:55:09 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 18F441FBF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480559; bh=96l3VcaXSj/SYQJ2JMHPfrDmLaAg13Um1VQ4qSPDBEQ=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=ZcmjH3fTi0FdzAONfZLe4MXiIqQlM3h0b+OT0RFW8576FR0rHSo6wOHMK5+hezd4N qAtlJ+6zunzNeo+yJeT1KzmGPElw83QixVvvkh7aTeOMlo2CQ803VGXfRkSxei1F2M COSRR9dRszl5h26Fi4HidY+1JU9qVJOTFIixElAE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 68C83F805E4; Wed, 28 Jul 2021 15:45:34 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4CD6EF805A0; Wed, 28 Jul 2021 15:45:26 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id DDDF3F804FC for ; Wed, 28 Jul 2021 15:44:45 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz DDDF3F804FC Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="lzOB0E2T" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUr3014335; Wed, 28 Jul 2021 08:44:44 -0500 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=5vyRKpHWzUCIxKnuzL8uynmnpCsZb66b8Ukt92ISVS0=; b=lzOB0E2TqNLBRmaCuTjmrKmJ8s3ZK1Q5fFvr1kaskUm4GwlsEJg0opOgfzFzmczvgcA6 2LUJ3g9R7zINGtjULtn7LV/HXoNglDHjbf637cYqgoQP0OlJr3a3rR6oPiMfKBm8dD1C 0uS6EUP7PKUmt8M5oUo7Lqdhnt8Z8ew1lbMFkFr9FmfnamRa5zTj9UJgdGeM1UI25vDe XKY5+nvn87rK91cSxrk8LaOUJQe3dp0/l+YYR5M1TjeCfei3eDgfWnxsx1TFXcSnQiRx ziqYYteK42rZthu+XdX1ZSAt8ZyuJAzSPmbJnWmZsBOiJqFHe9Ru1BPmtE+0tWAnOEwp Tg== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-17 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:44 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:38 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:38 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id E3DF846E; Wed, 28 Jul 2021 13:44:37 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 25/27] ALSA: hda/cs8409: Remove unnecessary delays Date: Wed, 28 Jul 2021 14:44:06 +0100 Message-ID: <20210728134408.369396-26-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: KUQgfGSsemspQDaebE0JBlq8oVSEp-hb X-Proofpoint-GUID: KUQgfGSsemspQDaebE0JBlq8oVSEp-hb X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Since delays when starting jack detection after initialization have been reduced/removed, it is necessary to add back in an extra 20ms delay after the init sequence to allow the CS42L42 to power up correctly. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 422381913bc6..1e48337b782b 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -520,12 +520,10 @@ static void cs42l42_run_jack_detect(struct sub_codec *cs42l42) cs8409_i2c_write(cs42l42, 0x1b74, 0x07); cs8409_i2c_write(cs42l42, 0x131b, 0xFD); cs8409_i2c_write(cs42l42, 0x1120, 0x80); - /* Wait ~110ms*/ - usleep_range(110000, 200000); + /* Wait ~100us*/ + usleep_range(100, 200); cs8409_i2c_write(cs42l42, 0x111f, 0x77); cs8409_i2c_write(cs42l42, 0x1120, 0xc0); - /* Wait ~10ms */ - usleep_range(10000, 25000); } static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ts_status) @@ -632,6 +630,7 @@ static void cs42l42_resume(struct sub_codec *cs42l42) /* Initialize CS42L42 companion codec */ cs8409_i2c_bulk_write(cs42l42, cs42l42->init_seq, cs42l42->init_seq_num); + usleep_range(20000, 25000); /* Clear interrupts, by reading interrupt status registers */ cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs)); @@ -899,7 +898,6 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, * Run immediately after init. */ cs42l42_run_jack_detect(spec->scodecs[CS8409_CODEC0]); - usleep_range(100000, 150000); break; default: break; @@ -1094,10 +1092,8 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac * been already plugged in. * Run immediately after init. */ - for (i = 0; i < spec->num_scodecs; i++) { + for (i = 0; i < spec->num_scodecs; i++) cs42l42_run_jack_detect(spec->scodecs[i]); - usleep_range(100000, 150000); - } break; default: From patchwork Wed Jul 28 13:44:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405893 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A1C4C4320A for ; Wed, 28 Jul 2021 13:54:08 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D6E886103E for ; Wed, 28 Jul 2021 13:54:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org D6E886103E Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 6F55D1F53; Wed, 28 Jul 2021 15:53:16 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 6F55D1F53 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480446; bh=HNemylcdSZ4eGEnljkAkyEoAkZdCkulwChTOlLs+3TU=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=CeBo3HMDj5auv6lLWPTyhurl72wrlbkRSr3we+mTPVYJ1zrUCAaT/rs2CkNU3M8DE 5UcLT8PH7QruH50NOMT6c3erKNhUBSUFqqiPBYAqCsykwAegQKX6oZSTs3lv5bQvl2 PQZsWB0uIMT+znY/JrslWWfX0Xi5jbgo2HzX9Uh0= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 979C9F805BA; Wed, 28 Jul 2021 15:45:29 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 19C10F805A1; Wed, 28 Jul 2021 15:45:22 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id D21C0F804FA for ; Wed, 28 Jul 2021 15:44:44 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz D21C0F804FA Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="aRn+OhQZ" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S674iW029982; Wed, 28 Jul 2021 08:44:40 -0500 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=eyP6h++2gOwhr+wnC1bIE5FbiFiAdnH3d/gCDZwEA64=; b=aRn+OhQZ4NdSdXT7Y0Jl5i9VSd2fiCeQzUZ3F41EHLy9aMfwG1PvgUfPcPKequGwJD7Z IQcc2CLeH/Ax4xERLc4f1O0Nn4rHkIXDXy7dRiYks+wxyBQk5vELclhDWWsk8kaxRRsk DOKnk4prQ3+desTP5+3ZTlDJgOihA+5bGypghI7sZqkRgr0VenLjFThb7ZBuVlFV7XsT Jj9OCjFA8r97VCALNngdtLelz/kypBPd/cHJl5e+qdNBzUQj6y2bD3ids0Ujr12f3vOt jYU6mLpXDvDOms5xkXS6wHCKfe4rhuzX/Z+g6WbdqR4MYrPV5S+z83bFNhm0kzHI0u1q bg== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a31m2resc-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:40 -0500 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.2242.4; Wed, 28 Jul 2021 14:44:38 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:38 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 4116D2BA; Wed, 28 Jul 2021 13:44:38 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 26/27] ALSA: hda/cs8409: Follow correct CS42L42 power down sequence for suspend Date: Wed, 28 Jul 2021 14:44:07 +0100 Message-ID: <20210728134408.369396-27-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: ySOGJnZ8qjlEBNnvN1Mpsh9UlcGK744w X-Proofpoint-ORIG-GUID: ySOGJnZ8qjlEBNnvN1Mpsh9UlcGK744w X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 suspectscore=0 lowpriorityscore=0 mlxlogscore=999 phishscore=0 spamscore=0 clxscore=1015 mlxscore=0 adultscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409.c | 23 ++++++++++++++++++++++- sound/pci/hda/patch_cs8409.h | 2 ++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 1e48337b782b..0baed8bebfbb 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "patch_cs8409.h" @@ -198,6 +199,7 @@ static int cs8409_i2c_read(struct sub_codec *scodec, unsigned int addr) read_data = cs8409_vendor_coef_get(codec, CS8409_I2C_QREAD); mutex_unlock(&spec->i2c_mux); + return read_data & 0x0ff; error: @@ -654,9 +656,28 @@ static void cs42l42_suspend(struct sub_codec *cs42l42) { struct hda_codec *codec = cs42l42->codec; unsigned int gpio_data; + int reg_cdc_status = 0; + const struct cs8409_i2c_param cs42l42_pwr_down_seq[] = { + { 0x2301, 0x3F }, + { 0x2302, 0x3F }, + { 0x2303, 0x3F }, + { 0x2001, 0x0F }, + { 0x2A01, 0x00 }, + { 0x1207, 0x00 }, + { 0x1101, 0xFE }, + { 0x1102, 0x8C }, + { 0x1101, 0xFF }, + }; + + cs8409_i2c_bulk_write(cs42l42, cs42l42_pwr_down_seq, ARRAY_SIZE(cs42l42_pwr_down_seq)); + + if (read_poll_timeout(cs8409_i2c_read, reg_cdc_status, + (reg_cdc_status & 0x1), CS42L42_PDN_SLEEP_US, CS42L42_PDN_TIMEOUT_US, + true, cs42l42, 0x1308) < 0) + codec_warn(codec, "Timeout waiting for PDN_DONE for CS42L42\n"); /* Power down CS42L42 ASP/EQ/MIX/HP */ - cs8409_i2c_write(cs42l42, 0x1101, 0xfe); + cs8409_i2c_write(cs42l42, 0x1102, 0x9C); cs42l42->suspended = 1; cs42l42->last_page = 0; diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 71dbbd8e2f3b..09987daa9cbf 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -233,6 +233,8 @@ enum cs8409_coefficient_index_registers { #define CS42L42_JACK_REMOVED (0x00) #define CS42L42_I2C_TIMEOUT_US (20000) #define CS42L42_I2C_SLEEP_US (2000) +#define CS42L42_PDN_TIMEOUT_US (250000) +#define CS42L42_PDN_SLEEP_US (2000) /* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */ From patchwork Wed Jul 28 13:44:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12405933 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69807C4320E for ; Wed, 28 Jul 2021 13:56:39 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EC10F60F59 for ; Wed, 28 Jul 2021 13:56:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org EC10F60F59 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=opensource.cirrus.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-project.org Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 8E1FB1FD9; Wed, 28 Jul 2021 15:55:47 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 8E1FB1FD9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627480597; bh=jcKcStgNmTLr5Auw+uUld9ZHUFnOK52Yh6CoxcioODM=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=GxjmnlrU+A1K/YLJfUHSqkGt04EQtGQTNUlwkNdEWnO5/8OKQ4LpOh25+m1bLmGZM +yrt5xHtQUJxr9MKKpTmgk3H2DecIoViAvWP4RcyMbz2R9A0jCWUk7zIC12roOHmQF dKucTGMDxfWOjvP8+xcjgXqoxcUK/pkHgsV7Uenw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 42C4EF805F3; Wed, 28 Jul 2021 15:45:36 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 48CE0F805A9; Wed, 28 Jul 2021 15:45:27 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 74D57F804FD for ; Wed, 28 Jul 2021 15:44:46 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 74D57F804FD Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="I6tNMckL" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16S5XUr4014335; Wed, 28 Jul 2021 08:44:45 -0500 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=yVqEmPZxiL8drklmk0pAesV5mI/FqvN84HmgOLrlxJo=; b=I6tNMckLpyrY1z5yWBWlMRPrc9mZVwSxc0uU8ZM5JIT4L5BVGOiiYK4GOHEB8hX1QpvH OsAG2luhKta2El+i67XGbMAubVEswDbmVamr3BF56mMlfhu4EkL+JjED1DAaCT8MnYwv 3YR4hYkZvKC2OdnKRLt6w6w8o2Tl0TRu7+61gVFGOvTptPR9L8y0yN8Rp3CT/IDK1qhC ueum5Yrnvmh54aBaOIwGbqWjhJ3eeArEPHxqkcLUmwjXLZt7s9EhxAMJ2JC06wji+jx+ CjDJHGq277fIdm4epyMm/xjjUHdf0d5VEiWfL2/05F8m0aJEdOzIq6OfXCVjKnaUREwj Qg== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3a30q20fx9-18 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 28 Jul 2021 08:44:44 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Wed, 28 Jul 2021 14:44:38 +0100 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.2242.4 via Frontend Transport; Wed, 28 Jul 2021 14:44:38 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 9268946E; Wed, 28 Jul 2021 13:44:38 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v2 27/27] ALSA: hda/cs8409: Unmute/Mute codec when stream starts/stops Date: Wed, 28 Jul 2021 14:44:08 +0100 Message-ID: <20210728134408.369396-28-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> References: <20210728134408.369396-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: t-waweEa4XHz3Kia3YUgNJX0hZgq2m_U X-Proofpoint-GUID: t-waweEa4XHz3Kia3YUgNJX0hZgq2m_U X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 bulkscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 adultscore=0 clxscore=1015 spamscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107280077 Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Stefan Binding X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" From: Stefan Binding Codec is muted on init, and then unmuted when the stream starts. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Changes in v2: - No changes --- sound/pci/hda/patch_cs8409-tables.c | 20 ++--- sound/pci/hda/patch_cs8409.c | 123 +++++++++++++++++++++++----- sound/pci/hda/patch_cs8409.h | 7 ++ 3 files changed, 120 insertions(+), 30 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index a9a0b8e3b2a9..0fb0a428428b 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -81,7 +81,7 @@ static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { { 0x1010, 0xB0 }, { 0x1D01, 0x00 }, { 0x1D02, 0x06 }, - { 0x1D03, 0x00 }, + { 0x1D03, 0x9F }, { 0x1107, 0x01 }, { 0x1009, 0x02 }, { 0x1007, 0x03 }, @@ -111,8 +111,8 @@ static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { { 0x2901, 0x01 }, { 0x1101, 0x0A }, { 0x1102, 0x84 }, - { 0x2301, 0x00 }, - { 0x2303, 0x00 }, + { 0x2301, 0x3F }, + { 0x2303, 0x3F }, { 0x2302, 0x3f }, { 0x2001, 0x03 }, { 0x1B75, 0xB6 }, @@ -284,7 +284,7 @@ static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = { { 0x1010, 0xB0 }, { 0x1D01, 0x00 }, { 0x1D02, 0x06 }, - { 0x1D03, 0x00 }, + { 0x1D03, 0x9F }, { 0x1107, 0x01 }, { 0x1009, 0x02 }, { 0x1007, 0x03 }, @@ -309,8 +309,8 @@ static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = { { 0x1101, 0x0A }, { 0x1102, 0x84 }, { 0x2001, 0x03 }, - { 0x2301, 0x00 }, - { 0x2303, 0x00 }, + { 0x2301, 0x3F }, + { 0x2303, 0x3F }, { 0x2302, 0x3f }, { 0x1B75, 0xB6 }, { 0x1B73, 0xC2 }, @@ -340,7 +340,7 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { { 0x1010, 0xB0 }, { 0x1D01, 0x00 }, { 0x1D02, 0x06 }, - { 0x1D03, 0x00 }, + { 0x1D03, 0x9F }, { 0x1107, 0x01 }, { 0x1009, 0x02 }, { 0x1007, 0x03 }, @@ -365,8 +365,8 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { { 0x1101, 0x0E }, { 0x1102, 0x84 }, { 0x2001, 0x01 }, - { 0x2301, 0x00 }, - { 0x2303, 0x00 }, + { 0x2301, 0x3F }, + { 0x2303, 0x3F }, { 0x2302, 0x3f }, { 0x1B75, 0xB6 }, { 0x1B73, 0xC2 }, @@ -377,7 +377,7 @@ static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = { { 0x1112, 0x00 }, { 0x1113, 0x80 }, { 0x1C03, 0xC0 }, - { 0x1101, 0x02 }, + { 0x1101, 0x06 }, { 0x1316, 0xff }, { 0x1317, 0xff }, { 0x1318, 0xff }, diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 0baed8bebfbb..bd81004fc81e 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -454,6 +454,38 @@ int cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc return 0; } +static void cs42l42_mute(struct sub_codec *cs42l42, int vol_type, + unsigned int chs, bool mute) +{ + if (mute) { + if (vol_type == CS42L42_VOL_DAC) { + if (chs & BIT(0)) + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, 0x3f); + if (chs & BIT(1)) + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, 0x3f); + } else if (vol_type == CS42L42_VOL_ADC) { + if (chs & BIT(0)) + cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, 0x9f); + } + } else { + if (vol_type == CS42L42_VOL_DAC) { + if (chs & BIT(0)) + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, + -(cs42l42->vol[CS42L42_DAC_CH0_VOL_OFFSET]) + & CS42L42_REG_HS_VOL_MASK); + if (chs & BIT(1)) + cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, + -(cs42l42->vol[CS42L42_DAC_CH1_VOL_OFFSET]) + & CS42L42_REG_HS_VOL_MASK); + } else if (vol_type == CS42L42_VOL_ADC) { + if (chs & BIT(0)) + cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, + cs42l42->vol[CS42L42_ADC_VOL_OFFSET] + & CS42L42_REG_AMIC_VOL_MASK); + } + } +} + int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) { struct hda_codec *codec = snd_kcontrol_chip(kctrl); @@ -465,25 +497,20 @@ int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc switch (ofs) { case CS42L42_VOL_DAC: - if (chs & BIT(0)) { + if (chs & BIT(0)) cs42l42->vol[ofs] = *valp; - cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, - -(cs42l42->vol[ofs]) & CS42L42_REG_HS_VOL_MASK); - } if (chs & BIT(1)) { - ofs++; valp++; - cs42l42->vol[ofs] = *valp; - cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, - -(cs42l42->vol[ofs]) & CS42L42_REG_HS_VOL_MASK); + cs42l42->vol[ofs + 1] = *valp; } + if (spec->playback_started) + cs42l42_mute(cs42l42, CS42L42_VOL_DAC, chs, false); break; case CS42L42_VOL_ADC: - if (chs & BIT(0)) { + if (chs & BIT(0)) cs42l42->vol[ofs] = *valp; - cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, - cs42l42->vol[ofs] & CS42L42_REG_AMIC_VOL_MASK); - } + if (spec->capture_started) + cs42l42_mute(cs42l42, CS42L42_VOL_ADC, chs, false); break; default: break; @@ -492,6 +519,64 @@ int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc return 0; } +static void cs42l42_playback_pcm_hook(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream, + int action) +{ + struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42; + int i; + bool mute; + + switch (action) { + case HDA_GEN_PCM_ACT_PREPARE: + mute = false; + spec->playback_started = 1; + break; + case HDA_GEN_PCM_ACT_CLEANUP: + mute = true; + spec->playback_started = 0; + break; + default: + return; + } + + for (i = 0; i < spec->num_scodecs; i++) { + cs42l42 = spec->scodecs[i]; + cs42l42_mute(cs42l42, CS42L42_VOL_DAC, 0x3, mute); + } +} + +static void cs42l42_capture_pcm_hook(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream, + int action) +{ + struct cs8409_spec *spec = codec->spec; + struct sub_codec *cs42l42; + int i; + bool mute; + + switch (action) { + case HDA_GEN_PCM_ACT_PREPARE: + mute = false; + spec->capture_started = 1; + break; + case HDA_GEN_PCM_ACT_CLEANUP: + mute = true; + spec->capture_started = 0; + break; + default: + return; + } + + for (i = 0; i < spec->num_scodecs; i++) { + cs42l42 = spec->scodecs[i]; + cs42l42_mute(cs42l42, CS42L42_VOL_ADC, 0x3, mute); + } +} + /* Configure CS42L42 slave codec for jack autodetect */ static void cs42l42_enable_jack_detect(struct sub_codec *cs42l42) { @@ -637,14 +722,6 @@ static void cs42l42_resume(struct sub_codec *cs42l42) /* Clear interrupts, by reading interrupt status registers */ cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs)); - /* Restore Volumes after Resume */ - cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHA, - -(cs42l42->vol[1]) & CS42L42_REG_HS_VOL_MASK); - cs8409_i2c_write(cs42l42, CS42L42_REG_HS_VOL_CHB, - -(cs42l42->vol[2]) & CS42L42_REG_HS_VOL_MASK); - cs8409_i2c_write(cs42l42, CS42L42_REG_AMIC_VOL, - cs42l42->vol[0] & CS42L42_REG_AMIC_VOL_MASK); - if (cs42l42->full_scale_vol) cs8409_i2c_write(cs42l42, 0x2001, 0x01); @@ -897,6 +974,9 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, /* Fix Sample Rate to 48kHz */ spec->gen.stream_analog_playback = &cs42l42_48k_pcm_analog_playback; spec->gen.stream_analog_capture = &cs42l42_48k_pcm_analog_capture; + /* add hooks */ + spec->gen.pcm_playback_hook = cs42l42_playback_pcm_hook; + spec->gen.pcm_capture_hook = cs42l42_capture_pcm_hook; /* Set initial DMIC volume to -26 dB */ snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, HDA_INPUT, 0, 0xff, 0x19); @@ -1092,6 +1172,9 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac /* Fix Sample Rate to 48kHz */ spec->gen.stream_analog_playback = &cs42l42_48k_pcm_analog_playback; spec->gen.stream_analog_capture = &cs42l42_48k_pcm_analog_capture; + /* add hooks */ + spec->gen.pcm_playback_hook = cs42l42_playback_pcm_hook; + spec->gen.pcm_capture_hook = cs42l42_capture_pcm_hook; snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume", &cs42l42_dac_volume_mixer); snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume", &cs42l42_adc_volume_mixer); diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 09987daa9cbf..207315ad5bf6 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -280,6 +280,10 @@ enum { CS42L42_VOL_DAC, }; +#define CS42L42_ADC_VOL_OFFSET (CS42L42_VOL_ADC) +#define CS42L42_DAC_CH0_VOL_OFFSET (CS42L42_VOL_DAC) +#define CS42L42_DAC_CH1_VOL_OFFSET (CS42L42_VOL_DAC + 1) + struct cs8409_i2c_param { unsigned int addr; unsigned int value; @@ -327,6 +331,9 @@ struct cs8409_spec { unsigned int dev_addr; struct delayed_work i2c_clk_work; + unsigned int playback_started:1; + unsigned int capture_started:1; + /* verb exec op override */ int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, unsigned int flags, unsigned int *res);