Linux Audio

Check our new training course

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