File Index
Files and directories
Sign in
FILE

lpass-wsa-macro.c

File preview with syntax highlighting.

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