From patchwork Fri Jun 6 06:51:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niranjan H Y X-Patchwork-Id: 895217 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id BEA29C61DB2 for ; Tue, 10 Jun 2025 19:34:19 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [45.14.194.44]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id EF85C60211; Tue, 10 Jun 2025 21:34:07 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz EF85C60211 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1749584058; bh=pZdGTznHsv4cdD6OCTuCEq6+0h2+yk0Syl0hUQiteBo=; h=From:To:CC:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=COQ6ZGR28JNnQ82f3u3scdd/6AzHwUR3tRCWkTvJNlLBAUtNyj4ZkERjlwtzOkH/X BjelVLX13nBpziqExFOEKRnCNnV02nf7G1K8qJf32PzKrLQulVAUzq9kprDPPYLpUy KtA+C/2X73YAhQLMeJLAbWVos/apeCeFMX2WM7Dk= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 36834F80612; Tue, 10 Jun 2025 21:33:08 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 1F701F8060C; Tue, 10 Jun 2025 21:33:08 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 439B2F800F0; Fri, 6 Jun 2025 08:52:25 +0200 (CEST) Received: from lelvem-ot02.ext.ti.com (lelvem-ot02.ext.ti.com [198.47.23.235]) (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 9B2CCF80072 for ; Fri, 6 Jun 2025 08:52:19 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 9B2CCF80072 Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key, unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=X3I8ndxj Received: from fllvem-sh04.itg.ti.com ([10.64.41.54]) by lelvem-ot02.ext.ti.com (8.15.2/8.15.2) with ESMTP id 5566qHMG099373; Fri, 6 Jun 2025 01:52:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1749192737; bh=N0RTx+qdWnKD4uxMjccP19imnY/sPVI84Wj7YQrixtU=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=X3I8ndxjVd/dZjVBf9gCBROcUCCaVA4sLcImOMPNQ4O++drwRuPaF0G59Ri/VJvgu VkG7aK/H1UzuF5uuW6oF4B6+fs31n3StlLu/bLfOAW8YMK8k7n/09oGBD4vdXprbhN hGoywlNWFOQqLTOif622PGcaXe76Zfu9rOH49RLs= Received: from DLEE106.ent.ti.com (dlee106.ent.ti.com [157.170.170.36]) by fllvem-sh04.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 5566qH2W1482952 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Fri, 6 Jun 2025 01:52:17 -0500 Received: from DLEE106.ent.ti.com (157.170.170.36) by DLEE106.ent.ti.com (157.170.170.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Fri, 6 Jun 2025 01:52:16 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) by DLEE106.ent.ti.com (157.170.170.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Fri, 6 Jun 2025 01:52:16 -0500 Received: from LTPW0EX92E.dhcp.ti.com (ltpw0ex92e.dhcp.ti.com [172.24.149.200]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 5566q4Oe677113; Fri, 6 Jun 2025 01:52:13 -0500 From: Niranjan H Y To: CC: , , , , , , , , , Subject: [PATCH v1 1/4] ASoc: tac5x1x: add codec driver tac5x1x family Date: Fri, 6 Jun 2025 12:21:33 +0530 Message-ID: <20250606065136.1821-2-niranjan.hy@ti.com> X-Mailer: git-send-email 2.33.0.windows.2 In-Reply-To: <20250606065136.1821-1-niranjan.hy@ti.com> References: <20250606065136.1821-1-niranjan.hy@ti.com> MIME-Version: 1.0 X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea X-MailFrom: niranjan.hy@ti.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1 Message-ID-Hash: XX233Z3EE66E4Z7CQJESARXPTK3IRMLG X-Message-ID-Hash: XX233Z3EE66E4Z7CQJESARXPTK3IRMLG X-Mailman-Approved-At: Tue, 10 Jun 2025 19:33:03 +0000 X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: tac5x1x family are series of low-power and high performance mono/stereo audio codecs consists of ADC and DAC combinations. The patch adds supports for Codecs(DAC & ADC), ADC only and DAC only configurations available in the tac5x1x family. Signed-off-by: Niranjan H Y --- sound/soc/codecs/Kconfig | 16 + sound/soc/codecs/Makefile | 6 +- sound/soc/codecs/tac5x1x-i2c.c | 81 ++ sound/soc/codecs/tac5x1x.c | 2389 ++++++++++++++++++++++++++++++++ sound/soc/codecs/tac5x1x.h | 302 ++++ 5 files changed, 2793 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/tac5x1x-i2c.c create mode 100644 sound/soc/codecs/tac5x1x.c create mode 100644 sound/soc/codecs/tac5x1x.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 477d33234fdd..74abc0d68237 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -258,6 +258,8 @@ config SND_SOC_ALL_CODECS imply SND_SOC_STA529 imply SND_SOC_STAC9766 imply SND_SOC_STI_SAS + imply SND_SOC_TAC5X1X + imply SND_SOC_TAC5X1X_I2C imply SND_SOC_TAS2552 imply SND_SOC_TAS2562 imply SND_SOC_TAS2764 @@ -2001,6 +2003,20 @@ config SND_SOC_STAC9766 config SND_SOC_STI_SAS tristate "codec Audio support for STI SAS codec" +config SND_SOC_TAC5X1X + tristate "Texas Instruments TAC5X1X family codecs" + depends on I2C && REGMAP_I2C + +config SND_SOC_TAC5X1X_I2C + tristate "Texas Instruments TAC5X1X family driver based on I2C" + depends on I2C && REGMAP_I2C + select SND_SOC_TAC5X1X + help + Enable support for Texas Instruments TAC5X1X family Audio chips. + The family consists mono/stereo audio codecs, DACs and ADCs. + Includes support for TAC5311-Q1, TAC5411-Q1, TAC5111, TAC5211, + TAA5212, TAA5412-Q1, TAD5112, TAD5212, TAC5312, TAC5412-Q1, + config SND_SOC_TAS2552 tristate "Texas Instruments TAS2552 Mono Audio amplifier" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 66e2f2381d40..ec315236f2d9 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -312,6 +312,8 @@ snd-soc-tas2770-y := tas2770.o snd-soc-tas2781-comlib-y := tas2781-comlib.o snd-soc-tas2781-fmwlib-y := tas2781-fmwlib.o snd-soc-tas2781-i2c-y := tas2781-i2c.o +snd-soc-tac5x1x-y := tac5x1x.o +snd-soc-tac5x1x-i2c-y := tac5x1x-i2c.o snd-soc-tfa9879-y := tfa9879.o snd-soc-tfa989x-y := tfa989x.o snd-soc-tlv320adc3xxx-y := tlv320adc3xxx.o @@ -717,6 +719,8 @@ obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o +obj-$(CONFIG_SND_SOC_TAC5X1X) += snd-soc-tac5x1x.o +obj-$(CONFIG_SND_SOC_TAC5X1X_I2C) += snd-soc-tac5x1x-i2c.o obj-$(CONFIG_SND_SOC_STI_SAS) += snd-soc-sti-sas.o obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS2562) += snd-soc-tas2562.o @@ -851,4 +855,4 @@ obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o obj-$(CONFIG_SND_SOC_LPASS_TX_MACRO) += snd-soc-lpass-tx-macro.o # Mux -obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o \ No newline at end of file +obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o diff --git a/sound/soc/codecs/tac5x1x-i2c.c b/sound/soc/codecs/tac5x1x-i2c.c new file mode 100644 index 000000000000..26af55a29b03 --- /dev/null +++ b/sound/soc/codecs/tac5x1x-i2c.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// ALSA SoC Texas Instruments TAC5x1x Audio Codec +// +// Copyright (C) 2020 - 2025 Texas Instruments Incorporated +// https://www.ti.com +// +// TAC5x1x are a series of low-power and high performance mono or stereo +// audio codecs, as well as multiple inputs and outputs programmable in +// single-ended or fully differential configurations. Device supports both +// Microphone and Line In input on ADC Channel. DAC Output can be configured +// for either Line Out or Head Phone Load. +// +// Author: Kevin Lu +// Author: Kokila Karuppusamy +// Author: Niranjan H Y +// + +#include +#include +#include + +#include "tac5x1x.h" + +static const struct i2c_device_id tac5x1x_id[] = { + { "taa5212", TAA5212 }, + { "taa5412", TAA5412 }, + { "tac5111", TAC5111 }, + { "tac5112", TAC5112 }, + { "tac5211", TAC5211 }, + { "tac5212", TAC5212 }, + { "tac5311", TAC5311 }, + { "tac5312", TAC5312 }, + { "tac5411", TAC5411 }, + { "tac5412", TAC5412 }, + { "tad5112", TAD5112 }, + { "tad5212", TAD5212 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, tac5x1x_id); + +static int tac5x1x_i2c_probe(struct i2c_client *i2c) +{ + int ret; + enum tac5x1x_type type; + struct regmap *regmap; + const struct regmap_config *config = &tac5x1x_regmap; + + regmap = devm_regmap_init_i2c(i2c, config); + type = (uintptr_t)i2c_get_match_data(i2c); + + dev_info(&i2c->dev, "probing %s codec_type = %d\n", + i2c->name, type); + + ret = tac5x1x_probe(&i2c->dev, regmap, type); + if (ret) + dev_err(&i2c->dev, "probe failed"); + + return ret; +} + +static void tac5x1x_i2c_remove(struct i2c_client *client) +{ + tac5x1x_remove(&client->dev); +} + +static struct i2c_driver tac5x1x_i2c_driver = { + .driver = { + .name = "tac5x1x-codec", + .of_match_table = of_match_ptr(tac5x1x_of_match), + }, + .probe = tac5x1x_i2c_probe, + .remove = tac5x1x_i2c_remove, + .id_table = tac5x1x_id, +}; + +module_i2c_driver(tac5x1x_i2c_driver); + +MODULE_DESCRIPTION("ASoC tac5x1x codec driver"); +MODULE_AUTHOR("Texas Instruments"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tac5x1x.c b/sound/soc/codecs/tac5x1x.c new file mode 100644 index 000000000000..f0481a2aebd0 --- /dev/null +++ b/sound/soc/codecs/tac5x1x.c @@ -0,0 +1,2389 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// tac5x1x.c +// +// Copyright (C) 2022 - 2025 Texas Instruments Incorporated +// +// Author: Kevin Lu +// Author: Kokila Karuppusamy +// Author: Niranjan H Y +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tac5x1x.h" + +struct tac5x1x_setup_gpio { + s32 gpio_func[3]; + s32 gpio_drive[3]; + s32 gpi1_func; + s32 gpa_gpio; +}; + +struct tac5x1x_input_diag_config { + s32 in_ch_en; + s32 out_ch_en; + s32 incl_se_inm; + s32 incl_ac_coup; +}; + +struct tac5x1x_irqinfo { + struct delayed_work irq_work; + s32 irq_gpio; + s32 irq; + bool irq_enable; +}; + +struct tac5x1x_dev { + u32 addr; + bool is_loading; +}; + +struct interrupt_info { + const char * const *names; + size_t size; +}; + +struct tac5x1x_priv { + struct snd_soc_component *component; + struct regmap *regmap; + struct device *dev; + enum tac5x1x_type codec_type; + bool pll_setup; + s32 irq; + s32 vref_vg; + s32 adc_en; + s32 dac_en; + s32 micbias_en; + s32 micbias_vg; + s32 agc_en; + s32 uad_en; + s32 vad_en; + s32 uag_en; + s32 dac_mute; + s32 dac_dig_vol[4]; + s32 dac_chns; + u32 sysclk; + s32 ndev; + s32 micbias_threshold[2]; + s32 gpa_threshold[2]; + u8 dev_name[20]; + struct snd_soc_jack *jack; + struct regulator *supply_avdd; + struct regulator *supply_iovdd; + struct tac5x1x_setup_gpio *gpio_setup; + struct tac5x1x_irqinfo irqinfo; + /* mutex to prevent simulataneous device read */ + struct mutex dev_lock; + struct tac5x1x_dev tac5x1x_dev[2]; + struct tac5x1x_input_diag_config input_diag_config; + void (*irq_work_func)(struct tac5x1x_priv *tac5x1x); +}; + +static const char * const int_ltch0[] = { + "Clock Error", + "PLL Lock", + "Boost Over Temperature", + "Boost Over Current", + "Boost Mode", + "Reserved", + "Reserved", + "Reserved", +}; + +static const char * const chx_ltch[] = { + "Input Channel1 fault", + "Input Channel2 fault", + "Output Channel1 fault", + "Output Channel2 fault", + "Short to VBAT_IN", + "Reserved", + "Reserved", + "Reserved", +}; + +static const char * const in_ch1_ltch[] = { + "IN_CH1 open Input", + "IN_CH1 Input shorted", + "IN_CH1 INP shorted to GND", + "IN_CH1 INM shorted to GND", + "IN_CH1 INP shorted to MICBIAS", + "IN_CH1 INM shorted to MICBIAS", + "IN_CH1 INP shorted to VBAT_IN", + "IN_CH1 INM shorted to VBAT_IN", +}; + +static const char * const in_ch2_ltch[] = { + "IN_CH2 open Input", + "IN_CH2 Input shorted", + "IN_CH2 INP shorted to GND", + "IN_CH2 INM shorted to GND", + "IN_CH2 INP shorted to MICBIAS", + "IN_CH2 INM shorted to MICBIAS", + "IN_CH2 INP shorted to VBAT_IN", + "IN_CH2 INM shorted to VBAT_IN", +}; + +static const char * const out_ch1_ltch[] = { + "OUT_CH1 OUT1P Short circuit Fault", + "OUT_CH1 OUT1M Short circuit Fault", + "OUT_CH1 DRVRP Virtual Ground Fault", + "OUT_CH1 DRVRM Virtual ground Fault", + "OUT_CH1 ADC CH1 Mask", + "OUT_CH1 ADC CH2 MASK", + "Reserved", + "Reserved", +}; + +static const char * const out_ch2_ltch[] = { + "OUT_CH2 OUT2P Short circuit Fault", + "OUT_CH2 OUT2M Short circuit Fault", + "OUT_CH2 DRVRP Virtual Ground Fault", + "OUT_CH2 DRVRM Virtual ground Fault", + "Reserved", + "Reserved", + "AREG SC Fault Mask", + "AREG SC Fault", +}; + +static const char * const int_ltch1[] = { + "CH1 INP Over Voltage", + "CH1 INM Over Voltage", + "CH2 INP over Voltage", + "CH2 INM Over Voltage", + "Headset Insert Detection", + "Headset Remove Detection", + "Headset Hook", + "MIPS Overload", +}; + +static const char * const int_ltch2[] = { + "GPA Up threashold Fault", + "GPA low threashold Fault", + "VAD Power up detect", + "VAD power down detect", + "Micbias short circuit", + "Micbias high current fault", + "Micbias low current fault", + "Micbias Over voltage fault", +}; + +static u32 int_reg_array[] = { + TAC5X1X_REG_INT_LTCH0, + TAC5X1X_REG_CHX_LTCH, + TAC5X1X_REG_IN_CH1_LTCH, + TAC5X1X_REG_IN_CH2_LTCH, + TAC5X1X_REG_OUT_CH1_LTCH, + TAC5X1X_REG_OUT_CH2_LTCH, + TAC5X1X_REG_INT_LTCH1, + TAC5X1X_REG_INT_LTCH2, +}; + +static const char * const int_reg_arr_name[] = { + "TAC5X1X_REG_INT_LTCH0", + "TAC5X1X_REG_CHX_LTCH", + "TAC5X1X_REG_IN_CH1_LTCH", + "TAC5X1X_REG_IN_CH2_LTCH", + "TAC5X1X_REG_OUT_CH1_LTCH", + "TAC5X1X_REG_OUT_CH2_LTCH", + "TAC5X1X_REG_INT_LTCH1", + "TAC5X1X_REG_INT_LTCH2", +}; + +static const struct interrupt_info interrupts[] = { + { int_ltch0, ARRAY_SIZE(int_ltch0) }, + { chx_ltch, ARRAY_SIZE(chx_ltch) }, + { in_ch1_ltch, ARRAY_SIZE(in_ch1_ltch) }, + { in_ch2_ltch, ARRAY_SIZE(in_ch2_ltch) }, + { out_ch1_ltch, ARRAY_SIZE(out_ch1_ltch) }, + { out_ch2_ltch, ARRAY_SIZE(out_ch2_ltch) }, + { int_ltch1, ARRAY_SIZE(int_ltch1) }, + { int_ltch2, ARRAY_SIZE(int_ltch2) }, +}; + +static s32 tac5x1x_regmap_write(struct tac5x1x_priv *tac5x1x, + u32 reg, u32 value) +{ + s32 ret; + s32 retry_count = 5; + + while (retry_count--) { + ret = regmap_write(tac5x1x->regmap, reg, + value); + if (ret >= 0) + break; + usleep_range(5000, 5050); + } + if (retry_count == -1) + return 3; + else + return ret; +} + +static s32 tac5x1x_regmap_read(struct tac5x1x_priv *tac5x1x, + u32 reg, u32 *value) +{ + s32 ret; + s32 retry_count = 5; + + ret = regmap_reinit_cache(tac5x1x->regmap, &tac5x1x_regmap); + if (ret) { + dev_err(tac5x1x->dev, "Failed to reinit reg cache\n"); + return ret; + } + + while (retry_count--) { + ret = regmap_read(tac5x1x->regmap, reg, + value); + if (ret >= 0) + break; + usleep_range(5000, 5050); + } + if (retry_count == -1) + return 3; + else + return ret; +} + +static s32 tac5x1x_dev_read(struct tac5x1x_priv *tac5x1x, + u32 dev_no, u32 reg, + u32 *ref_value) +{ + s32 ret; + + guard(mutex)(&tac5x1x->dev_lock); + if (dev_no < tac5x1x->ndev) { + ret = tac5x1x_regmap_write(tac5x1x, + TAC_PAGE_SELECT, 0); + if (ret < 0) { + dev_err(tac5x1x->dev, "%s, E=%d\n", + __func__, ret); + return ret; + } + + ret = tac5x1x_regmap_read(tac5x1x, reg, ref_value); + if (ret < 0) + dev_err(tac5x1x->dev, "read, ERROR, E=%d\n", + ret); + else + dev_dbg(tac5x1x->dev, + "read PAGE:REG 0x%02x:0x%02x,0x%02x\n", + TAC_PAGE_ID(reg), + TAC_PAGE_REG(reg), *ref_value); + } else { + dev_err(tac5x1x->dev, "%s, ERROR: no such device(%d)\n", + __func__, dev_no); + } + + return 0; +} + +static void tac5x1x_enable_irq(struct tac5x1x_priv *tac5x1x, bool is_enable) +{ + if (is_enable == tac5x1x->irqinfo.irq_enable && + !gpio_is_valid(tac5x1x->irqinfo.irq_gpio)) + return; + if (is_enable) + enable_irq(tac5x1x->irqinfo.irq); + else + disable_irq_nosync(tac5x1x->irqinfo.irq); + tac5x1x->irqinfo.irq_enable = is_enable; +} + +static void tac5x1x_irq_work_func(struct tac5x1x_priv *tac5x1x) +{ + u32 reg_val, array_size, i, index = 0, bit = 0; + s32 rc; + + tac5x1x_enable_irq(tac5x1x, false); + array_size = ARRAY_SIZE(int_reg_array); + for (i = 0; i < array_size; i++) { + rc = tac5x1x_dev_read(tac5x1x, index, + int_reg_array[i], ®_val); + if (!rc) { + for (s32 j = 0; j < interrupts[i].size; j++) { + bit = interrupts[i].size - 1 - j; + if (reg_val & (1 << bit)) + dev_info(tac5x1x->dev, + "Reg: %s || %s\n", + int_reg_arr_name[i], + interrupts[i].names[j]); + } + } else { + dev_err(tac5x1x->dev, + "%s DEV_NO%d Read Reg 0x%04x error(rc=%d)\n", + tac5x1x->dev_name, index, + int_reg_array[i], rc); + } + } + tac5x1x_enable_irq(tac5x1x, true); +} + +static const struct regmap_range_cfg tac5x1x_ranges[] = { + { + .range_min = 0, + .range_max = 12 * 128, + .selector_reg = TAC_PAGE_SELECT, + .selector_mask = GENMASK(7, 0), + .selector_shift = 0, + .window_start = 0, + .window_len = 128, + }, +}; + +const struct regmap_config tac5x1x_regmap = { + .max_register = 12 * 128, + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_MAPLE, + .ranges = tac5x1x_ranges, + .num_ranges = ARRAY_SIZE(tac5x1x_ranges), +}; +EXPORT_SYMBOL(tac5x1x_regmap); + +static void irq_work_routine(struct work_struct *work) +{ + struct tac5x1x_priv *tac5x1x = + container_of(work, struct tac5x1x_priv, irqinfo.irq_work.work); + + if (tac5x1x->irq_work_func) { + dev_dbg(tac5x1x->dev, "Calling irq_work_func\n"); + tac5x1x->irq_work_func(tac5x1x); + } else { + dev_dbg(tac5x1x->dev, + "%s, irq_work_func is NULL\n", __func__); + } +} + +static irqreturn_t tac5x1x_irq_handler(s32 irq, void *dev_id) +{ + struct tac5x1x_priv *tac5x1x = (struct tac5x1x_priv *)dev_id; + + /* get IRQ status after 100 ms */ + schedule_delayed_work(&tac5x1x->irqinfo.irq_work, + msecs_to_jiffies(100)); + return IRQ_HANDLED; +} + +static s32 tac5x1x_register_interrupt(struct tac5x1x_priv *tac5x1x) +{ + struct device_node *np = tac5x1x->dev->of_node; + s32 ret; + + mutex_init(&tac5x1x->dev_lock); + tac5x1x->irqinfo.irq = of_irq_get(np, 0); + INIT_DELAYED_WORK(&tac5x1x->irqinfo.irq_work, irq_work_routine); + + dev_dbg(tac5x1x->dev, "irq = %d\n", tac5x1x->irqinfo.irq); + ret = request_threaded_irq(tac5x1x->irqinfo.irq, tac5x1x_irq_handler, + NULL, IRQF_TRIGGER_FALLING, "TAC-IRQ", tac5x1x); + if (ret) { + dev_err(tac5x1x->dev, "request irq failed, ret %d\n", ret); + return ret; + } + tac5x1x->irq_work_func = tac5x1x_irq_work_func; + return 0; +}; + +static s32 tac5x1x_set_GPO1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 gpio_check, val; + + val = snd_soc_component_read(component, TAC5X1X_GPO1); + gpio_check = ((val & TAC5X1X_GPIOX_CFG_MASK) >> 0); + if (gpio_check != TAC5X1X_GPIO_GPO) { + dev_err(component->dev, + "%s: GPO1 is not configure as a GPO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0]) + val = 0; + else + val = TAC5X1X_GPO1_VAL; + + ucontrol->value.integer.value[0] = (val >> 0); + snd_soc_component_update_bits(component, TAC5X1X_GPIOVAL, + TAC5X1X_GPO1_VAL, val); + + return 1; +}; + +static s32 tac5x1x_get_GPIO1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 val; + + val = snd_soc_component_read(component, TAC5X1X_GPIOVAL); + ucontrol->value.integer.value[0] = ((val & TAC5X1X_GPIO1_MON) >> 0); + + return 0; +}; + +static s32 tac5x1x_set_GPIO1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 gpio_check, val; + + val = snd_soc_component_read(component, TAC5X1X_GPIO1); + gpio_check = ((val & TAC5X1X_GPIOX_CFG_MASK) >> 0); + if (gpio_check == TAC5X1X_GPIO_DISABLE) { + dev_err(component->dev, + "%s: GPIO1 is not configure as a GPO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0]) + val = 0; + else + val = TAC5X1X_GPIO1_VAL; + + ucontrol->value.integer.value[0] = (val >> 0); + snd_soc_component_update_bits(component, TAC5X1X_GPIOVAL, + TAC5X1X_GPIO1_VAL, val); + + return 1; +}; + +static s32 tac5x1x_get_GPIO2_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 val; + + val = snd_soc_component_read(component, TAC5X1X_GPIOVAL); + ucontrol->value.integer.value[0] = !!(val & TAC5X1X_GPIO2_MON); + + return 0; +}; + +static s32 tac5x1x_set_GPIO2_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 gpio_check, val; + + val = snd_soc_component_read(component, TAC5X1X_GPIO2); + gpio_check = ((val & TAC5X1X_GPIOX_CFG_MASK) >> 0); + if (gpio_check == TAC5X1X_GPIO_DISABLE) { + dev_err(component->dev, + "%s: GPIO2 is not configure as a GPO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0]) + val = 0; + else + val = TAC5X1X_GPIO2_VAL; + + ucontrol->value.integer.value[0] = (val >> 0); + snd_soc_component_update_bits(component, TAC5X1X_GPIOVAL, + TAC5X1X_GPIO2_VAL, val); + + return 1; +}; + +static s32 tac5x1x_get_GPI1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 val; + + val = snd_soc_component_read(component, TAC5X1X_GPIOVAL); + ucontrol->value.integer.value[0] = !!(val & TAC5X1X_GPI1_MON); + + return 0; +}; + +static const struct snd_kcontrol_new tac5x1x_GPO1[] = { + SOC_SINGLE_BOOL_EXT("GPO1 GPO", 0, NULL, tac5x1x_set_GPO1_gpio), +}; + +static const struct snd_kcontrol_new tac5x1x_GPIO1_I[] = { + SOC_SINGLE_BOOL_EXT("GPIO1 GPI", 0, tac5x1x_get_GPIO1_gpio, NULL), +}; + +static const struct snd_kcontrol_new tac5x1x_GPIO1_O[] = { + SOC_SINGLE_BOOL_EXT("GPIO1 GPO", 0, NULL, tac5x1x_set_GPIO1_gpio), +}; + +static const struct snd_kcontrol_new tac5x1x_GPIO2_I[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "GPIO2 GPI", + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .get = tac5x1x_get_GPIO2_gpio, + .info = snd_soc_info_bool_ext, + } +}; + +static const struct snd_kcontrol_new tac5x1x_GPIO2_O[] = { + SOC_SINGLE_BOOL_EXT("GPIO2 GPO", 0, NULL, tac5x1x_set_GPIO2_gpio), +}; + +static const struct snd_kcontrol_new tac5x1x_GPI1[] = { + SOC_SINGLE_BOOL_EXT("GPI1 GPI", 0, tac5x1x_get_GPI1_gpio, NULL), +}; + +/* Record */ +/* ADC Analog/PDM Selection */ +static const char *const tac5x1x_input_source_text[] = {"Analog", "PDM"}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_in1_source_enum, TAC5X1X_INTF4, 7, + tac5x1x_input_source_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_in2_source_enum, TAC5X1X_INTF4, 6, + tac5x1x_input_source_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_in1_source_control[] = { + SOC_DAPM_ENUM("CH1 Source MUX", tac5x1x_in1_source_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_in2_source_control[] = { + SOC_DAPM_ENUM("CH2 Source MUX", tac5x1x_in2_source_enum), +}; + +static const char *const tad5x1x_input_source_text[] = {"Disable", "PDM"}; +static SOC_ENUM_SINGLE_DECL(tad5x1x_in1_source_enum, TAC5X1X_INTF4, 7, + tad5x1x_input_source_text); +static SOC_ENUM_SINGLE_DECL(tad5x1x_in2_source_enum, TAC5X1X_INTF4, 6, + tad5x1x_input_source_text); + +static const struct snd_kcontrol_new tad5x1x_dapm_in1_source_control[] = { + SOC_DAPM_ENUM("CH1 Source MUX", tad5x1x_in1_source_enum), +}; + +static const struct snd_kcontrol_new tad5x1x_dapm_in2_source_control[] = { + SOC_DAPM_ENUM("CH2 Source MUX", tad5x1x_in2_source_enum), +}; + +/* ADC Analog source Selection */ +static const char *const tac5x1x_input_analog_sel_text[] = { + "Differential", + "Single-ended", + "Single-ended mux INxP", + "Single-ended mux INxM", +}; + +static const char *const tac5x1x_input_analog2_sel_text[] = { + "Differential", + "Single-ended", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_config_enum, TAC5X1X_ADCCH1C0, 6, + tac5x1x_input_analog_sel_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_config_enum, TAC5X1X_ADCCH2C0, 6, + tac5x1x_input_analog2_sel_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_adc1_config_control[] = { + SOC_DAPM_ENUM("ADC1 Analog MUX", tac5x1x_adc1_config_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_adc2_config_control[] = { + SOC_DAPM_ENUM("ADC2 Analog MUX", tac5x1x_adc2_config_enum), +}; + +/* + * ADC full-scale selection + * 2/10-VRMS is for TAX52xx/TAX51xx devices + * 4/5-VRMS is for TAX54xx/TAX53xx devices + */ +static const char *const tac5x1x_adc_fscale_text[] = {"2/10-VRMS", + "4/5-VRMS"}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_fscale_enum, TAC5X1X_ADCCH1C0, 1, + tac5x1x_adc_fscale_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_fscale_enum, TAC5X1X_ADCCH2C0, 1, + tac5x1x_adc_fscale_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_adc1_fscale_control[] = { + SOC_DAPM_ENUM("ADC1 FSCALE MUX", tac5x1x_adc1_fscale_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_adc2_fscale_control[] = { + SOC_DAPM_ENUM("ADC2 FSCALE MUX", tac5x1x_adc2_fscale_enum), +}; + +/* Impedance Selection */ +static const char *const resistor_text[] = { + "5 kOhm", + "10 kOhm", + "40 kOhm", +}; + +static SOC_ENUM_SINGLE_DECL(adc1_resistor_enum, TAC5X1X_ADCCH1C0, 4, + resistor_text); +static SOC_ENUM_SINGLE_DECL(adc2_resistor_enum, TAC5X1X_ADCCH2C0, 4, + resistor_text); + +/* PDM Data input pin Selection */ +static const char *const pdm_pin_text[] = { + "Disable", + "GPIO1", + "GPIO2", + "GPI1", +}; + +static SOC_ENUM_SINGLE_DECL(pdm_12_pin_enum, TAC5X1X_INTF4, 2, pdm_pin_text); +static SOC_ENUM_SINGLE_DECL(pdm_34_pin_enum, TAC5X1X_INTF4, 0, pdm_pin_text); +static const struct snd_kcontrol_new pdm_12_pin_controls[] = { + SOC_DAPM_ENUM("PDM chn12 Datain Select", pdm_12_pin_enum), +}; + +static const struct snd_kcontrol_new pdm_34_pin_controls[] = { + SOC_DAPM_ENUM("PDM chn34 Datain Select", pdm_34_pin_enum), +}; + +static const char *const pdmclk_text[] = { + "2.8224 MHz or 3.072 MHz", "1.4112 MHz or 1.536 MHz", + "705.6 kHz or 768 kHz", "5.6448 MHz or 6.144 MHz"}; + +static SOC_ENUM_SINGLE_DECL(pdmclk_select_enum, TAC5X1X_CNTCLK0, 6, + pdmclk_text); + +/* Digital Volume control. From -80 to 47 dB in 0.5 dB steps */ +static DECLARE_TLV_DB_SCALE(record_dig_vol_tlv, -8000, 50, 0); + +/* Gain Calibration control. From -0.8db to 0.7db dB in 0.1 dB steps */ +static DECLARE_TLV_DB_MINMAX(record_gain_cali_tlv, -80, 70); + +/* Analog Level control. From -12 to 24 dB in 6 dB steps */ +static DECLARE_TLV_DB_SCALE(playback_analog_level_tlv, -1200, 600, 0); + +/* Digital Volume control. From -100 to 27 dB in 0.5 dB steps */ +static DECLARE_TLV_DB_SCALE(dac_dig_vol_tlv, -10000, 50, 0); // mute ? + +/* Gain Calibration control. From -0.8db to 0.7db dB in 0.1 dB steps */ +static DECLARE_TLV_DB_MINMAX(playback_gain_cali_tlv, -80, 70); + +/* Output Source Selection */ +static const char *const tac5x1x_output_source_text[] = { + "Disabled", + "DAC Input", + "Analog Bypass", + "DAC + Analog Bypass Mix", + "DAC -> OUTxP, INxP -> OUTxM", + "INxM -> OUTxP, DAC -> OUTxM", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_out1_source_enum, TAC5X1X_OUT1CFG0, 5, + tac5x1x_output_source_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_out2_source_enum, TAC5X1X_OUT2CFG0, 5, + tac5x1x_output_source_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_out1_source_control[] = { + SOC_DAPM_ENUM("OUT1X MUX", tac5x1x_out1_source_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_out2_source_control[] = { + SOC_DAPM_ENUM("OUT2X MUX", tac5x1x_out2_source_enum), +}; + +/* Output Config Selection */ +static const char *const tac5x1x_output_config_text[] = { + "Differential", + "Stereo Single-ended", + "Mono Single-ended at OUTxP only", + "Mono Single-ended at OUTxM only", + "Pseudo differential with OUTxM as VCOM", + "Pseudo differential with OUTxM as external sensing", + "Pseudo differential with OUTxP as VCOM", +}; + +static const char *const tac5x1x_output2_config_text[] = { + "Differential", + "Stereo Single-ended", + "Mono Single-ended at OUTxP only", + "Mono Single-ended at OUTxM only", + "Pseudo differential with OUTxM as VCOM", + "Reserved", + "Pseudo differential with OUTxP as VCOM", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_out1_config_enum, TAC5X1X_OUT1CFG0, 2, + tac5x1x_output_config_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_out2_config_enum, TAC5X1X_OUT2CFG0, 2, + tac5x1x_output2_config_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_out1_config_control[] = { + SOC_DAPM_ENUM("OUT1X Config MUX", tac5x1x_out1_config_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_out2_config_control[] = { + SOC_DAPM_ENUM("OUT2X Config MUX", tac5x1x_out2_config_enum), +}; + +static const char *const tac5x1x_wideband_text[] = { + "Audio BW 24-kHz", + "Wide BW 96-kHz", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_wideband_enum, TAC5X1X_ADCCH1C0, 0, + tac5x1x_wideband_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_wideband_enum, TAC5X1X_ADCCH2C0, 0, + tac5x1x_wideband_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_dac1_wideband_enum, TAC5X1X_OUT1CFG1, 0, + tac5x1x_wideband_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_dac2_wideband_enum, TAC5X1X_OUT2CFG1, 0, + tac5x1x_wideband_text); + +static const char *const tac5x1x_tolerance_text[] = { + "AC Coupled with 100mVpp", + "AC/DC Coupled with 1Vpp", + "AC/DC Coupled with Rail-to-rail", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_tolerance_enum, TAC5X1X_ADCCH1C0, 2, + tac5x1x_tolerance_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_tolerance_enum, TAC5X1X_ADCCH2C0, 2, + tac5x1x_tolerance_text); + +/* Output Drive Selection */ +static const char *const tac5x1x_output_driver_text[] = { + "Line-out", + "Headphone", + "4 ohm", + "FD Receiver/Debug", +}; + +static SOC_ENUM_SINGLE_DECL(out1p_driver_enum, TAC5X1X_OUT1CFG1, 6, + tac5x1x_output_driver_text); + +static SOC_ENUM_SINGLE_DECL(out2p_driver_enum, TAC5X1X_OUT2CFG1, 6, + tac5x1x_output_driver_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_out1_driver_control[] = { + SOC_DAPM_ENUM("OUT1 driver MUX", out1p_driver_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_out2_driver_control[] = { + SOC_DAPM_ENUM("OUT2 driver MUX", out2p_driver_enum), +}; + +/* Decimation Filter Selection */ +static const char *const decimation_filter_text[] = { + "Linear Phase", "Low Latency", "Ultra-low Latency"}; + +static SOC_ENUM_SINGLE_DECL(decimation_filter_record_enum, TAC5X1X_DSP0, 6, + decimation_filter_text); +static SOC_ENUM_SINGLE_DECL(decimation_filter_playback_enum, TAC5X1X_DSP1, 6, + decimation_filter_text); + +static const struct snd_kcontrol_new tx_ch1_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH1, 5, 1, 0); +static const struct snd_kcontrol_new tx_ch2_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH2, 5, 1, 0); +static const struct snd_kcontrol_new tx_ch3_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH3, 5, 1, 0); +static const struct snd_kcontrol_new tx_ch4_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH4, 5, 1, 0); + +static const struct snd_kcontrol_new rx_ch1_asi_switch = + SOC_DAPM_SINGLE("Switch", TAC5X1X_PASIRXCH1, 5, 1, 0); +static const struct snd_kcontrol_new rx_ch2_asi_switch = + SOC_DAPM_SINGLE("Switch", TAC5X1X_PASIRXCH2, 5, 1, 0); + +static const char *const rx_ch3_asi_cfg_text[] = { + "Disable", + "DAC channel data", +}; + +static const char *const rx_ch5_asi_cfg_text[] = { + "Disable", + "DAC channel data", + "ADC channel output loopback", +}; + +static const char *const rx_ch6_asi_cfg_text[] = { + "Disable", + "DAC channel data", + "ADC channel output loopback", + "Channel Input to ICLA device", +}; + +static const char *const tx_ch5_asi_cfg_text[] = { + "Tristate", + "Input Channel Loopback data", + "Echo reference Channel data", +}; + +static const char *const tx_ch7_asi_cfg_text[] = { + "Tristate", + "Vbat_Wlby2,Temp_Wlby2", + "echo_ref_ch1,echo_ref_ch2", +}; + +static const char *const tx_ch8_asi_cfg_text[] = { + "Tristate", + "ICLA data", +}; + +static const char *const tac5x1x_slot_select_text[] = { + "Slot 0", "Slot 1", "Slot 2", "Slot 3", + "Slot 4", "Slot 5", "Slot 6", "Slot 7", + "Slot 8", "Slot 9", "Slot 10", "Slot 11", + "Slot 12", "Slot 13", "Slot 14", "Slot 15", + "Slot 16", "Slot 17", "Slot 18", "Slot 19", + "Slot 20", "Slot 21", "Slot 22", "Slot 23", + "Slot 24", "Slot 25", "Slot 26", "Slot 27", + "Slot 28", "Slot 29", "Slot 30", "Slot 31", +}; + +static const char *const out2x_vcom_text[] = { + "0.6 * Vref", + "AVDD by 2", +}; + +static const char *const diag_cfg_text[] = { + "0mv", "30mv", "60mv", "90mv", + "120mv", "150mv", "180mv", "210mv", + "240mv", "270mv", "300mv", "330mv", + "360mv", "390mv", "420mv", "450mv", +}; + +static const char *const diag_cfg_gnd_text[] = { + "0mv", "60mv", "120mv", "180mv", + "240mv", "300mv", "360mv", "420mv", + "480mv", "540mv", "600mv", "660mv", + "720mv", "780mv", "840mv", "900mv", +}; + +static SOC_ENUM_SINGLE_DECL(out2x_vcom_enum, TAC5X1X_OUT2CFG0, 1, + out2x_vcom_text); + +static SOC_ENUM_SINGLE_DECL(tx_ch5_asi_cfg_enum, TAC5X1X_PASITXCH5, 5, + tx_ch5_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch6_asi_cfg_enum, TAC5X1X_PASITXCH6, 5, + tx_ch5_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch7_asi_cfg_enum, TAC5X1X_PASITXCH7, 5, + tx_ch7_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch8_asi_cfg_enum, TAC5X1X_PASITXCH8, 5, + tx_ch8_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch1_slot_select_enum, TAC5X1X_PASITXCH1, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch2_slot_select_enum, TAC5X1X_PASITXCH2, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch3_slot_select_enum, TAC5X1X_PASITXCH3, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch4_slot_select_enum, TAC5X1X_PASITXCH4, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch5_slot_select_enum, TAC5X1X_PASITXCH5, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch6_slot_select_enum, TAC5X1X_PASITXCH6, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch7_slot_select_enum, TAC5X1X_PASITXCH7, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch8_slot_select_enum, TAC5X1X_PASITXCH8, 0, + tac5x1x_slot_select_text); + +static SOC_ENUM_SINGLE_DECL(rx_ch3_asi_cfg_enum, TAC5X1X_PASIRXCH3, 5, + rx_ch3_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch4_asi_cfg_enum, TAC5X1X_PASIRXCH4, 5, + rx_ch3_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch5_asi_cfg_enum, TAC5X1X_PASIRXCH5, 5, + rx_ch5_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch6_asi_cfg_enum, TAC5X1X_PASIRXCH6, 5, + rx_ch6_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch7_asi_cfg_enum, TAC5X1X_PASIRXCH7, 5, + rx_ch6_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch8_asi_cfg_enum, TAC5X1X_PASIRXCH8, 5, + rx_ch6_asi_cfg_text); + +static SOC_ENUM_SINGLE_DECL(rx_ch1_slot_select_enum, TAC5X1X_PASIRXCH1, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch2_slot_select_enum, TAC5X1X_PASIRXCH2, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch3_slot_select_enum, TAC5X1X_PASIRXCH3, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch4_slot_select_enum, TAC5X1X_PASIRXCH4, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch5_slot_select_enum, TAC5X1X_PASIRXCH5, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch6_slot_select_enum, TAC5X1X_PASIRXCH6, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch7_slot_select_enum, TAC5X1X_PASIRXCH7, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch8_slot_select_enum, TAC5X1X_PASIRXCH8, 0, + tac5x1x_slot_select_text); + +static SOC_ENUM_SINGLE_DECL(diag_cfg1_sht_term_enum, TAC5X1X_DIAG_CFG1, 4, + diag_cfg_text); +static SOC_ENUM_SINGLE_DECL(diag_cfg1_vbat_in_enum, TAC5X1X_DIAG_CFG1, 0, + diag_cfg_text); +static SOC_ENUM_SINGLE_DECL(diag_cfg2_sht_gnd_enum, TAC5X1X_DIAG_CFG2, 4, + diag_cfg_gnd_text); +static SOC_ENUM_SINGLE_DECL(diag_cfg2_micbias, TAC5X1X_DIAG_CFG2, 0, + diag_cfg_text); + +static const struct snd_kcontrol_new taa5x1x_controls[] = { + SOC_ENUM("Record Decimation Filter", + decimation_filter_record_enum), + SOC_ENUM("ADC1 Audio BW", tac5x1x_adc1_wideband_enum), + + SOC_SINGLE_TLV("ADC1 Digital Capture Volume", TAC5X1X_ADCCH1C2, + 0, 0xff, 0, record_dig_vol_tlv), + + SOC_SINGLE_TLV("ADC1 Fine Capture Volume", TAC5X1X_ADCCH1C3, + 0, 0xff, 0, record_gain_cali_tlv), + + SOC_SINGLE_RANGE("ADC1 Phase Capture Volume", TAC5X1X_ADCCH1C4, + 2, 0, 63, 0), + + SOC_ENUM("ASI_TX_CH5_CFG", tx_ch5_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH6_CFG", tx_ch6_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH7_CFG", tx_ch7_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH8_CFG", tx_ch8_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH1_SLOT", tx_ch1_slot_select_enum), + SOC_ENUM("ASI_TX_CH2_SLOT", tx_ch2_slot_select_enum), + SOC_ENUM("ASI_TX_CH3_SLOT", tx_ch3_slot_select_enum), + SOC_ENUM("ASI_TX_CH4_SLOT", tx_ch4_slot_select_enum), + SOC_ENUM("ASI_TX_CH5_SLOT", tx_ch5_slot_select_enum), + SOC_ENUM("ASI_TX_CH6_SLOT", tx_ch6_slot_select_enum), + SOC_ENUM("ASI_TX_CH7_SLOT", tx_ch7_slot_select_enum), + SOC_ENUM("ASI_TX_CH8_SLOT", tx_ch8_slot_select_enum), + SOC_SINGLE("IN_CH1_EN Capture Switch", TAC5X1X_CH_EN, 7, 1, 0), + SOC_SINGLE("IN_CH2_EN Capture Switch", TAC5X1X_CH_EN, 6, 1, 0), + SOC_SINGLE("IN_CH3_EN Capture Switch", TAC5X1X_CH_EN, 5, 1, 0), + SOC_SINGLE("IN_CH4_EN Capture Switch", TAC5X1X_CH_EN, 4, 1, 0), +}; + +static const struct snd_kcontrol_new tad5x1x_controls[] = { + SOC_ENUM("Playback Decimation Filter", + decimation_filter_playback_enum), + SOC_ENUM("DAC1 Audio BW", tac5x1x_dac1_wideband_enum), + SOC_SINGLE_TLV("OUT1P Analog Level Playback Volume", TAC5X1X_OUT1CFG1, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("OUT1M Analog Level Playback Volume", TAC5X1X_OUT1CFG2, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("DAC1 CHA Digital Playback Volume", TAC5X1X_DACCH1A0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC1 CHB Digital Playback Volume", TAC5X1X_DACCH1B0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC1 CHA Gain Calibration Playback Volume", + TAC5X1X_DACCH1A1, 4, 0xf, 0, + playback_gain_cali_tlv), + SOC_SINGLE_TLV("DAC1 CHB Gain Calibration Playback Volume", + TAC5X1X_DACCH1B1, 4, 0xf, 0, + playback_gain_cali_tlv), + + SOC_ENUM("ASI_RX_CH3_EN Playback", rx_ch3_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH4_EN Playback", rx_ch4_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH5_EN Playback", rx_ch5_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH6_EN Playback", rx_ch6_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH7_EN Playback", rx_ch7_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH8_EN Playback", rx_ch8_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH1_SLOT Playback", rx_ch1_slot_select_enum), + SOC_ENUM("ASI_RX_CH2_SLOT Playback", rx_ch2_slot_select_enum), + SOC_ENUM("ASI_RX_CH3_SLOT Playback", rx_ch3_slot_select_enum), + SOC_ENUM("ASI_RX_CH4_SLOT Playback", rx_ch4_slot_select_enum), + SOC_ENUM("ASI_RX_CH5_SLOT Playback", rx_ch5_slot_select_enum), + SOC_ENUM("ASI_RX_CH6_SLOT Playback", rx_ch6_slot_select_enum), + SOC_ENUM("ASI_RX_CH7_SLOT Playback", rx_ch7_slot_select_enum), + SOC_ENUM("ASI_RX_CH8_SLOT Playback", rx_ch8_slot_select_enum), + + SOC_SINGLE("OUT_CH1_EN Playback Switch", TAC5X1X_CH_EN, 3, 1, 0), + SOC_SINGLE("OUT_CH2_EN Playback Switch", TAC5X1X_CH_EN, 2, 1, 0), + SOC_SINGLE("OUT_CH3_EN Playback Switch", TAC5X1X_CH_EN, 1, 1, 0), + SOC_SINGLE("OUT_CH4_EN Playback Switch", TAC5X1X_CH_EN, 0, 1, 0), +}; + +static const struct snd_kcontrol_new tac5x11_controls[] = { + SOC_ENUM("ADC1 Common-mode Tolerance", tac5x1x_adc1_tolerance_enum), + SOC_ENUM("ADC1 Impedance Select", adc1_resistor_enum), +}; + +static const struct snd_kcontrol_new tad5x12_controls[] = { + SOC_SINGLE_TLV("OUT2P Analog Level Playback Volume", TAC5X1X_OUT2CFG1, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("OUT2M Analog Level Playback Volume", TAC5X1X_OUT2CFG2, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("DAC2 CHA Digital Playback Volume", TAC5X1X_DACCH2A0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC2 CHB Digital Playback Volume", TAC5X1X_DACCH2B0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC2 CHA Gain Calibration Playback Volume", + TAC5X1X_DACCH2A1, 4, 0xf, 0, + playback_gain_cali_tlv), + SOC_SINGLE_TLV("DAC2 CHB Gain Calibration Playback Volume", + TAC5X1X_DACCH2B1, 4, 0xf, 0, + playback_gain_cali_tlv), + SOC_ENUM("DAC2 Audio BW", tac5x1x_dac2_wideband_enum), + SOC_ENUM("OUT2X_VCOM", out2x_vcom_enum), +}; + +static const struct snd_kcontrol_new taa5x12_controls[] = { + SOC_ENUM("ADC2 Audio BW", tac5x1x_adc2_wideband_enum), + + SOC_SINGLE_TLV("ADC2 Digital Capture Volume", TAC5X1X_ADCCH2C2, + 0, 0xff, 0, record_dig_vol_tlv), + + SOC_SINGLE_TLV("ADC2 Fine Capture Volume", TAC5X1X_ADCCH2C3, + 0, 0xff, 0, record_gain_cali_tlv), + + SOC_SINGLE_RANGE("ADC2 Phase Capture Volume", TAC5X1X_ADCCH2C4, + 2, 0, 63, 0), +}; + +static const struct snd_kcontrol_new tac5x12_impedance_controls[] = { + SOC_ENUM("ADC1 Impedance Select", adc1_resistor_enum), + SOC_ENUM("ADC2 Impedance Select", adc2_resistor_enum), +}; + +static const struct snd_kcontrol_new tac5x12_tolerance_controls[] = { + SOC_ENUM("ADC1 Common-mode Tolerance", tac5x1x_adc1_tolerance_enum), + SOC_ENUM("ADC2 Common-mode Tolerance", tac5x1x_adc2_tolerance_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_pdm_controls[] = { + SOC_ENUM("PDM Clk Divider", pdmclk_select_enum), + + SOC_SINGLE_TLV("PDM1 Digital Capture Volume", TAC5X1X_ADCCH1C2, + 0, 0xff, 0, record_dig_vol_tlv), + SOC_SINGLE_TLV("PDM2 Digital Capture Volume", TAC5X1X_ADCCH2C2, + 0, 0xff, 0, record_dig_vol_tlv), + + SOC_SINGLE_TLV("PDM1 Fine Capture Volume", TAC5X1X_ADCCH1C3, + 0, 0xff, 0, record_gain_cali_tlv), + SOC_SINGLE_TLV("PDM2 Fine Capture Volume", TAC5X1X_ADCCH2C3, + 0, 0xff, 0, record_gain_cali_tlv), + + SOC_SINGLE_RANGE("PDM1 Phase Capture Volume", TAC5X1X_ADCCH1C4, + 2, 0, 63, 0), + SOC_SINGLE_RANGE("PDM2 Phase Capture Volume", TAC5X1X_ADCCH2C4, + 2, 0, 63, 0), + + SOC_SINGLE_TLV("PDM3 Digital Capture Volume", TAC5X1X_ADCCH3C2, + 0, 0xff, 0, record_dig_vol_tlv), + SOC_SINGLE_TLV("PDM4 Digital Capture Volume", TAC5X1X_ADCCH4C2, + 0, 0xff, 0, record_dig_vol_tlv), + + SOC_SINGLE_TLV("PDM3 Fine Capture Volume", TAC5X1X_ADCCH3C3, + 0, 0xff, 0, record_gain_cali_tlv), + SOC_SINGLE_TLV("PDM4 Fine Capture Volume", TAC5X1X_ADCCH4C3, + 0, 0xff, 0, record_gain_cali_tlv), + + SOC_SINGLE_RANGE("PDM3 Phase Capture Volume", TAC5X1X_ADCCH3C4, + 2, 0, 63, 0), + SOC_SINGLE_RANGE("PDM4 Phase Capture Volume", TAC5X1X_ADCCH4C4, + 2, 0, 63, 0), +}; + +static const struct snd_kcontrol_new taa5x1x_ip_controls[] = { + SOC_ENUM("DIAG_SHT_TERM", diag_cfg1_sht_term_enum), + SOC_ENUM("DIAG_SHT_VBAT_IN", diag_cfg1_vbat_in_enum), + SOC_ENUM("DIAG_SHT_GND", diag_cfg2_sht_gnd_enum), + SOC_ENUM("DIAG_SHT_MICBIAS", diag_cfg2_micbias), +}; + +static const struct snd_soc_dapm_widget taa5x1x_dapm_widgets[] = { + /* ADC1 */ + SND_SOC_DAPM_INPUT("AIN1"), + + SND_SOC_DAPM_MUX("ADC1 Full-Scale", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc1_fscale_control), + + SND_SOC_DAPM_MUX("ADC1 Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc1_config_control), + + SND_SOC_DAPM_ADC("CH1_ADC_EN", "CH1 Capture", TAC5X1X_CH_EN, 7, 0), + + SND_SOC_DAPM_SWITCH("ASI_TX_CH1_EN", SND_SOC_NOPM, 0, 0, + &tx_ch1_asi_switch), + + SND_SOC_DAPM_MICBIAS("Mic Bias", TAC5X1X_PWR_CFG, 5, 0), + SND_SOC_DAPM_SWITCH("ASI_TX_CH2_EN", SND_SOC_NOPM, 0, 0, + &tx_ch2_asi_switch), +}; + +static const struct snd_kcontrol_new tad5x1x_pdm_controls[] = { + SOC_ENUM("ASI_TX_CH1_SLOT", tx_ch1_slot_select_enum), + SOC_ENUM("ASI_TX_CH2_SLOT", tx_ch2_slot_select_enum), + SOC_ENUM("ASI_TX_CH3_SLOT", tx_ch3_slot_select_enum), + SOC_ENUM("ASI_TX_CH4_SLOT", tx_ch4_slot_select_enum), +}; + +static const struct snd_soc_dapm_widget tad5xx_dapm_widgets[] = { + /* pdm capture */ + SND_SOC_DAPM_SWITCH("ASI_TX_CH1_EN", SND_SOC_NOPM, 0, 0, + &tx_ch1_asi_switch), + SND_SOC_DAPM_SWITCH("ASI_TX_CH2_EN", SND_SOC_NOPM, 0, 0, + &tx_ch2_asi_switch), +}; + +static const struct snd_soc_dapm_widget tad5x1x_dapm_widgets[] = { + /* DAC1 */ + SND_SOC_DAPM_AIF_IN("ASI IN1", "ASI Playback", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_OUTPUT("OUT1"), + + SND_SOC_DAPM_MUX("OUT1x Source", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out1_source_control), + + SND_SOC_DAPM_MUX("OUT1x Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out1_config_control), + + SND_SOC_DAPM_MUX("OUT1x Driver", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out1_driver_control), + + SND_SOC_DAPM_DAC("Left DAC Enable", "Left Playback", TAC5X1X_CH_EN, 3, + 0), + SND_SOC_DAPM_PGA("Left DAC Power", TAC5X1X_PWR_CFG, 6, 0, NULL, 0), + + SND_SOC_DAPM_SWITCH("ASI_RX_CH1_EN", SND_SOC_NOPM, 0, 0, + &rx_ch1_asi_switch), +}; + +static const struct snd_soc_dapm_widget taa5x12_dapm_widgets[] = { + /* ADC2 */ + SND_SOC_DAPM_INPUT("AIN2"), + + SND_SOC_DAPM_MUX("ADC2 Full-Scale", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc2_fscale_control), + + SND_SOC_DAPM_MUX("ADC2 Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc2_config_control), + + SND_SOC_DAPM_ADC("CH2_ADC_EN", "CH2 Capture", TAC5X1X_CH_EN, 6, 0), + +}; + +static const struct snd_soc_dapm_widget tad5x12_dapm_widgets[] = { + /* DAC2 */ + SND_SOC_DAPM_OUTPUT("OUT2"), + + SND_SOC_DAPM_AIF_IN("ASI IN2", "ASI Playback", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MUX("OUT2x Source", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out2_source_control), + + SND_SOC_DAPM_MUX("OUT2x Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out2_config_control), + + SND_SOC_DAPM_MUX("OUT2x Driver", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out2_driver_control), + + SND_SOC_DAPM_DAC("Right DAC Enable", + "Right Playback", TAC5X1X_CH_EN, 2, 0), + SND_SOC_DAPM_PGA("Right DAC Power", TAC5X1X_PWR_CFG, 6, 0, NULL, 0), + + SND_SOC_DAPM_SWITCH("ASI_RX_CH2_EN", SND_SOC_NOPM, 0, 0, + &rx_ch2_asi_switch), +}; + +static const struct snd_soc_dapm_widget tac5x1x_dapm_pdm_widgets[] = { + /* PDM */ + SND_SOC_DAPM_INPUT("DIN1"), + SND_SOC_DAPM_INPUT("DIN2"), + SND_SOC_DAPM_INPUT("DIN3"), + SND_SOC_DAPM_INPUT("DIN4"), + + SND_SOC_DAPM_MUX("PDM ch1 & ch2 Datain Select", + SND_SOC_NOPM, 0, 0, pdm_12_pin_controls), + SND_SOC_DAPM_MUX("PDM ch3 & ch4 Datain Select", + SND_SOC_NOPM, 0, 0, pdm_34_pin_controls), + + SND_SOC_DAPM_ADC("CH1_PDM_EN", "PDM CH1 Capture", TAC5X1X_CH_EN, 7, 0), + SND_SOC_DAPM_ADC("CH2_PDM_EN", "PDM CH2 Capture", TAC5X1X_CH_EN, 6, 0), + SND_SOC_DAPM_ADC("CH3_PDM_EN", "PDM CH3 Capture", TAC5X1X_CH_EN, 5, 0), + SND_SOC_DAPM_ADC("CH4_PDM_EN", "PDM CH4 Capture", TAC5X1X_CH_EN, 4, 0), + + SND_SOC_DAPM_SWITCH("ASI_TX_CH3_EN", SND_SOC_NOPM, 0, 0, + &tx_ch3_asi_switch), + SND_SOC_DAPM_SWITCH("ASI_TX_CH4_EN", SND_SOC_NOPM, 0, 0, + &tx_ch4_asi_switch), +}; + +static const struct snd_soc_dapm_widget tac5x1x_common_dapm_widgets[] = { + SND_SOC_DAPM_MUX("IN1 Source Mux", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_in1_source_control), + SND_SOC_DAPM_MUX("IN2 Source Mux", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_in2_source_control), + SND_SOC_DAPM_PGA("ADC Power", TAC5X1X_PWR_CFG, 7, 0, NULL, 0), + SND_SOC_DAPM_AIF_OUT("AIF OUT", "ASI Capture", 0, SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_widget tad5x1x_common_dapm_widgets[] = { + SND_SOC_DAPM_MUX("IN1 Source Mux", SND_SOC_NOPM, 0, 0, + tad5x1x_dapm_in1_source_control), + SND_SOC_DAPM_MUX("IN2 Source Mux", SND_SOC_NOPM, 0, 0, + tad5x1x_dapm_in2_source_control), + SND_SOC_DAPM_PGA("ADC Power", TAC5X1X_PWR_CFG, 7, 0, NULL, 0), + SND_SOC_DAPM_AIF_OUT("AIF OUT", "ASI Capture", 0, SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_route taa5x1x_dapm_routes[] = { + /* ADC channel1 */ + {"IN1 Source Mux", "Analog", "AIN1"}, + {"IN2 Source Mux", "Analog", + "IN1 Source Mux"}, + + {"CH1_ADC_EN", NULL, "IN2 Source Mux"}, + {"ASI_TX_CH1_EN", "Capture Switch", "CH1_ADC_EN"}, + + {"ADC1 Config", "Differential", "ASI_TX_CH1_EN"}, + {"ADC1 Config", "Single-ended", "ASI_TX_CH1_EN"}, + {"ADC1 Config", "Single-ended mux INxP", + "ASI_TX_CH1_EN"}, + {"ADC1 Config", "Single-ended mux INxM", + "ASI_TX_CH1_EN"}, + + {"ADC1 Full-Scale", "2/10-VRMS", + "ADC1 Config"}, + {"ADC1 Full-Scale", "4/5-VRMS", + "ADC1 Config"}, + {"Mic Bias", NULL, "ADC1 Full-Scale"}, + +}; + +static const struct snd_soc_dapm_route tad5x1x_dapm_routes[] = { + /* Left Output */ + {"ASI_RX_CH1_EN", "Switch", "ASI IN1"}, + + {"OUT1x Source", "DAC + Analog Bypass Mix", "ASI_RX_CH1_EN"}, + {"OUT1x Source", "DAC -> OUTxP, INxP -> OUTxM", "ASI_RX_CH1_EN"}, + {"OUT1x Source", "INxM -> OUTxP, DAC -> OUTxM", "ASI_RX_CH1_EN"}, + + {"OUT1x Config", "Differential", "OUT1x Source"}, + // {"OUT1x Config", "Stereo Single-ended", "OUT1x Source"}, + {"OUT1x Config", "Mono Single-ended at OUTxP only", "OUT1x Source"}, + {"OUT1x Config", "Mono Single-ended at OUTxM only", "OUT1x Source"}, + {"OUT1x Config", "Pseudo differential with OUTxM as VCOM", + "OUT1x Source"}, + {"OUT1x Config", "Pseudo differential with OUTxM as external sensing", + "OUT1x Source"}, + {"OUT1x Config", "Pseudo differential with OUTxP as VCOM", + "OUT1x Source"}, + + {"OUT1x Driver", "Line-out", "OUT1x Config"}, + {"OUT1x Driver", "Headphone", "OUT1x Config"}, + + {"Left DAC Enable", NULL, "OUT1x Driver"}, + {"Left DAC Power", NULL, "Left DAC Enable"}, + + {"OUT1", NULL, "Left DAC Power"}, +}; + +static const struct snd_soc_dapm_route taa5x12_dapm_routes[] = { + /* ADC channel2 */ + {"CH2_ADC_EN", NULL, "AIN2"}, + + {"ASI_TX_CH2_EN", "Capture Switch", "CH2_ADC_EN"}, + + {"ADC2 Config", "Differential", "ASI_TX_CH2_EN"}, + {"ADC2 Config", "Single-ended", "ASI_TX_CH2_EN"}, + {"ADC2 Full-Scale", "2/10-VRMS", + "ADC2 Config"}, + {"ADC2 Full-Scale", "4/5-VRMS", + "ADC2 Config"}, + + {"Mic Bias", NULL, "ADC2 Full-Scale"}, +}; + +static const struct snd_soc_dapm_route tad5x12_dapm_routes[] = { + /* Right Output */ + {"ASI_RX_CH2_EN", "Switch", "ASI IN2"}, + + {"OUT2x Source", "DAC + Analog Bypass Mix", "ASI_RX_CH1_EN"}, + {"OUT2x Source", "DAC -> OUTxP, INxP -> OUTxM", "ASI_RX_CH1_EN"}, + {"OUT2x Source", "INxM -> OUTxP, DAC -> OUTxM", "ASI_RX_CH1_EN"}, + + {"OUT2x Config", "Differential", "OUT2x Source"}, + // {"OUT2x Config", "Stereo Single-ended", "OUT2x Source"}, + {"OUT2x Config", "Mono Single-ended at OUTxP only", "OUT2x Source"}, + {"OUT2x Config", "Mono Single-ended at OUTxM only", "OUT2x Source"}, + {"OUT2x Config", "Pseudo differential with OUTxM as VCOM", + "OUT2x Source"}, + {"OUT2x Config", "Pseudo differential with OUTxP as VCOM", + "OUT2x Source"}, + + {"OUT2x Driver", "Line-out", "OUT2x Config"}, + {"OUT2x Driver", "Headphone", "OUT2x Config"}, + + {"Right DAC Enable", NULL, "OUT2x Driver"}, + + {"Right DAC Power", NULL, "Right DAC Enable"}, + + {"OUT2", NULL, "Right DAC Power"}, +}; + +static const struct snd_soc_dapm_route tac5x1x_dapm_pdm_routes[] = { + /* PDM channel1 & Channel2 */ + {"IN1 Source Mux", "PDM", "DIN1"}, + {"IN2 Source Mux", "PDM", "DIN2"}, + + {"ASI_TX_CH1_EN", "Capture Switch", + "IN1 Source Mux"}, + {"ASI_TX_CH2_EN", "Capture Switch", + "IN2 Source Mux"}, + + {"CH1_PDM_EN", NULL, "ASI_TX_CH1_EN"}, + {"CH2_PDM_EN", NULL, "ASI_TX_CH2_EN"}, + + {"PDM ch1 & ch2 Datain Select", "GPIO1", "CH1_PDM_EN"}, + {"PDM ch1 & ch2 Datain Select", "GPIO2", "CH1_PDM_EN"}, + {"PDM ch1 & ch2 Datain Select", "GPI1", "CH1_PDM_EN"}, + + {"ADC Power", NULL, "PDM ch1 & ch2 Datain Select"}, + + /* PDM channel3 & Channel4 */ + {"ASI_TX_CH3_EN", "Capture Switch", "DIN3"}, + {"ASI_TX_CH4_EN", "Capture Switch", "DIN4"}, + + {"CH3_PDM_EN", NULL, "ASI_TX_CH3_EN"}, + {"CH4_PDM_EN", NULL, "ASI_TX_CH4_EN"}, + + {"PDM ch3 & ch4 Datain Select", "GPIO1", "CH3_PDM_EN"}, + {"PDM ch3 & ch4 Datain Select", "GPIO2", "CH3_PDM_EN"}, + {"PDM ch3 & ch4 Datain Select", "GPI1", "CH3_PDM_EN"}, + + {"ADC Power", NULL, "PDM ch3 & ch4 Datain Select"}, + {"AIF OUT", NULL, "ADC Power"}, +}; + +static const struct snd_soc_dapm_route tac5x1x_common_dapm_routes[] = { + {"ADC Power", NULL, "Mic Bias"}, + {"AIF OUT", NULL, "ADC Power"}, +}; + +static const struct reg_default tac5x1x_reg_defaults[] = { + {TAC5X1X_PGSEL, 0x00}, + {TAC5X1X_INT, 0x10}, + {TAC5X1X_ADCCH1C0, 0x04}, + {TAC5X1X_ADCCH2C0, 0x04}, + {TAC5X1X_OUT1CFG0, 0x20}, + {TAC5X1X_OUT2CFG0, 0x20}, + {TAC5X1X_CH_EN, 0x00}, + {TAC5X1X_PASITXCH1, 0x00}, + {TAC5X1X_PASITXCH2, 0x01}, + {TAC5X1X_PASIRXCH1, 0x00}, + {TAC5X1X_PASIRXCH2, 0x01}, + {}, +}; + +static s32 tac5x1x_pwr_ctrl(struct snd_soc_component *component, + bool power_state) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 active_ctrl, ret; + s32 pwr_ctrl = 0; + + if (power_state) { + active_ctrl = TAC5X1X_VREF_SLEEP_ACTIVE_MASK; + snd_soc_component_update_bits(component, TAC5X1X_VREFCFG, + TAC5X1X_VREFCFG_MICBIAS_VAL_MASK, + tac5x1x->micbias_vg << 2); + snd_soc_component_update_bits(component, TAC5X1X_VREFCFG, + TAC5X1X_VREFCFG_VREF_FSCALE_MASK, + tac5x1x->vref_vg); + + if (tac5x1x->uad_en) + pwr_ctrl |= TAC5X1X_PWR_CFG_UAD_EN; + if (tac5x1x->vad_en) + pwr_ctrl |= TAC5X1X_PWR_CFG_VAD_EN; + if (tac5x1x->uag_en) + pwr_ctrl |= TAC5X1X_PWR_CFG_UAG_EN; + } else { + active_ctrl = 0x0; + } + + ret = snd_soc_component_update_bits(component, TAC5X1X_VREF, + TAC5X1X_VREF_SLEEP_EXIT_VREF_EN | + TAC5X1X_VREF_SLEEP_ACTIVE_MASK, active_ctrl); + if (ret < 0) { + dev_err(tac5x1x->dev, + "%s, device active or sleep failed!, ret %d/n", + __func__, ret); + return ret; + } + + ret = snd_soc_component_update_bits(component, TAC5X1X_PWR_CFG, + TAC5X1X_PWR_CFG_UAD_EN | TAC5X1X_PWR_CFG_UAG_EN | + TAC5X1X_PWR_CFG_VAD_EN, pwr_ctrl); + if (ret < 0) + dev_err(tac5x1x->dev, + "%s, Power control set failed!, ret %d/n", + __func__, ret); + return ret; +} + +static s32 tac5x1x_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) +{ + struct snd_soc_component *component = codec_dai->component; + s32 iface_reg_1 = 0; + s32 iface_reg_2 = 0; + s32 iface_reg_3 = 0; + + dev_err(component->dev, "[tac5x1x] %s(), fmt=%d\n", __func__, fmt); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + iface_reg_1 |= TAC5X1X_PASI_MODE_MASK; + break; + case SND_SOC_DAIFMT_CBC_CFC: + break; + default: + dev_err(component->dev, + "%s: invalid DAI master/slave interface\n", + __func__); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface_reg_2 |= TAC5X1X_PASI_FMT_I2S; + break; + case SND_SOC_DAIFMT_DSP_A: + iface_reg_2 |= TAC5X1X_PASI_FMT_TDM; + iface_reg_3 |= BIT(0); /* add offset 1 */ + break; + case SND_SOC_DAIFMT_DSP_B: + iface_reg_2 |= TAC5X1X_PASI_FMT_TDM; + break; + case SND_SOC_DAIFMT_LEFT_J: + iface_reg_2 |= TAC5X1X_PASI_FMT_LJ; + break; + default: + dev_err(component->dev, + "%s: invalid DAI interface format\n", __func__); + return -EINVAL; + } + + snd_soc_component_update_bits(component, TAC5X1X_CNTCLK2, + TAC5X1X_PASI_MODE_MASK, iface_reg_1); + snd_soc_component_update_bits(component, TAC5X1X_PASI0, + TAC5X1X_PASI_FMT_MASK, iface_reg_2); + snd_soc_component_update_bits(component, TAC5X1X_PASITX1, + TAC5X1X_PASITX_OFFSET_MASK, iface_reg_3); + snd_soc_component_update_bits(component, TAC5X1X_PASIRX0, + TAC5X1X_PASIRX_OFFSET_MASK, iface_reg_3); + return 0; +} + +static s32 tac5x1x_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 sample_rate, word_length = 0; + + switch (params_rate(params)) { + case 24000: + sample_rate = 25; + break; + case 32000: + sample_rate = 23; + break; + case 44100: + case 48000: + sample_rate = 20; + break; + case 64000: + sample_rate = 18; + break; + case 96000: + sample_rate = 15; + break; + case 192000: + sample_rate = 10; + break; + default: + /* Auto detect sample rate */ + sample_rate = 0; + break; + } + + switch (params_physical_width(params)) { + case 16: + word_length |= TAC5X1X_WORD_LEN_16BITS; + break; + case 20: + word_length |= TAC5X1X_WORD_LEN_20BITS; + break; + case 24: + word_length |= TAC5X1X_WORD_LEN_24BITS; + break; + case 32: + word_length |= TAC5X1X_WORD_LEN_32BITS; + break; + default: + dev_err(tac5x1x->dev, "%s, set word length failed\n", + __func__); + return -EINVAL; + } + + snd_soc_component_update_bits(component, TAC5X1X_CLK0, TAC5X1X_PASI_SAMP_RATE_MASK, + sample_rate << 2); + snd_soc_component_update_bits(component, TAC5X1X_PASI0, + TAC5X1X_PASI_DATALEN_MASK, word_length); + + tac5x1x_pwr_ctrl(component, true); + return 0; +} + +static s32 tac5x1x_set_bias_level(struct snd_soc_component *component, + enum snd_soc_bias_level level) +{ + s32 ret; + struct tac5x1x_priv *tac5x1x = snd_soc_component_get_drvdata(component); + + switch (level) { + case SND_SOC_BIAS_ON: + ret = tac5x1x_pwr_ctrl(component, true); + if (ret < 0) + dev_err(tac5x1x->dev, "%s, power up failed!/n", __func__); + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + break; + case SND_SOC_BIAS_OFF: + ret = tac5x1x_pwr_ctrl(component, false); + if (ret < 0) + dev_err(tac5x1x->dev, "%s, power down failed!/n", __func__); + break; + } + + return ret; +} + +static const struct snd_soc_dai_ops tac5x1x_ops = { + .hw_params = tac5x1x_hw_params, + .set_fmt = tac5x1x_set_dai_fmt, + .no_capture_mute = 1, +}; + +static struct snd_soc_dai_driver tac5x1x_dai = { + .name = "tac5x1x-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .ops = &tac5x1x_ops, + .symmetric_rate = 1, +}; + +static struct snd_soc_dai_driver taa5x1x_dai = { + .name = "taa5x1x-hifi", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .ops = &tac5x1x_ops, + .symmetric_rate = 1, +}; + +static struct snd_soc_dai_driver tad5x1x_dai = { + .name = "tad5x1x-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .ops = &tac5x1x_ops, + .symmetric_rate = 1, +}; + +static void tac5x1x_setup_gpios(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 *gpio_drive = tac5x1x->gpio_setup->gpio_drive; + s32 *gpio_func = tac5x1x->gpio_setup->gpio_func; + + /* setup GPIO functions */ + /* GPIO1 */ + if (gpio_func[0] <= TAC5X1X_GPIO_DAISY_OUT) { + snd_soc_component_update_bits(component, TAC5X1X_GPIO1, TAC5X1X_GPIOX_CFG_MASK, + gpio_func[0] << 4); + snd_soc_component_update_bits(component, TAC5X1X_GPIO1, TAC5X1X_GPIOX_DRV_MASK, + gpio_drive[0]); + + if (gpio_func[0] == TAC5X1X_GPIO_GPI) + snd_soc_add_component_controls(component, tac5x1x_GPIO1_I, + ARRAY_SIZE(tac5x1x_GPIO1_I)); + else if (gpio_func[0] == TAC5X1X_GPIO_GPO) + snd_soc_add_component_controls(component, tac5x1x_GPIO1_O, + ARRAY_SIZE(tac5x1x_GPIO1_O)); + } + /* GPIO2 */ + if (gpio_func[1] <= TAC5X1X_GPIO_DAISY_OUT) { + snd_soc_component_update_bits(component, TAC5X1X_GPIO2, TAC5X1X_GPIOX_CFG_MASK, + gpio_func[1] << 4); + snd_soc_component_update_bits(component, TAC5X1X_GPIO2, TAC5X1X_GPIOX_DRV_MASK, + gpio_drive[1]); + + if (gpio_func[1] == TAC5X1X_GPIO_GPI) + snd_soc_add_component_controls(component, tac5x1x_GPIO2_I, + ARRAY_SIZE(tac5x1x_GPIO2_I)); + else if (gpio_func[1] == TAC5X1X_GPIO_GPO) + snd_soc_add_component_controls(component, tac5x1x_GPIO2_O, + ARRAY_SIZE(tac5x1x_GPIO2_O)); + } + /* GPO1 */ + if (gpio_func[2] <= TAC5X1X_GPIO_DAISY_OUT) { + snd_soc_component_update_bits(component, TAC5X1X_GPO1, TAC5X1X_GPIOX_CFG_MASK, + gpio_func[2] << 4); + snd_soc_component_update_bits(component, TAC5X1X_GPO1, TAC5X1X_GPIOX_DRV_MASK, + gpio_drive[2]); + + if (gpio_func[2] == TAC5X1X_GPIO_GPO) + snd_soc_add_component_controls(component, tac5x1x_GPO1, + ARRAY_SIZE(tac5x1x_GPO1)); + } + /* GPI1 */ + if (tac5x1x->gpio_setup->gpi1_func) { + snd_soc_component_update_bits(component, TAC5X1X_GPI1, TAC5X1X_GPI1_CFG_MASK, + TAC5X1X_GPI1_CFG_MASK); + snd_soc_add_component_controls(component, tac5x1x_GPI1, ARRAY_SIZE(tac5x1x_GPI1)); + } + /*GPA GPIO*/ + if (tac5x1x->gpio_setup->gpa_gpio) + snd_soc_component_update_bits(component, TAC5X1X_INTF5, TAC5X1X_GPA_CFG_MASK, + TAC5X1X_GPA_CFG_MASK); +} + +static s32 tac5x1x_reset(struct snd_soc_component *component) +{ + s32 ret, index; + + ret = snd_soc_component_write(component, TAC5X1X_RESET, 1); + if (ret < 0) + return ret; + /* Wait >= 10 ms after entering sleep mode. */ + usleep_range(10000, 100000); + + for (index = 0; index < ARRAY_SIZE(tac5x1x_reg_defaults); index++) { + ret = snd_soc_component_write(component, tac5x1x_reg_defaults[index].reg, + tac5x1x_reg_defaults[index].def); + if (ret < 0) + return ret; + } + return ret; +} + +static s32 tac5x1x_add_controls(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 *gpio_func = tac5x1x->gpio_setup->gpio_func; + s32 ret; + + switch (tac5x1x->codec_type) { + case TAA5212: + ret = snd_soc_add_component_controls(component, tac5x12_impedance_controls, + ARRAY_SIZE(tac5x12_impedance_controls)); + if (ret) + return ret; + fallthrough; + case TAA5412: + ret = snd_soc_add_component_controls(component, tac5x12_tolerance_controls, + ARRAY_SIZE(tac5x12_tolerance_controls)); + if (ret) + return ret; + ret = snd_soc_add_component_controls(component, taa5x1x_ip_controls, + ARRAY_SIZE(taa5x1x_ip_controls)); + if (ret) + return ret; + break; + /* For Mono */ + case TAC5111: + case TAC5211: + ret = snd_soc_add_component_controls(component, tac5x11_controls, + ARRAY_SIZE(tac5x11_controls)); + if (ret) + return ret; + fallthrough; + case TAC5311: + case TAC5411: + ret = snd_soc_add_component_controls(component, tad5x1x_controls, + ARRAY_SIZE(tad5x1x_controls)); + if (ret) + return ret; + break; + /* For Stereo */ + case TAC5112: + case TAC5212: + ret = snd_soc_add_component_controls(component, tac5x12_impedance_controls, + ARRAY_SIZE(tac5x12_impedance_controls)); + if (ret) + return ret; + fallthrough; + case TAC5312: + case TAC5412: + ret = snd_soc_add_component_controls(component, tac5x12_tolerance_controls, + ARRAY_SIZE(tac5x12_tolerance_controls)); + if (ret) + return ret; + ret = snd_soc_add_component_controls(component, tad5x1x_controls, + ARRAY_SIZE(tad5x1x_controls)); + if (ret) + return ret; + + ret = snd_soc_add_component_controls(component, taa5x12_controls, + ARRAY_SIZE(taa5x12_controls)); + if (ret) + return ret; + + ret = snd_soc_add_component_controls(component, tad5x12_controls, + ARRAY_SIZE(tad5x12_controls)); + if (ret) + return ret; + break; + case TAD5212: + case TAD5112: + ret = snd_soc_add_component_controls(component, tad5x12_controls, + ARRAY_SIZE(tad5x12_controls)); + if (ret) + return ret; + + ret = snd_soc_add_component_controls(component, tad5x1x_pdm_controls, + ARRAY_SIZE(tad5x1x_pdm_controls)); + if (ret) + return ret; + break; + default: + break; + } + + /* If enabled PDM GPIO*/ + if (memchr(gpio_func, TAC5X1X_GPIO_PDMCLK, + sizeof(*gpio_func) / sizeof(gpio_func[0]))) { + ret = snd_soc_add_component_controls(component, tac5x1x_pdm_controls, + ARRAY_SIZE(tac5x1x_pdm_controls)); + if (ret) + return ret; + } + + return 0; +} + +static s32 tac5x1x_add_ip_diag_controls(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 ret; + + switch (tac5x1x->codec_type) { + case TAA5212: + break; + case TAA5412: + case TAC5311: + case TAC5312: + case TAC5411: + case TAC5412: + if (tac5x1x->input_diag_config.in_ch_en) { + ret = snd_soc_add_component_controls(component, taa5x1x_ip_controls, + ARRAY_SIZE(taa5x1x_ip_controls)); + if (ret) + return ret; + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_IN_CH_DIAG_EN_MASK, + TAC5X1X_IN_CH_DIAG_EN_MASK); + } + if (tac5x1x->input_diag_config.out_ch_en) { + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_OUT1P_DIAG_EN_MASK, + TAC5X1X_OUT1P_DIAG_EN_MASK); + } + if (tac5x1x->input_diag_config.incl_se_inm) { + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_INCL_SE_INM_MASK, + TAC5X1X_INCL_SE_INM_MASK); + } + if (tac5x1x->input_diag_config.incl_ac_coup) { + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_INCL_AC_COUP_MASK, + TAC5X1X_INCL_AC_COUP_MASK); + } + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG7, 0xff, + tac5x1x->micbias_threshold[0]); + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG6, 0xff, + tac5x1x->micbias_threshold[1]); + ret = tac5x1x_register_interrupt(tac5x1x); + if (!ret) + dev_info(tac5x1x->dev, "Interrupt registration Done"); + fallthrough; + case TAC5111: + case TAC5112: + case TAC5211: + case TAC5212: + case TAD5112: + case TAD5212: + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG9, 0xff, + tac5x1x->gpa_threshold[0]); + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG8, 0xff, + tac5x1x->gpa_threshold[1]); + break; + default: + break; + }; + + return ret; +}; + +static s32 tac5x1x_add_widgets(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + s32 *gpio_func = tac5x1x->gpio_setup->gpio_func; + s32 ret; + + switch (tac5x1x->codec_type) { + case TAC5111: + case TAC5211: + case TAC5311: + case TAC5411: + ret = snd_soc_dapm_new_controls(dapm, tad5x1x_dapm_widgets, + ARRAY_SIZE(tad5x1x_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x1x_dapm_routes, + ARRAY_SIZE(tad5x1x_dapm_routes)); + if (ret) + return ret; + break; + case TAC5112: + case TAC5212: + case TAC5312: + case TAC5412: + ret = snd_soc_dapm_new_controls(dapm, tad5x1x_dapm_widgets, + ARRAY_SIZE(tad5x1x_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x1x_dapm_routes, + ARRAY_SIZE(tad5x1x_dapm_routes)); + if (ret) + return ret; + ret = snd_soc_dapm_new_controls(dapm, tad5x12_dapm_widgets, + ARRAY_SIZE(tad5x12_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x12_dapm_routes, + ARRAY_SIZE(tad5x12_dapm_routes)); + if (ret) + return ret; + fallthrough; + case TAA5212: + case TAA5412: + ret = snd_soc_dapm_new_controls(dapm, taa5x12_dapm_widgets, + ARRAY_SIZE(taa5x12_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, taa5x12_dapm_routes, + ARRAY_SIZE(taa5x12_dapm_routes)); + if (ret) + return ret; + break; + case TAD5212: + case TAD5112: + ret = snd_soc_dapm_new_controls(dapm, tad5xx_dapm_widgets, + ARRAY_SIZE(tad5xx_dapm_widgets)); + if (ret) + return ret; + + ret = snd_soc_dapm_new_controls(dapm, tad5x12_dapm_widgets, + ARRAY_SIZE(tad5x12_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x12_dapm_routes, + ARRAY_SIZE(tad5x12_dapm_routes)); + if (ret) + return ret; + + break; + default: + break; + } + + if (!(tac5x1x->codec_type == TAD5212 || tac5x1x->codec_type == TAD5112)) { + ret = snd_soc_dapm_new_controls(dapm, tac5x1x_common_dapm_widgets, + ARRAY_SIZE(tac5x1x_common_dapm_widgets)); + if (ret) + return ret; + + ret = snd_soc_dapm_add_routes(dapm, tac5x1x_common_dapm_routes, + ARRAY_SIZE(tac5x1x_common_dapm_routes)); + if (ret) + return ret; + } else { + ret = snd_soc_dapm_new_controls(dapm, tad5x1x_common_dapm_widgets, + ARRAY_SIZE(tad5x1x_common_dapm_widgets)); + if (ret) + return ret; + } + /* If enabled PDM GPIO*/ + if (memchr(gpio_func, TAC5X1X_GPIO_PDMCLK, + sizeof(*gpio_func) / sizeof(gpio_func[0]))) { + ret = snd_soc_dapm_new_controls(dapm, tac5x1x_dapm_pdm_widgets, + ARRAY_SIZE(tac5x1x_dapm_pdm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tac5x1x_dapm_pdm_routes, + ARRAY_SIZE(tac5x1x_dapm_pdm_routes)); + if (ret) + return ret; + } + return 0; +} + +static s32 tac5x1x_component_probe(struct snd_soc_component *component) +{ + s32 ret; + struct tac5x1x_priv *tac5x1x = snd_soc_component_get_drvdata(component); + + ret = tac5x1x_add_controls(component); + if (ret < 0) { + dev_err(tac5x1x->dev, "%s, add control failed\n", __func__); + return ret; + } + + ret = tac5x1x_add_widgets(component); + if (ret < 0) { + dev_err(tac5x1x->dev, "%s, device widget addition failed\n", __func__); + return ret; + } + + ret = tac5x1x_reset(component); + if (ret < 0) { + dev_err(tac5x1x->dev, "%s, device reset failed\n", __func__); + return ret; + } + + if (tac5x1x->gpio_setup) + tac5x1x_setup_gpios(component); + + ret = tac5x1x_add_ip_diag_controls(component); + if (ret < 0) { + dev_err(tac5x1x->dev, "%s, add Ip diag control failed\n", __func__); + return ret; + } + return ret; +} + +#ifdef CONFIG_PM +static s32 tac5x1x_soc_suspend(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + + regcache_cache_only(tac5x1x->regmap, true); + regcache_mark_dirty(tac5x1x->regmap); + + regulator_disable(tac5x1x->supply_avdd); + regulator_disable(tac5x1x->supply_iovdd); + + return 0; +} + +static s32 tac5x1x_soc_resume(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 ret; + + regcache_cache_only(tac5x1x->regmap, false); + snd_soc_component_cache_sync(component); + + ret = regulator_enable(tac5x1x->supply_avdd); + if (ret) { + regulator_disable(tac5x1x->supply_avdd); + return ret; + } + + ret = regulator_enable(tac5x1x->supply_iovdd); + if (ret) { + regulator_disable(tac5x1x->supply_iovdd); + return ret; + } + return 0; +} +#else +#define tac5x1x_soc_suspend NULL +#define tac5x1x_soc_resume NULL +#endif /* CONFIG_PM */ + +static const struct snd_soc_component_driver soc_component_dev_tac5x1x = { + .probe = tac5x1x_component_probe, + .set_bias_level = tac5x1x_set_bias_level, + .suspend = tac5x1x_soc_suspend, + .resume = tac5x1x_soc_resume, + .controls = taa5x1x_controls, + .num_controls = ARRAY_SIZE(taa5x1x_controls), + .dapm_widgets = taa5x1x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(taa5x1x_dapm_widgets), + .dapm_routes = taa5x1x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(taa5x1x_dapm_routes), + .suspend_bias_off = 1, + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, +}; + +static const struct snd_soc_component_driver soc_component_dev_taa5x1x = { + .probe = tac5x1x_component_probe, + .set_bias_level = tac5x1x_set_bias_level, + .suspend = tac5x1x_soc_suspend, + .resume = tac5x1x_soc_resume, + .controls = taa5x1x_controls, + .num_controls = ARRAY_SIZE(taa5x1x_controls), + .dapm_widgets = taa5x1x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(taa5x1x_dapm_widgets), + .dapm_routes = taa5x1x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(taa5x1x_dapm_routes), + .suspend_bias_off = 1, + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, +}; + +static const struct snd_soc_component_driver soc_component_dev_tad5x1x = { + .probe = tac5x1x_component_probe, + .set_bias_level = tac5x1x_set_bias_level, + .suspend = tac5x1x_soc_suspend, + .resume = tac5x1x_soc_resume, + .controls = tad5x1x_controls, + .num_controls = ARRAY_SIZE(tad5x1x_controls), + .dapm_widgets = tad5x1x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tad5x1x_dapm_widgets), + .dapm_routes = tad5x1x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(tad5x1x_dapm_routes), + .suspend_bias_off = 1, + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, +}; + +static s32 tac5x1x_parse_dt(struct tac5x1x_priv *tac5x1x, + struct device_node *np) +{ + struct tac5x1x_input_diag_config input_config; + struct tac5x1x_setup_gpio *tac5x1x_setup; + s32 micbias_value = TAC5X1X_MICBIAS_VREF; + s32 vref_value = TAC5X1X_VERF_2_5V; + s32 ret; + + tac5x1x_setup = devm_kzalloc(tac5x1x->dev, sizeof(*tac5x1x_setup), + GFP_KERNEL); + if (!tac5x1x_setup) + return -ENOMEM; + + ret = fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,vref", &vref_value); + if (ret) { + dev_err(tac5x1x->dev, "Fail to get verf E:%d\n", ret); + goto out; + } + ret = fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,micbias-vg", &micbias_value); + if (ret) { + dev_err(tac5x1x->dev, "Fail to get micbias-vg E:%d\n", ret); + goto out; + } + + if (micbias_value == TAC5X1X_MICBIAS_AVDD) { + tac5x1x->micbias_vg = micbias_value; + tac5x1x->vref_vg = TAC5X1X_VERF_2_75V; + tac5x1x->micbias_en = true; + } else { + switch (vref_value) { + case TAC5X1X_VERF_2_75V: + case TAC5X1X_VERF_2_5V: + switch (micbias_value) { + case TAC5X1X_MICBIAS_VREF: + case TAC5X1X_MICBIAS_0_5VREF: + tac5x1x->micbias_vg = micbias_value; + break; + default: + dev_err(tac5x1x->dev, "Bad tac5x1x-micbias-vg value %d\n", + micbias_value); + tac5x1x->micbias_vg = TAC5X1X_MICBIAS_AVDD; + break; + } + tac5x1x->vref_vg = vref_value; + tac5x1x->micbias_en = true; + break; + case TAC5X1X_VERF_1_375V: + if (micbias_value == TAC5X1X_MICBIAS_VREF) { + tac5x1x->micbias_vg = micbias_value; + } else { + dev_err(tac5x1x->dev, "Bad tac5x1x-micbias-vg value %d\n", + micbias_value); + tac5x1x->micbias_vg = TAC5X1X_MICBIAS_AVDD; + } + tac5x1x->micbias_en = true; + tac5x1x->vref_vg = vref_value; + break; + default: + dev_err(tac5x1x->dev, "Bad tac5x1x-vref-vg value %d\n", vref_value); + tac5x1x->vref_vg = TAC5X1X_VERF_2_5V; + tac5x1x->micbias_vg = TAC5X1X_MICBIAS_AVDD; + tac5x1x->micbias_en = true; + break; + } + } + + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,gpi1-func", + &tac5x1x_setup->gpi1_func)) + dev_err(tac5x1x->dev, "%s, Fail to get gpi1-func value\n", __func__); + + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,gpa-gpio", + &tac5x1x_setup->gpa_gpio)) + dev_err(tac5x1x->dev, "%s, Fail to get gpa-gpio value\n", __func__); + + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, "ti,gpios-func", + tac5x1x_setup->gpio_func, 3)) + dev_err(tac5x1x->dev, "%s, Fail to get gpios-func value\n", __func__); + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, "ti,gpios-drive", + tac5x1x_setup->gpio_drive, 3)) + dev_err(tac5x1x->dev, "%s, Fail to get gpios-drive value\n", __func__); + + tac5x1x->gpa_threshold[0] = TAC5X1X_GPA_LOW_THRESHOLD; + tac5x1x->gpa_threshold[1] = TAC5X1X_GPA_HIGH_THRESHOLD; + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, "ti,gpa-threshold", + tac5x1x->gpa_threshold, 2)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,gpa-threshold value\n", __func__); + + tac5x1x->gpio_setup = tac5x1x_setup; + + switch (tac5x1x->codec_type) { + case TAA5212: + case TAC5111: + case TAC5112: + case TAC5211: + case TAC5212: + case TAD5112: + case TAD5212: + break; + case TAA5412: + case TAC5411: + case TAC5412: + case TAC5311: + case TAC5312: + tac5x1x->input_diag_config.in_ch_en = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,in-ch-en", + &input_config.in_ch_en)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,in-ch-en value\n", __func__); + tac5x1x->input_diag_config.out_ch_en = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,out-ch-en", &input_config.in_ch_en)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,out-ch-en value\n", __func__); + tac5x1x->input_diag_config.incl_se_inm = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,incl-se-inm", + &input_config.incl_se_inm)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,incl-se-inm value\n", __func__); + tac5x1x->input_diag_config.incl_ac_coup = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,incl-ac-coup", &input_config.incl_ac_coup)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,incl-ac-coup value\n", __func__); + tac5x1x->input_diag_config = input_config; + + tac5x1x->micbias_threshold[0] = TAC5X1X_MICBIAS_LOW_THRESHOLD; + tac5x1x->micbias_threshold[1] = + TAC5X1X_MICBIAS_HIGH_THRESHOLD; + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, "ti,micbias-threshold", + tac5x1x->micbias_threshold, 2)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,micbias-threshold value\n", + __func__); + break; + } +out: + return ret; +} + +static void tac5x1x_disable_regulators(struct tac5x1x_priv *tac5x1x) +{ + if (!IS_ERR(tac5x1x->supply_iovdd)) + regulator_disable(tac5x1x->supply_iovdd); + + if (!IS_ERR(tac5x1x->supply_avdd)) + regulator_disable(tac5x1x->supply_avdd); +} + +static s32 tac5x1x_setup_regulators(struct device *dev, + struct tac5x1x_priv *tac5x1x) +{ + s32 ret; + + tac5x1x->supply_iovdd = devm_regulator_get(dev, "iovdd"); + tac5x1x->supply_avdd = devm_regulator_get(dev, "avdd"); + + /* Check if the regulator requirements are fulfilled */ + if (IS_ERR(tac5x1x->supply_iovdd)) { + dev_err(dev, "Missing supply 'iovdd'\n"); + return PTR_ERR(tac5x1x->supply_iovdd); + } + + if (IS_ERR(tac5x1x->supply_avdd)) { + dev_err(dev, "Missing supply 'avdd'\n"); + return PTR_ERR(tac5x1x->supply_avdd); + } + + ret = regulator_enable(tac5x1x->supply_iovdd); + if (ret) { + dev_err(dev, "Failed to enable regulator iovdd\n"); + regulator_disable(tac5x1x->supply_iovdd); + return ret; + } + + ret = regulator_enable(tac5x1x->supply_avdd); + if (ret) { + dev_err(dev, "Failed to enable regulator avdd\n"); + regulator_disable(tac5x1x->supply_avdd); + return ret; + } + + return 0; +} + +s32 tac5x1x_probe(struct device *dev, struct regmap *regmap, + enum tac5x1x_type type) +{ + struct device_node *np = dev->of_node; + struct tac5x1x_priv *tac5x1x; + s32 ret; + + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + tac5x1x = devm_kzalloc(dev, sizeof(struct tac5x1x_priv), + GFP_KERNEL); + if (!tac5x1x) + return -ENOMEM; + + tac5x1x->dev = dev; + tac5x1x->codec_type = type; + tac5x1x->regmap = regmap; + tac5x1x->ndev = 1; + + dev_set_drvdata(dev, tac5x1x); + if (np) { + ret = tac5x1x_parse_dt(tac5x1x, np); + if (ret) { + dev_err(dev, "Failed to parse DT node\n"); + return ret; + } + } else { + dev_err(dev, "%s: Fail to get device node\n", __func__); + } + + ret = tac5x1x_setup_regulators(dev, tac5x1x); + if (ret) { + dev_err(dev, "Failed to setup regulators\n"); + return ret; + } + + switch (tac5x1x->codec_type) { + case TAA5212: + case TAA5412: + ret = devm_snd_soc_register_component(dev, + &soc_component_dev_taa5x1x, &taa5x1x_dai, 1); + if (ret) { + dev_err(dev, "Failed to register component\n"); + goto err_disable_regulators; + } + break; + case TAC5111: + case TAC5112: + case TAC5211: + case TAC5212: + case TAC5311: + case TAC5312: + case TAC5411: + case TAC5412: + ret = devm_snd_soc_register_component(dev, + &soc_component_dev_tac5x1x, &tac5x1x_dai, 1); + if (ret) { + dev_err(dev, "Failed to register component\n"); + goto err_disable_regulators; + } + break; + case TAD5112: + case TAD5212: + ret = devm_snd_soc_register_component(dev, + &soc_component_dev_tad5x1x, &tad5x1x_dai, 1); + if (ret) { + dev_err(dev, "Failed to register component\n"); + goto err_disable_regulators; + } + break; + } + return 0; + +err_disable_regulators: + tac5x1x_disable_regulators(tac5x1x); + + return ret; +} +EXPORT_SYMBOL(tac5x1x_probe); + +s32 tac5x1x_remove(struct device *dev) +{ + struct tac5x1x_priv *tac5x1x = dev_get_drvdata(dev); + + tac5x1x_disable_regulators(tac5x1x); + if (tac5x1x->irq_work_func) { + dev_info(tac5x1x->dev, "Cancelled IRQ\n"); + free_irq(tac5x1x->irqinfo.irq, tac5x1x); + mutex_destroy(&tac5x1x->dev_lock); + } + return 0; +} +EXPORT_SYMBOL(tac5x1x_remove); + +const struct of_device_id tac5x1x_of_match[] = { + { .compatible = "ti,taa5212", .data = (void *)TAA5212 }, + { .compatible = "ti,taa5412", .data = (void *)TAA5412 }, + { .compatible = "ti,tac5111", .data = (void *)TAC5111 }, + { .compatible = "ti,tac5112", .data = (void *)TAC5112 }, + { .compatible = "ti,tac5211", .data = (void *)TAC5211 }, + { .compatible = "ti,tac5212", .data = (void *)TAC5212 }, + { .compatible = "ti,tac5311", .data = (void *)TAC5311 }, + { .compatible = "ti,tac5312", .data = (void *)TAC5312 }, + { .compatible = "ti,tac5411", .data = (void *)TAC5411 }, + { .compatible = "ti,tac5412", .data = (void *)TAC5412 }, + { .compatible = "ti,tad5112", .data = (void *)TAD5112 }, + { .compatible = "ti,tad5212", .data = (void *)TAD5212 }, + {} +}; +EXPORT_SYMBOL_GPL(tac5x1x_of_match); +MODULE_DEVICE_TABLE(of, tac5x1x_of_match); + +MODULE_DESCRIPTION("ASoC tac5x1x codec driver"); +MODULE_AUTHOR("Texas Instruments"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tac5x1x.h b/sound/soc/codecs/tac5x1x.h new file mode 100644 index 000000000000..d3f2d5b4769c --- /dev/null +++ b/sound/soc/codecs/tac5x1x.h @@ -0,0 +1,302 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Audio Codec Driver Supporting Devices + * TAA5X1X, TAC5X1X, TAD5X1X + * + * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com + * + * Author: Kevin Lu + * Author: Kokila Karuppusamy + * Author: Niranjan H Y + */ + +#ifndef _TAC5X1X_H +#define _TAC5X1X_H + +#define TAC5X1X_RATES SNDRV_PCM_RATE_8000_192000 +#define TAC5X1X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \ + | SNDRV_PCM_FMTBIT_S20_3LE \ + | SNDRV_PCM_FMTBIT_S24_LE \ + | SNDRV_PCM_FMTBIT_S24_3LE \ + | SNDRV_PCM_FMTBIT_S32_LE) + +/*PAGE Control Register (available in page0 of each book) */ +#define TAC_PAGE_SELECT 0x00 +#define TAC_PAGE_ID(reg) ((reg) / 128) +#define TAC_PAGE_REG(reg) ((reg) % 128) +#define TAC5X1X_REG(page, reg) (((page) * 128) + (reg)) + +#define TAC_PAGE1_SELECT 0x01 +#define TAC5X1X_PGSEL TAC5X1X_REG(0, 0x0) + +#define TAC5X1X_RESET TAC5X1X_REG(0, 0x1) +#define TAC5X1X_VREF TAC5X1X_REG(0, 0x2) +#define TAC5X1X_VDDSTS TAC5X1X_REG(0, 0x3) +#define TAC5X1X_MISC TAC5X1X_REG(0, 0x4) +#define TAC5X1X_MISC1 TAC5X1X_REG(0, 0x5) +#define TAC5X1X_DACA0 TAC5X1X_REG(0, 0x6) +#define TAC5X1X_MISC0 TAC5X1X_REG(0, 0x7) +#define TAC5X1X_GPIO1 TAC5X1X_REG(0, 0xa) +#define TAC5X1X_GPIO2 TAC5X1X_REG(0, 0xb) +#define TAC5X1X_GPO1 TAC5X1X_REG(0, 0xc) +#define TAC5X1X_GPI1 TAC5X1X_REG(0, 0xd) +#define TAC5X1X_GPIOVAL TAC5X1X_REG(0, 0xe) +#define TAC5X1X_INTF0 TAC5X1X_REG(0, 0xf) +#define TAC5X1X_INTF1 TAC5X1X_REG(0, 0x10) +#define TAC5X1X_INTF2 TAC5X1X_REG(0, 0x11) +#define TAC5X1X_INTF3 TAC5X1X_REG(0, 0x12) +#define TAC5X1X_INTF4 TAC5X1X_REG(0, 0x13) +#define TAC5X1X_INTF5 TAC5X1X_REG(0, 0x14) +#define TAC5X1X_INTF6 TAC5X1X_REG(0, 0x15) +#define TAC5X1X_ASI0 TAC5X1X_REG(0, 0x18) +#define TAC5X1X_ASI1 TAC5X1X_REG(0, 0x19) +#define TAC5X1X_PASI0 TAC5X1X_REG(0, 0x1a) +#define TAC5X1X_PASITX0 TAC5X1X_REG(0, 0x1b) +#define TAC5X1X_PASITX1 TAC5X1X_REG(0, 0x1c) +#define TAC5X1X_PASITX2 TAC5X1X_REG(0, 0x1d) +#define TAC5X1X_PASITXCH1 TAC5X1X_REG(0, 0x1e) +#define TAC5X1X_PASITXCH2 TAC5X1X_REG(0, 0x1f) +#define TAC5X1X_PASITXCH3 TAC5X1X_REG(0, 0x20) +#define TAC5X1X_PASITXCH4 TAC5X1X_REG(0, 0x21) +#define TAC5X1X_PASITXCH5 TAC5X1X_REG(0, 0x22) +#define TAC5X1X_PASITXCH6 TAC5X1X_REG(0, 0x23) +#define TAC5X1X_PASITXCH7 TAC5X1X_REG(0, 0x24) +#define TAC5X1X_PASITXCH8 TAC5X1X_REG(0, 0x25) +#define TAC5X1X_PASIRX0 TAC5X1X_REG(0, 0x26) +#define TAC5X1X_PASIRX1 TAC5X1X_REG(0, 0x27) +#define TAC5X1X_PASIRXCH1 TAC5X1X_REG(0, 0x28) +#define TAC5X1X_PASIRXCH2 TAC5X1X_REG(0, 0x29) +#define TAC5X1X_PASIRXCH3 TAC5X1X_REG(0, 0x2a) +#define TAC5X1X_PASIRXCH4 TAC5X1X_REG(0, 0x2b) +#define TAC5X1X_PASIRXCH5 TAC5X1X_REG(0, 0x2c) +#define TAC5X1X_PASIRXCH6 TAC5X1X_REG(0, 0x2d) +#define TAC5X1X_PASIRXCH7 TAC5X1X_REG(0, 0x2e) +#define TAC5X1X_PASIRXCH8 TAC5X1X_REG(0, 0x2f) +#define TAC5X1X_CLK0 TAC5X1X_REG(0, 0x32) +#define TAC5X1X_CLK1 TAC5X1X_REG(0, 0x33) +#define TAC5X1X_CLK2 TAC5X1X_REG(0, 0x34) +#define TAC5X1X_CNTCLK0 TAC5X1X_REG(0, 0x35) +#define TAC5X1X_CNTCLK1 TAC5X1X_REG(0, 0x36) +#define TAC5X1X_CNTCLK2 TAC5X1X_REG(0, 0x37) +#define TAC5X1X_CNTCLK3 TAC5X1X_REG(0, 0x38) +#define TAC5X1X_CNTCLK4 TAC5X1X_REG(0, 0x39) +#define TAC5X1X_CNTCLK5 TAC5X1X_REG(0, 0x3a) +#define TAC5X1X_CNTCLK6 TAC5X1X_REG(0, 0x3b) +#define TAC5X1X_CLKERRSTS0 TAC5X1X_REG(0, 0x3c) +#define TAC5X1X_CLKERRSTS1 TAC5X1X_REG(0, 0x3d) +#define TAC5X1X_CLKDETSTS0 TAC5X1X_REG(0, 0x3e) +#define TAC5X1X_CLKDETSTS1 TAC5X1X_REG(0, 0x3f) +#define TAC5X1X_CLKDETSTS2 TAC5X1X_REG(0, 0x40) +#define TAC5X1X_CLKDETSTS3 TAC5X1X_REG(0, 0x41) +#define TAC5X1X_INT TAC5X1X_REG(0, 0x42) +#define TAC5X1X_DAC_FLT TAC5X1X_REG(0, 0x43) +#define TAC5X1X_ADCDACMISC TAC5X1X_REG(0, 0x4b) +#define TAC5X1X_IADC TAC5X1X_REG(0, 0x4c) +#define TAC5X1X_VREFCFG TAC5X1X_REG(0, 0x4d) +#define TAC5X1X_PWRTUNE0 TAC5X1X_REG(0, 0x4e) +#define TAC5X1X_PWRTUNE1 TAC5X1X_REG(0, 0x4f) +#define TAC5X1X_ADCCH1C0 TAC5X1X_REG(0, 0x50) +#define TAC5X1X_ADCCH TAC5X1X_REG(0, 0x51) +#define TAC5X1X_ADCCH1C2 TAC5X1X_REG(0, 0x52) +#define TAC5X1X_ADCCH1C3 TAC5X1X_REG(0, 0x53) +#define TAC5X1X_ADCCH1C4 TAC5X1X_REG(0, 0x54) +#define TAC5X1X_ADCCH2C0 TAC5X1X_REG(0, 0x55) +#define TAC5X1X_ADCCH2C2 TAC5X1X_REG(0, 0x57) +#define TAC5X1X_ADCCH2C3 TAC5X1X_REG(0, 0x58) +#define TAC5X1X_ADCCH2C4 TAC5X1X_REG(0, 0x59) +#define TAC5X1X_ADCCH3C0 TAC5X1X_REG(0, 0x5a) +#define TAC5X1X_ADCCH3C2 TAC5X1X_REG(0, 0x5b) +#define TAC5X1X_ADCCH3C3 TAC5X1X_REG(0, 0x5c) +#define TAC5X1X_ADCCH3C4 TAC5X1X_REG(0, 0x5d) +#define TAC5X1X_ADCCH4C0 TAC5X1X_REG(0, 0x5e) +#define TAC5X1X_ADCCH4C2 TAC5X1X_REG(0, 0x5f) +#define TAC5X1X_ADCCH4C3 TAC5X1X_REG(0, 0x60) +#define TAC5X1X_ADCCH4C4 TAC5X1X_REG(0, 0x61) +#define TAC5X1X_ADCCFG1 TAC5X1X_REG(0, 0x62) +#define TAC5X1X_OUT1CFG0 TAC5X1X_REG(0, 0x64) +#define TAC5X1X_OUT1CFG1 TAC5X1X_REG(0, 0x65) +#define TAC5X1X_OUT1CFG2 TAC5X1X_REG(0, 0x66) +#define TAC5X1X_DACCH1A0 TAC5X1X_REG(0, 0x67) +#define TAC5X1X_DACCH1A1 TAC5X1X_REG(0, 0x68) +#define TAC5X1X_DACCH1B0 TAC5X1X_REG(0, 0x69) +#define TAC5X1X_DACCH1B1 TAC5X1X_REG(0, 0x6a) +#define TAC5X1X_OUT2CFG0 TAC5X1X_REG(0, 0x6b) +#define TAC5X1X_OUT2CFG1 TAC5X1X_REG(0, 0x6c) +#define TAC5X1X_OUT2CFG2 TAC5X1X_REG(0, 0x6d) +#define TAC5X1X_DACCH2A0 TAC5X1X_REG(0, 0x6e) +#define TAC5X1X_DACCH2A1 TAC5X1X_REG(0, 0x6f) +#define TAC5X1X_DACCH2B0 TAC5X1X_REG(0, 0x70) +#define TAC5X1X_DACCH2B1 TAC5X1X_REG(0, 0x71) +#define TAC5X1X_DSP0 TAC5X1X_REG(0, 0x72) +#define TAC5X1X_DSP1 TAC5X1X_REG(0, 0x73) +#define TAC5X1X_CH_EN TAC5X1X_REG(0, 0x76) +#define TAC5X1X_DYN_PUPD TAC5X1X_REG(0, 0x77) +#define TAC5X1X_PWR_CFG TAC5X1X_REG(0, 0x78) +#define TAC5X1X_DEVSTS0 TAC5X1X_REG(0, 0x79) +#define TAC5X1X_DEVSTS1 TAC5X1X_REG(0, 0x7a) + +#define TAC5X1X_CLKCFG0 TAC5X1X_REG(1, 0xd) +#define TAC5X1X_MICBIAS1 TAC5X1X_REG(1, 0x16) +#define TAC5X1X_AGC_DRC TAC5X1X_REG(1, 0x24) +#define TAC5X1X_PLIM TAC5X1X_REG(1, 0x2b) +#define TAC5X1X_MIXER TAC5X1X_REG(1, 0x2c) + +#define TAC5X1X_DIAG_CFG0 TAC5X1X_REG(1, 0x46) +#define TAC5X1X_DIAG_CFG1 TAC5X1X_REG(1, 0x47) +#define TAC5X1X_DIAG_CFG2 TAC5X1X_REG(1, 0x48) +#define TAC5X1X_DIAG_CFG8 TAC5X1X_REG(1, 0x4e) +#define TAC5X1X_DIAG_CFG9 TAC5X1X_REG(1, 0x4b) +#define TAC5X1X_DIAG_CFG6 TAC5X1X_REG(1, 0x4c) +#define TAC5X1X_DIAG_CFG7 TAC5X1X_REG(1, 0x4d) +/* Bits, masks, and shifts */ + +#define TAC5X1X_REG_INT_LTCH0 TAC5X1X_REG(0x1, 0x34) +#define TAC5X1X_REG_CHX_LTCH TAC5X1X_REG(0x1, 0x35) +#define TAC5X1X_REG_IN_CH1_LTCH TAC5X1X_REG(0x1, 0x36) +#define TAC5X1X_REG_IN_CH2_LTCH TAC5X1X_REG(0x1, 0x37) +#define TAC5X1X_REG_OUT_CH1_LTCH TAC5X1X_REG(0x1, 0x38) +#define TAC5X1X_REG_OUT_CH2_LTCH TAC5X1X_REG(0x1, 0x39) +#define TAC5X1X_REG_INT_LTCH1 TAC5X1X_REG(0x1, 0x3A) +#define TAC5X1X_REG_INT_LTCH2 TAC5X1X_REG(0x1, 0x3B) + +/* TAC5X1X_CH_EN */ + +#define TAC5X1X_CH_EN_ADC_MASK GENMASK(7, 4) +#define TAC5X1X_CH_EN_ADC_CH1 BIT(7) +#define TAC5X1X_CH_EN_ADC_CH2 BIT(6) +#define TAC5X1X_CH_EN_ADC_CH3 BIT(5) +#define TAC5X1X_CH_EN_ADC_CH4 BIT(4) + +#define TAC5X1X_CH_EN_DAC_MASK GENMASK(3, 0) +#define TAC5X1X_CH_EN_DAC_CH1 BIT(3) +#define TAC5X1X_CH_EN_DAC_CH2 BIT(2) +#define TAC5X1X_CH_EN_DAC_CH3 BIT(1) +#define TAC5X1X_CH_EN_DAC_CH4 BIT(0) + +/* TAC5X1X_GPIOVAL */ +#define TAC5X1X_GPIO1_VAL BIT(7) +#define TAC5X1X_GPIO2_VAL BIT(6) +#define TAC5X1X_GPO1_VAL BIT(5) +#define TAC5X1X_GPIO1_MON BIT(3) +#define TAC5X1X_GPIO2_MON BIT(2) +#define TAC5X1X_GPI1_MON BIT(1) + +/* TAC5X1X_DIAG_CFG0 */ +#define TAC5X1X_IN_CH_DIAG_EN_MASK 0xc0 +#define TAC5X1X_INCL_SE_INM_MASK 0x20 +#define TAC5X1X_INCL_AC_COUP_MASK 0x10 +#define TAC5X1X_OUT1P_DIAG_EN_MASK 0x0f +#define TAC5X1X_MICBIAS_LOW_THRESHOLD 0x48 +#define TAC5X1X_MICBIAS_HIGH_THRESHOLD 0xa2 +#define TAC5X1X_GPA_LOW_THRESHOLD 0x4b +#define TAC5X1X_GPA_HIGH_THRESHOLD 0xba + +/* TAC5X1X_PASI */ +#define TAC5X1X_PASI_SAMP_RATE_MASK GENMASK(7, 2) +#define TAC5X1X_PASI_FMT_MASK GENMASK(7, 6) +#define TAC5X1X_PASI_FMT_TDM 0x00 +#define TAC5X1X_PASI_FMT_I2S 0x40 +#define TAC5X1X_PASI_FMT_LJ 0x80 + +#define TAC5X1X_PASI_DATALEN_MASK GENMASK(5, 4) +#define TAC5X1X_WORD_LEN_16BITS 0x00 +#define TAC5X1X_WORD_LEN_20BITS 0x10 +#define TAC5X1X_WORD_LEN_24BITS 0x20 +#define TAC5X1X_WORD_LEN_32BITS 0x30 + +/* TAC5X1X_CNTCLK2 */ +#define TAC5X1X_PASI_MODE_MASK 0x10 +#define TAC5X1X_SASI_MODE_MASK 0x08 +#define TAC5X1X_ASI_RATE_MASK 0x01 + +#define TAC5X1X_PASI_RATE_48000 0x00 +#define TAC5X1X_PASI_RATE_44100 0x01 + +/* TAC5X1X_PASITX0 */ +#define TAC5X1X_PASITX_OFFSET_MASK 0x1f + +/* TAC5X1X_PASIRX0 */ +#define TAC5X1X_PASIRX_OFFSET_MASK 0x1f + +/* TAC5X1X_VREF */ +#define TAC5X1X_VREF_SLEEP_EXIT_VREF_EN 0x80 +#define TAC5X1X_VREF_SLEEP_ACTIVE_MASK 0x01 + +/* TAC5X1X_PWRCFG */ +#define TAC5X1X_PWR_CFG_ADC_PDZ BIT(7) +#define TAC5X1X_PWR_CFG_DAC_PDZ BIT(6) +#define TAC5X1X_PWR_CFG_MICBIAS BIT(5) +#define TAC5X1X_PWR_CFG_UAD_EN BIT(3) +#define TAC5X1X_PWR_CFG_VAD_EN BIT(2) +#define TAC5X1X_PWR_CFG_UAG_EN BIT(1) + +/* TAC5X1X_GPIOx */ +#define TAC5X1X_GPIO1_DEFAULT_VAL 0x32 +#define TAC5X1X_GPIO2_DEFAULT_VAL 0x00 +#define TAC5X1X_GPI1_DEFAULT_VAL 0x00 +#define TAC5X1X_GPO1_DEFAULT_VAL 0x00 + +#define TAC5X1X_GPIOX_CFG_MASK 0xf0 +#define TAC5X1X_GPIOX_DRV_MASK 0x07 + +#define TAC5X1X_GPIO_DISABLE 0 +#define TAC5X1X_GPIO_GPI 1 +#define TAC5X1X_GPIO_GPO 2 +#define TAC5X1X_GPIO_IRQ 3 +#define TAC5X1X_GPIO_PDMCLK 4 +#define TAC5X1X_GPIO_P_DOUT 5 +#define TAC5X1X_GPIO_P_DOUT2 6 +#define TAC5X1X_GPIO_S_DOUT 7 +#define TAC5X1X_GPIO_S_DOUT2 8 +#define TAC5X1X_GPIO_S_BCLK 9 +#define TAC5X1X_GPIO_S_FSYNC 10 +#define TAC5X1X_GPIO_CLKOUT 11 +#define TAC5X1X_GPIO_DOUT_MUX 12 +#define TAC5X1X_GPIO_DAISY_OUT 13 + +#define TAC5X1X_GPIO_DRV_HIZ 0 +#define TAC5X1X_GPIO_DRV_ALAH 1 +#define TAC5X1X_GPIO_DRV_ALWH 2 +#define TAC5X1X_GPIO_DRV_ALHIZ 3 +#define TAC5X1X_GPIO_DRV_WLAH 4 +#define TAC5X1X_GPIO_DRV_HIZAH 5 + +/* TAC5X1X_GPI1 */ +#define TAC5X1X_GPI1_CFG_MASK BIT(1) +#define TAC5X1X_GPA_CFG_MASK BIT(0) + +/* TAC5X1X_VREFCFG */ +#define TAC5X1X_VREFCFG_MICBIAS_VAL_MASK GENMASK(3, 2) +#define TAC5X1X_VREFCFG_VREF_FSCALE_MASK GENMASK(1, 0) + +#define TAC5X1X_MICBIAS_VREF 0 +#define TAC5X1X_MICBIAS_0_5VREF 1 +#define TAC5X1X_MICBIAS_AVDD 3 + +#define TAC5X1X_VERF_2_75V 0 +#define TAC5X1X_VERF_2_5V 1 +#define TAC5X1X_VERF_1_375V 2 + +enum tac5x1x_type { + TAA5212 = 0, + TAA5412, + TAC5111, + TAC5112, + TAC5211, + TAC5212, + TAC5311, + TAC5312, + TAC5411, + TAC5412, + TAD5112, + TAD5212, +}; + +extern const struct regmap_config tac5x1x_regmap; +extern const struct of_device_id tac5x1x_of_match[]; + +int tac5x1x_probe(struct device *dev, struct regmap *regmap, + enum tac5x1x_type type); +int tac5x1x_remove(struct device *dev); + +#endif /* _TAC5X1X_H */ From patchwork Fri Jun 6 06:51:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niranjan H Y X-Patchwork-Id: 895550 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id D861DC71137 for ; Tue, 10 Jun 2025 19:34:39 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [45.14.194.44]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 3AA5B60220; Tue, 10 Jun 2025 21:34:28 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 3AA5B60220 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1749584078; bh=L7qGxXV8eZiD5/jyQOHC+rZAPECQCH1J988p+BGY234=; h=From:To:CC:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=G4ANPYqX36FUsRsfphkUSa82hlWfPUIQrYSMU/khTsKka3Eg2Gr9CeHMQhENWbFtB T1uxcG260//J882mZmxMwZijaKkECMVbWyVJ7BwGAs/drqgbkraeAluN+dTD3JBCaj h9NEQzmbLXdWwutqrrd+XV5yDag0nxg2ydXKoe4k= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0FF5BF80651; Tue, 10 Jun 2025 21:33:08 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id DA5E6F80637; Tue, 10 Jun 2025 21:33:08 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 64B79F80100; Fri, 6 Jun 2025 08:52:29 +0200 (CEST) Received: from fllvem-ot04.ext.ti.com (fllvem-ot04.ext.ti.com [198.47.19.246]) (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 488DCF800E4 for ; Fri, 6 Jun 2025 08:52:25 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 488DCF800E4 Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key, unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=Jr4ifuEC Received: from lelvem-sh02.itg.ti.com ([10.180.78.226]) by fllvem-ot04.ext.ti.com (8.15.2/8.15.2) with ESMTP id 5566qMoc134076; Fri, 6 Jun 2025 01:52:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1749192742; bh=oUkWrCM4AdO9JKlqFqQG1TcKELCtTBQ0XyUehDOp7AE=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=Jr4ifuEC84xeAszlpaogD3zaTYpusAUaUpumg8SzmhXBRUu3gwA3tdnUPvkEuCw01 nYd0egjKlPQjPMnZ2gSE9nW0JCZBiYPIgTOI7HgOtB06MWjo8vqa6gMnr6AimKG0R5 W1sl6PyIeZJelNmZ7io10cSJmyyVLsauhMuW3/Bs= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by lelvem-sh02.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 5566qMWr3323139 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Fri, 6 Jun 2025 01:52:22 -0500 Received: from DFLE103.ent.ti.com (10.64.6.24) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Fri, 6 Jun 2025 01:52:22 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Fri, 6 Jun 2025 01:52:22 -0500 Received: from LTPW0EX92E.dhcp.ti.com (ltpw0ex92e.dhcp.ti.com [172.24.149.200]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 5566q4Of677113; Fri, 6 Jun 2025 01:52:18 -0500 From: Niranjan H Y To: CC: , , , , , , , , , Subject: [PATCH v1 2/4] Asoc: tac5x1x: document tac5x1x codec Date: Fri, 6 Jun 2025 12:21:34 +0530 Message-ID: <20250606065136.1821-3-niranjan.hy@ti.com> X-Mailer: git-send-email 2.33.0.windows.2 In-Reply-To: <20250606065136.1821-1-niranjan.hy@ti.com> References: <20250606065136.1821-1-niranjan.hy@ti.com> MIME-Version: 1.0 X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea X-MailFrom: niranjan.hy@ti.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1 Message-ID-Hash: ARQACESFBQUCEBGTPMK6DJRQFI44CTCJ X-Message-ID-Hash: ARQACESFBQUCEBGTPMK6DJRQFI44CTCJ X-Mailman-Approved-At: Tue, 10 Jun 2025 19:33:03 +0000 X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: tac5x1x family are series of low-power and high performance mono/stereo audio codecs consists of ADC and DAC combinations. The family consist of Codecs(DAC & ADC), ADC only and DAC only configurations. The documentation explains the list of devices in the family, their power supply configurations and gpio configuration options available for various functionality. Signed-off-by: Niranjan H Y --- .../devicetree/bindings/sound/ti,tac5x1x.yaml | 222 ++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml diff --git a/Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml b/Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml new file mode 100644 index 000000000000..b5f3f09a0465 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml @@ -0,0 +1,222 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +# Copyright (C) 2025 Texas Instruments Incorporated +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/ti,tac5x1x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TAC5X1X Codec + +description: | + TAC5X1X are series of low-power and high performance mono or stereo + audio codecs, as well as multiple inputs and outputs programmable in + single-ended or fully differential configurations. Device supports both + Microphone and Line In input on ADC Channel. DAC Output can be configured + for either Line Out or Head Phone Load. + + The serial control bus supports SPI or I2C protocols, while the serial audio + data bus is programmable for I2S, left/right-justified, DSP, or TDM modes. + + Specification about the codecs can be found at: + https://www.ti.com/lit/gpn/taa5212 + https://www.ti.com/lit/gpn/taa5412-q1 + https://www.ti.com/lit/gpn/tac5111 + https://www.ti.com/lit/gpn/tac5112 + https://www.ti.com/lit/gpn/tac5211 + https://www.ti.com/lit/gpn/tac5212 + https://www.ti.com/lit/gpn/tac5311-q1 + https://www.ti.com/lit/gpn/tac5312-q1 + https://www.ti.com/lit/gpn/tac5411-q1 + https://www.ti.com/lit/gpn/tac5412-q1 + https://www.ti.com/lit/gpn/tad5112 + https://www.ti.com/lit/gpn/tad5212 + +maintainers: + - Niranjan H Y + - Kevin Lu + +properties: + compatible: + enum: + - ti,taa5212 + - ti,taa5412 + - ti,tac5111 + - ti,tac5112 + - ti,tac5211 + - ti,tac5212 + - ti,tac5311 + - ti,tac5312 + - ti,tac5411 + - ti,tac5412 + - ti,tad5112 + - ti,tad5212 + + reg: + maxItems: 1 + + ti,vref: + description: VREF required voltage. If node is omitted then VREF is powered down. + $ref: /schemas/types.yaml#/definitions/uint32 + oneOf: + - const: 0 + description: VREF output is powered to 2.75V. + - const: 1 + description: VREF output is powered to 2.5V. + - const: 2 + description: VREF output is powered to 1.375V. + + ti,micbias-vg: + description: MicBias required voltage. If node is omitted then MicBias is powered down. + $ref: /schemas/types.yaml#/definitions/uint32 + oneOf: + - const: 0 + description: MICBIAS output is same as the VREF output + - const: 1 + description: MICBIAS output is 0.5 times the VREF output + - const: 3 + description: MICBIAS output is same as the AVDD + + avdd-supply: + description: Analog DAC voltage. + + iovdd-supply: + description: I/O voltage. + + ti,gpios-func: + description: | + Array indicating the GPIO1, GPIO2, GPO1 Functionality in the same order. + Each integer elemnent in the array represent the following + - 0 TAC5X1X_GPIO_DISABLE - GPIO is Disabled + - 1 TAC5X1X_GPIO_GPI - General Purpose Input + - 2 ADC3XXX_GPIO_GPO - General Purpose Output + - 3 TAC5X1X_GPIO_IRQ - Chip Interrupt + - 4 TAC5X1X_GPIO_PDMCLK - PDM CLK Output + - 5 TAC5X1X_GPIO_P_DOUT - Primary ASI DOUT + - 6 TAC5X1X_GPIO_P_DOUT2 - Primary ASI DOUT2 + - 7 TAC5X1X_GPIO_S_DOUT - Secondary ASI DOUT + - 8 TAC5X1X_GPIO_S_DOUT2 - Secondary ASI DOUT2 + - 9 TAC5X1X_GPIO_S_BCLK - Secondary BCLK Output + - 10 TAC5X1X_GPIO_S_FSYNC - Secondary FSYNC Output + - 11 TAC5X1X_GPIO_CLKOUT - General Purpose Output + - 12 TAC5X1X_GPIO_DOUT_MUX + - 13 TAC5X1X_GPIO_DAISY_OUT + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 3 + maxItems: 3 + + ti,gpios-drive: + description: | + Array indicating the GPIO1, GPIO2, GPO1 Driver values + Each number in the array indicate the following driver values. + - 0 # Hi-Z Output + - 1 # Drive active low and active High + - 2 # Drive active low and weak High + - 3 # Drive acive low and Hi-Z + - 4 # Drive weak low and active High + - 5 # Drive Hi-Z and active High + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 3 + maxItems: 3 + + ti,gpi1-func: + description: GPI1 Functionality + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # TAC5X1X_GPIO_DISABLE - I/O buffers powered down and not used + - 1 # TAC5X1X_GPIO_GPI - General purpose input + default: 0 + + '#sound-dai-cells': + const: 0 + + clocks: + maxItems: 1 + + ti,gpa-gpio: + description: GPA using GPIO1 configuration + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # GPA using GPIO1 is disabled + - 1 # GPA using GPIO1 + default: 0 + + ti,in-ch-en: + description: Enable Input channel diagnostics for TAC54XX and TAC53XX device. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # Disable input channel diagnostics + - 1 # Enable input channel diagnostics + + ti,out-ch-en: + description: Enable Output channel diagnostics for TAC54XX and TAC53XX device + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # Disable Output channel diagnostics + - 1 # Enable Output channel Diagnostics + + ti,incl-se-inm: + description: INxM pin Diagnostics Scan Selection for Single Ended Configuration + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # INxM pin Diagnostics Scan Selection for Single Ended excluded for diagnosis + - 1 # INxM pin Diagnostics Scan Selection for Single Ended included for diagnosis + + ti,incl-ac-coup: + description: AC coupled channels pins Scan Selection for Diagnostics + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # AC coupled channels pins Scan Selection for Diagnostics exluded for diagnosis + - 1 # AC coupled channels pins Scan Selection for Diagnostics included for diagnosis + + ti,micbias-threshold: + description: Micbias Low and High threshold values for TAC54XX and TAC53XX series + $ref: /schemas/types.yaml#/definitions/uint32-array + maxItems: 2 + minItems: 2 + items: + minimum: 72 + maximum: 162 + + ti,gpa-threshold: + description: GPA Low and High threshold Values + $ref: /schemas/types.yaml#/definitions/uint32-array + maxItems: 2 + minItems: 2 + items: + minimum: 75 + maximum: 186 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + tac5x1x: tac5x1x@52 { + compatible = "ti,tac5212"; + reg = <0x52>; + #sound-dai-cells = <0>; + avdd-supply = <&vdd_3v3_reg>; + iovdd-supply = <&vdd_3v3_reg>; + ti,vref = <0>; + ti,micbias-vg = <3>; + ti,gpi1-func = <0>; + ti,gpios-func = <4>, <1>, <0>; + ti,gpios-drive = <0>, <0>, <0>; + ti,gpa-gpio = <0>; + ti,in-ch-en = <1>; + ti,out-ch-en = <1>; + ti,incl-ac-coup = <0>; + ti,incl-se-inm = <0>; + ti,gpa-threshold = <75>, <186>; + }; + }; +... From patchwork Fri Jun 6 06:51:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niranjan H Y X-Patchwork-Id: 895216 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id F30CAC61DB2 for ; Tue, 10 Jun 2025 19:34:57 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [45.14.194.44]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B3FC360211; Tue, 10 Jun 2025 21:34:43 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B3FC360211 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1749584093; bh=nxa3PYsW5o+v8bg44bRchymZgJvbA1YySSHeKd9Iwao=; h=From:To:CC:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=pr/hFv1Inygea3YQOlbsa7nI5A5vph61qdNQzxTtsgYPDLqJubLHak1uSe0tw4mjJ qU4nS4GGGJpaYyRrv0kjtxXs2lZNA61zElv3WpJycM5ckJO1BKZUlIhc/gQ4Bb5l/z 3ZzHs1UY0KzboW7SyniRkXAPrZ5RfiKahFJsVeRw= Received: by alsa1.perex.cz (Postfix, from userid 50401) id B134DF8068E; Tue, 10 Jun 2025 21:33:10 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id A47EEF80687; Tue, 10 Jun 2025 21:33:10 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B271DF8010B; Fri, 6 Jun 2025 08:52:32 +0200 (CEST) Received: from lelvem-ot01.ext.ti.com (lelvem-ot01.ext.ti.com [198.47.23.234]) (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 73320F8003A for ; Fri, 6 Jun 2025 08:52:29 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 73320F8003A Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key, unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=pfleOSId Received: from fllvem-sh03.itg.ti.com ([10.64.41.86]) by lelvem-ot01.ext.ti.com (8.15.2/8.15.2) with ESMTP id 5566qRtw1323395; Fri, 6 Jun 2025 01:52:27 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1749192747; bh=IL0UbWjx4pPSayogeWKWnaFYfqNTkvm+cXMiKv5fADM=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=pfleOSIdimShbX/6IxQErQs/GH7iZ7PFINH6ZL9OFaUlgfWDbCnTpny89lWgb1zO5 F3H4ON9h2YL9cbDH7fE+Pv29V/UkEFAKpMGF63JJgBO+qfS6IHkuXE0ddgBpGQ5TBq +BYdN/1hiyY3Bb0FsTwbtr0Xy9BYU+Bpi10aVfXI= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by fllvem-sh03.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 5566qRZS1386607 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Fri, 6 Jun 2025 01:52:27 -0500 Received: from DFLE110.ent.ti.com (10.64.6.31) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Fri, 6 Jun 2025 01:52:27 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) by DFLE110.ent.ti.com (10.64.6.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Fri, 6 Jun 2025 01:52:27 -0500 Received: from LTPW0EX92E.dhcp.ti.com (ltpw0ex92e.dhcp.ti.com [172.24.149.200]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 5566q4Og677113; Fri, 6 Jun 2025 01:52:23 -0500 From: Niranjan H Y To: CC: , , , , , , , , , Subject: [PATCH v1 3/4] Asoc: pcm6240: remove support for taac5x1x family Date: Fri, 6 Jun 2025 12:21:35 +0530 Message-ID: <20250606065136.1821-4-niranjan.hy@ti.com> X-Mailer: git-send-email 2.33.0.windows.2 In-Reply-To: <20250606065136.1821-1-niranjan.hy@ti.com> References: <20250606065136.1821-1-niranjan.hy@ti.com> MIME-Version: 1.0 X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea X-MailFrom: niranjan.hy@ti.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1 Message-ID-Hash: WODALYJTML3OZ5V7OJ4VGRX7W6CO7GE7 X-Message-ID-Hash: WODALYJTML3OZ5V7OJ4VGRX7W6CO7GE7 X-Mailman-Approved-At: Tue, 10 Jun 2025 19:33:03 +0000 X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: tac5x1x codec driver suporrts tac5x1x family which includes the following ADCs and DACs. So removed the duplicate entries in the pcm6240 i2c driver. Signed-off-by: Niranjan H Y --- sound/soc/codecs/pcm6240.c | 124 +------------------------------------ sound/soc/codecs/pcm6240.h | 4 -- 2 files changed, 3 insertions(+), 125 deletions(-) diff --git a/sound/soc/codecs/pcm6240.c b/sound/soc/codecs/pcm6240.c index 75af12231d1d..bbf3eb18bf54 100644 --- a/sound/soc/codecs/pcm6240.c +++ b/sound/soc/codecs/pcm6240.c @@ -44,10 +44,6 @@ static const struct i2c_device_id pcmdevice_i2c_id[] = { { "pcmd3140", PCMD3140 }, { "pcmd3180", PCMD3180 }, { "pcmd512x", PCMD512X }, - { "taa5212", TAA5212 }, - { "taa5412", TAA5412 }, - { "tad5212", TAD5212 }, - { "tad5412", TAD5412 }, {} }; MODULE_DEVICE_TABLE(i2c, pcmdevice_i2c_id); @@ -442,60 +438,6 @@ static const struct pcmdevice_mixer_control pcmd3180_fine_gain_ctl[] = { } }; -static const struct pcmdevice_mixer_control taa5412_digi_vol_ctl[] = { - { - .shift = 0, - .reg = TAA5412_REG_CH1_DIGITAL_VOLUME, - .max = 0xff, - .invert = 0, - }, - { - .shift = 0, - .reg = TAA5412_REG_CH2_DIGITAL_VOLUME, - .max = 0xff, - .invert = 0, - }, - { - .shift = 0, - .reg = TAA5412_REG_CH3_DIGITAL_VOLUME, - .max = 0xff, - .invert = 0, - }, - { - .shift = 0, - .reg = TAA5412_REG_CH4_DIGITAL_VOLUME, - .max = 0xff, - .invert = 0, - } -}; - -static const struct pcmdevice_mixer_control taa5412_fine_gain_ctl[] = { - { - .shift = 4, - .reg = TAA5412_REG_CH1_FINE_GAIN, - .max = 0xf, - .invert = 0, - }, - { - .shift = 4, - .reg = TAA5412_REG_CH2_FINE_GAIN, - .max = 0xf, - .invert = 0, - }, - { - .shift = 4, - .reg = TAA5412_REG_CH3_FINE_GAIN, - .max = 0xf, - .invert = 4, - }, - { - .shift = 0, - .reg = TAA5412_REG_CH4_FINE_GAIN, - .max = 0xf, - .invert = 4, - } -}; - static const DECLARE_TLV_DB_MINMAX_MUTE(pcmd3140_dig_gain_tlv, -10000, 2700); static const DECLARE_TLV_DB_MINMAX_MUTE(pcm1690_fine_dig_gain_tlv, @@ -512,7 +454,7 @@ static const DECLARE_TLV_DB_MINMAX_MUTE(pcm6260_fgain_tlv, static const DECLARE_TLV_DB_LINEAR(pcm6260_chgain_tlv, 0, 4200); static const DECLARE_TLV_DB_MINMAX_MUTE(taa5412_dig_vol_tlv, -8050, 4700); -static const DECLARE_TLV_DB_LINEAR(taa5412_fine_gain_tlv, +static const DECLARE_TLV_DB_LINEAR(pcmd31x0_fine_gain_tlv, -80, 70); static int pcmdev_change_dev(struct pcmdevice_priv *pcm_priv, @@ -981,7 +923,7 @@ static const struct pcmdev_ctrl_info pcmdev_gain_ctl_info[][2] = { // PCMD3140 { { - .gain = taa5412_fine_gain_tlv, + .gain = pcmd31x0_fine_gain_tlv, .pcmdev_ctrl = pcmd3140_fine_gain_ctl, .ctrl_array_size = ARRAY_SIZE(pcmd3140_fine_gain_ctl), .get = pcmdevice_get_volsw, @@ -1000,7 +942,7 @@ static const struct pcmdev_ctrl_info pcmdev_gain_ctl_info[][2] = { // PCMD3180 { { - .gain = taa5412_fine_gain_tlv, + .gain = pcmd31x0_fine_gain_tlv, .pcmdev_ctrl = pcmd3180_fine_gain_ctl, .ctrl_array_size = ARRAY_SIZE(pcmd3180_fine_gain_ctl), .get = pcmdevice_get_volsw, @@ -1025,62 +967,6 @@ static const struct pcmdev_ctrl_info pcmdev_gain_ctl_info[][2] = { .ctrl_array_size = 0, }, }, - // TAA5212 - { - { - .gain = taa5412_fine_gain_tlv, - .pcmdev_ctrl = taa5412_fine_gain_ctl, - .ctrl_array_size = ARRAY_SIZE(taa5412_fine_gain_ctl), - .get = pcmdevice_get_volsw, - .put = pcmdevice_put_volsw, - .pcmdev_ctrl_name_id = 2, - }, - { - .gain = taa5412_dig_vol_tlv, - .pcmdev_ctrl = taa5412_digi_vol_ctl, - .ctrl_array_size = ARRAY_SIZE(taa5412_digi_vol_ctl), - .get = pcmdevice_get_volsw, - .put = pcmdevice_put_volsw, - .pcmdev_ctrl_name_id = 1, - }, - }, - // TAA5412 - { - { - .gain = taa5412_fine_gain_tlv, - .pcmdev_ctrl = taa5412_fine_gain_ctl, - .ctrl_array_size = ARRAY_SIZE(taa5412_fine_gain_ctl), - .get = pcmdevice_get_volsw, - .put = pcmdevice_put_volsw, - .pcmdev_ctrl_name_id = 2, - }, - { - .gain = taa5412_dig_vol_tlv, - .pcmdev_ctrl = taa5412_digi_vol_ctl, - .ctrl_array_size = ARRAY_SIZE(taa5412_digi_vol_ctl), - .get = pcmdevice_get_volsw, - .put = pcmdevice_put_volsw, - .pcmdev_ctrl_name_id = 1, - }, - }, - // TAD5212 - { - { - .ctrl_array_size = 0, - }, - { - .ctrl_array_size = 0, - }, - }, - // TAD5412 - { - { - .ctrl_array_size = 0, - }, - { - .ctrl_array_size = 0, - }, - }, }; static int pcmdev_dev_bulk_write(struct pcmdevice_priv *pcm_dev, @@ -2002,10 +1888,6 @@ static const struct of_device_id pcmdevice_of_match[] = { { .compatible = "ti,pcmd3140" }, { .compatible = "ti,pcmd3180" }, { .compatible = "ti,pcmd512x" }, - { .compatible = "ti,taa5212" }, - { .compatible = "ti,taa5412" }, - { .compatible = "ti,tad5212" }, - { .compatible = "ti,tad5412" }, {}, }; MODULE_DEVICE_TABLE(of, pcmdevice_of_match); diff --git a/sound/soc/codecs/pcm6240.h b/sound/soc/codecs/pcm6240.h index 2d8f9e798139..86b1ef734a3d 100644 --- a/sound/soc/codecs/pcm6240.h +++ b/sound/soc/codecs/pcm6240.h @@ -33,10 +33,6 @@ enum pcm_device { PCMD3140, PCMD3180, PCMD512X, - TAA5212, - TAA5412, - TAD5212, - TAD5412, MAX_DEVICE, }; From patchwork Fri Jun 6 06:51:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niranjan H Y X-Patchwork-Id: 895549 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id F1334C677C4 for ; Tue, 10 Jun 2025 19:35:13 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [45.14.194.44]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 9262860208; Tue, 10 Jun 2025 21:35:01 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9262860208 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1749584111; bh=/r9pwoqHSypc19PvCxVj/r8Ve69yToxx+Vy37CM3NUI=; h=From:To:CC:Subject:Date:In-Reply-To:References:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=XHLfxETYFQCS+N1LkDMATsLR1ak/5UpsVYPqA1rAwj7odudoph5czYB4WVxAEh37B p74aY9sW14XC/11KAa741qGJTTTtDz0QyHYCMxkLoB1HxsWqbFj9+MDrB0kC3GKOgC e+5Y315jBsgPfgUCEr5U+gP1gp8BSwzvoICm3WKQ= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 38BC0F806A5; Tue, 10 Jun 2025 21:33:11 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 0F98EF806A5; Tue, 10 Jun 2025 21:33:11 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id ACD29F800F0; Fri, 6 Jun 2025 08:52:37 +0200 (CEST) Received: from fllvem-ot03.ext.ti.com (fllvem-ot03.ext.ti.com [198.47.19.245]) (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 CEC7BF8003A for ; Fri, 6 Jun 2025 08:52:35 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CEC7BF8003A Authentication-Results: alsa1.perex.cz; dkim=pass (1024-bit key, unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=I0lxQSqm Received: from fllvem-sh03.itg.ti.com ([10.64.41.86]) by fllvem-ot03.ext.ti.com (8.15.2/8.15.2) with ESMTP id 5566qXBa1331324; Fri, 6 Jun 2025 01:52:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1749192753; bh=WWmGvKTM9mfHp7Y8pdnp8aSwGoQqZcaC+mkl9jwP7YU=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=I0lxQSqmVVcn7eTcJaibSeEoy712WMsUgl4gyyqKY/XBuy5Kl3Jwz8oS98Sgq5AQJ AbXoRtnxbNPu6whdyl/Y4nzfXJZFHKS2CbwRZ8vL4epFSebVoNseKh9+9FIgcWeswJ F7zJZXL6oO6wmlyqNLLYIGUqGIfKKfe1j7VU4FVo= Received: from DFLE100.ent.ti.com (dfle100.ent.ti.com [10.64.6.21]) by fllvem-sh03.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 5566qWeS1386643 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Fri, 6 Jun 2025 01:52:33 -0500 Received: from DFLE110.ent.ti.com (10.64.6.31) by DFLE100.ent.ti.com (10.64.6.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Fri, 6 Jun 2025 01:52:32 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) by DFLE110.ent.ti.com (10.64.6.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Fri, 6 Jun 2025 01:52:32 -0500 Received: from LTPW0EX92E.dhcp.ti.com (ltpw0ex92e.dhcp.ti.com [172.24.149.200]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 5566q4Oh677113; Fri, 6 Jun 2025 01:52:29 -0500 From: Niranjan H Y To: CC: , , , , , , , , , Subject: [PATCH v1 4/4] ASoc: pcm6240: dt-bindings device support list update Date: Fri, 6 Jun 2025 12:21:36 +0530 Message-ID: <20250606065136.1821-5-niranjan.hy@ti.com> X-Mailer: git-send-email 2.33.0.windows.2 In-Reply-To: <20250606065136.1821-1-niranjan.hy@ti.com> References: <20250606065136.1821-1-niranjan.hy@ti.com> MIME-Version: 1.0 X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea X-MailFrom: niranjan.hy@ti.com X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1 Message-ID-Hash: N4V6TH2GLBZFIDQF3UFC6ZLGFMMQTSLZ X-Message-ID-Hash: N4V6TH2GLBZFIDQF3UFC6ZLGFMMQTSLZ X-Mailman-Approved-At: Tue, 10 Jun 2025 19:33:03 +0000 X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Removed taa* and tad* device from the support list as these devices are supported by tac5x1x codec driver Signed-off-by: Niranjan H Y --- .../devicetree/bindings/sound/ti,pcm6240.yaml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/ti,pcm6240.yaml b/Documentation/devicetree/bindings/sound/ti,pcm6240.yaml index d89b4255b51c..b0d5f57dc0f5 100644 --- a/Documentation/devicetree/bindings/sound/ti,pcm6240.yaml +++ b/Documentation/devicetree/bindings/sound/ti,pcm6240.yaml @@ -29,8 +29,6 @@ description: | https://www.ti.com/lit/gpn/pcm9211 https://www.ti.com/lit/gpn/pcmd3140 https://www.ti.com/lit/gpn/pcmd3180 - https://www.ti.com/lit/gpn/taa5212 - https://www.ti.com/lit/gpn/tad5212 properties: compatible: @@ -81,10 +79,6 @@ properties: ti,pcmd3180: Eight-channel pulse-density-modulation input to TDM or I2S output converter. - ti,taa5212: Low-power high-performance stereo audio ADC with 118-dB - dynamic range. - - ti,tad5212: Low-power stereo audio DAC with 120-dB dynamic range. oneOf: - items: - enum: @@ -98,8 +92,6 @@ properties: - enum: - ti,pcmd512x - ti,pcm9211 - - ti,taa5212 - - ti,tad5212 - const: ti,adc6120 - items: - enum: @@ -114,8 +106,6 @@ properties: - ti,pcmd3140 - ti,pcmd3180 - ti,pcm1690 - - ti,taa5412 - - ti,tad5412 - const: ti,pcm6240 - enum: - ti,adc6120