From patchwork Fri Jul 30 15:18:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411593 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 C5327C4320A for ; Fri, 30 Jul 2021 15:26:20 +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 2B42160EBB for ; Fri, 30 Jul 2021 15:26:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2B42160EBB 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 BE21B202F; Fri, 30 Jul 2021 17:25:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz BE21B202F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658778; bh=XqJs0ch7G3HZbN41qrBhPNl166hX0c0Wj2MF6+GnKko=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=L49IfFqXhX3BqqeMqgwluekHAx/Nq9P7L/QUmHPYVfyr4WQ6B2z9DPyT7LiOOWJ9N Yay8JVp8cpjXltxvv0MDxLc+icbD+oOT+caYVcipNDVEX2zotYBAls5CrEjh0GvrV2 wzuAqY9zdyrtAISwvTX8Zk4kZe/ciXVS4MIKfA5A= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B5C47F80564; Fri, 30 Jul 2021 17:20:04 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 58407F80548; Fri, 30 Jul 2021 17:19:53 +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 03CF9F804B1 for ; Fri, 30 Jul 2021 17:19:17 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 03CF9F804B1 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="B/ferT2h" 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 16UELBKY004490; Fri, 30 Jul 2021 10:19:15 -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=PRNYuZjnIv1FtKwvEnOYtmAk6iX75MPpxbiK7VxayVY=; b=B/ferT2hM0qtteBazzuvIF/slSK9NUoKxJ+qmoqDX4P9fmE9i8NwZYHtlb9soQu6bnAA R+fcSdGPXRrsv769u97SOXhCRBiJaGVuklugOPVPXesg5XdoNJVxSluBKwZqqt/7Zdy0 8sy4+u4YoH/PsYd1tiXpsA1i9vmMUyOZa9N5l8Olfsi//cOwDkt5SHM0WXV1GoCtpM3n hcsp+xaOHMm1JX4wOMZKtjQSohPLEgWUQMpYzbT2YiyvmqjUUzVUU+ZaULcgWYrAICIv fJCJWZ4ZxCTvk3OpMVhwaIyfTHzAfu8LNerkdbPZqo8XvX/gJ2HuQZe/x7WsSdy5Szys GQ== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:14 -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; Fri, 30 Jul 2021 16:19:06 +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; Fri, 30 Jul 2021 16:19:06 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id AB40946E; Fri, 30 Jul 2021 15:19:06 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 01/27] ALSA: hda/cirrus: Move CS8409 HDA bridge to separate module Date: Fri, 30 Jul 2021 16:18:18 +0100 Message-ID: <20210730151844.7873-2-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: buxE_m5uPjY1fNPwz7wRST_y6mxzQoXr X-Proofpoint-ORIG-GUID: buxE_m5uPjY1fNPwz7wRST_y6mxzQoXr X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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. Changes in v3: - No changes 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 Fri Jul 30 15:18:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411555 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=-14.0 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 5B6D9C432BE for ; Fri, 30 Jul 2021 15:21:20 +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 B1B2560F46 for ; Fri, 30 Jul 2021 15:21:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org B1B2560F46 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 5A1F51AB3; Fri, 30 Jul 2021 17:20:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 5A1F51AB3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658478; bh=nXotjjtOvshzr+tWtEXcilFEhXa62tt1NH15vJeSXcs=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=O7gAURrIElOOZgxaQLZRSDIvveozboOieBFAluNPOhkWND4ePkXXp12UsG9ggno5g 7kngyP38DvdAOqgzFHmJZJZS/nLFNCrlLotLIeNKsUIu9gEKc2to2tCH0/5VveyXOM 5wG+EOjxNnlyF3YrcPNPM4OjWqVYh9aTO4hJ/JNI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 25A7BF802A9; Fri, 30 Jul 2021 17:19:34 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id C61A9F804E6; Fri, 30 Jul 2021 17:19:30 +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 D662CF80212 for ; Fri, 30 Jul 2021 17:19:17 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz D662CF80212 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="aa+u6fr9" 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 16UEL0da003614; Fri, 30 Jul 2021 10:19:14 -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=9Kx9BsFO9dNzEKW7mqFOtP20g9jFZ71/Ye9aVZkJ8Eo=; b=aa+u6fr9Eb205Rp4av8nEhjShw7F/DgXDn40pnyox7t0sQaRdijpCGVKmTJuBqrjw1LR 7HVi5xqxVXdxF+NRYgcDHmnKAMogn91lzN2KINK1Cb6gov0IF9dFJe14KFWTSyG0hdQc XuxHufx0UF318UF4PwaESBrDe25mN1NMPcL1e7Nj4NnGmVXXnfC6GfzTbdqie+v7JiHm zXNpB2zthFX0bWW8Cgzate73XCbp97og1TQquzgJN0zPIAfQ6JpHoNZ8Uru2fcOBnxbU IPwNGFrLT3qBQEPmN4qR5gn53JIi8vgVy+/Uo2hOb7nJDGIU7JW72AcJ0abmquTXpAS3 fg== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:13 -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; Fri, 30 Jul 2021 16:19:07 +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; Fri, 30 Jul 2021 16:19:07 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 00E8245D; Fri, 30 Jul 2021 15:19:06 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 02/27] ALSA: hda/cs8409: Move arrays of configuration to a new file Date: Fri, 30 Jul 2021 16:18:19 +0100 Message-ID: <20210730151844.7873-3-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: xAt8I9x5fJ8SIAiQPodGRrxZZIvOEOuh X-Proofpoint-ORIG-GUID: xAt8I9x5fJ8SIAiQPodGRrxZZIvOEOuh X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411551 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 2CA04C4320E for ; Fri, 30 Jul 2021 15:20: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 D79B760F94 for ; Fri, 30 Jul 2021 15:20:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org D79B760F94 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 0DF891928; Fri, 30 Jul 2021 17:19:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 0DF891928 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658418; bh=Ajt16E2ZZOvxpoYWsndEMbYhXBnYX79GwnjluE6DBAQ=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=jsaXZHf8PoymIqj2Eql0HoT706p011NG6Zcc/s/uVfKq1snErQj9ukXYzWbT3z45Q YqbzCiFv+eaiZXVzoE62Z75GEOeSv/Jw57/bFbtXSujHo4Dh8C8pcMTcNS8LojJNm8 15VXQCg6zpkk8hPBxYANaLtemW+Rog+hvRToPRag= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 0860EF804EC; Fri, 30 Jul 2021 17:19:27 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 7F152F804E3; Fri, 30 Jul 2021 17:19:24 +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 D91C6F8019B for ; Fri, 30 Jul 2021 17:19:17 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz D91C6F8019B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="aGdluOju" 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 16UEL0db003614; Fri, 30 Jul 2021 10:19:15 -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=2rB2V6jtYNh++iqGEApDiXcs+oA0wQB3mfg+9mbASRQ=; b=aGdluOju4aLLyaFeBUaqAB/WThq67jmSNFQs2iVZ6LbouB1/kJ0GPZM7B2yBBU5mR3pL xfr4R63tLk4m/9/MPaVTp1scaiPcGYgSbcAY1XwwibI0GXrzs2wZTFH0FWM/SXyP47FA MpBTaXzgrbAwede6CRNLdokSlC3m2irefeiXt1weu/1ovQvUtw7IhPmmSgyYEBTT69oe TpKY8bcpyuF76o/tqr7ZHHADWEUH0Di2/cw6mU4DIB7ZEQn65G1PxbhNYCcJbE8+OvrJ o+H/1kBSEJ3Xl3vLhEDfaZpwuAuQUsjgTtLOnm5oZ1JZvLm+gi5l+aHJ4nkcdmCUzQSY Jg== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:14 -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; Fri, 30 Jul 2021 16:19:07 +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; Fri, 30 Jul 2021 16:19:07 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 3AE032BA; Fri, 30 Jul 2021 15:19:07 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 03/27] ALSA: hda/cs8409: Use enums for register names and coefficients Date: Fri, 30 Jul 2021 16:18:20 +0100 Message-ID: <20210730151844.7873-4-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: L8DEocHvLVfzfKJBFAFmR0eFG-EeD5TR X-Proofpoint-ORIG-GUID: L8DEocHvLVfzfKJBFAFmR0eFG-EeD5TR X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3 - 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 Fri Jul 30 15:18:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411557 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 66786C4338F for ; Fri, 30 Jul 2021 15:21: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 D738260F4B for ; Fri, 30 Jul 2021 15:21:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org D738260F4B 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 6B2C71EF7; Fri, 30 Jul 2021 17:21:01 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 6B2C71EF7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658511; bh=MgFexWTudBMqmbAliQ5G3DDZl8OAYEmeJFKnn/UQzi4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=iIbjJHDa4kFGLzLV2AyVCSwPFl3Kh8E2yJMq9xAOs0tMUrRqm2e9U+p0e+QdHu7NU aSrfoVaBtQZPcTx7yPH33ybjRnyDT9Sw+SlUkRzEscDjgZe2tGXm5vwtG3vZ7LSZ0d 1x28Ly6foNqlVYKNuMmdpUi6LZ5KH3IYUC/+gfhk= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 7C12AF80517; Fri, 30 Jul 2021 17:19:35 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 75225F80518; Fri, 30 Jul 2021 17:19:32 +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 6AFBAF8025E for ; Fri, 30 Jul 2021 17:19:17 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 6AFBAF8025E Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="mEyNJ4Yc" 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 16UELBKZ004490; Fri, 30 Jul 2021 10:19:16 -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=K8OUVtkx5MXW4mcNUh8AurLTfJooQUkcdQjXzfU28n8=; b=mEyNJ4Yc+BNqcouwbkMid8c44Nta4I/3I8MudF3H7eAV7TPhwxi83Ta1t1OjUU7iNrl8 4k7NTqSKps00WSionNfNX7mN8Nng55/SU6dN1uIPZZJNAWXmUn52pRAng6ELttEj592p NUf2Rp4efqM+E/moQoZ2Runk/JyuS3ArgobWzVjWQWULBwk3Qg/CYVjUqkcOwkwu2yKf eCldjWAG48WHCUQDc81XWnSuaOW15AMPIlVk1/r73Gr1DZxcPMJUHBqqyr8+o2sgaUnx JpsPsHMBIvwSMX5INGfcXnxVq8My/QDWI4s6xQApHlhJ4kpCu8L0pVj/XXFQyAE3LYnO 2w== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:16 -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; Fri, 30 Jul 2021 16:19:07 +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; Fri, 30 Jul 2021 16:19:07 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 6FAF946E; Fri, 30 Jul 2021 15:19:07 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 04/27] ALSA: hda/cs8409: Mask all CS42L42 interrupts on initialization Date: Fri, 30 Jul 2021 16:18:21 +0100 Message-ID: <20210730151844.7873-5-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: a4WeqlZ1UxEqyI4eoutObzZxJRyIGkOJ X-Proofpoint-ORIG-GUID: a4WeqlZ1UxEqyI4eoutObzZxJRyIGkOJ X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411561 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 E3DFAC4338F for ; Fri, 30 Jul 2021 15:22:43 +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 6A1CC60F4B for ; Fri, 30 Jul 2021 15:22:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 6A1CC60F4B 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 E85351F44; Fri, 30 Jul 2021 17:21:51 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz E85351F44 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658562; bh=v0KtxKFska3QMofvmbtWOvkJ/rPmrl2SO663OGLNaB4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=U4FHJApWNGUV1u5qfdRES1be+c44oURnrcYgx4cX4IcBCOIAAhA3cM7GgSh/1Igac IRsC0oPM3x3uCbyZ32hQryT3UJskEsT+iDWky9eKc6g68M4jyXaekT9ar0OWf6E97Z V2urick4r5H8IjnkF3G3K7I33WbPLUC24R3aSJLI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 22F3BF80526; Fri, 30 Jul 2021 17:19:40 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 1BE93F8025E; Fri, 30 Jul 2021 17:19:34 +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 F20F0F802A9 for ; Fri, 30 Jul 2021 17:19:18 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz F20F0F802A9 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="N+MzE0R0" 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 16UELBKa004490; Fri, 30 Jul 2021 10:19:17 -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=sdNJX5YFNPnPzDGQ1e26y8574N32EAEVl8h95PtVUUs=; b=N+MzE0R0s07OiT43kqWjTXOQbBP4bEDQf3RBe6C9nfwlARHOsmc1HFYTH+sq5jxSB3Eg fI+aT42D2MeAUO0DX2GhX43TTNRN5mgFhbRGbBg30jBiQAaoSKFj+Z5qEKkvCjifV0Em 3JK+Df70hBK66Zeo7mqPqdNLOH8BCqnfDXcntehiGp4IvFpg6Rq3XTthIlEp4P9df+85 +ov3rpTrTlT8LOOWEvLRKL78TnDlWr338odLpHphbnqFi7/6YQIsme4v1ksO94Z0Zbhb DVQqSRYAnXZ4f56dFA6uDZ7yigjh+jD4UdD1tEzIHcVws7HHHBlBFPYRgNY4QfHtqGN4 FA== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:16 -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; Fri, 30 Jul 2021 16:19:07 +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; Fri, 30 Jul 2021 16:19:07 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id AFD5445D; Fri, 30 Jul 2021 15:19:07 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 05/27] ALSA: hda/cs8409: Reduce HS pops/clicks for Cyborg Date: Fri, 30 Jul 2021 16:18:22 +0100 Message-ID: <20210730151844.7873-6-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: mHocgNSMHFXFwaqJJ7UKr4jvY2T2CHTM X-Proofpoint-ORIG-GUID: mHocgNSMHFXFwaqJJ7UKr4jvY2T2CHTM X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=930 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411559 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 9FD9DC4320A for ; Fri, 30 Jul 2021 15:22:16 +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 EE2E460F46 for ; Fri, 30 Jul 2021 15:22:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org EE2E460F46 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 7B8891F30; Fri, 30 Jul 2021 17:21:24 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 7B8891F30 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658534; bh=9nlbypjhBKGjS4xH3B0RCVMJz6vVyn5bXoUuPO8Qt6w=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=c4Vsr2JXkKG2US0y3WB7LSw6KXjHSgsUQQxaT3kc5/ivsxJiLBp6utiKEIAY6l/Nd vVXnc+aPFurXKGbc7TruL8TR6UARU2+xDu1j3gOz6M6XeCWV8dGKzBQLkgNJGXxYfu T7PCFaPJL32MFthIaZ13IwcfLMhwzU52wXbEF1QQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 5070AF8051C; Fri, 30 Jul 2021 17:19:39 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 81ABCF80517; Fri, 30 Jul 2021 17:19:33 +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 30FC4F80253 for ; Fri, 30 Jul 2021 17:19:17 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 30FC4F80253 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="VBpuQ8FX" 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 16UEL0dc003614; Fri, 30 Jul 2021 10:19:15 -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=Zd/RDxP2XaDPsJNruJHbBUQdzVkYO4aWDGlyG9+WR3w=; b=VBpuQ8FXBvkwOuaTZiFn+REWTmYrzPj48WNGv/A6ZdlWnCHKdXVBtxmDX3ycYzK4rvsB if1HGSSNemB1WD1ybego341fvtXOZuSVLYyL71NVDaHDe67e5VJsCr4X5wrbx7KCPVWQ sX8LpVPTATkPkioqyX2yJ4tye146Eb+bFhWc6QnsZP1YYO/mZgTHDM95iZX0pLYuyeBb FKIYnavPCbJj+XJ8xJG2+cJXpNDxMA8464eRT7SVcFrp0GFXC7CqwNmaYExuXNRP4Z1j rYp0aenBrpp7NHfDQfDMrP/ITQpqOv0wydRVMdxopgxuA+8nQ6RWgEB1juoShX2H+zuO Dg== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:15 -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; Fri, 30 Jul 2021 16:19:08 +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; Fri, 30 Jul 2021 16:19:08 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id E67F62BA; Fri, 30 Jul 2021 15:19:07 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 06/27] ALSA: hda/cs8409: Disable unnecessary Ring Sense for Cyborg/Warlock/Bullseye Date: Fri, 30 Jul 2021 16:18:23 +0100 Message-ID: <20210730151844.7873-7-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: iRLKhLFLB28fYKSb43zMDf0mY4HhnM7w X-Proofpoint-ORIG-GUID: iRLKhLFLB28fYKSb43zMDf0mY4HhnM7w X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411591 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 7DD84C432BE for ; Fri, 30 Jul 2021 15:25: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 017C160F46 for ; Fri, 30 Jul 2021 15:25:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 017C160F46 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 9C94D201C; Fri, 30 Jul 2021 17:25:03 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9C94D201C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658753; bh=o3O3U1g+jLBWkzHk6nReWolAChi8nucrv+F3JLzI5AA=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=uYl2S3rV3G7qqoU9YeB7JT/dVLromh3r+88fP8bGZ6mgAAAc2ZSBgawgHGsejMuzW SvUKuJRsO3uHzP0VoikllZtCjztMrS3iRtMeiKEVYQm0yTZoq8CRE8DK6R54QKp8lp Lj2Xu+MaJ5GdHrkh0buNYmDN5DVs7yC2p5tzVemw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id E4D33F804FA; Fri, 30 Jul 2021 17:20:01 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0D669F804E5; Fri, 30 Jul 2021 17:19:52 +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 97E8EF804E2 for ; Fri, 30 Jul 2021 17:19:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 97E8EF804E2 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="cC7nR0O4" 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 16UELBKc004490; Fri, 30 Jul 2021 10:19:17 -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=GyuBDKCyV1SaoYri8Dc97gkB/CeJ6cBI4M+5dF98PXM=; b=cC7nR0O41CDT9JX3QVu9FpLpodBgYCqkfV2T/SfJYB3zMWTpV7PWg9/rFTv93Ou9O31X KShqcZYmTeqSer6B7DjJQbZJmf0qHlN/mCgx1wCWYywVrlLEShgp2f6F0DkWqahBLGnF o3aPmqfsISnkq54AJx9PCsYNxMJHGa9uKbYNsdFkWuFXRgYvpra3AsF3Mo3xjpKJ9uPf RGfEuB3l/oKlE87rgjL7Pll8EP9s0+6Nb2b9jB+Si+kfAVaTdq8ADh2jut5oZYKHZ5LB R3vlpKNBL4hSjWzQps/4H/YsmBMNQ+/hZFZqhoIK5RTRAFYXowS3ks5W8LDg3Ofr1K7l hw== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:17 -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; Fri, 30 Jul 2021 16:19:08 +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; Fri, 30 Jul 2021 16:19:08 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 3509245D; Fri, 30 Jul 2021 15:19:08 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 07/27] ALSA: hda/cs8409: Disable unsolicited responses during suspend Date: Fri, 30 Jul 2021 16:18:24 +0100 Message-ID: <20210730151844.7873-8-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: zFd4Bgtw-Iwn67I9jovgG-GMJAn_fMlw X-Proofpoint-ORIG-GUID: zFd4Bgtw-Iwn67I9jovgG-GMJAn_fMlw X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411565 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 6D971C4338F for ; Fri, 30 Jul 2021 15:23:20 +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 ECD9A60F4B for ; Fri, 30 Jul 2021 15:23:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org ECD9A60F4B 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 864E51F7C; Fri, 30 Jul 2021 17:22:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 864E51F7C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658598; bh=GECveVSI+76S7QwM4p2tiEtrSQ+HBwehai/F/frHvYM=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=ojEZVRvuYgMjXvP2CK1tIsCBl7179NlYtPaqEvqj4eMPOwQcSahjGQcNOlcAfqcAK rOjcbrd8dFgQQhKko2vmGqfH/rZC04DEet9uscuVUxTJEuKYhk/V6bv967tPcK9eI7 6iShViNjWacz8p4vQbkcH/CwnbSI8aGkmqKhpzoE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 72010F80533; Fri, 30 Jul 2021 17:19:43 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id DEDDAF8051C; Fri, 30 Jul 2021 17:19:36 +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 8B9B0F804E1 for ; Fri, 30 Jul 2021 17:19:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 8B9B0F804E1 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="PsY6R2Bn" 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 16UELBKd004490; Fri, 30 Jul 2021 10:19:18 -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=SY3gWby+jsBVNB3sOjtEiZnHHv37iz01pUDXfInWjtM=; b=PsY6R2Bnyv9bTeNgr8azqwhJ3IpzWvkMm6qJth9os+ud6S0sGMlguJKv594jk2JkMec8 ddSHJ3pG5Xru85YUNFyT2RuljO3Vx8ebYwITOzXMHxQ/QNyiXOaH/9prI1wzrvRNawjR S4yrKMK07gX7SGl5iIRr81Zm7w91LQfFDrMgFqYUgEHLzD6r9HnKnx9WFd3JI2jnmCYU gMN5SChACKyIpD1kVKee9EJKVP4T73vhvT7DrB/vHmByHkESmr++PIFnth4vs33HC4TV f6VUpq2YhYSo4dgkKKVtRBQ+r5EY2i3JcKGGMMlAsXyX1NpbCxs/8ngO77AcInunhkG3 rA== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:18 -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; Fri, 30 Jul 2021 16:19:08 +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; Fri, 30 Jul 2021 16:19:08 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 6D61A46E; Fri, 30 Jul 2021 15:19:08 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 08/27] ALSA: hda/cs8409: Disable unsolicited response for the first boot Date: Fri, 30 Jul 2021 16:18:25 +0100 Message-ID: <20210730151844.7873-9-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: gJ3H8hOzuS3Le2_v9QZBZOXz0HrGS6Ph X-Proofpoint-ORIG-GUID: gJ3H8hOzuS3Le2_v9QZBZOXz0HrGS6Ph X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411569 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 25368C4338F for ; Fri, 30 Jul 2021 15:24:12 +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 A944460F4B for ; Fri, 30 Jul 2021 15:24:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A944460F4B 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 477081FBE; Fri, 30 Jul 2021 17:23:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 477081FBE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658650; bh=kKLpOLWA9vVxg+OzFwoqrVqFxWeKnSkgrkAXhXbyNM4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=uH3E50p+DCtlBbwSkU35pLcyyQ8w68ZgbDzDGZQeDRwY+TAfwQTLED6kEkUnp5a9f UZFEHN5RYT7BSK9f/NhHkGbJ2xjurb9A/jsAxK28MJu9sgzF3jJhOGRHqOx6/mM1ws BIj8yMG84MeRmgo/UKr4HC2qB61BzfjigubKzJAA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 45326F80544; Fri, 30 Jul 2021 17:19:47 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id BA935F8051C; Fri, 30 Jul 2021 17:19:38 +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 EC9F7F8028B for ; Fri, 30 Jul 2021 17:19:18 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz EC9F7F8028B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="Ah2iLbZr" 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 16UEL0dd003614; Fri, 30 Jul 2021 10:19:16 -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=WKlGN4RkhYQZrnAwtQH2778vJN/8PBcw8ThBUQ4dR2o=; b=Ah2iLbZrV9vUQxUhMGtciVQAVB9dfmrbH64nDF6XV20i8tGh1t1PEnAEi4F6U06K0K3X mct5kHnxFq/WVUduts7BPzZWgci4HoPb7IGdB/agQEz2EgI+V1q8E8+rej5jO19A0WtK A+o8JjmyBSaxk5UmbljC/elrlxCeko3zxaOWJFEXnrjjKRqlkcQQ6DFaQYqbOuLlkrbd +nyS/hofHVXU4sVtvmlxITyoyngrUS9wyhCST6b6Oc361m8Tbp0hbeNfGm+8UktBgGib vzhJqFRe9Mmv0QF4WUUnIiaCZhDANUO1dkGF+8ywNxw0ZgtcZoYrsbdbZXCDgGa/N1va Rg== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:16 -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; Fri, 30 Jul 2021 16:19:08 +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; Fri, 30 Jul 2021 16:19:08 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id A4D472BA; Fri, 30 Jul 2021 15:19:08 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 09/27] ALSA: hda/cs8409: Mask CS42L42 wake events Date: Fri, 30 Jul 2021 16:18:26 +0100 Message-ID: <20210730151844.7873-10-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: OVbprVk955y4o4qhLHfJN_uDan8nFauZ X-Proofpoint-ORIG-GUID: OVbprVk955y4o4qhLHfJN_uDan8nFauZ X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=985 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411567 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 305A4C4338F for ; Fri, 30 Jul 2021 15:23: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 A9FE660F46 for ; Fri, 30 Jul 2021 15:23:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A9FE660F46 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 53A7C1F98; Fri, 30 Jul 2021 17:22:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 53A7C1F98 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658619; bh=p7pxk6L85sZFs+9EnI+0ul7uQsPS9+H3uiy+QFWZGcY=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=VLGfBx8mc1fn1nF9+Y2R5Gvj2AfSxz6WUu9x8T9YTYXVqjJBX2llqmzb0PL/XVboz alPQro+sanzFta78Nd7fYdTnOgEAolCZpktCLotlLv/pfzRZN7cYsTmMNBVEIoPpI1 bZpNfi4BAu0drue+4unq1MGNgfvS+PM7CQYVdPcA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 63B81F80538; Fri, 30 Jul 2021 17:19:44 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6DFA8F8051B; Fri, 30 Jul 2021 17:19:37 +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 03DE9F804DF for ; Fri, 30 Jul 2021 17:19:18 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 03DE9F804DF Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="oF89afQO" 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 16UEL0de003614; Fri, 30 Jul 2021 10:19:17 -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=qXnhA08RtU4zCi8AoDT0rgBXkwBCgCERbCi2OvDOJpY=; b=oF89afQO6kTdjyBg2dgJY2SrRxmeDKrOod/EJmTo7u1rGPWaAeaiFrQmcH+r9IoUY1oK xmPOlnzGReg0aRjUFBmi+6S38pHexmLQZrLg+r4ep294tfiyu0qZqJB4WjTC+eXVuuQv PxRFLZrNI9cdIVjF0UchNRrvaQlyYUU3oYmOqQrwLgTOm7zsbnjyBGg1nNTbVTxXqpYi fibldAUPmu7MZxeBy9536HOZiZax+Cu9nUyzmvjRVAiJQu/kIFL6AGr8dTwgQ+07bKqY e+H0U7vbPrvaLWxmgq0v6lVZvxOaXyEzoMBsabgEMJx0mgNeEmEjt20kCnFHNfxF7kU4 5A== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:17 -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; Fri, 30 Jul 2021 16:19:09 +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; Fri, 30 Jul 2021 16:19:09 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id E2C5046E; Fri, 30 Jul 2021 15:19:08 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 10/27] ALSA: hda/cs8409: Simplify CS42L42 jack detect. Date: Fri, 30 Jul 2021 16:18:27 +0100 Message-ID: <20210730151844.7873-11-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: BX0fg_c5JvuheRCoVMrj8VuI8GhuKuuT X-Proofpoint-ORIG-GUID: BX0fg_c5JvuheRCoVMrj8VuI8GhuKuuT X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=839 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411563 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 BE459C4338F for ; Fri, 30 Jul 2021 15:23:00 +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 9C06D60FE7 for ; Fri, 30 Jul 2021 15:22:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 9C06D60FE7 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 339221F32; Fri, 30 Jul 2021 17:22:08 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 339221F32 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658578; bh=DxkaBpHZTtSGJq2/tx/bcpvXlfXUeyD3c+A0Dih8XBQ=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=bapzHV4yfJ+WQEFmrHR3ej5mgRhX9izKVf8UfwfJLmyoT3pWbUOlBAbhrNbUbUF6R xmLsSPvd3gcAVpx+7Q0CB15DVgZgl81q8HIVdxCDkmZSs6hqrTcBAcwEyW4O5ov/7N Q7KLbCzr8ZCCZA2yECl6AyqopebOy2kZHZDJ6OnU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 11B3AF8052D; Fri, 30 Jul 2021 17:19:41 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 96A17F8051B; Fri, 30 Jul 2021 17:19:35 +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 AC092F8025A for ; Fri, 30 Jul 2021 17:19:19 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz AC092F8025A Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="YUcTjmrZ" 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 16UEL0df003614; Fri, 30 Jul 2021 10:19:17 -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=u/raanWu8QxKw7hxEaMYUQ8wjoKB+rgkVuf1kEvYiUU=; b=YUcTjmrZSHI2cDqTVPeK6rvlz7mcdzI+oPkmMRAfYk3iLCpzo4o5OPtOrUxM9Fz0vnyD BUMd2yWIfHCoa5WOPhTrHbV4o7BLO2sndqzeLv/pPxaskkWl8DGNd+k4ywoOocM+lnNa 1DJhg0NOcPuuE4CWpMr5NfCozXGwwrcSNgcaSNj0nYPRzdIQBR2RRYXz/uGrV0JxjEus 7mLS+I8H6cR/IxhjGCLoXC7J3zETveA7+diwPyfeXoEwOpVT9WhCflGk9TeCWbBbxnQ5 NVbs4lARN64wsD/hbUc8C6O1Y5rBI7qfZfH4RaVniht1a0GrUaLejcbvukskUmasaEDG vA== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:17 -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; Fri, 30 Jul 2021 16:19:09 +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; Fri, 30 Jul 2021 16:19:09 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 22DEB45D; Fri, 30 Jul 2021 15:19:09 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 11/27] ALSA: hda/cs8409: Prevent I2C access during suspend time Date: Fri, 30 Jul 2021 16:18:28 +0100 Message-ID: <20210730151844.7873-12-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: GVslHpCjrnPGDDMmvazMJ7M8BKSt3lkv X-Proofpoint-ORIG-GUID: GVslHpCjrnPGDDMmvazMJ7M8BKSt3lkv X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411597 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=-14.0 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 5C9B6C4338F for ; Fri, 30 Jul 2021 15:27:17 +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 D1A3D60EBB for ; Fri, 30 Jul 2021 15:27:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org D1A3D60EBB 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 72C1E2061; Fri, 30 Jul 2021 17:26:25 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 72C1E2061 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658835; bh=TEgif/ypjbU48okXspV60CqhkCT3fuCqORFHv5S3Mp4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Zif3uxGuz3q2aItYk5iCB2WBxx8gDOXgCs6mC5jjpqtTADHyCchY+2yrP8AE0PeWt ot2kWq2DedR3LCZLGxlSdx2BV5sDq3gy5PjsMjmgKOdVV6WEqx+qVr1S13izprFSQb KPz2qkKW3x6lastiy7y+UKmiIrItrLYrOa6dN1xg= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id F3D51F8019B; Fri, 30 Jul 2021 17:20:11 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0C957F80559; Fri, 30 Jul 2021 17:19:57 +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 4C450F804ED for ; Fri, 30 Jul 2021 17:19:21 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 4C450F804ED Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="FWxl4IJ/" 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 16UELBKe004490; Fri, 30 Jul 2021 10:19:19 -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=jcwnYwwAbgxy9esPuv1XX+/Ga/4UwxSjPTcSU4qpyIg=; b=FWxl4IJ/cu7Q9s5c1T24BoKYuUbtsfu55FfjOZaJBIrLDApqDuyUaXPYOZS6UN297pRZ 3z7gllcsJNf5JpFP3ESreV9u+Kf5ADd+0Nskv9NvSqIfSUQ4HE9Wd8Xe94Dea1fSGM4Y 7mxHjt+p6v+N95uiyv6oFjITnYCGfP9EErTUrXB9+zkWNvBbr5tgj87ywA8a2hiZ+i+B sbiy7SR9cGt8+YzgYA08HYuU8P4EA2dbZPULd6KneJDQ0ClcitTb5BbiceE1LfbeML3B Q53CHRdsXsQ8f/Rz8v9Hyea0QA3/sZc4/MMKi2tZeak5nyt7RkR/rEBT7lce+qPR6/Tx uw== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:19 -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; Fri, 30 Jul 2021 16:19:09 +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; Fri, 30 Jul 2021 16:19:09 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 58D5F2BA; Fri, 30 Jul 2021 15:19:09 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 12/27] ALSA: hda/cs8409: Generalize volume controls Date: Fri, 30 Jul 2021 16:18:29 +0100 Message-ID: <20210730151844.7873-13-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: EpLTeiBCemHUKEkfsr92aDtPr_-5rccP X-Proofpoint-ORIG-GUID: EpLTeiBCemHUKEkfsr92aDtPr_-5rccP X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411571 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 A30DAC4338F for ; Fri, 30 Jul 2021 15:24:31 +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 2C77860F4B for ; Fri, 30 Jul 2021 15:24:31 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2C77860F4B 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 BF1631FDB; Fri, 30 Jul 2021 17:23:39 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz BF1631FDB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658669; bh=gcnyQ7WgZAwdPc554rD4y+4rlXLkajNQc4a8EdnVTss=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=KBMaB1OB7ikgq5VhqC4tjQLeS8ctgmQkDtXmsgIr8onBCtIWwsrxFuXBYpBHOXluI bpZuPvDP7FNZrcWz5KqO1Yc/YIaU36M/woAPxq5ENgyQ5nBRa1mh1ZMQWFQCZEqrUQ rFcHRVrNefw7kEsjiuKKksTHDMcDrhRDeRVkgV0A= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 5D8DDF804E2; Fri, 30 Jul 2021 17:19:54 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 9F7F6F80534; Fri, 30 Jul 2021 17:19:42 +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 8ADD3F8049E for ; Fri, 30 Jul 2021 17:19:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 8ADD3F8049E Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="Ix/ajP3H" 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 16UEL0dg003614; Fri, 30 Jul 2021 10:19:18 -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=x+8N5rtoDpowqZ1EFeAifI9PMkD9XbHHnj9C9dge1/4=; b=Ix/ajP3HYUi714LESobw6J4JU0bklJD4API6XtkV+9Jh0S8Sp/Dbpj1io5xyq8pESvP2 tXo7TmznSu4pT0CNnjGOb4fH/Y3Ykv3XiO6aFcRHUXgZgm8n9gesF90W8N6MUiA2Lz8r hejvHQG6h66i8DpS1NP0tsHTksUPSvxy+KLo0m6M3C4IpncDGB/x/mmJvJULAn7SUFI9 lllYMIxqhdBw85TnczAnwWSkfhfLin+3+Bb1X2hpWAPpifVZMZf0DmR5Cb9C+2xXWjnf uVBYnQPEaTw3tcYYIDCi8RwOu14JLoYsUlYb2J6ytxi8S7Ar1iM8OE+eTGoE9U0l/PhJ 7w== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:18 -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; Fri, 30 Jul 2021 16:19:09 +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; Fri, 30 Jul 2021 16:19:09 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 8D10246E; Fri, 30 Jul 2021 15:19:09 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 13/27] ALSA: hda/cs8409: Dont disable I2C clock between consecutive accesses Date: Fri, 30 Jul 2021 16:18:30 +0100 Message-ID: <20210730151844.7873-14-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: c1JEct2FLvZptsQHDHbNQn4lAWAHNWgZ X-Proofpoint-ORIG-GUID: c1JEct2FLvZptsQHDHbNQn4lAWAHNWgZ X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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. Changes in v3: - Cancel the disable timer, but do not wait for any running disable functions to finish. If the disable timer runs out before cancel, the delayed work thread will be blocked, waiting for the mutex to become unlocked. This mutex will be locked for the duration of any i2c transaction, so the disable function will run to completion immediately afterwards in the scenario. The next enable call will re-enable the clock, regardless. sound/pci/hda/patch_cs8409.c | 64 ++++++++++++++++++++++++++---------- sound/pci/hda/patch_cs8409.h | 4 +++ 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 08205c19698c..1c75aa262ebc 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,45 @@ 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); + if (spec->i2c_clck_enabled) { + 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 the disable timer, but do not wait for any running disable functions to finish. + * If the disable timer runs out before cancel, the delayed work thread will be blocked, + * waiting for the mutex to become unlocked. This mutex will be locked for the duration of + * any i2c transaction, so the disable function will run to completion immediately + * afterwards in the scenario. The next enable call will re-enable the clock, regardless. + */ + cancel_delayed_work(&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 +160,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 +183,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 +206,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 +227,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 +573,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 +663,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 +815,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 Fri Jul 30 15:18:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411595 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 92D37C4338F for ; Fri, 30 Jul 2021 15:26: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 12AC86023E for ; Fri, 30 Jul 2021 15:26:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 12AC86023E 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 B3D892046; Fri, 30 Jul 2021 17:25:44 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B3D892046 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658794; bh=XJRMptHMOjdUyTg7HUrURq2FBvyS8Tu3ngitlX9u7uI=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=skl1be7YHmzBVDAvKTXivzcUhOHJnHP8/K7z8dqoxRimU/MYDWr+yhJPUUyxyx71e 32UDXDLSU9pFdhtIg8YTbClQ/aSPKqYlEVJ4cddHhDo1sPvALPPQRIm9eDXVbRPXn1 aXtVPh01Azli6/XMoRJJZCSXvdFKRmqjRESkH+hA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id D3DE5F80568; Fri, 30 Jul 2021 17:20:05 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 664DBF804E0; Fri, 30 Jul 2021 17:19:53 +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 DD95CF804E7 for ; Fri, 30 Jul 2021 17:19:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz DD95CF804E7 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="EJ5CFhxr" 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 16UEL0dh003614; Fri, 30 Jul 2021 10:19:19 -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=TixhcZY7/wbCBALVUdI2rnLLWXDwWmwgoIeBd4GXQgg=; b=EJ5CFhxrodFAVeFLh/eoeVyWPAffzdEd4pFTUy2eLHUCgE1ICr/uo9NmJggeWZC27fML LPx+O0tiC1/Q+0u/HcgvIM45ZhNDS8MIo6esCqDZM34EcA9CDr1/a8PUPNMMAzhYmMXS 9moYpJSiAy/Png6zQw33c5ZOxQWfPDlmpnntrGQqAhOyYQ5XI5f5M64WYft6X6Dkj6rF vwJJZo0BcI3Ozgk/Hzl2C5YIFVgzAVkU+ZnaxsmIfMu9xK37pbr5Xw/3KAesJLZxPwms do7DGDxkofVCKygfZDbpdeIQoh1NLYnm0tVhCiyMGJGXHcMm2JLtlnOXRDEs9gRZ+cqU FQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-8 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:19 -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; Fri, 30 Jul 2021 16:19:09 +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; Fri, 30 Jul 2021 16:19:09 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id C566A2BA; Fri, 30 Jul 2021 15:19:09 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 14/27] ALSA: hda/cs8409: Avoid setting the same I2C address for every access Date: Fri, 30 Jul 2021 16:18:31 +0100 Message-ID: <20210730151844.7873-15-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: lezbnKcJAK_6LBqL-CjEP85LtiXl-b3e X-Proofpoint-ORIG-GUID: lezbnKcJAK_6LBqL-CjEP85LtiXl-b3e X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=983 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 1c75aa262ebc..194d336cb060 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -140,6 +140,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 @@ -161,7 +176,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); @@ -207,7 +222,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 Fri Jul 30 15:18:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411589 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 2CC83C4338F for ; Fri, 30 Jul 2021 15:25:31 +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 AB57560F4B for ; Fri, 30 Jul 2021 15:25:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org AB57560F4B 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 472D9200C; Fri, 30 Jul 2021 17:24:39 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 472D9200C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658729; bh=0KXmR6duHaFx6e8XWa9ZeeGivs4ck86zDHE0ruejaAw=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=PEf9FmhcUafBniFgNRRHqwVjRC/gbVo2BlAWcFjmP0sYuNYIDAOqlyNw6TyqJjfjk 6VntqXxucibZ92TOJWs9lQfoPmyVy9uhfEKg83joAeXrqMjy6l+DTfKEbPszT7bBxW dEFwKdJ7vful/bIEnDr5VPOpynO4x0fqCq3T54vA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 678A7F804EB; Fri, 30 Jul 2021 17:20:00 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 2E495F804E5; Fri, 30 Jul 2021 17:19:51 +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 910F3F804E5 for ; Fri, 30 Jul 2021 17:19:21 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 910F3F804E5 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="LVwzmGqR" 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 16UELBKf004490; Fri, 30 Jul 2021 10:19:20 -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=74oP7/xqNX6orDotETyzf/XTbYFaTr9rGi5Nj2AWXIw=; b=LVwzmGqRYN+V/FjO8DUmbdR5q5aXUncRhLHIxgHUFPT93bUArYoXTZBF0XLcFTPS6Mx6 AlroHKiNtrSLv8HEAGkUj6KCVTNeXYyOYcTwO8NCQFbcaPU+1b81js9eMsxMs+3k1U1h +Lz40WQAwuNbglJhU6UAw/AWyiKY6AUtctBC+u+tvfId18+7XlSC96GNX4nsKnDSthXM WsvQ5fxtpD2icfKkaSIqegqoqoOwCSvhHylYy9uXpCrbeTq7oxY7sk4FtJeypnW8gvqq C58FZywkgDX6sjZ4NrboKl+dMmhDRZKR7e3BDfqVC9mklqt0f3Fre1G2OgKsX+43zM0d Ug== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-8 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:19 -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; Fri, 30 Jul 2021 16:19:10 +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; Fri, 30 Jul 2021 16:19:10 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 0A58B45D; Fri, 30 Jul 2021 15:19:10 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 15/27] ALSA: hda/cs8409: Avoid re-setting the same page as the last access Date: Fri, 30 Jul 2021 16:18:32 +0100 Message-ID: <20210730151844.7873-16-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: yXlWA1f9QdXSdibjSqbW3iJQFwx7YBWl X-Proofpoint-ORIG-GUID: yXlWA1f9QdXSdibjSqbW3iJQFwx7YBWl X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 194d336cb060..a6aaeabd2279 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -155,18 +155,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; @@ -178,13 +197,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; @@ -207,13 +223,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; @@ -224,13 +239,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); @@ -310,14 +322,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; @@ -326,7 +338,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; @@ -352,14 +364,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); @@ -376,20 +389,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); } @@ -402,20 +415,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); @@ -431,7 +444,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); @@ -465,9 +478,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); @@ -480,7 +493,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); @@ -507,7 +520,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 { @@ -574,7 +587,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; @@ -630,7 +643,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); @@ -639,11 +652,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); @@ -749,6 +762,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 Fri Jul 30 15:18:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411617 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 BB541C4320A for ; Fri, 30 Jul 2021 15:30:59 +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 393AA6052B for ; Fri, 30 Jul 2021 15:30:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 393AA6052B 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 BE7412113; Fri, 30 Jul 2021 17:30:07 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz BE7412113 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627659057; bh=d31UY4exa8XahjoKDH0MuoOPc21t8tNpKGarAuYkR8Q=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=LplgSMHjQYIhbX1aHvd2DDazUvxBuG3IBYai1cGesQ2DJXMmk4SiCJcUSB/ZfPF4m Diw4Z2cRi9/alaE5ekdPqcJmyZH7vzShrf4z4YD4cW/qm1S4Ys7DLbpoh81yXFUbkR 3eliIXl6QOk383C2tC3Z6pTbNiesuo6XSVffjk8E= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id E2A07F805E8; Fri, 30 Jul 2021 17:20:20 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 82BC5F80588; Fri, 30 Jul 2021 17:20:11 +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 91041F8019B for ; Fri, 30 Jul 2021 17:19:22 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 91041F8019B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="q+53uzcf" 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 16UELBKg004490; Fri, 30 Jul 2021 10:19:20 -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=sAbQ29dPYV+oaYxS5NowDKFQkOMcXcnzbp9s2IIodCQ=; b=q+53uzcfwB/0DYCl4hqNDZgUq1e37k8mUsdHlhLLBTu0f8r8VHfVh570zwkk3oNOYKK4 pe4/o1dRSrQBFqhqSYywEv91j/i1b+W3Z0cFIjynt7kBabef5PsKlmidDiOkJk77+MLz 1H0jQHREDtbA4oDSSCdocT3baE2cq4jdoI1MXNVZekgbDCkN7Hmt7FAAAktJ8H3rQFDz 8geyKSR1Iajr+xDps3ektXan489k0eIkxs7HYDD7SWt02r9wwEvIuWepF3mdmsKqma75 6vKIJ27j1OqJ/BJR/r/zeqVHRL5qHxVtEXBOwO/AncwKspBt/sewyNrtOGZQWt4o3ptB Bg== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-9 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:20 -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; Fri, 30 Jul 2021 16:19:10 +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; Fri, 30 Jul 2021 16:19:10 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 465C046E; Fri, 30 Jul 2021 15:19:10 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 16/27] ALSA: hda/cs8409: Support i2c bulk read/write functions Date: Fri, 30 Jul 2021 16:18:33 +0100 Message-ID: <20210730151844.7873-17-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: ehdtJ1K137wM6vW6ItY35mvt2ZlJchjj X-Proofpoint-ORIG-GUID: ehdtJ1K137wM6vW6ItY35mvt2ZlJchjj X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 a6aaeabd2279..9569c06bdc48 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -81,13 +81,13 @@ 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); if (spec->i2c_clck_enabled) { 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); } /* @@ -180,12 +180,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; @@ -194,41 +194,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; @@ -236,25 +285,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) @@ -318,7 +415,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, @@ -331,16 +427,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; @@ -353,6 +446,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); @@ -366,25 +465,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. */ @@ -403,17 +490,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); @@ -432,22 +513,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); - } /* @@ -475,15 +540,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; @@ -491,10 +552,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 @@ -518,10 +577,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 */ @@ -585,10 +642,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; @@ -638,26 +693,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); @@ -746,7 +798,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 Fri Jul 30 15:18:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411605 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=-14.0 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 990A4C4338F for ; Fri, 30 Jul 2021 15:28: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 156826052B for ; Fri, 30 Jul 2021 15:28:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 156826052B 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 AF8F52094; Fri, 30 Jul 2021 17:27:44 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz AF8F52094 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658914; bh=LaoimItoQgfFf6FN55jqLQNxkJ1iDMgJ74bw6fKvgpg=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=ayqvddg77RVqxHylZI/ZSZkcLWdzRotIEU8UmNEFnMAvZEJbyxCyCtdn0Uld+L2RT 1obq1D8ThLlFeMkrp0rULoUW5cJplv0FDSV2lfXfA5pj57Cs3Kyl9zSOOmnNueqjNB 0M46x+YxpLbHjtQHeJkpY3UREScSQcGMAMp+gL3k= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 581DBF805B0; Fri, 30 Jul 2021 17:20:14 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 5AE38F80564; Fri, 30 Jul 2021 17:20:03 +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 34AF1F804F3 for ; Fri, 30 Jul 2021 17:19:26 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 34AF1F804F3 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="m+MzkfIc" 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 16UELBKh004490; Fri, 30 Jul 2021 10:19:21 -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=N4Jr3E2QGvjYiJs1dpH4KuNvC6pZkwKIPCb7FQLBvOE=; b=m+MzkfIc9ewb4Mj4zDl6N95d361MDeB7ofsdrUtlBT9M0d93ve/vwVSJjfhUpNheb6ot Nbjc0hy10jPsLD4aD8IonLFEdOcthyQ+iD/A4H3wnfjxipB1uXu/n5zquDg+soA+C6Pp qp4BV5ljyWlsFPT56YsfhFlESsihSHYBy4WTX7M3+kgPbxriXcK8jLx7bN/YMpyRRYcx ryULnBU2rH4nB6B4G1uoL9Wo390yrrnQSHhKsheSclX3wG36SU3wZpW4R02qxeXX+AtT Z6LBg63A3tPvGZQQgObhA8Ijn+CACRYURfNXQ13DtmiTooYLNLpEwPcLKglPduCCv9MU Qg== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-10 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:21 -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; Fri, 30 Jul 2021 16:19:10 +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; Fri, 30 Jul 2021 16:19:10 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 826D32BA; Fri, 30 Jul 2021 15:19:10 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 17/27] ALSA: hda/cs8409: Separate CS8409, CS42L42 and project functions Date: Fri, 30 Jul 2021 16:18:34 +0100 Message-ID: <20210730151844.7873-18-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: O0ACObWgL58zyv8Xom2hnCpRaHAgYukp X-Proofpoint-ORIG-GUID: O0ACObWgL58zyv8Xom2hnCpRaHAgYukp X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 9569c06bdc48..257dd9006786 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); @@ -354,7 +361,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); @@ -365,12 +432,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; @@ -379,7 +446,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; @@ -405,7 +472,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; @@ -417,22 +484,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: @@ -442,35 +509,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. @@ -493,7 +533,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); @@ -515,14 +555,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; @@ -530,15 +563,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); @@ -547,7 +571,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) { @@ -584,7 +608,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: @@ -602,48 +626,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; @@ -656,14 +734,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... */ @@ -690,7 +760,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, @@ -704,49 +774,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 }; @@ -789,7 +837,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: @@ -798,8 +845,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; @@ -819,35 +864,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 */ @@ -871,7 +890,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 Fri Jul 30 15:18:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411575 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 16731C4338F for ; Fri, 30 Jul 2021 15:25: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 6F8F660F46 for ; Fri, 30 Jul 2021 15:25:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 6F8F660F46 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 0E76D1FF7; Fri, 30 Jul 2021 17:24:22 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 0E76D1FF7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658712; bh=BkoSTNwjU83IeM3qQlU/Pd6MiaKatKrVWzXhhx/7OdA=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=EjvadSD1814B5pHAU93GQ/m5/a2wiztfiONM3h0G1VoCL49Fs/FWlEUC1KZ3eapEA q5orCELkcYP67a8fbJ02k4CLg4L4yw9JVzFtStUUcUOUoFyjiwDmJ71ugCk0mG8MQo dofZ+QcDpQP6rhjAAZum+6uHcfRkHU972U/LTrgo= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 07109F80557; Fri, 30 Jul 2021 17:19:57 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 92128F80551; Fri, 30 Jul 2021 17:19:50 +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 C60DAF804E0 for ; Fri, 30 Jul 2021 17:19:22 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz C60DAF804E0 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="FkrkjIHr" 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 16UEL0di003614; Fri, 30 Jul 2021 10:19:20 -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=bvS5KnTgjT/Y5vjLZdH2CwYK1XiKXkelSdNR140qxX8=; b=FkrkjIHrhegnOFYcqPAan4Z2ZxD1ZtX7UAcDyViRxZIGvyTtSvEyme7ZZJlFnczNOUcF yYY+LiX12vuIz0dd6maZ52jT0/NJYzunkMmQDvSCxIvcMidSkJSs9F1ssPQ6fqkYNAA/ jqPUlh3rOjgfVVl5lCeJEa7o++TEvM0DJj9ranlaDKO5p5zUU5GlGMdrZBQdTWPkek/n 0J2XLntRJ19lq2EGDH6DujZUlOW4AMtp8dE53KcVABigj5RpG8Jp0VtmCv5xSlGOlau2 bP9juPDz/g3qyghWFxhGqsFne0pwt+GCrHt4daL59546wsjf1rbOmvQs+buLcIse0Lfd sQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-9 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:19 -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; Fri, 30 Jul 2021 16:19:11 +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; Fri, 30 Jul 2021 16:19:11 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id BD01545D; Fri, 30 Jul 2021 15:19:10 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 18/27] ALSA: hda/cs8409: Move codec properties to its own struct Date: Fri, 30 Jul 2021 16:18:35 +0100 Message-ID: <20210730151844.7873-19-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: RLhzP2K0xPeHTrXQWRbubq6S20yQytTD X-Proofpoint-ORIG-GUID: RLhzP2K0xPeHTrXQWRbubq6S20yQytTD X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 257dd9006786..4b4f4dc54617 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -164,20 +164,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; @@ -185,31 +185,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); @@ -224,34 +220,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; @@ -269,39 +265,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); @@ -314,34 +305,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); @@ -357,7 +349,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; } @@ -450,6 +442,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; @@ -457,13 +450,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; @@ -476,6 +469,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; @@ -483,23 +477,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: @@ -510,54 +504,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; @@ -565,9 +550,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) @@ -577,45 +562,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; @@ -629,10 +614,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 }, @@ -640,27 +623,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 @@ -684,9 +675,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. @@ -694,12 +686,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) @@ -721,9 +713,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); @@ -742,6 +732,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, @@ -755,33 +746,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); @@ -792,7 +771,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 @@ -803,6 +782,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); @@ -815,18 +795,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; } @@ -845,6 +823,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; @@ -852,21 +833,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 */ @@ -890,7 +888,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 Fri Jul 30 15:18:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411603 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 D3340C432BE for ; Fri, 30 Jul 2021 15:28: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 60A0F60F4A for ; Fri, 30 Jul 2021 15:28:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 60A0F60F4A 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 057732089; Fri, 30 Jul 2021 17:27:24 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 057732089 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658894; bh=2BGAKSQi6fglk+gfThQ3+FbDIzWTG9Q9QGpM+vJa0xU=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=G5Gg8KxBZPfSI+YCWtbJP3m6ob1mvqAXYX72ASCtp++QKrYkr9Ab4bj5X04KBPmpf Tp8GaR30ylYWxDcrxCW9XUjhSlXQ2Jtp4J1V8E/aQ6SoUhp3QTpNh3bo21WjiuAGfL aGBInQzpgT8H4YDuKe5u2vFcUnTHq2z5aUGLND8A= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id D159AF805AE; Fri, 30 Jul 2021 17:20:13 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 744A0F80564; Fri, 30 Jul 2021 17:20:02 +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 031D1F804FB for ; Fri, 30 Jul 2021 17:19:27 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 031D1F804FB Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="EJV4U3PT" 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 16UELBKi004490; Fri, 30 Jul 2021 10:19:22 -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=SsFLSnzjZ1fMNZj2qyH1OFSOeebrqaHmwBP+1BvnjNY=; b=EJV4U3PTruzcLTUsWDsvX008ZQYstnYQPVy+7on9os29EdSsJ8elUboP+a3nX151QVRp ab8ypMcwx3SElgcMblSqobRFI3AEoFSIU+7nxPe1FLcndDn03t6Ya8GuEMW9dUwGUhM9 jOWEIJvi8p1My4vFgYb9NxApMxgi7Pw9FoQrvEwjPAVZYdjymiRPrIwSLZEb65QSkSu8 KkgACaq1hN07OxFbT28c3vASkwQkCw8mPHgxukgifFQVmO456WahCUnsQjXFqNMODmM3 cslZi476e6F3uyrZp98TjJ8x3DZ8AiEDUdGw0PCkdyuaaFfpJul59KgUU3NyyucmBEl5 1Q== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-11 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:22 -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; Fri, 30 Jul 2021 16:19:11 +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; Fri, 30 Jul 2021 16:19:11 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 5A6B32BA; Fri, 30 Jul 2021 15:19:11 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 19/27] ALSA: hda/cs8409: Support multiple sub_codecs for Suspend/Resume/Unsol events Date: Fri, 30 Jul 2021 16:18:36 +0100 Message-ID: <20210730151844.7873-20-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: L_3Mi8aOWv7Jp1Bo-vtN2NCpEgxf38c3 X-Proofpoint-ORIG-GUID: L_3Mi8aOWv7Jp1Bo-vtN2NCpEgxf38c3 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 4b4f4dc54617..8b048ff12eb7 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -375,16 +375,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) @@ -616,6 +621,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 }, @@ -623,6 +630,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 */ @@ -648,10 +661,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 @@ -710,13 +731,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); @@ -755,11 +775,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 Fri Jul 30 15:18:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411573 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 39DF5C4338F for ; Fri, 30 Jul 2021 15:24: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 BB1C860F4B for ; Fri, 30 Jul 2021 15:24:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org BB1C860F4B 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 434EA1FEE; Fri, 30 Jul 2021 17:24:01 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 434EA1FEE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658691; bh=7tfjVFaOwcHHAJwW3zX2bJCj5VYup1iMY+gDn5HTnQY=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=dDkXgcXBgzFls1D17YQiaab6vIJVCyu2sY5ruCit/QekICUQynlJBXL0NFw0/7gdL XzqxsQAqMDIv6zY00PcILSy2wEBxnlu5UBpYL0vYFBsrhPCjxn1J66uCLBudd/uVpy 9aI+utUZbgIqFNYp5PvgbVOsp2wBGzG/V9ngRx4Y= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 5D333F8054A; Fri, 30 Jul 2021 17:19:55 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id A3C1AF8053E; Fri, 30 Jul 2021 17:19:45 +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 E1E20F804E4 for ; Fri, 30 Jul 2021 17:19:22 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz E1E20F804E4 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="TSjBtv0F" 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 16UEL0dj003614; Fri, 30 Jul 2021 10:19:20 -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=uJiDGgAZuNVUz1HRRzwVIuea32lseF95YXkiOXKc9ug=; b=TSjBtv0Fsl/3sNywHLpc1/2TPtW+wETG9ilyLexwPf7BM6lzdW7AFb7s7NmFm95S07cI 4YtOfDi6/ME09OYVH7zl0vpT0zMuUsFUmfPDc1i+bejc5K4kboXPyazdaELm8SK96ygm pQS1aIP5GuukAsVn4t3gsKDoR3/0f9yzNqrbnIO1FJ8nzLov2M+hkiHN04oMOIQBWQTZ SBvhD3lc18oaQ2RWoqLpEXAZr+dlThtGw7JjgqjBNxWSaVtzVKSWDK68J6MCjh+GjHVk edrOz8cKreHiMzJZYVPq4fc3xpDmHvzzSJx+KkRcnPAvjX2NmKhIpRFqiGGkX+cq2nCo lQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-10 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:20 -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; Fri, 30 Jul 2021 16:19:11 +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; Fri, 30 Jul 2021 16:19:11 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 8FE46478; Fri, 30 Jul 2021 15:19:11 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 20/27] ALSA: hda/cs8409: Add Support to disable jack type detection for CS42L42 Date: Fri, 30 Jul 2021 16:18:37 +0100 Message-ID: <20210730151844.7873-21-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: DTeWFsHqg1ET8z8txKButRkPOH-k6J7f X-Proofpoint-ORIG-GUID: DTeWFsHqg1ET8z8txKButRkPOH-k6J7f X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 8b048ff12eb7..10903bcc3fcd 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -546,6 +546,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; @@ -570,10 +603,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; @@ -583,37 +619,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 Fri Jul 30 15:18:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411599 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 8C60FC4338F for ; Fri, 30 Jul 2021 15:27: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 0DCFF6052B for ; Fri, 30 Jul 2021 15:27:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 0DCFF6052B 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 887642077; Fri, 30 Jul 2021 17:26:41 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 887642077 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658851; bh=oLeMwDdXm7rCq6pB+9Iycp/Rdh7YuQrAWct4horZdoU=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Pe+zFaoNvk5K1dQpX39Ep6ZXBzZhjZseHhozsyV7PlPjQQ+mRuZDTGfduI3dKLj67 l4V5fKcRs0FJpGq1MfTtxaGM1pNW0G14mzj+qc9YlAkNwmnLA6IuY84zN5nbipht10 2pIFvsM6dmNpc02xwBAHiKnuO1nqIGhQ1uKkIiy8= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id A0B35F805A0; Fri, 30 Jul 2021 17:20:12 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id AC6EEF80559; Fri, 30 Jul 2021 17:19:59 +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 BB968F804EB for ; Fri, 30 Jul 2021 17:19:23 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz BB968F804EB Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="j6xCuZJd" 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 16UEL0dk003614; Fri, 30 Jul 2021 10:19:21 -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=e+0joj0ZY32l40Bv2P36YSWkXQwz9TbIMe/0rkB5JIw=; b=j6xCuZJdEIZVaCtmqht+5YpPkTMnRpC1VLvd+oh/vh/NW7n4VB9nTzjezSUGqL2OPSAV 9TkvLOacBoXOmTM1tzEE5hQDmP/H80wnaa9jsP86vbfiTRRFb+IL9c2lpfDyxBWljz6c LaLSbaawYzRumJ7sQrRVMv+ENW5QS5Qwa2g/jh1J9qtQ0BBEgzZRYIC0uEyyOKUHqew1 dkDnTNdBdfOKhvkSU4JA6b6arpBgPnO4o1kmX/S7beB6hkKkpG2wSkFbdRT05tGWkzkl lDEfQpS/9Ec23rpPpo6k+lx5Yl7PzYrDavl73aRM8a/9OpXwpTH5vIhbJjGGnxKYVPaB tQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-11 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:21 -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; Fri, 30 Jul 2021 16:19:12 +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; Fri, 30 Jul 2021 16:19:12 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id C40852BA; Fri, 30 Jul 2021 15:19:11 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 21/27] ALSA: hda/cs8409: Add support for dolphin Date: Fri, 30 Jul 2021 16:18:38 +0100 Message-ID: <20210730151844.7873-22-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: iz6vEgeOO3EkrgNToVlRDGP1iGQnR-rB X-Proofpoint-ORIG-GUID: iz6vEgeOO3EkrgNToVlRDGP1iGQnR-rB X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - No changes 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 10903bcc3fcd..42192d83b361 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -921,6 +921,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 Fri Jul 30 15:18:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411613 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 95791C4338F for ; Fri, 30 Jul 2021 15:30:17 +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 210086052B for ; Fri, 30 Jul 2021 15:30:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 210086052B 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 AD6D320F5; Fri, 30 Jul 2021 17:29:25 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz AD6D320F5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627659015; bh=9z2e9BtTDpS51tqlGCy5mTykuSSpjHdhzKeURAj5Yb4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=lyKC95cDumxuA51GbbXVkHPrbjXrYtdohkvovBCOIShVFXCMvmUaQQxUuT0tmKOIC 1RZjVbDUr6RmmpcICe5H23Z6xMhaIBf7Gr43uFd8zeuld0WDn7hnzZokLUcbysXDSZ XhqqT6HmtwstLGM+dgVA36JIHP/ZO4tNYuy6nvzE= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 6E831F805E1; Fri, 30 Jul 2021 17:20:19 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0974AF80588; Fri, 30 Jul 2021 17:20:10 +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 5D4F1F804F1 for ; Fri, 30 Jul 2021 17:19:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 5D4F1F804F1 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="Sja0UmNJ" 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 16UELBKj004490; Fri, 30 Jul 2021 10:19:23 -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=uawk5b33voVjY3bghHvV3ONUFdbXjRaXatzoz/b06cA=; b=Sja0UmNJLz6zH2q0a/W8w2k5+f1ZqsKT51BU9Bvym8uWNV8PSca/6rOj/n3RZe4zuSxC Owhx4VHN/A+Ux+2Q6UEwfw61mOLV528AvFDe1YAuXR4/EF8WHe6HpMxw9ylVu9ajP+lk +NTeKq/ssFWAajz1YNZTmDq9Zi3xGCzlbs1RYrNqeYjy8/Uy6lkKKXxHm567m/JOXf8j FJdTUvQ2J7VwKUfarFwdqa/9SeJk85EPpAGtrin0nSPEwwqDpa72Pugrb/p6lpnT++zf 232cMAPhlINuKdVXmb9nnnNa0Xq3/Ik9yTlrY5NjDU4L3B/JGitq5W533uU9PK90CPDc ow== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-12 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:23 -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; Fri, 30 Jul 2021 16:19:12 +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; Fri, 30 Jul 2021 16:19:12 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 0A8B045D; Fri, 30 Jul 2021 15:19:12 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 22/27] ALSA: hda/cs8409: Enable Full Scale Volume for Line Out Codec on Dolphin Date: Fri, 30 Jul 2021 16:18:39 +0100 Message-ID: <20210730151844.7873-23-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: vbaXteauHS5Wxr3OuxjJk6qiEFvbXRtz X-Proofpoint-ORIG-GUID: vbaXteauHS5Wxr3OuxjJk6qiEFvbXRtz X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 Fri Jul 30 15:18:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411601 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 EB5E7C4320A for ; Fri, 30 Jul 2021 15:27:58 +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 527A461076 for ; Fri, 30 Jul 2021 15:27:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 527A461076 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 E7EB52080; Fri, 30 Jul 2021 17:27:06 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz E7EB52080 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658877; bh=Iyr9fBqOF4H9OkYDfx2OccsU+CEhyJDiYd4AJoSXpLA=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=s56g8120m+dhL0jbCzjrT5fApsr/CJRA2etnlaM0CsLgoteen8XjTUFY+MuYfNWG4 WhQGZk3gVjpPlchHHHguuTP+2GySgPYSkX4nqhin2SpZWlpdGUXw+vBw/w8ml26mOS tTyjRxRjGB+tcBxiAAw7QyYd4LBXB+MOGp3rpcvg= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 4C363F805A8; Fri, 30 Jul 2021 17:20:13 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0ECE2F80563; Fri, 30 Jul 2021 17:20:01 +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 CC117F804FA for ; Fri, 30 Jul 2021 17:19:27 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CC117F804FA Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="TddyXOOQ" 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 16UEL0dl003614; Fri, 30 Jul 2021 10:19:22 -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=kPMnYciWtAXu6NQ2BEZKqviuN9LILh+HOgCkEAJPCIs=; b=TddyXOOQjLCbYRYYIRcqr9UnBbpC0V8EkO2jE/G8KpmaT5IM/nmnUKehiuDmIyzsbAkh DBdvsmBe6t8EsrgyIqyjzhSvv96ucVl93LjTBE/j1wr2PGhNDLBzlYlKPtHUhj8pbu2x /V0hn980zONmXNG0LpJyMkHfhlbp7b3zFK2f9G//hfMoLztj6SV8/fkSExy3kzZ7quMz FeNdKO7KEo5JTZnNLUw7KisEFU7YIqDz1+vtMcbh7bKdpSz/H11j9NDKx1nOUNrg6+W1 ZQWBZvgSL4V1X9EAy/cRFw5j8z8dvtOEQOHsNVmQovo7U3whdB7JSMbRqz2Djp7URShg tw== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-12 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:22 -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; Fri, 30 Jul 2021 16:19:12 +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; Fri, 30 Jul 2021 16:19:12 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 48E832BA; Fri, 30 Jul 2021 15:19:12 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 23/27] ALSA: hda/cs8409: Set fixed sample rate of 48kHz for CS42L42 Date: Fri, 30 Jul 2021 16:18:40 +0100 Message-ID: <20210730151844.7873-24-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: MljEXSRakZH9DWizqavwXNM8GidBFrjh X-Proofpoint-ORIG-GUID: MljEXSRakZH9DWizqavwXNM8GidBFrjh X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 42192d83b361..08e991a33344 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -892,6 +892,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); @@ -1085,6 +1088,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 Fri Jul 30 15:18:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vitaly Rodionov X-Patchwork-Id: 12411615 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 9A7BCC4338F for ; Fri, 30 Jul 2021 15:30:38 +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 278BD60F4A for ; Fri, 30 Jul 2021 15:30:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 278BD60F4A 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 C49DC20B4; Fri, 30 Jul 2021 17:29:46 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C49DC20B4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627659036; bh=dPyeS64dHbEeOcT1TF++Q7vl9x+qwc3KMBRZHPmKUUU=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Hn9DpbEB7lFUvKRiqrJSm88HmJHpFlc9UmYFLAP0RAFzEF2vbs1XNBw908gY5m8/j K+EQKRXUFdh2MdjcwWJHtYP8vff2TVmNVoAWTV4COzSMoJOC6Hgf4cXzE9WN75KBdg mqRJPLJD3LIUtGrBWsZxaJXKURCghgMBxqZwLNw4= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 31B37F805E4; Fri, 30 Jul 2021 17:20:20 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 08E30F80589; Fri, 30 Jul 2021 17:20:11 +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 24DC6F804FC for ; Fri, 30 Jul 2021 17:19:27 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 24DC6F804FC Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="O1X8JGrb" 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 16UEL0dm003614; Fri, 30 Jul 2021 10:19:23 -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=iJGWgZ1yqdx9RaXMcDbcc/ICPIOOJeAeaCEft2wV0Mw=; b=O1X8JGrbQvENNfw5V95C9oSmtziIMAmtmh+cvwyZjGMblhtzuSnQxNUiqtGUnEuU7eqP KZk6MSPsTPDQHT7C13t8fqN+Q/fuvvZGkSyPcIPEop+qP5zz41Iz4Pt5aIrCE09MK8v7 hoth5XRJ/iv/3VKDA+v6LCOK+tEPc3p2tFOUk5ZAXXjp//RtGbJubAM+BootjCidf0Tj n54yeztOKFvzB+bUkGGOhfUWpFpU6u9l3gXK3HY3+ZblYJvLbT1yJv3YkOsUFU9p/I7z ySy33c8JXOtrVlsvVyPH7krOehvkciN3gN7ArShzNZe9ep1UfSf9mUPXdq1Cltk3doya 7Q== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181n-13 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:23 -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; Fri, 30 Jul 2021 16:19:12 +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; Fri, 30 Jul 2021 16:19:12 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 7E43146E; Fri, 30 Jul 2021 15:19:12 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 24/27] ALSA: hda/cs8409: Use timeout rather than retries for I2C transaction waits Date: Fri, 30 Jul 2021 16:18:41 +0100 Message-ID: <20210730151844.7873-25-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: g2E6px2xx8VCJX5M10O9Jj-EMNcz6Bri X-Proofpoint-ORIG-GUID: g2E6px2xx8VCJX5M10O9Jj-EMNcz6Bri X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 08e991a33344..b53653ef73cb 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -127,24 +127,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 Fri Jul 30 15:18: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: 12411607 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 829ACC4338F for ; Fri, 30 Jul 2021 15:29:17 +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 0BCAB6052B for ; Fri, 30 Jul 2021 15:29:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 0BCAB6052B 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 A93F720C7; Fri, 30 Jul 2021 17:28:25 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz A93F720C7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658955; bh=Nfv5SLYXdwGGQc6MAAIHu/uJahVV2eR/vn84cB0xQl0=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=BblnCfuIyuuL7vsRitIGzqUzblJEFvExfYiWkMisDCHzPxHGRylAchHxMXNQIhVFi j4Obq9DUT1aK8Qkr+U0RPG7QBTKApcxpXvNiycPYZtCb8JYnmWGOdqQB2neAeCNwEU DYQQ4j+TPw+beQynsYa6c1T/1DHmNJmQmH4Lo82U= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 10E53F805C9; Fri, 30 Jul 2021 17:20:17 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 42C66F80578; Fri, 30 Jul 2021 17:20:07 +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 6E854F804FD for ; Fri, 30 Jul 2021 17:19:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 6E854F804FD Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="eBnau58A" 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 16UELBKk004490; Fri, 30 Jul 2021 10:19:24 -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=BHyNK2Rh1TJDLlgd9nsKy7JfYNclo2aQ2qneV7wlq+4=; b=eBnau58AKs5Hr3md7SJXEPz4C/5qZdlxOFsIpDFPIS/5bwZSwC4nneQHqkqiJQ6FnKgW LfRogi6FjxZHo2v9CaJW90OQuf1lVaHQaWg8gWjL6Gx+LMxTCWuYjyEMMmb+U8HlLq7i eju2xfxx60xkiLYMYXXDpXvaAkdD3hkKJY6T7iNpSQQ0S5QdJoSohoZMO6pFqWc5+Sdx brmo09/tCA9Io5Dj0WFaqDCQknTak+LNMNEVRximYfKeyxRYySOUxR+xD7li1F5Im4rE C+bdW7zwD9snwQhpI8/EngLlim1Pu1SBgYD4cXabESFgC+Glc+vouGQ0CftE5Kc1Lj31 Wg== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-13 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:23 -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; Fri, 30 Jul 2021 16:19:12 +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; Fri, 30 Jul 2021 16:19:12 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id B3FAF45D; Fri, 30 Jul 2021 15:19:12 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 25/27] ALSA: hda/cs8409: Remove unnecessary delays Date: Fri, 30 Jul 2021 16:18:42 +0100 Message-ID: <20210730151844.7873-26-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: bi2sux3K20pdjOJ-Qq8iaea1evZ0nCap X-Proofpoint-ORIG-GUID: bi2sux3K20pdjOJ-Qq8iaea1evZ0nCap X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=984 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 b53653ef73cb..f4c53088fa4e 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -528,12 +528,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) @@ -640,6 +638,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)); @@ -907,7 +906,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; @@ -1102,10 +1100,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 Fri Jul 30 15:18: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: 12411611 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 CE7C3C4338F for ; Fri, 30 Jul 2021 15:29:57 +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 570C36052B for ; Fri, 30 Jul 2021 15:29:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 570C36052B 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 DD93D20B2; Fri, 30 Jul 2021 17:29:05 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz DD93D20B2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658996; bh=xK/TWUdqwF3Daj6Ox5FyT2DypZWVpagXTqiR9syLf5g=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=FMcsoIUhHz9AtUVCsfFJ3+mGPWbTVecAxtz9GfldwHPT+/3uoA9Dw/P4ynOtVEaNT A9OQWFXHcWKRE72O5c9GGFlwUKLHAMfxjjiFiwdxjKvA6G0DcvSmhc7hNYDB9S4Nym HvmxvKzLbLFbG0qH+ixBNCef4ZcY466bVgxw7CUU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 4BC53F805DA; Fri, 30 Jul 2021 17:20:18 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 8E65EF80587; Fri, 30 Jul 2021 17:20:09 +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 9BF1BF804FF for ; Fri, 30 Jul 2021 17:19:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 9BF1BF804FF Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="aG4qLciv" 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 16UELBKl004490; Fri, 30 Jul 2021 10:19:24 -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=4aewaRG2Ws8MYZlNy27pbkaKvgZ3jxtw9I4cDaz4YUE=; b=aG4qLcivdqbGbGO5N0iPzt4tQaoHmZB9u/DkL5qSf3B/1iWdUtaPnsGZ3N0yLqyWxW61 5b2GYNpE6afOyOcz9xf1nwfKRWdNwKciNxmhyW3+SbKRzpC34ZUQNpdEE5ptHwR6P9aJ TGSwDm9MklKiuFGsCLmGrREAS0HhOGzmZelIBonekFagiWrLeCBf0te7v93vHOn8hnTe /y00VnMyrYDJbKZshlHlJ0YGieYbq/U2uvcTCvynUy/FycJq2mBj5n2pDsPo6UC2VbOZ taBcS+OIvlQmN8AdHzJJo7hTbNX2Vn/4wmzw5uxn5tCxcMSECH5MFGV60pxlHF4d9Yy+ Ww== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-14 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:24 -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; Fri, 30 Jul 2021 16:19:13 +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; Fri, 30 Jul 2021 16:19:13 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id E929E2BA; Fri, 30 Jul 2021 15:19:12 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 26/27] ALSA: hda/cs8409: Follow correct CS42L42 power down sequence for suspend Date: Fri, 30 Jul 2021 16:18:43 +0100 Message-ID: <20210730151844.7873-27-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: QiTiCKMmOJBVHkvvB2CvqiVZ7OkRSQc4 X-Proofpoint-ORIG-GUID: QiTiCKMmOJBVHkvvB2CvqiVZ7OkRSQc4 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 f4c53088fa4e..b42ef3c3e447 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" @@ -206,6 +207,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: @@ -662,9 +664,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 Fri Jul 30 15:18: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: 12411609 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 045A8C4338F for ; Fri, 30 Jul 2021 15:29: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 78AB060EBB for ; Fri, 30 Jul 2021 15:29:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 78AB060EBB 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 1ADFC20B6; Fri, 30 Jul 2021 17:28:45 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 1ADFC20B6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1627658975; bh=EKmDiXbYPUqAK3G2wAFpOrR1p/JIe0zYu38015uPgwY=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=us+D57RxWZ/ZB/VVWvzzfmJAbRmyGdAl2muCxgv7mFi6O73Q6K98OsIOa6TH4CNzK oqUQuHlm5eeyoToIqk+muoufvjNZIBpbvEp8UGdb90z/IN/SunVHq0h17KoFsr+VuW QrxXpgkeiwMOqAiBYDPdZElY6t9eOJ6Mk4y1b2c0= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id A7FB8F805D6; Fri, 30 Jul 2021 17:20:17 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 79E41F8057C; Fri, 30 Jul 2021 17:20:08 +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 51AF1F80507 for ; Fri, 30 Jul 2021 17:19:29 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 51AF1F80507 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="KFnNACdw" 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 16UELBKm004490; Fri, 30 Jul 2021 10:19:25 -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=EnyMXI8nGzyDUVwWtl0Uf7Wja5882nm0boliFXDggtA=; b=KFnNACdwS67NdMM7MXLvJAHsEFWCWI70Zhcj839KETG/i7Lfr2d+oFWFely82yu8AtMK v6MSbUudQiS9CRrtlu7whAAo/DDTxshXotGx7KkVC4FSjqq12A9xtkR+XwjfzF9xeSPq 4Z4NL5DGo+8doIQ4ew6EJGGYWnIHGqBdx8XBhpF0G3giMQodxgrSqZtNN853pCi5BM3G Aqbe4eLgTExFwSSUKeonY4aCVEioik4JD+5erHpx3TcJFabvLz8bTAM1QVbAOgHrmJY4 nZToUptLtfDKSjf3PC7J/5MC4xFQDfjmywaQ1K64TfmVxw9HQcVjAK7T8HF0Wd3osP1U sw== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-15 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:25 -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; Fri, 30 Jul 2021 16:19:13 +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; Fri, 30 Jul 2021 16:19:13 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 311B646E; Fri, 30 Jul 2021 15:19:13 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai Subject: [PATCH v3 27/27] ALSA: hda/cs8409: Unmute/Mute codec when stream starts/stops Date: Fri, 30 Jul 2021 16:18:44 +0100 Message-ID: <20210730151844.7873-28-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: xi2DrGJs3yLKq1CDiCy5Xs_vg3D7fqV7 X-Proofpoint-ORIG-GUID: xi2DrGJs3yLKq1CDiCy5Xs_vg3D7fqV7 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 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 Changes in v3: - 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 b42ef3c3e447..86d33ae9d024 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -462,6 +462,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); @@ -473,25 +505,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; @@ -500,6 +527,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) { @@ -645,14 +730,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); @@ -905,6 +982,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); @@ -1100,6 +1180,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);