brintos

brintos / linux-shallow public Read only

0
0
Text · 95.3 KiB · c989d82 Raw
2989 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2// Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.3 4#include <linux/cleanup.h>5#include <linux/module.h>6#include <linux/init.h>7#include <linux/io.h>8#include <linux/of.h>9#include <linux/platform_device.h>10#include <linux/clk.h>11#include <linux/of_clk.h>12#include <linux/clk-provider.h>13#include <sound/soc.h>14#include <sound/soc-dapm.h>15#include <linux/pm_runtime.h>16#include <linux/of_platform.h>17#include <sound/tlv.h>18 19#include "lpass-macro-common.h"20#include "lpass-wsa-macro.h"21 22#define CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL	(0x0000)23#define CDC_WSA_MCLK_EN_MASK			BIT(0)24#define CDC_WSA_MCLK_ENABLE			BIT(0)25#define CDC_WSA_MCLK_DISABLE			026#define CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL	(0x0004)27#define CDC_WSA_FS_CNT_EN_MASK			BIT(0)28#define CDC_WSA_FS_CNT_ENABLE			BIT(0)29#define CDC_WSA_FS_CNT_DISABLE			030#define CDC_WSA_CLK_RST_CTRL_SWR_CONTROL	(0x0008)31#define CDC_WSA_SWR_CLK_EN_MASK			BIT(0)32#define CDC_WSA_SWR_CLK_ENABLE			BIT(0)33#define CDC_WSA_SWR_RST_EN_MASK			BIT(1)34#define CDC_WSA_SWR_RST_ENABLE			BIT(1)35#define CDC_WSA_SWR_RST_DISABLE			036#define CDC_WSA_TOP_TOP_CFG0			(0x0080)37#define CDC_WSA_TOP_TOP_CFG1			(0x0084)38#define CDC_WSA_TOP_FREQ_MCLK			(0x0088)39#define CDC_WSA_TOP_DEBUG_BUS_SEL		(0x008C)40#define CDC_WSA_TOP_DEBUG_EN0			(0x0090)41#define CDC_WSA_TOP_DEBUG_EN1			(0x0094)42#define CDC_WSA_TOP_DEBUG_DSM_LB		(0x0098)43#define CDC_WSA_TOP_RX_I2S_CTL			(0x009C)44#define CDC_WSA_TOP_TX_I2S_CTL			(0x00A0)45#define CDC_WSA_TOP_I2S_CLK			(0x00A4)46#define CDC_WSA_TOP_I2S_RESET			(0x00A8)47#define CDC_WSA_RX_INP_MUX_RX_INT0_CFG0		(0x0100)48#define CDC_WSA_RX_INP_MUX_RX_INT0_CFG1		(0x0104)49#define CDC_WSA_RX_INP_MUX_RX_INT1_CFG0		(0x0108)50#define CDC_WSA_RX_INP_MUX_RX_INT1_CFG1		(0x010C)51#define CDC_WSA_RX_INP_MUX_RX_MIX_CFG0		(0x0110)52#define CDC_WSA_RX_MIX_TX1_SEL_MASK		GENMASK(5, 3)53#define CDC_WSA_RX_MIX_TX1_SEL_SHFT		354#define CDC_WSA_RX_MIX_TX0_SEL_MASK		GENMASK(2, 0)55#define CDC_WSA_RX_INP_MUX_RX_EC_CFG0		(0x0114)56#define CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0	(0x0118)57#define CDC_WSA_TX0_SPKR_PROT_PATH_CTL		(0x0244)58#define CDC_WSA_TX_SPKR_PROT_RESET_MASK		BIT(5)59#define CDC_WSA_TX_SPKR_PROT_RESET		BIT(5)60#define CDC_WSA_TX_SPKR_PROT_NO_RESET		061#define CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK	BIT(4)62#define CDC_WSA_TX_SPKR_PROT_CLK_ENABLE		BIT(4)63#define CDC_WSA_TX_SPKR_PROT_CLK_DISABLE	064#define CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK	GENMASK(3, 0)65#define CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K	066#define CDC_WSA_TX0_SPKR_PROT_PATH_CFG0		(0x0248)67#define CDC_WSA_TX1_SPKR_PROT_PATH_CTL		(0x0264)68#define CDC_WSA_TX1_SPKR_PROT_PATH_CFG0		(0x0268)69#define CDC_WSA_TX2_SPKR_PROT_PATH_CTL		(0x0284)70#define CDC_WSA_TX2_SPKR_PROT_PATH_CFG0		(0x0288)71#define CDC_WSA_TX3_SPKR_PROT_PATH_CTL		(0x02A4)72#define CDC_WSA_TX3_SPKR_PROT_PATH_CFG0		(0x02A8)73#define CDC_WSA_INTR_CTRL_CFG			(0x0340)74#define CDC_WSA_INTR_CTRL_CLR_COMMIT		(0x0344)75#define CDC_WSA_INTR_CTRL_PIN1_MASK0		(0x0360)76#define CDC_WSA_INTR_CTRL_PIN1_STATUS0		(0x0368)77#define CDC_WSA_INTR_CTRL_PIN1_CLEAR0		(0x0370)78#define CDC_WSA_INTR_CTRL_PIN2_MASK0		(0x0380)79#define CDC_WSA_INTR_CTRL_PIN2_STATUS0		(0x0388)80#define CDC_WSA_INTR_CTRL_PIN2_CLEAR0		(0x0390)81#define CDC_WSA_INTR_CTRL_LEVEL0		(0x03C0)82#define CDC_WSA_INTR_CTRL_BYPASS0		(0x03C8)83#define CDC_WSA_INTR_CTRL_SET0			(0x03D0)84#define CDC_WSA_RX0_RX_PATH_CTL			(0x0400)85#define CDC_WSA_RX_PATH_CLK_EN_MASK		BIT(5)86#define CDC_WSA_RX_PATH_CLK_ENABLE		BIT(5)87#define CDC_WSA_RX_PATH_CLK_DISABLE		088#define CDC_WSA_RX_PATH_PGA_MUTE_EN_MASK	BIT(4)89#define CDC_WSA_RX_PATH_PGA_MUTE_ENABLE		BIT(4)90#define CDC_WSA_RX_PATH_PGA_MUTE_DISABLE	091#define CDC_WSA_RX0_RX_PATH_CFG0		(0x0404)92#define CDC_WSA_RX_PATH_COMP_EN_MASK		BIT(1)93#define CDC_WSA_RX_PATH_COMP_ENABLE		BIT(1)94#define CDC_WSA_RX_PATH_HD2_EN_MASK		BIT(2)95#define CDC_WSA_RX_PATH_HD2_ENABLE		BIT(2)96#define CDC_WSA_RX_PATH_SPKR_RATE_MASK		BIT(3)97#define CDC_WSA_RX_PATH_SPKR_RATE_FS_2P4_3P072	BIT(3)98#define CDC_WSA_RX0_RX_PATH_CFG1		(0x0408)99#define CDC_WSA_RX_PATH_SMART_BST_EN_MASK	BIT(0)100#define CDC_WSA_RX_PATH_SMART_BST_ENABLE	BIT(0)101#define CDC_WSA_RX_PATH_SMART_BST_DISABLE	0102#define CDC_WSA_RX0_RX_PATH_CFG2		(0x040C)103#define CDC_WSA_RX0_RX_PATH_CFG3		(0x0410)104#define CDC_WSA_RX_DC_DCOEFF_MASK		GENMASK(1, 0)105#define CDC_WSA_RX0_RX_VOL_CTL			(0x0414)106#define CDC_WSA_RX0_RX_PATH_MIX_CTL		(0x0418)107#define CDC_WSA_RX_PATH_MIX_CLK_EN_MASK		BIT(5)108#define CDC_WSA_RX_PATH_MIX_CLK_ENABLE		BIT(5)109#define CDC_WSA_RX_PATH_MIX_CLK_DISABLE		0110#define CDC_WSA_RX0_RX_PATH_MIX_CFG		(0x041C)111#define CDC_WSA_RX0_RX_VOL_MIX_CTL		(0x0420)112#define CDC_WSA_RX0_RX_PATH_SEC0		(0x0424)113#define CDC_WSA_RX0_RX_PATH_SEC1		(0x0428)114#define CDC_WSA_RX_PGA_HALF_DB_MASK		BIT(0)115#define CDC_WSA_RX_PGA_HALF_DB_ENABLE		BIT(0)116#define CDC_WSA_RX_PGA_HALF_DB_DISABLE		0117#define CDC_WSA_RX0_RX_PATH_SEC2		(0x042C)118#define CDC_WSA_RX0_RX_PATH_SEC3		(0x0430)119#define CDC_WSA_RX_PATH_HD2_SCALE_MASK		GENMASK(1, 0)120#define CDC_WSA_RX_PATH_HD2_ALPHA_MASK		GENMASK(5, 2)121#define CDC_WSA_RX0_RX_PATH_SEC5		(0x0438)122#define CDC_WSA_RX0_RX_PATH_SEC6		(0x043C)123#define CDC_WSA_RX0_RX_PATH_SEC7		(0x0440)124#define CDC_WSA_RX0_RX_PATH_MIX_SEC0		(0x0444)125#define CDC_WSA_RX0_RX_PATH_MIX_SEC1		(0x0448)126#define CDC_WSA_RX0_RX_PATH_DSMDEM_CTL		(0x044C)127#define CDC_WSA_RX_DSMDEM_CLK_EN_MASK		BIT(0)128#define CDC_WSA_RX_DSMDEM_CLK_ENABLE		BIT(0)129#define CDC_WSA_RX1_RX_PATH_CTL			(0x0480)130#define CDC_WSA_RX1_RX_PATH_CFG0		(0x0484)131#define CDC_WSA_RX1_RX_PATH_CFG1		(0x0488)132#define CDC_WSA_RX1_RX_PATH_CFG2		(0x048C)133#define CDC_WSA_RX1_RX_PATH_CFG3		(0x0490)134#define CDC_WSA_RX1_RX_VOL_CTL			(0x0494)135#define CDC_WSA_RX1_RX_PATH_MIX_CTL		(0x0498)136#define CDC_WSA_RX1_RX_PATH_MIX_CFG		(0x049C)137#define CDC_WSA_RX1_RX_VOL_MIX_CTL		(0x04A0)138#define CDC_WSA_RX1_RX_PATH_SEC0		(0x04A4)139#define CDC_WSA_RX1_RX_PATH_SEC1		(0x04A8)140#define CDC_WSA_RX1_RX_PATH_SEC2		(0x04AC)141#define CDC_WSA_RX1_RX_PATH_SEC3		(0x04B0)142#define CDC_WSA_RX1_RX_PATH_SEC5		(0x04B8)143#define CDC_WSA_RX1_RX_PATH_SEC6		(0x04BC)144#define CDC_WSA_RX1_RX_PATH_SEC7		(0x04C0)145#define CDC_WSA_RX1_RX_PATH_MIX_SEC0		(0x04C4)146#define CDC_WSA_RX1_RX_PATH_MIX_SEC1		(0x04C8)147#define CDC_WSA_RX1_RX_PATH_DSMDEM_CTL		(0x04CC)148#define CDC_WSA_BOOST0_BOOST_PATH_CTL		(0x0500)149#define CDC_WSA_BOOST_PATH_CLK_EN_MASK		BIT(4)150#define CDC_WSA_BOOST_PATH_CLK_ENABLE		BIT(4)151#define CDC_WSA_BOOST_PATH_CLK_DISABLE		0152#define CDC_WSA_BOOST0_BOOST_CTL		(0x0504)153#define CDC_WSA_BOOST0_BOOST_CFG1		(0x0508)154#define CDC_WSA_BOOST0_BOOST_CFG2		(0x050C)155#define CDC_WSA_BOOST1_BOOST_PATH_CTL		(0x0540)156#define CDC_WSA_BOOST1_BOOST_CTL		(0x0544)157#define CDC_WSA_BOOST1_BOOST_CFG1		(0x0548)158#define CDC_WSA_BOOST1_BOOST_CFG2		(0x054C)159#define CDC_WSA_COMPANDER0_CTL0			(0x0580)160#define CDC_WSA_COMPANDER_CLK_EN_MASK		BIT(0)161#define CDC_WSA_COMPANDER_CLK_ENABLE		BIT(0)162#define CDC_WSA_COMPANDER_SOFT_RST_MASK		BIT(1)163#define CDC_WSA_COMPANDER_SOFT_RST_ENABLE	BIT(1)164#define CDC_WSA_COMPANDER_HALT_MASK		BIT(2)165#define CDC_WSA_COMPANDER_HALT			BIT(2)166#define CDC_WSA_COMPANDER0_CTL1			(0x0584)167#define CDC_WSA_COMPANDER0_CTL2			(0x0588)168#define CDC_WSA_COMPANDER0_CTL3			(0x058C)169#define CDC_WSA_COMPANDER0_CTL4			(0x0590)170#define CDC_WSA_COMPANDER0_CTL5			(0x0594)171#define CDC_WSA_COMPANDER0_CTL6			(0x0598)172#define CDC_WSA_COMPANDER0_CTL7			(0x059C)173/* CDC_WSA_COMPANDER1_CTLx and CDC_WSA_SOFTCLIPx differ per LPASS codec versions */174#define CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL	(0x0680)175#define CDC_WSA_EC_HQ_EC_CLK_EN_MASK		BIT(0)176#define CDC_WSA_EC_HQ_EC_CLK_ENABLE		BIT(0)177#define CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0		(0x0684)178#define CDC_WSA_EC_HQ_EC_REF_PCM_RATE_MASK	GENMASK(4, 1)179#define CDC_WSA_EC_HQ_EC_REF_PCM_RATE_48K	BIT(3)180#define CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL	(0x06C0)181#define CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0		(0x06C4)182#define CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL	(0x0700)183#define CDC_WSA_SPLINE_ASRC0_CTL0		(0x0704)184#define CDC_WSA_SPLINE_ASRC0_CTL1		(0x0708)185#define CDC_WSA_SPLINE_ASRC0_FIFO_CTL		(0x070C)186#define CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB	(0x0710)187#define CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB	(0x0714)188#define CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB	(0x0718)189#define CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB	(0x071C)190#define CDC_WSA_SPLINE_ASRC0_STATUS_FIFO		(0x0720)191#define CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL		(0x0740)192#define CDC_WSA_SPLINE_ASRC1_CTL0		(0x0744)193#define CDC_WSA_SPLINE_ASRC1_CTL1		(0x0748)194#define CDC_WSA_SPLINE_ASRC1_FIFO_CTL		(0x074C)195#define CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB (0x0750)196#define CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB (0x0754)197#define CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB (0x0758)198#define CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB (0x075C)199#define CDC_WSA_SPLINE_ASRC1_STATUS_FIFO	(0x0760)200#define WSA_MAX_OFFSET				(0x0760)201 202/* LPASS codec version <=2.4 register offsets */203#define CDC_WSA_COMPANDER1_CTL0			(0x05C0)204#define CDC_WSA_COMPANDER1_CTL1			(0x05C4)205#define CDC_WSA_COMPANDER1_CTL2			(0x05C8)206#define CDC_WSA_COMPANDER1_CTL3			(0x05CC)207#define CDC_WSA_COMPANDER1_CTL4			(0x05D0)208#define CDC_WSA_COMPANDER1_CTL5			(0x05D4)209#define CDC_WSA_COMPANDER1_CTL6			(0x05D8)210#define CDC_WSA_COMPANDER1_CTL7			(0x05DC)211#define CDC_WSA_SOFTCLIP0_CRC			(0x0600)212#define CDC_WSA_SOFTCLIP_CLK_EN_MASK		BIT(0)213#define CDC_WSA_SOFTCLIP_CLK_ENABLE		BIT(0)214#define CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL		(0x0604)215#define CDC_WSA_SOFTCLIP_EN_MASK		BIT(0)216#define CDC_WSA_SOFTCLIP_ENABLE			BIT(0)217#define CDC_WSA_SOFTCLIP1_CRC			(0x0640)218#define CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL		(0x0644)219 220/* LPASS codec version >=2.5 register offsets */221#define CDC_WSA_TOP_FS_UNGATE			(0x00AC)222#define CDC_WSA_TOP_GRP_SEL			(0x00B0)223#define CDC_WSA_TOP_FS_UNGATE2			(0x00DC)224#define CDC_2_5_WSA_COMPANDER0_CTL8		(0x05A0)225#define CDC_2_5_WSA_COMPANDER0_CTL9		(0x05A4)226#define CDC_2_5_WSA_COMPANDER0_CTL10		(0x05A8)227#define CDC_2_5_WSA_COMPANDER0_CTL11		(0x05AC)228#define CDC_2_5_WSA_COMPANDER0_CTL12		(0x05B0)229#define CDC_2_5_WSA_COMPANDER0_CTL13		(0x05B4)230#define CDC_2_5_WSA_COMPANDER0_CTL14		(0x05B8)231#define CDC_2_5_WSA_COMPANDER0_CTL15		(0x05BC)232#define CDC_2_5_WSA_COMPANDER0_CTL16		(0x05C0)233#define CDC_2_5_WSA_COMPANDER0_CTL17		(0x05C4)234#define CDC_2_5_WSA_COMPANDER0_CTL18		(0x05C8)235#define CDC_2_5_WSA_COMPANDER0_CTL19		(0x05CC)236#define CDC_2_5_WSA_COMPANDER1_CTL0		(0x05E0)237#define CDC_2_5_WSA_COMPANDER1_CTL1		(0x05E4)238#define CDC_2_5_WSA_COMPANDER1_CTL2		(0x05E8)239#define CDC_2_5_WSA_COMPANDER1_CTL3		(0x05EC)240#define CDC_2_5_WSA_COMPANDER1_CTL4		(0x05F0)241#define CDC_2_5_WSA_COMPANDER1_CTL5		(0x05F4)242#define CDC_2_5_WSA_COMPANDER1_CTL6		(0x05F8)243#define CDC_2_5_WSA_COMPANDER1_CTL7		(0x05FC)244#define CDC_2_5_WSA_COMPANDER1_CTL8		(0x0600)245#define CDC_2_5_WSA_COMPANDER1_CTL9		(0x0604)246#define CDC_2_5_WSA_COMPANDER1_CTL10		(0x0608)247#define CDC_2_5_WSA_COMPANDER1_CTL11		(0x060C)248#define CDC_2_5_WSA_COMPANDER1_CTL12		(0x0610)249#define CDC_2_5_WSA_COMPANDER1_CTL13		(0x0614)250#define CDC_2_5_WSA_COMPANDER1_CTL14		(0x0618)251#define CDC_2_5_WSA_COMPANDER1_CTL15		(0x061C)252#define CDC_2_5_WSA_COMPANDER1_CTL16		(0x0620)253#define CDC_2_5_WSA_COMPANDER1_CTL17		(0x0624)254#define CDC_2_5_WSA_COMPANDER1_CTL18		(0x0628)255#define CDC_2_5_WSA_COMPANDER1_CTL19		(0x062C)256#define CDC_2_5_WSA_SOFTCLIP0_CRC		(0x0640)257#define CDC_2_5_WSA_SOFTCLIP0_SOFTCLIP_CTRL	(0x0644)258#define CDC_2_5_WSA_SOFTCLIP1_CRC		(0x0660)259#define CDC_2_5_WSA_SOFTCLIP1_SOFTCLIP_CTRL	(0x0664)260 261#define WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\262			SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\263			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)264#define WSA_MACRO_RX_MIX_RATES (SNDRV_PCM_RATE_48000 |\265			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)266#define WSA_MACRO_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\267		SNDRV_PCM_FMTBIT_S24_LE |\268		SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)269 270#define WSA_MACRO_ECHO_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\271			SNDRV_PCM_RATE_48000)272#define WSA_MACRO_ECHO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\273		SNDRV_PCM_FMTBIT_S24_LE |\274		SNDRV_PCM_FMTBIT_S24_3LE)275 276#define NUM_INTERPOLATORS 2277#define WSA_NUM_CLKS_MAX	5278#define WSA_MACRO_MCLK_FREQ 19200000279#define WSA_MACRO_MUX_CFG_OFFSET 0x8280#define WSA_MACRO_MUX_CFG1_OFFSET 0x4281#define WSA_MACRO_RX_PATH_OFFSET 0x80282#define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10283#define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C284#define WSA_MACRO_FS_RATE_MASK 0x0F285#define WSA_MACRO_EC_MIX_TX0_MASK 0x03286#define WSA_MACRO_EC_MIX_TX1_MASK 0x18287#define WSA_MACRO_MAX_DMA_CH_PER_PORT 0x2288 289enum {290	WSA_MACRO_GAIN_OFFSET_M1P5_DB,291	WSA_MACRO_GAIN_OFFSET_0_DB,292};293enum {294	WSA_MACRO_RX0 = 0,295	WSA_MACRO_RX1,296	WSA_MACRO_RX_MIX,297	WSA_MACRO_RX_MIX0 = WSA_MACRO_RX_MIX,298	WSA_MACRO_RX_MIX1,299	WSA_MACRO_RX_MAX,300};301 302enum {303	WSA_MACRO_TX0 = 0,304	WSA_MACRO_TX1,305	WSA_MACRO_TX_MAX,306};307 308enum {309	WSA_MACRO_EC0_MUX = 0,310	WSA_MACRO_EC1_MUX,311	WSA_MACRO_EC_MUX_MAX,312};313 314enum {315	WSA_MACRO_COMP1, /* SPK_L */316	WSA_MACRO_COMP2, /* SPK_R */317	WSA_MACRO_COMP_MAX318};319 320enum {321	WSA_MACRO_SOFTCLIP0, /* RX0 */322	WSA_MACRO_SOFTCLIP1, /* RX1 */323	WSA_MACRO_SOFTCLIP_MAX324};325 326enum {327	INTn_1_INP_SEL_ZERO = 0,328	INTn_1_INP_SEL_RX0,329	INTn_1_INP_SEL_RX1,330	INTn_1_INP_SEL_RX2,331	INTn_1_INP_SEL_RX3,332	INTn_1_INP_SEL_DEC0,333	INTn_1_INP_SEL_DEC1,334};335 336enum {337	INTn_2_INP_SEL_ZERO = 0,338	INTn_2_INP_SEL_RX0,339	INTn_2_INP_SEL_RX1,340	INTn_2_INP_SEL_RX2,341	INTn_2_INP_SEL_RX3,342};343 344struct interp_sample_rate {345	int sample_rate;346	int rate_val;347};348 349static struct interp_sample_rate int_prim_sample_rate_val[] = {350	{8000, 0x0},	/* 8K */351	{16000, 0x1},	/* 16K */352	{24000, -EINVAL},/* 24K */353	{32000, 0x3},	/* 32K */354	{48000, 0x4},	/* 48K */355	{96000, 0x5},	/* 96K */356	{192000, 0x6},	/* 192K */357	{384000, 0x7},	/* 384K */358	{44100, 0x8}, /* 44.1K */359};360 361static struct interp_sample_rate int_mix_sample_rate_val[] = {362	{48000, 0x4},	/* 48K */363	{96000, 0x5},	/* 96K */364	{192000, 0x6},	/* 192K */365};366 367enum {368	WSA_MACRO_AIF_INVALID = 0,369	WSA_MACRO_AIF1_PB,370	WSA_MACRO_AIF_MIX1_PB,371	WSA_MACRO_AIF_VI,372	WSA_MACRO_AIF_ECHO,373	WSA_MACRO_MAX_DAIS,374};375 376/**377 * struct wsa_reg_layout - Register layout differences378 * @rx_intx_1_mix_inp0_sel_mask: register mask for RX_INTX_1_MIX_INP0_SEL_MASK379 * @rx_intx_1_mix_inp1_sel_mask: register mask for RX_INTX_1_MIX_INP1_SEL_MASK380 * @rx_intx_1_mix_inp2_sel_mask: register mask for RX_INTX_1_MIX_INP2_SEL_MASK381 * @rx_intx_2_sel_mask: register mask for RX_INTX_2_SEL_MASK382 * @compander1_reg_offset: offset between compander registers (compander1 - compander0)383 * @softclip0_reg_base: base address of softclip0 register384 * @softclip1_reg_offset: offset between compander registers (softclip1 - softclip0)385 */386struct wsa_reg_layout {387	unsigned int rx_intx_1_mix_inp0_sel_mask;388	unsigned int rx_intx_1_mix_inp1_sel_mask;389	unsigned int rx_intx_1_mix_inp2_sel_mask;390	unsigned int rx_intx_2_sel_mask;391	unsigned int compander1_reg_offset;392	unsigned int softclip0_reg_base;393	unsigned int softclip1_reg_offset;394};395 396struct wsa_macro {397	struct device *dev;398	int comp_enabled[WSA_MACRO_COMP_MAX];399	int ec_hq[WSA_MACRO_RX1 + 1];400	u16 prim_int_users[WSA_MACRO_RX1 + 1];401	u16 wsa_mclk_users;402	enum lpass_codec_version codec_version;403	const struct wsa_reg_layout *reg_layout;404	unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS];405	unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS];406	int rx_port_value[WSA_MACRO_RX_MAX];407	int ear_spkr_gain;408	int spkr_gain_offset;409	int spkr_mode;410	int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX];411	int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX];412	struct regmap *regmap;413	struct clk *mclk;414	struct clk *npl;415	struct clk *macro;416	struct clk *dcodec;417	struct clk *fsgen;418	struct clk_hw hw;419};420#define to_wsa_macro(_hw) container_of(_hw, struct wsa_macro, hw)421 422static const struct wsa_reg_layout wsa_codec_v2_1 = {423	.rx_intx_1_mix_inp0_sel_mask		= GENMASK(2, 0),424	.rx_intx_1_mix_inp1_sel_mask		= GENMASK(5, 3),425	.rx_intx_1_mix_inp2_sel_mask		= GENMASK(5, 3),426	.rx_intx_2_sel_mask			= GENMASK(2, 0),427	.compander1_reg_offset			= 0x40,428	.softclip0_reg_base			= 0x600,429	.softclip1_reg_offset			= 0x40,430};431 432static const struct wsa_reg_layout wsa_codec_v2_5 = {433	.rx_intx_1_mix_inp0_sel_mask		= GENMASK(3, 0),434	.rx_intx_1_mix_inp1_sel_mask		= GENMASK(7, 4),435	.rx_intx_1_mix_inp2_sel_mask		= GENMASK(7, 4),436	.rx_intx_2_sel_mask			= GENMASK(3, 0),437	.compander1_reg_offset			= 0x60,438	.softclip0_reg_base			= 0x640,439	.softclip1_reg_offset			= 0x20,440};441 442static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);443 444static const char *const rx_text_v2_1[] = {445	"ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1"446};447 448static const char *const rx_text_v2_5[] = {449	"ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "RX4", "RX5", "RX6", "RX7", "RX8", "DEC0", "DEC1"450};451 452static const char *const rx_mix_text_v2_1[] = {453	"ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1"454};455 456static const char *const rx_mix_text_v2_5[] = {457	"ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "RX4", "RX5", "RX6", "RX7", "RX8"458};459 460static const char *const rx_mix_ec_text[] = {461	"ZERO", "RX_MIX_TX0", "RX_MIX_TX1"462};463 464static const char *const rx_mux_text[] = {465	"ZERO", "AIF1_PB", "AIF_MIX1_PB"466};467 468static const char *const rx_sidetone_mix_text[] = {469	"ZERO", "SRC0"470};471 472static const char * const wsa_macro_ear_spkr_pa_gain_text[] = {473	"G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",474	"G_4_DB", "G_5_DB", "G_6_DB"475};476 477static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum,478				wsa_macro_ear_spkr_pa_gain_text);479 480/* RX INT0 */481static const struct soc_enum rx0_prim_inp0_chain_enum_v2_1 =482	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,483		0, 7, rx_text_v2_1);484 485static const struct soc_enum rx0_prim_inp1_chain_enum_v2_1 =486	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,487		3, 7, rx_text_v2_1);488 489static const struct soc_enum rx0_prim_inp2_chain_enum_v2_1 =490	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,491		3, 7, rx_text_v2_1);492 493static const struct soc_enum rx0_mix_chain_enum_v2_1 =494	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,495		0, 5, rx_mix_text_v2_1);496 497static const struct soc_enum rx0_prim_inp0_chain_enum_v2_5 =498	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,499		0, 12, rx_text_v2_5);500 501static const struct soc_enum rx0_prim_inp1_chain_enum_v2_5 =502	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG0,503		4, 12, rx_text_v2_5);504 505static const struct soc_enum rx0_prim_inp2_chain_enum_v2_5 =506	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,507		4, 12, rx_text_v2_5);508 509static const struct soc_enum rx0_mix_chain_enum_v2_5 =510	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG1,511		0, 10, rx_mix_text_v2_5);512 513static const struct soc_enum rx0_sidetone_mix_enum =514	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text);515 516static const struct snd_kcontrol_new rx0_prim_inp0_mux_v2_1 =517	SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum_v2_1);518 519static const struct snd_kcontrol_new rx0_prim_inp1_mux_v2_1 =520	SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum_v2_1);521 522static const struct snd_kcontrol_new rx0_prim_inp2_mux_v2_1 =523	SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum_v2_1);524 525static const struct snd_kcontrol_new rx0_mix_mux_v2_1 =526	SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum_v2_1);527 528static const struct snd_kcontrol_new rx0_prim_inp0_mux_v2_5 =529	SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum_v2_5);530 531static const struct snd_kcontrol_new rx0_prim_inp1_mux_v2_5 =532	SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum_v2_5);533 534static const struct snd_kcontrol_new rx0_prim_inp2_mux_v2_5 =535	SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum_v2_5);536 537static const struct snd_kcontrol_new rx0_mix_mux_v2_5 =538	SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum_v2_5);539 540static const struct snd_kcontrol_new rx0_sidetone_mix_mux =541	SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum);542 543/* RX INT1 */544static const struct soc_enum rx1_prim_inp0_chain_enum_v2_1 =545	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,546		0, 7, rx_text_v2_1);547 548static const struct soc_enum rx1_prim_inp1_chain_enum_v2_1 =549	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,550		3, 7, rx_text_v2_1);551 552static const struct soc_enum rx1_prim_inp2_chain_enum_v2_1 =553	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,554		3, 7, rx_text_v2_1);555 556static const struct soc_enum rx1_mix_chain_enum_v2_1 =557	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,558		0, 5, rx_mix_text_v2_1);559 560static const struct soc_enum rx1_prim_inp0_chain_enum_v2_5 =561	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,562		0, 12, rx_text_v2_5);563 564static const struct soc_enum rx1_prim_inp1_chain_enum_v2_5 =565	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG0,566		4, 12, rx_text_v2_5);567 568static const struct soc_enum rx1_prim_inp2_chain_enum_v2_5 =569	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,570		4, 12, rx_text_v2_5);571 572static const struct soc_enum rx1_mix_chain_enum_v2_5 =573	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG1,574		0, 10, rx_mix_text_v2_5);575 576static const struct snd_kcontrol_new rx1_prim_inp0_mux_v2_1 =577	SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum_v2_1);578 579static const struct snd_kcontrol_new rx1_prim_inp1_mux_v2_1 =580	SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum_v2_1);581 582static const struct snd_kcontrol_new rx1_prim_inp2_mux_v2_1 =583	SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum_v2_1);584 585static const struct snd_kcontrol_new rx1_mix_mux_v2_1 =586	SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum_v2_1);587 588static const struct snd_kcontrol_new rx1_prim_inp0_mux_v2_5 =589	SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum_v2_5);590 591static const struct snd_kcontrol_new rx1_prim_inp1_mux_v2_5 =592	SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum_v2_5);593 594static const struct snd_kcontrol_new rx1_prim_inp2_mux_v2_5 =595	SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum_v2_5);596 597static const struct snd_kcontrol_new rx1_mix_mux_v2_5 =598	SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum_v2_5);599 600static const struct soc_enum rx_mix_ec0_enum =601	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,602		0, 3, rx_mix_ec_text);603 604static const struct soc_enum rx_mix_ec1_enum =605	SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_MIX_CFG0,606		3, 3, rx_mix_ec_text);607 608static const struct snd_kcontrol_new rx_mix_ec0_mux =609	SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum);610 611static const struct snd_kcontrol_new rx_mix_ec1_mux =612	SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum);613 614static const struct reg_default wsa_defaults[] = {615	/* WSA Macro */616	{ CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL, 0x00},617	{ CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},618	{ CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x00},619	{ CDC_WSA_TOP_TOP_CFG0, 0x00},620	{ CDC_WSA_TOP_TOP_CFG1, 0x00},621	{ CDC_WSA_TOP_FREQ_MCLK, 0x00},622	{ CDC_WSA_TOP_DEBUG_BUS_SEL, 0x00},623	{ CDC_WSA_TOP_DEBUG_EN0, 0x00},624	{ CDC_WSA_TOP_DEBUG_EN1, 0x00},625	{ CDC_WSA_TOP_DEBUG_DSM_LB, 0x88},626	{ CDC_WSA_TOP_RX_I2S_CTL, 0x0C},627	{ CDC_WSA_TOP_TX_I2S_CTL, 0x0C},628	{ CDC_WSA_TOP_I2S_CLK, 0x02},629	{ CDC_WSA_TOP_I2S_RESET, 0x00},630	{ CDC_WSA_RX_INP_MUX_RX_INT0_CFG0, 0x00},631	{ CDC_WSA_RX_INP_MUX_RX_INT0_CFG1, 0x00},632	{ CDC_WSA_RX_INP_MUX_RX_INT1_CFG0, 0x00},633	{ CDC_WSA_RX_INP_MUX_RX_INT1_CFG1, 0x00},634	{ CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, 0x00},635	{ CDC_WSA_RX_INP_MUX_RX_EC_CFG0, 0x00},636	{ CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, 0x00},637	{ CDC_WSA_INTR_CTRL_CFG, 0x00},638	{ CDC_WSA_INTR_CTRL_CLR_COMMIT, 0x00},639	{ CDC_WSA_INTR_CTRL_PIN1_MASK0, 0xFF},640	{ CDC_WSA_INTR_CTRL_PIN1_STATUS0, 0x00},641	{ CDC_WSA_INTR_CTRL_PIN1_CLEAR0, 0x00},642	{ CDC_WSA_INTR_CTRL_PIN2_MASK0, 0xFF},643	{ CDC_WSA_INTR_CTRL_PIN2_STATUS0, 0x00},644	{ CDC_WSA_INTR_CTRL_PIN2_CLEAR0, 0x00},645	{ CDC_WSA_INTR_CTRL_LEVEL0, 0x00},646	{ CDC_WSA_INTR_CTRL_BYPASS0, 0x00},647	{ CDC_WSA_INTR_CTRL_SET0, 0x00},648	{ CDC_WSA_RX0_RX_PATH_CTL, 0x04},649	{ CDC_WSA_RX0_RX_PATH_CFG0, 0x00},650	{ CDC_WSA_RX0_RX_PATH_CFG1, 0x64},651	{ CDC_WSA_RX0_RX_PATH_CFG2, 0x8F},652	{ CDC_WSA_RX0_RX_PATH_CFG3, 0x00},653	{ CDC_WSA_RX0_RX_VOL_CTL, 0x00},654	{ CDC_WSA_RX0_RX_PATH_MIX_CTL, 0x04},655	{ CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x7E},656	{ CDC_WSA_RX0_RX_VOL_MIX_CTL, 0x00},657	{ CDC_WSA_RX0_RX_PATH_SEC0, 0x04},658	{ CDC_WSA_RX0_RX_PATH_SEC1, 0x08},659	{ CDC_WSA_RX0_RX_PATH_SEC2, 0x00},660	{ CDC_WSA_RX0_RX_PATH_SEC3, 0x00},661	{ CDC_WSA_RX0_RX_PATH_SEC5, 0x00},662	{ CDC_WSA_RX0_RX_PATH_SEC6, 0x00},663	{ CDC_WSA_RX0_RX_PATH_SEC7, 0x00},664	{ CDC_WSA_RX0_RX_PATH_MIX_SEC0, 0x08},665	{ CDC_WSA_RX0_RX_PATH_MIX_SEC1, 0x00},666	{ CDC_WSA_RX0_RX_PATH_DSMDEM_CTL, 0x00},667	{ CDC_WSA_RX1_RX_PATH_CFG0, 0x00},668	{ CDC_WSA_RX1_RX_PATH_CFG1, 0x64},669	{ CDC_WSA_RX1_RX_PATH_CFG2, 0x8F},670	{ CDC_WSA_RX1_RX_PATH_CFG3, 0x00},671	{ CDC_WSA_RX1_RX_VOL_CTL, 0x00},672	{ CDC_WSA_RX1_RX_PATH_MIX_CTL, 0x04},673	{ CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x7E},674	{ CDC_WSA_RX1_RX_VOL_MIX_CTL, 0x00},675	{ CDC_WSA_RX1_RX_PATH_SEC0, 0x04},676	{ CDC_WSA_RX1_RX_PATH_SEC1, 0x08},677	{ CDC_WSA_RX1_RX_PATH_SEC2, 0x00},678	{ CDC_WSA_RX1_RX_PATH_SEC3, 0x00},679	{ CDC_WSA_RX1_RX_PATH_SEC5, 0x00},680	{ CDC_WSA_RX1_RX_PATH_SEC6, 0x00},681	{ CDC_WSA_RX1_RX_PATH_SEC7, 0x00},682	{ CDC_WSA_RX1_RX_PATH_MIX_SEC0, 0x08},683	{ CDC_WSA_RX1_RX_PATH_MIX_SEC1, 0x00},684	{ CDC_WSA_RX1_RX_PATH_DSMDEM_CTL, 0x00},685	{ CDC_WSA_BOOST0_BOOST_PATH_CTL, 0x00},686	{ CDC_WSA_BOOST0_BOOST_CTL, 0xD0},687	{ CDC_WSA_BOOST0_BOOST_CFG1, 0x89},688	{ CDC_WSA_BOOST0_BOOST_CFG2, 0x04},689	{ CDC_WSA_BOOST1_BOOST_PATH_CTL, 0x00},690	{ CDC_WSA_BOOST1_BOOST_CTL, 0xD0},691	{ CDC_WSA_BOOST1_BOOST_CFG1, 0x89},692	{ CDC_WSA_BOOST1_BOOST_CFG2, 0x04},693	{ CDC_WSA_COMPANDER0_CTL0, 0x60},694	{ CDC_WSA_COMPANDER0_CTL1, 0xDB},695	{ CDC_WSA_COMPANDER0_CTL2, 0xFF},696	{ CDC_WSA_COMPANDER0_CTL3, 0x35},697	{ CDC_WSA_COMPANDER0_CTL4, 0xFF},698	{ CDC_WSA_COMPANDER0_CTL5, 0x00},699	{ CDC_WSA_COMPANDER0_CTL6, 0x01},700	{ CDC_WSA_COMPANDER0_CTL7, 0x28},701	{ CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL, 0x00},702	{ CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0, 0x01},703	{ CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL, 0x00},704	{ CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0, 0x01},705	{ CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL, 0x00},706	{ CDC_WSA_SPLINE_ASRC0_CTL0, 0x00},707	{ CDC_WSA_SPLINE_ASRC0_CTL1, 0x00},708	{ CDC_WSA_SPLINE_ASRC0_FIFO_CTL, 0xA8},709	{ CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},710	{ CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},711	{ CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},712	{ CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},713	{ CDC_WSA_SPLINE_ASRC0_STATUS_FIFO, 0x00},714	{ CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL, 0x00},715	{ CDC_WSA_SPLINE_ASRC1_CTL0, 0x00},716	{ CDC_WSA_SPLINE_ASRC1_CTL1, 0x00},717	{ CDC_WSA_SPLINE_ASRC1_FIFO_CTL, 0xA8},718	{ CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00},719	{ CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00},720	{ CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00},721	{ CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00},722	{ CDC_WSA_SPLINE_ASRC1_STATUS_FIFO, 0x00},723};724 725static const struct reg_default wsa_defaults_v2_1[] = {726	{ CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x02},727	{ CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x00},728	{ CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x02},729	{ CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x00},730	{ CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x02},731	{ CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x00},732	{ CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x02},733	{ CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x00},734	{ CDC_WSA_COMPANDER1_CTL0, 0x60},735	{ CDC_WSA_COMPANDER1_CTL1, 0xDB},736	{ CDC_WSA_COMPANDER1_CTL2, 0xFF},737	{ CDC_WSA_COMPANDER1_CTL3, 0x35},738	{ CDC_WSA_COMPANDER1_CTL4, 0xFF},739	{ CDC_WSA_COMPANDER1_CTL5, 0x00},740	{ CDC_WSA_COMPANDER1_CTL6, 0x01},741	{ CDC_WSA_COMPANDER1_CTL7, 0x28},742	{ CDC_WSA_SOFTCLIP0_CRC, 0x00},743	{ CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL, 0x38},744	{ CDC_WSA_SOFTCLIP1_CRC, 0x00},745	{ CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL, 0x38},746};747 748static const struct reg_default wsa_defaults_v2_5[] = {749	{ CDC_WSA_TOP_FS_UNGATE, 0xFF},750	{ CDC_WSA_TOP_GRP_SEL, 0x08},751	{ CDC_WSA_TOP_FS_UNGATE2, 0x1F},752	{ CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x04},753	{ CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x02},754	{ CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x04},755	{ CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x02},756	{ CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x04},757	{ CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x02},758	{ CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x04},759	{ CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x02},760	{ CDC_2_5_WSA_COMPANDER0_CTL8, 0x00},761	{ CDC_2_5_WSA_COMPANDER0_CTL9, 0x00},762	{ CDC_2_5_WSA_COMPANDER0_CTL10, 0x06},763	{ CDC_2_5_WSA_COMPANDER0_CTL11, 0x12},764	{ CDC_2_5_WSA_COMPANDER0_CTL12, 0x1E},765	{ CDC_2_5_WSA_COMPANDER0_CTL13, 0x24},766	{ CDC_2_5_WSA_COMPANDER0_CTL14, 0x24},767	{ CDC_2_5_WSA_COMPANDER0_CTL15, 0x24},768	{ CDC_2_5_WSA_COMPANDER0_CTL16, 0x00},769	{ CDC_2_5_WSA_COMPANDER0_CTL17, 0x24},770	{ CDC_2_5_WSA_COMPANDER0_CTL18, 0x2A},771	{ CDC_2_5_WSA_COMPANDER0_CTL19, 0x16},772	{ CDC_2_5_WSA_COMPANDER1_CTL0, 0x60},773	{ CDC_2_5_WSA_COMPANDER1_CTL1, 0xDB},774	{ CDC_2_5_WSA_COMPANDER1_CTL2, 0xFF},775	{ CDC_2_5_WSA_COMPANDER1_CTL3, 0x35},776	{ CDC_2_5_WSA_COMPANDER1_CTL4, 0xFF},777	{ CDC_2_5_WSA_COMPANDER1_CTL5, 0x00},778	{ CDC_2_5_WSA_COMPANDER1_CTL6, 0x01},779	{ CDC_2_5_WSA_COMPANDER1_CTL7, 0x28},780	{ CDC_2_5_WSA_COMPANDER1_CTL8, 0x00},781	{ CDC_2_5_WSA_COMPANDER1_CTL9, 0x00},782	{ CDC_2_5_WSA_COMPANDER1_CTL10, 0x06},783	{ CDC_2_5_WSA_COMPANDER1_CTL11, 0x12},784	{ CDC_2_5_WSA_COMPANDER1_CTL12, 0x1E},785	{ CDC_2_5_WSA_COMPANDER1_CTL13, 0x24},786	{ CDC_2_5_WSA_COMPANDER1_CTL14, 0x24},787	{ CDC_2_5_WSA_COMPANDER1_CTL15, 0x24},788	{ CDC_2_5_WSA_COMPANDER1_CTL16, 0x00},789	{ CDC_2_5_WSA_COMPANDER1_CTL17, 0x24},790	{ CDC_2_5_WSA_COMPANDER1_CTL18, 0x2A},791	{ CDC_2_5_WSA_COMPANDER1_CTL19, 0x16},792	{ CDC_2_5_WSA_SOFTCLIP0_CRC, 0x00},793	{ CDC_2_5_WSA_SOFTCLIP0_SOFTCLIP_CTRL, 0x38},794	{ CDC_2_5_WSA_SOFTCLIP1_CRC, 0x00},795	{ CDC_2_5_WSA_SOFTCLIP1_SOFTCLIP_CTRL, 0x38},796};797 798static bool wsa_is_wronly_register(struct device *dev,799					unsigned int reg)800{801	switch (reg) {802	case CDC_WSA_INTR_CTRL_CLR_COMMIT:803	case CDC_WSA_INTR_CTRL_PIN1_CLEAR0:804	case CDC_WSA_INTR_CTRL_PIN2_CLEAR0:805		return true;806	}807 808	return false;809}810 811static bool wsa_is_rw_register_v2_1(struct device *dev, unsigned int reg)812{813	switch (reg) {814	case CDC_WSA_COMPANDER1_CTL0:815	case CDC_WSA_COMPANDER1_CTL1:816	case CDC_WSA_COMPANDER1_CTL2:817	case CDC_WSA_COMPANDER1_CTL3:818	case CDC_WSA_COMPANDER1_CTL4:819	case CDC_WSA_COMPANDER1_CTL5:820	case CDC_WSA_COMPANDER1_CTL7:821	case CDC_WSA_SOFTCLIP0_CRC:822	case CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL:823	case CDC_WSA_SOFTCLIP1_CRC:824	case CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL:825		return true;826	}827 828	return false;829}830 831static bool wsa_is_rw_register_v2_5(struct device *dev, unsigned int reg)832{833	switch (reg) {834	case CDC_WSA_TOP_FS_UNGATE:835	case CDC_WSA_TOP_GRP_SEL:836	case CDC_WSA_TOP_FS_UNGATE2:837	case CDC_2_5_WSA_COMPANDER0_CTL8:838	case CDC_2_5_WSA_COMPANDER0_CTL9:839	case CDC_2_5_WSA_COMPANDER0_CTL10:840	case CDC_2_5_WSA_COMPANDER0_CTL11:841	case CDC_2_5_WSA_COMPANDER0_CTL12:842	case CDC_2_5_WSA_COMPANDER0_CTL13:843	case CDC_2_5_WSA_COMPANDER0_CTL14:844	case CDC_2_5_WSA_COMPANDER0_CTL15:845	case CDC_2_5_WSA_COMPANDER0_CTL16:846	case CDC_2_5_WSA_COMPANDER0_CTL17:847	case CDC_2_5_WSA_COMPANDER0_CTL18:848	case CDC_2_5_WSA_COMPANDER0_CTL19:849	case CDC_2_5_WSA_COMPANDER1_CTL0:850	case CDC_2_5_WSA_COMPANDER1_CTL1:851	case CDC_2_5_WSA_COMPANDER1_CTL2:852	case CDC_2_5_WSA_COMPANDER1_CTL3:853	case CDC_2_5_WSA_COMPANDER1_CTL4:854	case CDC_2_5_WSA_COMPANDER1_CTL5:855	case CDC_2_5_WSA_COMPANDER1_CTL7:856	case CDC_2_5_WSA_COMPANDER1_CTL8:857	case CDC_2_5_WSA_COMPANDER1_CTL9:858	case CDC_2_5_WSA_COMPANDER1_CTL10:859	case CDC_2_5_WSA_COMPANDER1_CTL11:860	case CDC_2_5_WSA_COMPANDER1_CTL12:861	case CDC_2_5_WSA_COMPANDER1_CTL13:862	case CDC_2_5_WSA_COMPANDER1_CTL14:863	case CDC_2_5_WSA_COMPANDER1_CTL15:864	case CDC_2_5_WSA_COMPANDER1_CTL16:865	case CDC_2_5_WSA_COMPANDER1_CTL17:866	case CDC_2_5_WSA_COMPANDER1_CTL18:867	case CDC_2_5_WSA_COMPANDER1_CTL19:868	case CDC_2_5_WSA_SOFTCLIP0_CRC:869	case CDC_2_5_WSA_SOFTCLIP0_SOFTCLIP_CTRL:870	case CDC_2_5_WSA_SOFTCLIP1_CRC:871	case CDC_2_5_WSA_SOFTCLIP1_SOFTCLIP_CTRL:872		return true;873	}874 875	return false;876}877 878static bool wsa_is_rw_register(struct device *dev, unsigned int reg)879{880	struct wsa_macro *wsa = dev_get_drvdata(dev);881 882	switch (reg) {883	case CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL:884	case CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL:885	case CDC_WSA_CLK_RST_CTRL_SWR_CONTROL:886	case CDC_WSA_TOP_TOP_CFG0:887	case CDC_WSA_TOP_TOP_CFG1:888	case CDC_WSA_TOP_FREQ_MCLK:889	case CDC_WSA_TOP_DEBUG_BUS_SEL:890	case CDC_WSA_TOP_DEBUG_EN0:891	case CDC_WSA_TOP_DEBUG_EN1:892	case CDC_WSA_TOP_DEBUG_DSM_LB:893	case CDC_WSA_TOP_RX_I2S_CTL:894	case CDC_WSA_TOP_TX_I2S_CTL:895	case CDC_WSA_TOP_I2S_CLK:896	case CDC_WSA_TOP_I2S_RESET:897	case CDC_WSA_RX_INP_MUX_RX_INT0_CFG0:898	case CDC_WSA_RX_INP_MUX_RX_INT0_CFG1:899	case CDC_WSA_RX_INP_MUX_RX_INT1_CFG0:900	case CDC_WSA_RX_INP_MUX_RX_INT1_CFG1:901	case CDC_WSA_RX_INP_MUX_RX_MIX_CFG0:902	case CDC_WSA_RX_INP_MUX_RX_EC_CFG0:903	case CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0:904	case CDC_WSA_TX0_SPKR_PROT_PATH_CTL:905	case CDC_WSA_TX0_SPKR_PROT_PATH_CFG0:906	case CDC_WSA_TX1_SPKR_PROT_PATH_CTL:907	case CDC_WSA_TX1_SPKR_PROT_PATH_CFG0:908	case CDC_WSA_TX2_SPKR_PROT_PATH_CTL:909	case CDC_WSA_TX2_SPKR_PROT_PATH_CFG0:910	case CDC_WSA_TX3_SPKR_PROT_PATH_CTL:911	case CDC_WSA_TX3_SPKR_PROT_PATH_CFG0:912	case CDC_WSA_INTR_CTRL_CFG:913	case CDC_WSA_INTR_CTRL_PIN1_MASK0:914	case CDC_WSA_INTR_CTRL_PIN2_MASK0:915	case CDC_WSA_INTR_CTRL_LEVEL0:916	case CDC_WSA_INTR_CTRL_BYPASS0:917	case CDC_WSA_INTR_CTRL_SET0:918	case CDC_WSA_RX0_RX_PATH_CTL:919	case CDC_WSA_RX0_RX_PATH_CFG0:920	case CDC_WSA_RX0_RX_PATH_CFG1:921	case CDC_WSA_RX0_RX_PATH_CFG2:922	case CDC_WSA_RX0_RX_PATH_CFG3:923	case CDC_WSA_RX0_RX_VOL_CTL:924	case CDC_WSA_RX0_RX_PATH_MIX_CTL:925	case CDC_WSA_RX0_RX_PATH_MIX_CFG:926	case CDC_WSA_RX0_RX_VOL_MIX_CTL:927	case CDC_WSA_RX0_RX_PATH_SEC0:928	case CDC_WSA_RX0_RX_PATH_SEC1:929	case CDC_WSA_RX0_RX_PATH_SEC2:930	case CDC_WSA_RX0_RX_PATH_SEC3:931	case CDC_WSA_RX0_RX_PATH_SEC5:932	case CDC_WSA_RX0_RX_PATH_SEC6:933	case CDC_WSA_RX0_RX_PATH_SEC7:934	case CDC_WSA_RX0_RX_PATH_MIX_SEC0:935	case CDC_WSA_RX0_RX_PATH_MIX_SEC1:936	case CDC_WSA_RX0_RX_PATH_DSMDEM_CTL:937	case CDC_WSA_RX1_RX_PATH_CTL:938	case CDC_WSA_RX1_RX_PATH_CFG0:939	case CDC_WSA_RX1_RX_PATH_CFG1:940	case CDC_WSA_RX1_RX_PATH_CFG2:941	case CDC_WSA_RX1_RX_PATH_CFG3:942	case CDC_WSA_RX1_RX_VOL_CTL:943	case CDC_WSA_RX1_RX_PATH_MIX_CTL:944	case CDC_WSA_RX1_RX_PATH_MIX_CFG:945	case CDC_WSA_RX1_RX_VOL_MIX_CTL:946	case CDC_WSA_RX1_RX_PATH_SEC0:947	case CDC_WSA_RX1_RX_PATH_SEC1:948	case CDC_WSA_RX1_RX_PATH_SEC2:949	case CDC_WSA_RX1_RX_PATH_SEC3:950	case CDC_WSA_RX1_RX_PATH_SEC5:951	case CDC_WSA_RX1_RX_PATH_SEC6:952	case CDC_WSA_RX1_RX_PATH_SEC7:953	case CDC_WSA_RX1_RX_PATH_MIX_SEC0:954	case CDC_WSA_RX1_RX_PATH_MIX_SEC1:955	case CDC_WSA_RX1_RX_PATH_DSMDEM_CTL:956	case CDC_WSA_BOOST0_BOOST_PATH_CTL:957	case CDC_WSA_BOOST0_BOOST_CTL:958	case CDC_WSA_BOOST0_BOOST_CFG1:959	case CDC_WSA_BOOST0_BOOST_CFG2:960	case CDC_WSA_BOOST1_BOOST_PATH_CTL:961	case CDC_WSA_BOOST1_BOOST_CTL:962	case CDC_WSA_BOOST1_BOOST_CFG1:963	case CDC_WSA_BOOST1_BOOST_CFG2:964	case CDC_WSA_COMPANDER0_CTL0:965	case CDC_WSA_COMPANDER0_CTL1:966	case CDC_WSA_COMPANDER0_CTL2:967	case CDC_WSA_COMPANDER0_CTL3:968	case CDC_WSA_COMPANDER0_CTL4:969	case CDC_WSA_COMPANDER0_CTL5:970	case CDC_WSA_COMPANDER0_CTL7:971	case CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL:972	case CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0:973	case CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL:974	case CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0:975	case CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL:976	case CDC_WSA_SPLINE_ASRC0_CTL0:977	case CDC_WSA_SPLINE_ASRC0_CTL1:978	case CDC_WSA_SPLINE_ASRC0_FIFO_CTL:979	case CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL:980	case CDC_WSA_SPLINE_ASRC1_CTL0:981	case CDC_WSA_SPLINE_ASRC1_CTL1:982	case CDC_WSA_SPLINE_ASRC1_FIFO_CTL:983		return true;984	}985 986	if (wsa->codec_version >= LPASS_CODEC_VERSION_2_5)987		return wsa_is_rw_register_v2_5(dev, reg);988 989	return wsa_is_rw_register_v2_1(dev, reg);990}991 992static bool wsa_is_writeable_register(struct device *dev, unsigned int reg)993{994	bool ret;995 996	ret = wsa_is_rw_register(dev, reg);997	if (!ret)998		return wsa_is_wronly_register(dev, reg);999 1000	return ret;1001}1002 1003static bool wsa_is_readable_register_v2_1(struct device *dev, unsigned int reg)1004{1005	switch (reg) {1006	case CDC_WSA_COMPANDER1_CTL6:1007		return true;1008	}1009 1010	return wsa_is_rw_register(dev, reg);1011}1012 1013static bool wsa_is_readable_register_v2_5(struct device *dev, unsigned int reg)1014{1015	switch (reg) {1016	case CDC_2_5_WSA_COMPANDER1_CTL6:1017		return true;1018	}1019 1020	return wsa_is_rw_register(dev, reg);1021}1022 1023static bool wsa_is_readable_register(struct device *dev, unsigned int reg)1024{1025	struct wsa_macro *wsa = dev_get_drvdata(dev);1026 1027	switch (reg) {1028	case CDC_WSA_INTR_CTRL_CLR_COMMIT:1029	case CDC_WSA_INTR_CTRL_PIN1_CLEAR0:1030	case CDC_WSA_INTR_CTRL_PIN2_CLEAR0:1031	case CDC_WSA_INTR_CTRL_PIN1_STATUS0:1032	case CDC_WSA_INTR_CTRL_PIN2_STATUS0:1033	case CDC_WSA_COMPANDER0_CTL6:1034	case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB:1035	case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB:1036	case CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB:1037	case CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB:1038	case CDC_WSA_SPLINE_ASRC0_STATUS_FIFO:1039	case CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB:1040	case CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB:1041	case CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB:1042	case CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB:1043	case CDC_WSA_SPLINE_ASRC1_STATUS_FIFO:1044		return true;1045	}1046 1047	if (wsa->codec_version >= LPASS_CODEC_VERSION_2_5)1048		return wsa_is_readable_register_v2_5(dev, reg);1049 1050	return wsa_is_readable_register_v2_1(dev, reg);1051}1052 1053static bool wsa_is_volatile_register_v2_1(struct device *dev, unsigned int reg)1054{1055	switch (reg) {1056	case CDC_WSA_COMPANDER1_CTL6:1057		return true;1058	}1059 1060	return false;1061}1062 1063static bool wsa_is_volatile_register_v2_5(struct device *dev, unsigned int reg)1064{1065	switch (reg) {1066	case CDC_2_5_WSA_COMPANDER1_CTL6:1067		return true;1068	}1069 1070	return false;1071}1072 1073static bool wsa_is_volatile_register(struct device *dev, unsigned int reg)1074{1075	struct wsa_macro *wsa = dev_get_drvdata(dev);1076 1077	/* Update volatile list for rx/tx macros */1078	switch (reg) {1079	case CDC_WSA_INTR_CTRL_PIN1_STATUS0:1080	case CDC_WSA_INTR_CTRL_PIN2_STATUS0:1081	case CDC_WSA_COMPANDER0_CTL6:1082	case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB:1083	case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB:1084	case CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB:1085	case CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB:1086	case CDC_WSA_SPLINE_ASRC0_STATUS_FIFO:1087	case CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB:1088	case CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB:1089	case CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB:1090	case CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB:1091	case CDC_WSA_SPLINE_ASRC1_STATUS_FIFO:1092		return true;1093	}1094 1095	if (wsa->codec_version >= LPASS_CODEC_VERSION_2_5)1096		return wsa_is_volatile_register_v2_5(dev, reg);1097 1098	return wsa_is_volatile_register_v2_1(dev, reg);1099}1100 1101static const struct regmap_config wsa_regmap_config = {1102	.name = "wsa_macro",1103	.reg_bits = 16,1104	.val_bits = 32, /* 8 but with 32 bit read/write */1105	.reg_stride = 4,1106	.cache_type = REGCACHE_FLAT,1107	/* .reg_defaults and .num_reg_defaults set in probe() */1108	.max_register = WSA_MAX_OFFSET,1109	.writeable_reg = wsa_is_writeable_register,1110	.volatile_reg = wsa_is_volatile_register,1111	.readable_reg = wsa_is_readable_register,1112};1113 1114/**1115 * wsa_macro_set_spkr_mode - Configures speaker compander and smartboost1116 * settings based on speaker mode.1117 *1118 * @component: codec instance1119 * @mode: Indicates speaker configuration mode.1120 *1121 * Returns 0 on success or -EINVAL on error.1122 */1123int wsa_macro_set_spkr_mode(struct snd_soc_component *component, int mode)1124{1125	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1126 1127	wsa->spkr_mode = mode;1128 1129	switch (mode) {1130	case WSA_MACRO_SPKR_MODE_1:1131		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL3, 0x80, 0x00);1132		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL3, 0x80, 0x00);1133		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL7, 0x01, 0x00);1134		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL7, 0x01, 0x00);1135		snd_soc_component_update_bits(component, CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x44);1136		snd_soc_component_update_bits(component, CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x44);1137		break;1138	default:1139		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL3, 0x80, 0x80);1140		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL3, 0x80, 0x80);1141		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER0_CTL7, 0x01, 0x01);1142		snd_soc_component_update_bits(component, CDC_WSA_COMPANDER1_CTL7, 0x01, 0x01);1143		snd_soc_component_update_bits(component, CDC_WSA_BOOST0_BOOST_CTL, 0x7C, 0x58);1144		snd_soc_component_update_bits(component, CDC_WSA_BOOST1_BOOST_CTL, 0x7C, 0x58);1145		break;1146	}1147	return 0;1148}1149EXPORT_SYMBOL(wsa_macro_set_spkr_mode);1150 1151static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,1152						u8 int_prim_fs_rate_reg_val,1153						u32 sample_rate)1154{1155	u8 int_1_mix1_inp;1156	u32 j, port;1157	u16 int_mux_cfg0, int_mux_cfg1;1158	u16 int_fs_reg;1159	u8 inp0_sel, inp1_sel, inp2_sel;1160	struct snd_soc_component *component = dai->component;1161	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1162 1163	for_each_set_bit(port, &wsa->active_ch_mask[dai->id], WSA_MACRO_RX_MAX) {1164		int_1_mix1_inp = port;1165		if ((int_1_mix1_inp < WSA_MACRO_RX0) || (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) {1166			dev_err(component->dev,	"%s: Invalid RX port, Dai ID is %d\n",1167				__func__, dai->id);1168			return -EINVAL;1169		}1170 1171		int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0;1172 1173		/*1174		 * Loop through all interpolator MUX inputs and find out1175		 * to which interpolator input, the cdc_dma rx port1176		 * is connected1177		 */1178		for (j = 0; j < NUM_INTERPOLATORS; j++) {1179			int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;1180			inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0, 1181								wsa->reg_layout->rx_intx_1_mix_inp0_sel_mask);1182			inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0,1183								wsa->reg_layout->rx_intx_1_mix_inp1_sel_mask);1184			inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1,1185								wsa->reg_layout->rx_intx_1_mix_inp2_sel_mask);1186 1187			if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||1188			    (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||1189			    (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) {1190				int_fs_reg = CDC_WSA_RX0_RX_PATH_CTL +1191					     WSA_MACRO_RX_PATH_OFFSET * j;1192				/* sample_rate is in Hz */1193				snd_soc_component_update_bits(component, int_fs_reg,1194							      WSA_MACRO_FS_RATE_MASK,1195							      int_prim_fs_rate_reg_val);1196			}1197			int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET;1198		}1199	}1200 1201	return 0;1202}1203 1204static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,1205					       u8 int_mix_fs_rate_reg_val,1206					       u32 sample_rate)1207{1208	u8 int_2_inp;1209	u32 j, port;1210	u16 int_mux_cfg1, int_fs_reg;1211	u8 int_mux_cfg1_val;1212	struct snd_soc_component *component = dai->component;1213	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1214 1215	for_each_set_bit(port, &wsa->active_ch_mask[dai->id], WSA_MACRO_RX_MAX) {1216		int_2_inp = port;1217		if ((int_2_inp < WSA_MACRO_RX0) || (int_2_inp > WSA_MACRO_RX_MIX1)) {1218			dev_err(component->dev,	"%s: Invalid RX port, Dai ID is %d\n",1219				__func__, dai->id);1220			return -EINVAL;1221		}1222 1223		int_mux_cfg1 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;1224		for (j = 0; j < NUM_INTERPOLATORS; j++) {1225			int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1,1226									wsa->reg_layout->rx_intx_2_sel_mask);1227 1228			if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) {1229				int_fs_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL +1230					WSA_MACRO_RX_PATH_OFFSET * j;1231 1232				snd_soc_component_update_bits(component,1233						      int_fs_reg,1234						      WSA_MACRO_FS_RATE_MASK,1235						      int_mix_fs_rate_reg_val);1236			}1237			int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET;1238		}1239	}1240	return 0;1241}1242 1243static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai,1244					   u32 sample_rate)1245{1246	int rate_val = 0;1247	int i, ret;1248 1249	/* set mixing path rate */1250	for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) {1251		if (sample_rate == int_mix_sample_rate_val[i].sample_rate) {1252			rate_val = int_mix_sample_rate_val[i].rate_val;1253			break;1254		}1255	}1256	if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) || (rate_val < 0))1257		goto prim_rate;1258 1259	ret = wsa_macro_set_mix_interpolator_rate(dai, (u8) rate_val, sample_rate);1260	if (ret < 0)1261		return ret;1262prim_rate:1263	/* set primary path sample rate */1264	for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) {1265		if (sample_rate == int_prim_sample_rate_val[i].sample_rate) {1266			rate_val = int_prim_sample_rate_val[i].rate_val;1267			break;1268		}1269	}1270	if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) || (rate_val < 0))1271		return -EINVAL;1272 1273	ret = wsa_macro_set_prim_interpolator_rate(dai, (u8) rate_val, sample_rate);1274 1275	return ret;1276}1277 1278static int wsa_macro_hw_params(struct snd_pcm_substream *substream,1279			       struct snd_pcm_hw_params *params,1280			       struct snd_soc_dai *dai)1281{1282	struct snd_soc_component *component = dai->component;1283	int ret;1284 1285	switch (substream->stream) {1286	case SNDRV_PCM_STREAM_PLAYBACK:1287		ret = wsa_macro_set_interpolator_rate(dai, params_rate(params));1288		if (ret) {1289			dev_err(component->dev,1290				"%s: cannot set sample rate: %u\n",1291				__func__, params_rate(params));1292			return ret;1293		}1294		break;1295	default:1296		break;1297	}1298	return 0;1299}1300 1301static int wsa_macro_get_channel_map(const struct snd_soc_dai *dai,1302				     unsigned int *tx_num, unsigned int *tx_slot,1303				     unsigned int *rx_num, unsigned int *rx_slot)1304{1305	struct snd_soc_component *component = dai->component;1306	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1307	u16 val, mask = 0, cnt = 0, temp;1308 1309	switch (dai->id) {1310	case WSA_MACRO_AIF_VI:1311		*tx_slot = wsa->active_ch_mask[dai->id];1312		*tx_num = wsa->active_ch_cnt[dai->id];1313		break;1314	case WSA_MACRO_AIF1_PB:1315	case WSA_MACRO_AIF_MIX1_PB:1316		for_each_set_bit(temp, &wsa->active_ch_mask[dai->id],1317					WSA_MACRO_RX_MAX) {1318			mask |= (1 << temp);1319			if (++cnt == WSA_MACRO_MAX_DMA_CH_PER_PORT)1320				break;1321		}1322		if (mask & 0x0C)1323			mask = mask >> 0x2;1324		*rx_slot = mask;1325		*rx_num = cnt;1326		break;1327	case WSA_MACRO_AIF_ECHO:1328		val = snd_soc_component_read(component, CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);1329		if (val & WSA_MACRO_EC_MIX_TX1_MASK) {1330			mask |= 0x2;1331			cnt++;1332		}1333		if (val & WSA_MACRO_EC_MIX_TX0_MASK) {1334			mask |= 0x1;1335			cnt++;1336		}1337		*tx_slot = mask;1338		*tx_num = cnt;1339		break;1340	default:1341		dev_err(component->dev, "%s: Invalid AIF\n", __func__);1342		break;1343	}1344	return 0;1345}1346 1347static const struct snd_soc_dai_ops wsa_macro_dai_ops = {1348	.hw_params = wsa_macro_hw_params,1349	.get_channel_map = wsa_macro_get_channel_map,1350};1351 1352static struct snd_soc_dai_driver wsa_macro_dai[] = {1353	{1354		.name = "wsa_macro_rx1",1355		.id = WSA_MACRO_AIF1_PB,1356		.playback = {1357			.stream_name = "WSA_AIF1 Playback",1358			.rates = WSA_MACRO_RX_RATES,1359			.formats = WSA_MACRO_RX_FORMATS,1360			.rate_max = 384000,1361			.rate_min = 8000,1362			.channels_min = 1,1363			.channels_max = 2,1364		},1365		.ops = &wsa_macro_dai_ops,1366	},1367	{1368		.name = "wsa_macro_rx_mix",1369		.id = WSA_MACRO_AIF_MIX1_PB,1370		.playback = {1371			.stream_name = "WSA_AIF_MIX1 Playback",1372			.rates = WSA_MACRO_RX_MIX_RATES,1373			.formats = WSA_MACRO_RX_FORMATS,1374			.rate_max = 192000,1375			.rate_min = 48000,1376			.channels_min = 1,1377			.channels_max = 2,1378		},1379		.ops = &wsa_macro_dai_ops,1380	},1381	{1382		.name = "wsa_macro_vifeedback",1383		.id = WSA_MACRO_AIF_VI,1384		.capture = {1385			.stream_name = "WSA_AIF_VI Capture",1386			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,1387			.formats = WSA_MACRO_RX_FORMATS,1388			.rate_max = 48000,1389			.rate_min = 8000,1390			.channels_min = 1,1391			.channels_max = 4,1392		},1393		.ops = &wsa_macro_dai_ops,1394	},1395	{1396		.name = "wsa_macro_echo",1397		.id = WSA_MACRO_AIF_ECHO,1398		.capture = {1399			.stream_name = "WSA_AIF_ECHO Capture",1400			.rates = WSA_MACRO_ECHO_RATES,1401			.formats = WSA_MACRO_ECHO_FORMATS,1402			.rate_max = 48000,1403			.rate_min = 8000,1404			.channels_min = 1,1405			.channels_max = 2,1406		},1407		.ops = &wsa_macro_dai_ops,1408	},1409};1410 1411static void wsa_macro_mclk_enable(struct wsa_macro *wsa, bool mclk_enable)1412{1413	struct regmap *regmap = wsa->regmap;1414 1415	if (mclk_enable) {1416		if (wsa->wsa_mclk_users == 0) {1417			regcache_mark_dirty(regmap);1418			regcache_sync(regmap);1419			/* 9.6MHz MCLK, set value 0x00 if other frequency */1420			regmap_update_bits(regmap, CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);1421			regmap_update_bits(regmap,1422					   CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,1423					   CDC_WSA_MCLK_EN_MASK,1424					   CDC_WSA_MCLK_ENABLE);1425			regmap_update_bits(regmap,1426					   CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,1427					   CDC_WSA_FS_CNT_EN_MASK,1428					   CDC_WSA_FS_CNT_ENABLE);1429		}1430		wsa->wsa_mclk_users++;1431	} else {1432		if (wsa->wsa_mclk_users <= 0) {1433			dev_err(wsa->dev, "clock already disabled\n");1434			wsa->wsa_mclk_users = 0;1435			return;1436		}1437		wsa->wsa_mclk_users--;1438		if (wsa->wsa_mclk_users == 0) {1439			regmap_update_bits(regmap,1440					   CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL,1441					   CDC_WSA_FS_CNT_EN_MASK,1442					   CDC_WSA_FS_CNT_DISABLE);1443			regmap_update_bits(regmap,1444					   CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL,1445					   CDC_WSA_MCLK_EN_MASK,1446					   CDC_WSA_MCLK_DISABLE);1447		}1448	}1449}1450 1451static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,1452				struct snd_kcontrol *kcontrol, int event)1453{1454	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1455	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1456 1457	wsa_macro_mclk_enable(wsa, event == SND_SOC_DAPM_PRE_PMU);1458	return 0;1459}1460 1461static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,1462					struct snd_kcontrol *kcontrol,1463					int event)1464{1465	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1466	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1467	u32 tx_reg0, tx_reg1;1468 1469	if (test_bit(WSA_MACRO_TX0, &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {1470		tx_reg0 = CDC_WSA_TX0_SPKR_PROT_PATH_CTL;1471		tx_reg1 = CDC_WSA_TX1_SPKR_PROT_PATH_CTL;1472	} else if (test_bit(WSA_MACRO_TX1, &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {1473		tx_reg0 = CDC_WSA_TX2_SPKR_PROT_PATH_CTL;1474		tx_reg1 = CDC_WSA_TX3_SPKR_PROT_PATH_CTL;1475	}1476 1477	switch (event) {1478	case SND_SOC_DAPM_POST_PMU:1479			/* Enable V&I sensing */1480		snd_soc_component_update_bits(component, tx_reg0,1481					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,1482					      CDC_WSA_TX_SPKR_PROT_RESET);1483		snd_soc_component_update_bits(component, tx_reg1,1484					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,1485					      CDC_WSA_TX_SPKR_PROT_RESET);1486		snd_soc_component_update_bits(component, tx_reg0,1487					      CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK,1488					      CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K);1489		snd_soc_component_update_bits(component, tx_reg1,1490					      CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK,1491					      CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K);1492		snd_soc_component_update_bits(component, tx_reg0,1493					      CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,1494					      CDC_WSA_TX_SPKR_PROT_CLK_ENABLE);1495		snd_soc_component_update_bits(component, tx_reg1,1496					      CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,1497					      CDC_WSA_TX_SPKR_PROT_CLK_ENABLE);1498		snd_soc_component_update_bits(component, tx_reg0,1499					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,1500					      CDC_WSA_TX_SPKR_PROT_NO_RESET);1501		snd_soc_component_update_bits(component, tx_reg1,1502					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,1503					      CDC_WSA_TX_SPKR_PROT_NO_RESET);1504		break;1505	case SND_SOC_DAPM_POST_PMD:1506		/* Disable V&I sensing */1507		snd_soc_component_update_bits(component, tx_reg0,1508					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,1509					      CDC_WSA_TX_SPKR_PROT_RESET);1510		snd_soc_component_update_bits(component, tx_reg1,1511					      CDC_WSA_TX_SPKR_PROT_RESET_MASK,1512					      CDC_WSA_TX_SPKR_PROT_RESET);1513		snd_soc_component_update_bits(component, tx_reg0,1514					      CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,1515					      CDC_WSA_TX_SPKR_PROT_CLK_DISABLE);1516		snd_soc_component_update_bits(component, tx_reg1,1517					      CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK,1518					      CDC_WSA_TX_SPKR_PROT_CLK_DISABLE);1519		break;1520	}1521 1522	return 0;1523}1524 1525static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w,1526				     struct snd_kcontrol *kcontrol, int event)1527{1528	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1529	u16 path_reg, gain_reg;1530	int val;1531 1532	switch (w->shift) {1533	case WSA_MACRO_RX_MIX0:1534		path_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL;1535		gain_reg = CDC_WSA_RX0_RX_VOL_MIX_CTL;1536		break;1537	case WSA_MACRO_RX_MIX1:1538		path_reg = CDC_WSA_RX1_RX_PATH_MIX_CTL;1539		gain_reg = CDC_WSA_RX1_RX_VOL_MIX_CTL;1540		break;1541	default:1542		return 0;1543	}1544 1545	switch (event) {1546	case SND_SOC_DAPM_POST_PMU:1547		val = snd_soc_component_read(component, gain_reg);1548		snd_soc_component_write(component, gain_reg, val);1549		break;1550	case SND_SOC_DAPM_POST_PMD:1551		snd_soc_component_update_bits(component, path_reg,1552					      CDC_WSA_RX_PATH_MIX_CLK_EN_MASK,1553					      CDC_WSA_RX_PATH_MIX_CLK_DISABLE);1554		break;1555	}1556 1557	return 0;1558}1559 1560static void wsa_macro_hd2_control(struct snd_soc_component *component,1561				  u16 reg, int event)1562{1563	u16 hd2_scale_reg;1564	u16 hd2_enable_reg;1565 1566	if (reg == CDC_WSA_RX0_RX_PATH_CTL) {1567		hd2_scale_reg = CDC_WSA_RX0_RX_PATH_SEC3;1568		hd2_enable_reg = CDC_WSA_RX0_RX_PATH_CFG0;1569	}1570	if (reg == CDC_WSA_RX1_RX_PATH_CTL) {1571		hd2_scale_reg = CDC_WSA_RX1_RX_PATH_SEC3;1572		hd2_enable_reg = CDC_WSA_RX1_RX_PATH_CFG0;1573	}1574 1575	if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {1576		snd_soc_component_update_bits(component, hd2_scale_reg,1577					      CDC_WSA_RX_PATH_HD2_ALPHA_MASK,1578					      0x10);1579		snd_soc_component_update_bits(component, hd2_scale_reg,1580					      CDC_WSA_RX_PATH_HD2_SCALE_MASK,1581					      0x1);1582		snd_soc_component_update_bits(component, hd2_enable_reg,1583					      CDC_WSA_RX_PATH_HD2_EN_MASK,1584					      CDC_WSA_RX_PATH_HD2_ENABLE);1585	}1586 1587	if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {1588		snd_soc_component_update_bits(component, hd2_enable_reg,1589					      CDC_WSA_RX_PATH_HD2_EN_MASK, 0);1590		snd_soc_component_update_bits(component, hd2_scale_reg,1591					      CDC_WSA_RX_PATH_HD2_SCALE_MASK,1592					      0);1593		snd_soc_component_update_bits(component, hd2_scale_reg,1594					      CDC_WSA_RX_PATH_HD2_ALPHA_MASK,1595					      0);1596	}1597}1598 1599static int wsa_macro_config_compander(struct snd_soc_component *component,1600				      int comp, int event)1601{1602	u16 comp_ctl0_reg, rx_path_cfg0_reg;1603	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1604 1605	if (!wsa->comp_enabled[comp])1606		return 0;1607 1608	comp_ctl0_reg = CDC_WSA_COMPANDER0_CTL0 +1609					(comp * wsa->reg_layout->compander1_reg_offset);1610	rx_path_cfg0_reg = CDC_WSA_RX0_RX_PATH_CFG0 +1611					(comp * WSA_MACRO_RX_PATH_OFFSET);1612 1613	if (SND_SOC_DAPM_EVENT_ON(event)) {1614		/* Enable Compander Clock */1615		snd_soc_component_update_bits(component, comp_ctl0_reg,1616					      CDC_WSA_COMPANDER_CLK_EN_MASK,1617					      CDC_WSA_COMPANDER_CLK_ENABLE);1618		snd_soc_component_update_bits(component, comp_ctl0_reg,1619					      CDC_WSA_COMPANDER_SOFT_RST_MASK,1620					      CDC_WSA_COMPANDER_SOFT_RST_ENABLE);1621		snd_soc_component_update_bits(component, comp_ctl0_reg,1622					      CDC_WSA_COMPANDER_SOFT_RST_MASK,1623					      0);1624		snd_soc_component_update_bits(component, rx_path_cfg0_reg,1625					      CDC_WSA_RX_PATH_COMP_EN_MASK,1626					      CDC_WSA_RX_PATH_COMP_ENABLE);1627	}1628 1629	if (SND_SOC_DAPM_EVENT_OFF(event)) {1630		snd_soc_component_update_bits(component, comp_ctl0_reg,1631					      CDC_WSA_COMPANDER_HALT_MASK,1632					      CDC_WSA_COMPANDER_HALT);1633		snd_soc_component_update_bits(component, rx_path_cfg0_reg,1634					      CDC_WSA_RX_PATH_COMP_EN_MASK, 0);1635		snd_soc_component_update_bits(component, comp_ctl0_reg,1636					      CDC_WSA_COMPANDER_SOFT_RST_MASK,1637					      CDC_WSA_COMPANDER_SOFT_RST_ENABLE);1638		snd_soc_component_update_bits(component, comp_ctl0_reg,1639					      CDC_WSA_COMPANDER_SOFT_RST_MASK,1640					      0);1641		snd_soc_component_update_bits(component, comp_ctl0_reg,1642					      CDC_WSA_COMPANDER_CLK_EN_MASK, 0);1643		snd_soc_component_update_bits(component, comp_ctl0_reg,1644					      CDC_WSA_COMPANDER_HALT_MASK, 0);1645	}1646 1647	return 0;1648}1649 1650static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component,1651					 struct wsa_macro *wsa,1652					 int path,1653					 bool enable)1654{1655	u16 softclip_clk_reg = wsa->reg_layout->softclip0_reg_base +1656			(path * wsa->reg_layout->softclip1_reg_offset);1657	u8 softclip_mux_mask = (1 << path);1658	u8 softclip_mux_value = (1 << path);1659 1660	if (enable) {1661		if (wsa->softclip_clk_users[path] == 0) {1662			snd_soc_component_update_bits(component,1663						softclip_clk_reg,1664						CDC_WSA_SOFTCLIP_CLK_EN_MASK,1665						CDC_WSA_SOFTCLIP_CLK_ENABLE);1666			snd_soc_component_update_bits(component,1667				CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,1668				softclip_mux_mask, softclip_mux_value);1669		}1670		wsa->softclip_clk_users[path]++;1671	} else {1672		wsa->softclip_clk_users[path]--;1673		if (wsa->softclip_clk_users[path] == 0) {1674			snd_soc_component_update_bits(component,1675						softclip_clk_reg,1676						CDC_WSA_SOFTCLIP_CLK_EN_MASK,1677						0);1678			snd_soc_component_update_bits(component,1679				CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0,1680				softclip_mux_mask, 0x00);1681		}1682	}1683}1684 1685static int wsa_macro_config_softclip(struct snd_soc_component *component,1686				     int path, int event)1687{1688	u16 softclip_ctrl_reg;1689	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1690	int softclip_path = 0;1691 1692	if (path == WSA_MACRO_COMP1)1693		softclip_path = WSA_MACRO_SOFTCLIP0;1694	else if (path == WSA_MACRO_COMP2)1695		softclip_path = WSA_MACRO_SOFTCLIP1;1696 1697	if (!wsa->is_softclip_on[softclip_path])1698		return 0;1699 1700	softclip_ctrl_reg = CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL +1701				(softclip_path * wsa->reg_layout->softclip1_reg_offset);1702 1703	if (SND_SOC_DAPM_EVENT_ON(event)) {1704		/* Enable Softclip clock and mux */1705		wsa_macro_enable_softclip_clk(component, wsa, softclip_path,1706					      true);1707		/* Enable Softclip control */1708		snd_soc_component_update_bits(component, softclip_ctrl_reg,1709					      CDC_WSA_SOFTCLIP_EN_MASK,1710					      CDC_WSA_SOFTCLIP_ENABLE);1711	}1712 1713	if (SND_SOC_DAPM_EVENT_OFF(event)) {1714		snd_soc_component_update_bits(component, softclip_ctrl_reg,1715					      CDC_WSA_SOFTCLIP_EN_MASK, 0);1716		wsa_macro_enable_softclip_clk(component, wsa, softclip_path,1717					      false);1718	}1719 1720	return 0;1721}1722 1723static bool wsa_macro_adie_lb(struct snd_soc_component *component,1724			      int interp_idx)1725{1726	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1727	u16 int_mux_cfg0,  int_mux_cfg1;1728	u8 int_n_inp0, int_n_inp1, int_n_inp2;1729 1730	int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8;1731	int_mux_cfg1 = int_mux_cfg0 + 4;1732 1733	int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0,1734						  wsa->reg_layout->rx_intx_1_mix_inp0_sel_mask);1735	if (int_n_inp0 == INTn_1_INP_SEL_DEC0 ||1736		int_n_inp0 == INTn_1_INP_SEL_DEC1)1737		return true;1738 1739	int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0,1740						  wsa->reg_layout->rx_intx_1_mix_inp1_sel_mask);1741	if (int_n_inp1 == INTn_1_INP_SEL_DEC0 ||1742		int_n_inp1 == INTn_1_INP_SEL_DEC1)1743		return true;1744 1745	int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1,1746						  wsa->reg_layout->rx_intx_1_mix_inp2_sel_mask);1747	if (int_n_inp2 == INTn_1_INP_SEL_DEC0 ||1748		int_n_inp2 == INTn_1_INP_SEL_DEC1)1749		return true;1750 1751	return false;1752}1753 1754static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w,1755				      struct snd_kcontrol *kcontrol,1756				      int event)1757{1758	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1759	u16 reg;1760 1761	reg = CDC_WSA_RX0_RX_PATH_CTL + WSA_MACRO_RX_PATH_OFFSET * w->shift;1762	switch (event) {1763	case SND_SOC_DAPM_PRE_PMU:1764		if (wsa_macro_adie_lb(component, w->shift)) {1765			snd_soc_component_update_bits(component, reg,1766					     CDC_WSA_RX_PATH_CLK_EN_MASK,1767					     CDC_WSA_RX_PATH_CLK_ENABLE);1768		}1769		break;1770	default:1771		break;1772	}1773	return 0;1774}1775 1776static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind)1777{1778	u16 prim_int_reg = 0;1779 1780	switch (reg) {1781	case CDC_WSA_RX0_RX_PATH_CTL:1782	case CDC_WSA_RX0_RX_PATH_MIX_CTL:1783		prim_int_reg = CDC_WSA_RX0_RX_PATH_CTL;1784		*ind = 0;1785		break;1786	case CDC_WSA_RX1_RX_PATH_CTL:1787	case CDC_WSA_RX1_RX_PATH_MIX_CTL:1788		prim_int_reg = CDC_WSA_RX1_RX_PATH_CTL;1789		*ind = 1;1790		break;1791	}1792 1793	return prim_int_reg;1794}1795 1796static int wsa_macro_enable_prim_interpolator(struct snd_soc_component *component,1797					      u16 reg, int event)1798{1799	u16 prim_int_reg;1800	u16 ind = 0;1801	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1802 1803	prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind);1804 1805	switch (event) {1806	case SND_SOC_DAPM_PRE_PMU:1807		wsa->prim_int_users[ind]++;1808		if (wsa->prim_int_users[ind] == 1) {1809			snd_soc_component_update_bits(component,1810						      prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET,1811						      CDC_WSA_RX_DC_DCOEFF_MASK,1812						      0x3);1813			snd_soc_component_update_bits(component, prim_int_reg,1814					CDC_WSA_RX_PATH_PGA_MUTE_EN_MASK,1815					CDC_WSA_RX_PATH_PGA_MUTE_ENABLE);1816			wsa_macro_hd2_control(component, prim_int_reg, event);1817			snd_soc_component_update_bits(component,1818				prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,1819				CDC_WSA_RX_DSMDEM_CLK_EN_MASK,1820				CDC_WSA_RX_DSMDEM_CLK_ENABLE);1821		}1822		if ((reg != prim_int_reg) &&1823		    ((snd_soc_component_read(1824				component, prim_int_reg)) & 0x10))1825			snd_soc_component_update_bits(component, reg,1826					0x10, 0x10);1827		break;1828	case SND_SOC_DAPM_POST_PMD:1829		wsa->prim_int_users[ind]--;1830		if (wsa->prim_int_users[ind] == 0) {1831			snd_soc_component_update_bits(component,1832				prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET,1833				CDC_WSA_RX_DSMDEM_CLK_EN_MASK, 0);1834			wsa_macro_hd2_control(component, prim_int_reg, event);1835		}1836		break;1837	}1838 1839	return 0;1840}1841 1842static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,1843					  struct wsa_macro *wsa,1844					  int event, int gain_reg)1845{1846	int comp_gain_offset, val;1847 1848	switch (wsa->spkr_mode) {1849	/* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */1850	case WSA_MACRO_SPKR_MODE_1:1851		comp_gain_offset = -12;1852		break;1853	/* Default case compander gain is 15 dB */1854	default:1855		comp_gain_offset = -15;1856		break;1857	}1858 1859	switch (event) {1860	case SND_SOC_DAPM_POST_PMU:1861		/* Apply ear spkr gain only if compander is enabled */1862		if (wsa->comp_enabled[WSA_MACRO_COMP1] &&1863		    (gain_reg == CDC_WSA_RX0_RX_VOL_CTL) &&1864		    (wsa->ear_spkr_gain != 0)) {1865			/* For example, val is -8(-12+5-1) for 4dB of gain */1866			val = comp_gain_offset + wsa->ear_spkr_gain - 1;1867			snd_soc_component_write(component, gain_reg, val);1868		}1869		break;1870	case SND_SOC_DAPM_POST_PMD:1871		/*1872		 * Reset RX0 volume to 0 dB if compander is enabled and1873		 * ear_spkr_gain is non-zero.1874		 */1875		if (wsa->comp_enabled[WSA_MACRO_COMP1] &&1876		    (gain_reg == CDC_WSA_RX0_RX_VOL_CTL) &&1877		    (wsa->ear_spkr_gain != 0)) {1878			snd_soc_component_write(component, gain_reg, 0x0);1879		}1880		break;1881	}1882 1883	return 0;1884}1885 1886static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w,1887					 struct snd_kcontrol *kcontrol,1888					 int event)1889{1890	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1891	u16 gain_reg;1892	u16 reg;1893	int val;1894	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);1895 1896	if (w->shift == WSA_MACRO_COMP1) {1897		reg = CDC_WSA_RX0_RX_PATH_CTL;1898		gain_reg = CDC_WSA_RX0_RX_VOL_CTL;1899	} else if (w->shift == WSA_MACRO_COMP2) {1900		reg = CDC_WSA_RX1_RX_PATH_CTL;1901		gain_reg = CDC_WSA_RX1_RX_VOL_CTL;1902	}1903 1904	switch (event) {1905	case SND_SOC_DAPM_PRE_PMU:1906		/* Reset if needed */1907		wsa_macro_enable_prim_interpolator(component, reg, event);1908		break;1909	case SND_SOC_DAPM_POST_PMU:1910		wsa_macro_config_compander(component, w->shift, event);1911		wsa_macro_config_softclip(component, w->shift, event);1912		/* apply gain after int clk is enabled */1913		if ((wsa->spkr_gain_offset == WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&1914		    (wsa->comp_enabled[WSA_MACRO_COMP1] ||1915		     wsa->comp_enabled[WSA_MACRO_COMP2])) {1916			snd_soc_component_update_bits(component,1917					CDC_WSA_RX0_RX_PATH_SEC1,1918					CDC_WSA_RX_PGA_HALF_DB_MASK,1919					CDC_WSA_RX_PGA_HALF_DB_ENABLE);1920			snd_soc_component_update_bits(component,1921					CDC_WSA_RX0_RX_PATH_MIX_SEC0,1922					CDC_WSA_RX_PGA_HALF_DB_MASK,1923					CDC_WSA_RX_PGA_HALF_DB_ENABLE);1924			snd_soc_component_update_bits(component,1925					CDC_WSA_RX1_RX_PATH_SEC1,1926					CDC_WSA_RX_PGA_HALF_DB_MASK,1927					CDC_WSA_RX_PGA_HALF_DB_ENABLE);1928			snd_soc_component_update_bits(component,1929					CDC_WSA_RX1_RX_PATH_MIX_SEC0,1930					CDC_WSA_RX_PGA_HALF_DB_MASK,1931					CDC_WSA_RX_PGA_HALF_DB_ENABLE);1932		}1933		val = snd_soc_component_read(component, gain_reg);1934		snd_soc_component_write(component, gain_reg, val);1935		wsa_macro_config_ear_spkr_gain(component, wsa,1936						event, gain_reg);1937		break;1938	case SND_SOC_DAPM_POST_PMD:1939		wsa_macro_config_compander(component, w->shift, event);1940		wsa_macro_config_softclip(component, w->shift, event);1941		wsa_macro_enable_prim_interpolator(component, reg, event);1942		if ((wsa->spkr_gain_offset == WSA_MACRO_GAIN_OFFSET_M1P5_DB) &&1943		    (wsa->comp_enabled[WSA_MACRO_COMP1] ||1944		     wsa->comp_enabled[WSA_MACRO_COMP2])) {1945			snd_soc_component_update_bits(component,1946					CDC_WSA_RX0_RX_PATH_SEC1,1947					CDC_WSA_RX_PGA_HALF_DB_MASK,1948					CDC_WSA_RX_PGA_HALF_DB_DISABLE);1949			snd_soc_component_update_bits(component,1950					CDC_WSA_RX0_RX_PATH_MIX_SEC0,1951					CDC_WSA_RX_PGA_HALF_DB_MASK,1952					CDC_WSA_RX_PGA_HALF_DB_DISABLE);1953			snd_soc_component_update_bits(component,1954					CDC_WSA_RX1_RX_PATH_SEC1,1955					CDC_WSA_RX_PGA_HALF_DB_MASK,1956					CDC_WSA_RX_PGA_HALF_DB_DISABLE);1957			snd_soc_component_update_bits(component,1958					CDC_WSA_RX1_RX_PATH_MIX_SEC0,1959					CDC_WSA_RX_PGA_HALF_DB_MASK,1960					CDC_WSA_RX_PGA_HALF_DB_DISABLE);1961		}1962		wsa_macro_config_ear_spkr_gain(component, wsa,1963						event, gain_reg);1964		break;1965	}1966 1967	return 0;1968}1969 1970static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w,1971				     struct snd_kcontrol *kcontrol,1972				     int event)1973{1974	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1975	u16 boost_path_ctl, boost_path_cfg1;1976	u16 reg, reg_mix;1977 1978	if (!snd_soc_dapm_widget_name_cmp(w, "WSA_RX INT0 CHAIN")) {1979		boost_path_ctl = CDC_WSA_BOOST0_BOOST_PATH_CTL;1980		boost_path_cfg1 = CDC_WSA_RX0_RX_PATH_CFG1;1981		reg = CDC_WSA_RX0_RX_PATH_CTL;1982		reg_mix = CDC_WSA_RX0_RX_PATH_MIX_CTL;1983	} else if (!snd_soc_dapm_widget_name_cmp(w, "WSA_RX INT1 CHAIN")) {1984		boost_path_ctl = CDC_WSA_BOOST1_BOOST_PATH_CTL;1985		boost_path_cfg1 = CDC_WSA_RX1_RX_PATH_CFG1;1986		reg = CDC_WSA_RX1_RX_PATH_CTL;1987		reg_mix = CDC_WSA_RX1_RX_PATH_MIX_CTL;1988	} else {1989		dev_warn(component->dev, "Incorrect widget name in the driver\n");1990		return -EINVAL;1991	}1992 1993	switch (event) {1994	case SND_SOC_DAPM_PRE_PMU:1995		snd_soc_component_update_bits(component, boost_path_cfg1,1996					      CDC_WSA_RX_PATH_SMART_BST_EN_MASK,1997					      CDC_WSA_RX_PATH_SMART_BST_ENABLE);1998		snd_soc_component_update_bits(component, boost_path_ctl,1999					      CDC_WSA_BOOST_PATH_CLK_EN_MASK,2000					      CDC_WSA_BOOST_PATH_CLK_ENABLE);2001		if ((snd_soc_component_read(component, reg_mix)) & 0x10)2002			snd_soc_component_update_bits(component, reg_mix,2003						0x10, 0x00);2004		break;2005	case SND_SOC_DAPM_POST_PMU:2006		snd_soc_component_update_bits(component, reg, 0x10, 0x00);2007		break;2008	case SND_SOC_DAPM_POST_PMD:2009		snd_soc_component_update_bits(component, boost_path_ctl,2010					      CDC_WSA_BOOST_PATH_CLK_EN_MASK,2011					      CDC_WSA_BOOST_PATH_CLK_DISABLE);2012		snd_soc_component_update_bits(component, boost_path_cfg1,2013					      CDC_WSA_RX_PATH_SMART_BST_EN_MASK,2014					      CDC_WSA_RX_PATH_SMART_BST_DISABLE);2015		break;2016	}2017 2018	return 0;2019}2020 2021static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,2022				 struct snd_kcontrol *kcontrol,2023				 int event)2024{2025	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);2026	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2027	u16 val, ec_tx, ec_hq_reg;2028 2029	val = snd_soc_component_read(component, CDC_WSA_RX_INP_MUX_RX_MIX_CFG0);2030 2031	switch (w->shift) {2032	case WSA_MACRO_EC0_MUX:2033		val = val & CDC_WSA_RX_MIX_TX0_SEL_MASK;2034		ec_tx = val - 1;2035		break;2036	case WSA_MACRO_EC1_MUX:2037		val = val & CDC_WSA_RX_MIX_TX1_SEL_MASK;2038		ec_tx = (val >> CDC_WSA_RX_MIX_TX1_SEL_SHFT) - 1;2039		break;2040	default:2041		dev_err(component->dev,	"%s: Invalid shift %u\n",2042			__func__, w->shift);2043		return -EINVAL;2044	}2045 2046	if (wsa->ec_hq[ec_tx]) {2047		ec_hq_reg = CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL +	0x40 * ec_tx;2048		snd_soc_component_update_bits(component, ec_hq_reg,2049					     CDC_WSA_EC_HQ_EC_CLK_EN_MASK,2050					     CDC_WSA_EC_HQ_EC_CLK_ENABLE);2051		ec_hq_reg = CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 + 0x40 * ec_tx;2052		/* default set to 48k */2053		snd_soc_component_update_bits(component, ec_hq_reg,2054				      CDC_WSA_EC_HQ_EC_REF_PCM_RATE_MASK,2055				      CDC_WSA_EC_HQ_EC_REF_PCM_RATE_48K);2056	}2057 2058	return 0;2059}2060 2061static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol,2062			       struct snd_ctl_elem_value *ucontrol)2063{2064 2065	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);2066	int ec_tx = ((struct soc_mixer_control *) kcontrol->private_value)->shift;2067	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2068 2069	ucontrol->value.integer.value[0] = wsa->ec_hq[ec_tx];2070 2071	return 0;2072}2073 2074static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol,2075			       struct snd_ctl_elem_value *ucontrol)2076{2077	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);2078	int ec_tx = ((struct soc_mixer_control *) kcontrol->private_value)->shift;2079	int value = ucontrol->value.integer.value[0];2080	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2081 2082	wsa->ec_hq[ec_tx] = value;2083 2084	return 0;2085}2086 2087static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,2088				   struct snd_ctl_elem_value *ucontrol)2089{2090 2091	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);2092	int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift;2093	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2094 2095	ucontrol->value.integer.value[0] = wsa->comp_enabled[comp];2096	return 0;2097}2098 2099static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol,2100				   struct snd_ctl_elem_value *ucontrol)2101{2102	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);2103	int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift;2104	int value = ucontrol->value.integer.value[0];2105	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2106 2107	wsa->comp_enabled[comp] = value;2108 2109	return 0;2110}2111 2112static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,2113					  struct snd_ctl_elem_value *ucontrol)2114{2115	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);2116	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2117 2118	ucontrol->value.integer.value[0] = wsa->ear_spkr_gain;2119 2120	return 0;2121}2122 2123static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,2124					  struct snd_ctl_elem_value *ucontrol)2125{2126	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);2127	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2128 2129	wsa->ear_spkr_gain =  ucontrol->value.integer.value[0];2130 2131	return 0;2132}2133 2134static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol,2135				struct snd_ctl_elem_value *ucontrol)2136{2137	struct snd_soc_dapm_widget *widget =2138		snd_soc_dapm_kcontrol_widget(kcontrol);2139	struct snd_soc_component *component =2140				snd_soc_dapm_to_component(widget->dapm);2141	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2142 2143	ucontrol->value.integer.value[0] =2144			wsa->rx_port_value[widget->shift];2145	return 0;2146}2147 2148static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,2149				struct snd_ctl_elem_value *ucontrol)2150{2151	struct snd_soc_dapm_widget *widget =2152		snd_soc_dapm_kcontrol_widget(kcontrol);2153	struct snd_soc_component *component =2154				snd_soc_dapm_to_component(widget->dapm);2155	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;2156	struct snd_soc_dapm_update *update = NULL;2157	u32 rx_port_value = ucontrol->value.integer.value[0];2158	u32 bit_input;2159	u32 aif_rst;2160	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2161 2162	aif_rst = wsa->rx_port_value[widget->shift];2163	if (!rx_port_value) {2164		if (aif_rst == 0)2165			return 0;2166		if (aif_rst >= WSA_MACRO_RX_MAX) {2167			dev_err(component->dev, "%s: Invalid AIF reset\n", __func__);2168			return 0;2169		}2170	}2171	wsa->rx_port_value[widget->shift] = rx_port_value;2172 2173	bit_input = widget->shift;2174 2175	switch (rx_port_value) {2176	case 0:2177		if (wsa->active_ch_cnt[aif_rst]) {2178			clear_bit(bit_input,2179				  &wsa->active_ch_mask[aif_rst]);2180			wsa->active_ch_cnt[aif_rst]--;2181		}2182		break;2183	case 1:2184	case 2:2185		set_bit(bit_input,2186			&wsa->active_ch_mask[rx_port_value]);2187		wsa->active_ch_cnt[rx_port_value]++;2188		break;2189	default:2190		dev_err(component->dev,2191			"%s: Invalid AIF_ID for WSA RX MUX %d\n",2192			__func__, rx_port_value);2193		return -EINVAL;2194	}2195 2196	snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,2197					rx_port_value, e, update);2198	return 0;2199}2200 2201static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol,2202					  struct snd_ctl_elem_value *ucontrol)2203{2204	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);2205	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2206	int path = ((struct soc_mixer_control *)kcontrol->private_value)->shift;2207 2208	ucontrol->value.integer.value[0] = wsa->is_softclip_on[path];2209 2210	return 0;2211}2212 2213static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol,2214					  struct snd_ctl_elem_value *ucontrol)2215{2216	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);2217	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2218	int path = ((struct soc_mixer_control *) kcontrol->private_value)->shift;2219 2220	wsa->is_softclip_on[path] =  ucontrol->value.integer.value[0];2221 2222	return 0;2223}2224 2225static const struct snd_kcontrol_new wsa_macro_snd_controls[] = {2226	SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum,2227		     wsa_macro_ear_spkr_pa_gain_get,2228		     wsa_macro_ear_spkr_pa_gain_put),2229	SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM,2230			WSA_MACRO_SOFTCLIP0, 1, 0,2231			wsa_macro_soft_clip_enable_get,2232			wsa_macro_soft_clip_enable_put),2233	SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM,2234			WSA_MACRO_SOFTCLIP1, 1, 0,2235			wsa_macro_soft_clip_enable_get,2236			wsa_macro_soft_clip_enable_put),2237 2238	SOC_SINGLE_S8_TLV("WSA_RX0 Digital Volume", CDC_WSA_RX0_RX_VOL_CTL,2239			  -84, 40, digital_gain),2240	SOC_SINGLE_S8_TLV("WSA_RX1 Digital Volume", CDC_WSA_RX1_RX_VOL_CTL,2241			  -84, 40, digital_gain),2242 2243	SOC_SINGLE("WSA_RX0 Digital Mute", CDC_WSA_RX0_RX_PATH_CTL, 4, 1, 0),2244	SOC_SINGLE("WSA_RX1 Digital Mute", CDC_WSA_RX1_RX_PATH_CTL, 4, 1, 0),2245	SOC_SINGLE("WSA_RX0_MIX Digital Mute", CDC_WSA_RX0_RX_PATH_MIX_CTL, 4,2246		   1, 0),2247	SOC_SINGLE("WSA_RX1_MIX Digital Mute", CDC_WSA_RX1_RX_PATH_MIX_CTL, 4,2248		   1, 0),2249	SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,2250		       wsa_macro_get_compander, wsa_macro_set_compander),2251	SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,2252		       wsa_macro_get_compander, wsa_macro_set_compander),2253	SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0, 1, 0,2254		       wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),2255	SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1, 1, 0,2256		       wsa_macro_get_ec_hq, wsa_macro_set_ec_hq),2257};2258 2259static const struct soc_enum rx_mux_enum =2260	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text);2261 2262static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = {2263	SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum,2264			  wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),2265	SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum,2266			  wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),2267	SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum,2268			  wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),2269	SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum,2270			  wsa_macro_rx_mux_get, wsa_macro_rx_mux_put),2271};2272 2273static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,2274				       struct snd_ctl_elem_value *ucontrol)2275{2276	struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol);2277	struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm);2278	struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;2279	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2280	u32 spk_tx_id = mixer->shift;2281	u32 dai_id = widget->shift;2282 2283	if (test_bit(spk_tx_id, &wsa->active_ch_mask[dai_id]))2284		ucontrol->value.integer.value[0] = 1;2285	else2286		ucontrol->value.integer.value[0] = 0;2287 2288	return 0;2289}2290 2291static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,2292				       struct snd_ctl_elem_value *ucontrol)2293{2294	struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol);2295	struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm);2296	struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;2297	struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);2298	u32 enable = ucontrol->value.integer.value[0];2299	u32 spk_tx_id = mixer->shift;2300	u32 dai_id = widget->shift;2301 2302	if (enable) {2303		if (spk_tx_id == WSA_MACRO_TX0 &&2304			!test_bit(WSA_MACRO_TX0,2305				&wsa->active_ch_mask[dai_id])) {2306			set_bit(WSA_MACRO_TX0,2307				&wsa->active_ch_mask[dai_id]);2308			wsa->active_ch_cnt[dai_id]++;2309		}2310		if (spk_tx_id == WSA_MACRO_TX1 &&2311			!test_bit(WSA_MACRO_TX1,2312				&wsa->active_ch_mask[dai_id])) {2313			set_bit(WSA_MACRO_TX1,2314				&wsa->active_ch_mask[dai_id]);2315			wsa->active_ch_cnt[dai_id]++;2316		}2317	} else {2318		if (spk_tx_id == WSA_MACRO_TX0 &&2319			test_bit(WSA_MACRO_TX0,2320				&wsa->active_ch_mask[dai_id])) {2321			clear_bit(WSA_MACRO_TX0,2322				&wsa->active_ch_mask[dai_id]);2323			wsa->active_ch_cnt[dai_id]--;2324		}2325		if (spk_tx_id == WSA_MACRO_TX1 &&2326			test_bit(WSA_MACRO_TX1,2327				&wsa->active_ch_mask[dai_id])) {2328			clear_bit(WSA_MACRO_TX1,2329				&wsa->active_ch_mask[dai_id]);2330			wsa->active_ch_cnt[dai_id]--;2331		}2332	}2333	snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);2334 2335	return 0;2336}2337 2338static const struct snd_kcontrol_new aif_vi_mixer[] = {2339	SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0,2340			wsa_macro_vi_feed_mixer_get,2341			wsa_macro_vi_feed_mixer_put),2342	SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0,2343			wsa_macro_vi_feed_mixer_get,2344			wsa_macro_vi_feed_mixer_put),2345};2346 2347static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = {2348	SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0,2349			    SND_SOC_NOPM, 0, 0),2350	SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0,2351			    SND_SOC_NOPM, 0, 0),2352 2353	SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0,2354			       SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0,2355			       wsa_macro_enable_vi_feedback,2356			       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),2357	SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0,2358			     SND_SOC_NOPM, 0, 0),2359 2360	SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI,2361			   0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)),2362	SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM,2363			   WSA_MACRO_EC0_MUX, 0,2364			   &rx_mix_ec0_mux, wsa_macro_enable_echo,2365			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2366	SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM,2367			   WSA_MACRO_EC1_MUX, 0,2368			   &rx_mix_ec1_mux, wsa_macro_enable_echo,2369			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2370 2371	SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0,2372			 &rx_mux[WSA_MACRO_RX0]),2373	SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0,2374			 &rx_mux[WSA_MACRO_RX1]),2375	SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0,2376			 &rx_mux[WSA_MACRO_RX_MIX0]),2377	SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0,2378			 &rx_mux[WSA_MACRO_RX_MIX1]),2379 2380	SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0),2381	SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0),2382	SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0),2383	SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),2384 2385	SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0,2386			     wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU),2387	SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM, 1, 0, NULL, 0,2388			     wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU),2389 2390	SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),2391	SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),2392 2393	SND_SOC_DAPM_MUX("WSA_RX0 INT0 SIDETONE MIX", CDC_WSA_RX0_RX_PATH_CFG1,2394			 4, 0, &rx0_sidetone_mix_mux),2395 2396	SND_SOC_DAPM_INPUT("WSA SRC0_INP"),2397	SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"),2398	SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"),2399 2400	SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM,2401			     WSA_MACRO_COMP1, 0, NULL, 0,2402			     wsa_macro_enable_interpolator,2403			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |2404			     SND_SOC_DAPM_POST_PMD),2405 2406	SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM,2407			     WSA_MACRO_COMP2, 0, NULL, 0,2408			     wsa_macro_enable_interpolator,2409			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |2410			     SND_SOC_DAPM_POST_PMD),2411 2412	SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0,2413			     NULL, 0, wsa_macro_spk_boost_event,2414			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |2415			     SND_SOC_DAPM_POST_PMD),2416 2417	SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0,2418			     NULL, 0, wsa_macro_spk_boost_event,2419			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |2420			     SND_SOC_DAPM_POST_PMD),2421 2422	SND_SOC_DAPM_INPUT("VIINPUT_WSA"),2423	SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"),2424	SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"),2425 2426	SND_SOC_DAPM_SUPPLY("WSA_RX0_CLK", CDC_WSA_RX0_RX_PATH_CTL, 5, 0, NULL, 0),2427	SND_SOC_DAPM_SUPPLY("WSA_RX1_CLK", CDC_WSA_RX1_RX_PATH_CTL, 5, 0, NULL, 0),2428	SND_SOC_DAPM_SUPPLY("WSA_RX_MIX0_CLK", CDC_WSA_RX0_RX_PATH_MIX_CTL, 5, 0, NULL, 0),2429	SND_SOC_DAPM_SUPPLY("WSA_RX_MIX1_CLK", CDC_WSA_RX1_RX_PATH_MIX_CTL, 5, 0, NULL, 0),2430	SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0,2431			      wsa_macro_mclk_event,2432			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2433};2434 2435static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets_v2_1[] = {2436	SND_SOC_DAPM_MUX("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0, &rx0_prim_inp0_mux_v2_1),2437	SND_SOC_DAPM_MUX("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0, &rx0_prim_inp1_mux_v2_1),2438	SND_SOC_DAPM_MUX("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux_v2_1),2439	SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX0,2440			   0, &rx0_mix_mux_v2_1, wsa_macro_enable_mix_path,2441			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2442	SND_SOC_DAPM_MUX("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, &rx1_prim_inp0_mux_v2_1),2443	SND_SOC_DAPM_MUX("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0, &rx1_prim_inp1_mux_v2_1),2444	SND_SOC_DAPM_MUX("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux_v2_1),2445	SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX1,2446			   0, &rx1_mix_mux_v2_1, wsa_macro_enable_mix_path,2447			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2448};2449 2450static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets_v2_5[] = {2451	SND_SOC_DAPM_MUX("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0, &rx0_prim_inp0_mux_v2_5),2452	SND_SOC_DAPM_MUX("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0, &rx0_prim_inp1_mux_v2_5),2453	SND_SOC_DAPM_MUX("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux_v2_5),2454	SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX0,2455			   0, &rx0_mix_mux_v2_5, wsa_macro_enable_mix_path,2456			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2457	SND_SOC_DAPM_MUX("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, &rx1_prim_inp0_mux_v2_5),2458	SND_SOC_DAPM_MUX("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0, &rx1_prim_inp1_mux_v2_5),2459	SND_SOC_DAPM_MUX("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux_v2_5),2460	SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX1,2461			   0, &rx1_mix_mux_v2_5, wsa_macro_enable_mix_path,2462			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2463};2464 2465static const struct snd_soc_dapm_route wsa_audio_map[] = {2466	/* VI Feedback */2467	{"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"},2468	{"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"},2469	{"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"},2470	{"WSA AIF_VI", NULL, "WSA_MCLK"},2471 2472	{"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},2473	{"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"},2474	{"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},2475	{"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"},2476	{"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"},2477	{"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"},2478	{"WSA AIF_ECHO", NULL, "WSA_MCLK"},2479 2480	{"WSA AIF1 PB", NULL, "WSA_MCLK"},2481	{"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"},2482 2483	{"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"},2484	{"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"},2485	{"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"},2486	{"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"},2487 2488	{"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},2489	{"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},2490	{"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},2491	{"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"},2492 2493	{"WSA RX0", NULL, "WSA RX0 MUX"},2494	{"WSA RX1", NULL, "WSA RX1 MUX"},2495	{"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"},2496	{"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"},2497 2498	{"WSA RX0", NULL, "WSA_RX0_CLK"},2499	{"WSA RX1", NULL, "WSA_RX1_CLK"},2500	{"WSA RX_MIX0", NULL, "WSA_RX_MIX0_CLK"},2501	{"WSA RX_MIX1", NULL, "WSA_RX_MIX1_CLK"},2502 2503	{"WSA_RX0 INP0", "RX0", "WSA RX0"},2504	{"WSA_RX0 INP0", "RX1", "WSA RX1"},2505	{"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"},2506	{"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"},2507	{"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"},2508	{"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"},2509	{"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"},2510 2511	{"WSA_RX0 INP1", "RX0", "WSA RX0"},2512	{"WSA_RX0 INP1", "RX1", "WSA RX1"},2513	{"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"},2514	{"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"},2515	{"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"},2516	{"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"},2517	{"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"},2518 2519	{"WSA_RX0 INP2", "RX0", "WSA RX0"},2520	{"WSA_RX0 INP2", "RX1", "WSA RX1"},2521	{"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"},2522	{"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"},2523	{"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"},2524	{"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"},2525	{"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"},2526 2527	{"WSA_RX0 MIX INP", "RX0", "WSA RX0"},2528	{"WSA_RX0 MIX INP", "RX1", "WSA RX1"},2529	{"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"},2530	{"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"},2531	{"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"},2532 2533	{"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"},2534	{"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"},2535	{"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"},2536	{"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"},2537	{"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"},2538 2539	{"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"},2540	{"WSA_SPK1 OUT", NULL, "WSA_MCLK"},2541 2542	{"WSA_RX1 INP0", "RX0", "WSA RX0"},2543	{"WSA_RX1 INP0", "RX1", "WSA RX1"},2544	{"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"},2545	{"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"},2546	{"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"},2547	{"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"},2548	{"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"},2549 2550	{"WSA_RX1 INP1", "RX0", "WSA RX0"},2551	{"WSA_RX1 INP1", "RX1", "WSA RX1"},2552	{"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"},2553	{"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"},2554	{"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"},2555	{"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"},2556	{"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"},2557 2558	{"WSA_RX1 INP2", "RX0", "WSA RX0"},2559	{"WSA_RX1 INP2", "RX1", "WSA RX1"},2560	{"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"},2561	{"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"},2562	{"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"},2563	{"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"},2564	{"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"},2565 2566	{"WSA_RX1 MIX INP", "RX0", "WSA RX0"},2567	{"WSA_RX1 MIX INP", "RX1", "WSA RX1"},2568	{"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"},2569	{"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"},2570	{"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"},2571 2572	{"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"},2573	{"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"},2574 2575	{"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"},2576	{"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"},2577	{"WSA_SPK2 OUT", NULL, "WSA_MCLK"},2578};2579 2580static int wsa_swrm_clock(struct wsa_macro *wsa, bool enable)2581{2582	struct regmap *regmap = wsa->regmap;2583 2584	if (enable) {2585		int ret;2586 2587		ret = clk_prepare_enable(wsa->mclk);2588		if (ret) {2589			dev_err(wsa->dev, "failed to enable mclk\n");2590			return ret;2591		}2592		wsa_macro_mclk_enable(wsa, true);2593 2594		regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,2595				   CDC_WSA_SWR_CLK_EN_MASK,2596				   CDC_WSA_SWR_CLK_ENABLE);2597 2598	} else {2599		regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,2600				   CDC_WSA_SWR_CLK_EN_MASK, 0);2601		wsa_macro_mclk_enable(wsa, false);2602		clk_disable_unprepare(wsa->mclk);2603	}2604 2605	return 0;2606}2607 2608static int wsa_macro_component_probe(struct snd_soc_component *comp)2609{2610	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(comp);2611	struct wsa_macro *wsa = snd_soc_component_get_drvdata(comp);2612	const struct snd_soc_dapm_widget *widgets;2613	unsigned int num_widgets;2614 2615	snd_soc_component_init_regmap(comp, wsa->regmap);2616 2617	wsa->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_M1P5_DB;2618 2619	/* set SPKR rate to FS_2P4_3P072 */2620	snd_soc_component_update_bits(comp, CDC_WSA_RX0_RX_PATH_CFG1,2621				CDC_WSA_RX_PATH_SPKR_RATE_MASK,2622				CDC_WSA_RX_PATH_SPKR_RATE_FS_2P4_3P072);2623 2624	snd_soc_component_update_bits(comp, CDC_WSA_RX1_RX_PATH_CFG1,2625				CDC_WSA_RX_PATH_SPKR_RATE_MASK,2626				CDC_WSA_RX_PATH_SPKR_RATE_FS_2P4_3P072);2627 2628	wsa_macro_set_spkr_mode(comp, WSA_MACRO_SPKR_MODE_1);2629 2630	switch (wsa->codec_version) {2631	case LPASS_CODEC_VERSION_1_0:2632	case LPASS_CODEC_VERSION_1_1:2633	case LPASS_CODEC_VERSION_1_2:2634	case LPASS_CODEC_VERSION_2_0:2635	case LPASS_CODEC_VERSION_2_1:2636		widgets = wsa_macro_dapm_widgets_v2_1;2637		num_widgets = ARRAY_SIZE(wsa_macro_dapm_widgets_v2_1);2638		break;2639	case LPASS_CODEC_VERSION_2_5:2640	case LPASS_CODEC_VERSION_2_6:2641	case LPASS_CODEC_VERSION_2_7:2642	case LPASS_CODEC_VERSION_2_8:2643		widgets = wsa_macro_dapm_widgets_v2_5;2644		num_widgets = ARRAY_SIZE(wsa_macro_dapm_widgets_v2_5);2645		break;2646	default:2647		return -EINVAL;2648	}2649 2650	return snd_soc_dapm_new_controls(dapm, widgets, num_widgets);2651}2652 2653static int swclk_gate_enable(struct clk_hw *hw)2654{2655	return wsa_swrm_clock(to_wsa_macro(hw), true);2656}2657 2658static void swclk_gate_disable(struct clk_hw *hw)2659{2660	wsa_swrm_clock(to_wsa_macro(hw), false);2661}2662 2663static int swclk_gate_is_enabled(struct clk_hw *hw)2664{2665	struct wsa_macro *wsa = to_wsa_macro(hw);2666	int ret, val;2667 2668	regmap_read(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, &val);2669	ret = val & BIT(0);2670 2671	return ret;2672}2673 2674static unsigned long swclk_recalc_rate(struct clk_hw *hw,2675				       unsigned long parent_rate)2676{2677	return parent_rate / 2;2678}2679 2680static const struct clk_ops swclk_gate_ops = {2681	.prepare = swclk_gate_enable,2682	.unprepare = swclk_gate_disable,2683	.is_enabled = swclk_gate_is_enabled,2684	.recalc_rate = swclk_recalc_rate,2685};2686 2687static int wsa_macro_register_mclk_output(struct wsa_macro *wsa)2688{2689	struct device *dev = wsa->dev;2690	const char *parent_clk_name;2691	struct clk_hw *hw;2692	struct clk_init_data init;2693	int ret;2694 2695	if (wsa->npl)2696		parent_clk_name = __clk_get_name(wsa->npl);2697	else2698		parent_clk_name = __clk_get_name(wsa->mclk);2699 2700	init.name = "mclk";2701	of_property_read_string(dev_of_node(dev), "clock-output-names",2702				&init.name);2703	init.ops = &swclk_gate_ops;2704	init.flags = 0;2705	init.parent_names = &parent_clk_name;2706	init.num_parents = 1;2707	wsa->hw.init = &init;2708	hw = &wsa->hw;2709	ret = clk_hw_register(wsa->dev, hw);2710	if (ret)2711		return ret;2712 2713	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);2714}2715 2716static const struct snd_soc_component_driver wsa_macro_component_drv = {2717	.name = "WSA MACRO",2718	.probe = wsa_macro_component_probe,2719	.controls = wsa_macro_snd_controls,2720	.num_controls = ARRAY_SIZE(wsa_macro_snd_controls),2721	.dapm_widgets = wsa_macro_dapm_widgets,2722	.num_dapm_widgets = ARRAY_SIZE(wsa_macro_dapm_widgets),2723	.dapm_routes = wsa_audio_map,2724	.num_dapm_routes = ARRAY_SIZE(wsa_audio_map),2725};2726 2727static int wsa_macro_probe(struct platform_device *pdev)2728{2729	struct device *dev = &pdev->dev;2730	struct wsa_macro *wsa;2731	kernel_ulong_t flags;2732	void __iomem *base;2733	int ret, def_count;2734 2735	flags = (kernel_ulong_t)device_get_match_data(dev);2736 2737	wsa = devm_kzalloc(dev, sizeof(*wsa), GFP_KERNEL);2738	if (!wsa)2739		return -ENOMEM;2740 2741	wsa->macro = devm_clk_get_optional(dev, "macro");2742	if (IS_ERR(wsa->macro))2743		return dev_err_probe(dev, PTR_ERR(wsa->macro), "unable to get macro clock\n");2744 2745	wsa->dcodec = devm_clk_get_optional(dev, "dcodec");2746	if (IS_ERR(wsa->dcodec))2747		return dev_err_probe(dev, PTR_ERR(wsa->dcodec), "unable to get dcodec clock\n");2748 2749	wsa->mclk = devm_clk_get(dev, "mclk");2750	if (IS_ERR(wsa->mclk))2751		return dev_err_probe(dev, PTR_ERR(wsa->mclk), "unable to get mclk clock\n");2752 2753	if (flags & LPASS_MACRO_FLAG_HAS_NPL_CLOCK) {2754		wsa->npl = devm_clk_get(dev, "npl");2755		if (IS_ERR(wsa->npl))2756			return dev_err_probe(dev, PTR_ERR(wsa->npl), "unable to get npl clock\n");2757	}2758 2759	wsa->fsgen = devm_clk_get(dev, "fsgen");2760	if (IS_ERR(wsa->fsgen))2761		return dev_err_probe(dev, PTR_ERR(wsa->fsgen), "unable to get fsgen clock\n");2762 2763	base = devm_platform_ioremap_resource(pdev, 0);2764	if (IS_ERR(base))2765		return PTR_ERR(base);2766 2767	wsa->codec_version = lpass_macro_get_codec_version();2768	struct reg_default *reg_defaults __free(kfree) = NULL;2769 2770	switch (wsa->codec_version) {2771	case LPASS_CODEC_VERSION_1_0:2772	case LPASS_CODEC_VERSION_1_1:2773	case LPASS_CODEC_VERSION_1_2:2774	case LPASS_CODEC_VERSION_2_0:2775	case LPASS_CODEC_VERSION_2_1:2776		wsa->reg_layout = &wsa_codec_v2_1;2777		def_count = ARRAY_SIZE(wsa_defaults) + ARRAY_SIZE(wsa_defaults_v2_1);2778		reg_defaults = kmalloc_array(def_count, sizeof(*reg_defaults),2779					     GFP_KERNEL);2780		if (!reg_defaults)2781			return -ENOMEM;2782		memcpy(&reg_defaults[0], wsa_defaults, sizeof(wsa_defaults));2783		memcpy(&reg_defaults[ARRAY_SIZE(wsa_defaults)],2784		       wsa_defaults_v2_1, sizeof(wsa_defaults_v2_1));2785		break;2786 2787	case LPASS_CODEC_VERSION_2_5:2788	case LPASS_CODEC_VERSION_2_6:2789	case LPASS_CODEC_VERSION_2_7:2790	case LPASS_CODEC_VERSION_2_8:2791		wsa->reg_layout = &wsa_codec_v2_5;2792		def_count = ARRAY_SIZE(wsa_defaults) + ARRAY_SIZE(wsa_defaults_v2_5);2793		reg_defaults = kmalloc_array(def_count, sizeof(*reg_defaults),2794					     GFP_KERNEL);2795		if (!reg_defaults)2796			return -ENOMEM;2797		memcpy(&reg_defaults[0], wsa_defaults, sizeof(wsa_defaults));2798		memcpy(&reg_defaults[ARRAY_SIZE(wsa_defaults)],2799		       wsa_defaults_v2_5, sizeof(wsa_defaults_v2_5));2800		break;2801 2802	default:2803		dev_err(dev, "Unsupported Codec version (%d)\n", wsa->codec_version);2804		return -EINVAL;2805	}2806 2807	struct regmap_config *reg_config __free(kfree) = kmemdup(&wsa_regmap_config,2808								 sizeof(*reg_config),2809								 GFP_KERNEL);2810	if (!reg_config)2811		return -ENOMEM;2812 2813	reg_config->reg_defaults = reg_defaults;2814	reg_config->num_reg_defaults = def_count;2815 2816	wsa->regmap = devm_regmap_init_mmio(dev, base, reg_config);2817	if (IS_ERR(wsa->regmap))2818		return PTR_ERR(wsa->regmap);2819 2820	dev_set_drvdata(dev, wsa);2821 2822	wsa->dev = dev;2823 2824	/* set MCLK and NPL rates */2825	clk_set_rate(wsa->mclk, WSA_MACRO_MCLK_FREQ);2826	clk_set_rate(wsa->npl, WSA_MACRO_MCLK_FREQ);2827 2828	ret = clk_prepare_enable(wsa->macro);2829	if (ret)2830		goto err;2831 2832	ret = clk_prepare_enable(wsa->dcodec);2833	if (ret)2834		goto err_dcodec;2835 2836	ret = clk_prepare_enable(wsa->mclk);2837	if (ret)2838		goto err_mclk;2839 2840	ret = clk_prepare_enable(wsa->npl);2841	if (ret)2842		goto err_npl;2843 2844	ret = clk_prepare_enable(wsa->fsgen);2845	if (ret)2846		goto err_fsgen;2847 2848	/* reset swr ip */2849	regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,2850			   CDC_WSA_SWR_RST_EN_MASK, CDC_WSA_SWR_RST_ENABLE);2851 2852	regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,2853			   CDC_WSA_SWR_CLK_EN_MASK, CDC_WSA_SWR_CLK_ENABLE);2854 2855	/* Bring out of reset */2856	regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,2857			   CDC_WSA_SWR_RST_EN_MASK, CDC_WSA_SWR_RST_DISABLE);2858 2859	ret = devm_snd_soc_register_component(dev, &wsa_macro_component_drv,2860					      wsa_macro_dai,2861					      ARRAY_SIZE(wsa_macro_dai));2862	if (ret)2863		goto err_clkout;2864 2865	pm_runtime_set_autosuspend_delay(dev, 3000);2866	pm_runtime_use_autosuspend(dev);2867	pm_runtime_mark_last_busy(dev);2868	pm_runtime_set_active(dev);2869	pm_runtime_enable(dev);2870 2871	ret = wsa_macro_register_mclk_output(wsa);2872	if (ret)2873		goto err_clkout;2874 2875	return 0;2876 2877err_clkout:2878	clk_disable_unprepare(wsa->fsgen);2879err_fsgen:2880	clk_disable_unprepare(wsa->npl);2881err_npl:2882	clk_disable_unprepare(wsa->mclk);2883err_mclk:2884	clk_disable_unprepare(wsa->dcodec);2885err_dcodec:2886	clk_disable_unprepare(wsa->macro);2887err:2888	return ret;2889 2890}2891 2892static void wsa_macro_remove(struct platform_device *pdev)2893{2894	struct wsa_macro *wsa = dev_get_drvdata(&pdev->dev);2895 2896	clk_disable_unprepare(wsa->macro);2897	clk_disable_unprepare(wsa->dcodec);2898	clk_disable_unprepare(wsa->mclk);2899	clk_disable_unprepare(wsa->npl);2900	clk_disable_unprepare(wsa->fsgen);2901}2902 2903static int __maybe_unused wsa_macro_runtime_suspend(struct device *dev)2904{2905	struct wsa_macro *wsa = dev_get_drvdata(dev);2906 2907	regcache_cache_only(wsa->regmap, true);2908	regcache_mark_dirty(wsa->regmap);2909 2910	clk_disable_unprepare(wsa->fsgen);2911	clk_disable_unprepare(wsa->npl);2912	clk_disable_unprepare(wsa->mclk);2913 2914	return 0;2915}2916 2917static int __maybe_unused wsa_macro_runtime_resume(struct device *dev)2918{2919	struct wsa_macro *wsa = dev_get_drvdata(dev);2920	int ret;2921 2922	ret = clk_prepare_enable(wsa->mclk);2923	if (ret) {2924		dev_err(dev, "unable to prepare mclk\n");2925		return ret;2926	}2927 2928	ret = clk_prepare_enable(wsa->npl);2929	if (ret) {2930		dev_err(dev, "unable to prepare mclkx2\n");2931		goto err_npl;2932	}2933 2934	ret = clk_prepare_enable(wsa->fsgen);2935	if (ret) {2936		dev_err(dev, "unable to prepare fsgen\n");2937		goto err_fsgen;2938	}2939 2940	regcache_cache_only(wsa->regmap, false);2941	regcache_sync(wsa->regmap);2942 2943	return 0;2944err_fsgen:2945	clk_disable_unprepare(wsa->npl);2946err_npl:2947	clk_disable_unprepare(wsa->mclk);2948 2949	return ret;2950}2951 2952static const struct dev_pm_ops wsa_macro_pm_ops = {2953	SET_RUNTIME_PM_OPS(wsa_macro_runtime_suspend, wsa_macro_runtime_resume, NULL)2954};2955 2956static const struct of_device_id wsa_macro_dt_match[] = {2957	{2958		.compatible = "qcom,sc7280-lpass-wsa-macro",2959		.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,2960	}, {2961		.compatible = "qcom,sm8250-lpass-wsa-macro",2962		.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,2963	}, {2964		.compatible = "qcom,sm8450-lpass-wsa-macro",2965		.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,2966	}, {2967		.compatible = "qcom,sm8550-lpass-wsa-macro",2968	}, {2969		.compatible = "qcom,sc8280xp-lpass-wsa-macro",2970		.data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK,2971	},2972	{}2973};2974MODULE_DEVICE_TABLE(of, wsa_macro_dt_match);2975 2976static struct platform_driver wsa_macro_driver = {2977	.driver = {2978		.name = "wsa_macro",2979		.of_match_table = wsa_macro_dt_match,2980		.pm = &wsa_macro_pm_ops,2981	},2982	.probe = wsa_macro_probe,2983	.remove = wsa_macro_remove,2984};2985 2986module_platform_driver(wsa_macro_driver);2987MODULE_DESCRIPTION("WSA macro driver");2988MODULE_LICENSE("GPL");2989