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 293 enum { 294 WSA_MACRO_GAIN_OFFSET_M1P5_DB, 295 WSA_MACRO_GAIN_OFFSET_0_DB, 296 }; 297 enum { 298 WSA_MACRO_RX0 = 0, 299 WSA_MACRO_RX1, 300 WSA_MACRO_RX_MIX, 301 WSA_MACRO_RX_MIX0 = WSA_MACRO_RX_MIX, 302 WSA_MACRO_RX_MIX1, 303 WSA_MACRO_RX_MAX, 304 }; 305 306 enum { 307 WSA_MACRO_TX0 = 0, 308 WSA_MACRO_TX1, 309 WSA_MACRO_TX_MAX, 310 }; 311 312 enum { 313 WSA_MACRO_EC0_MUX = 0, 314 WSA_MACRO_EC1_MUX, 315 WSA_MACRO_EC_MUX_MAX, 316 }; 317 318 enum { 319 WSA_MACRO_COMP1, /* SPK_L */ 320 WSA_MACRO_COMP2, /* SPK_R */ 321 WSA_MACRO_COMP_MAX 322 }; 323 324 enum { 325 WSA_MACRO_SOFTCLIP0, /* RX0 */ 326 WSA_MACRO_SOFTCLIP1, /* RX1 */ 327 WSA_MACRO_SOFTCLIP_MAX 328 }; 329 330 enum { 331 INTn_1_INP_SEL_ZERO = 0, 332 INTn_1_INP_SEL_RX0, 333 INTn_1_INP_SEL_RX1, 334 INTn_1_INP_SEL_RX2, 335 INTn_1_INP_SEL_RX3, 336 INTn_1_INP_SEL_DEC0, 337 INTn_1_INP_SEL_DEC1, 338 }; 339 340 enum { 341 INTn_2_INP_SEL_ZERO = 0, 342 INTn_2_INP_SEL_RX0, 343 INTn_2_INP_SEL_RX1, 344 INTn_2_INP_SEL_RX2, 345 INTn_2_INP_SEL_RX3, 346 }; 347 348 struct interp_sample_rate { 349 int sample_rate; 350 int rate_val; 351 }; 352 353 static struct interp_sample_rate int_prim_sample_rate_val[] = { 354 {8000, 0x0}, /* 8K */ 355 {16000, 0x1}, /* 16K */ 356 {24000, -EINVAL},/* 24K */ 357 {32000, 0x3}, /* 32K */ 358 {48000, 0x4}, /* 48K */ 359 {96000, 0x5}, /* 96K */ 360 {192000, 0x6}, /* 192K */ 361 {384000, 0x7}, /* 384K */ 362 {44100, 0x8}, /* 44.1K */ 363 }; 364 365 static struct interp_sample_rate int_mix_sample_rate_val[] = { 366 {48000, 0x4}, /* 48K */ 367 {96000, 0x5}, /* 96K */ 368 {192000, 0x6}, /* 192K */ 369 }; 370 371 enum { 372 WSA_MACRO_AIF_INVALID = 0, 373 WSA_MACRO_AIF1_PB, 374 WSA_MACRO_AIF_MIX1_PB, 375 WSA_MACRO_AIF_VI, 376 WSA_MACRO_AIF_ECHO, 377 WSA_MACRO_MAX_DAIS, 378 }; 379 380 /** 381 * struct wsa_reg_layout - Register layout differences 382 * @rx_intx_1_mix_inp0_sel_mask: register mask for RX_INTX_1_MIX_INP0_SEL_MASK 383 * @rx_intx_1_mix_inp1_sel_mask: register mask for RX_INTX_1_MIX_INP1_SEL_MASK 384 * @rx_intx_1_mix_inp2_sel_mask: register mask for RX_INTX_1_MIX_INP2_SEL_MASK 385 * @rx_intx_2_sel_mask: register mask for RX_INTX_2_SEL_MASK 386 * @compander1_reg_offset: offset between compander registers (compander1 - compander0) 387 * @softclip0_reg_base: base address of softclip0 register 388 * @softclip1_reg_offset: offset between compander registers (softclip1 - softclip0) 389 */ 390 struct wsa_reg_layout { 391 unsigned int rx_intx_1_mix_inp0_sel_mask; 392 unsigned int rx_intx_1_mix_inp1_sel_mask; 393 unsigned int rx_intx_1_mix_inp2_sel_mask; 394 unsigned int rx_intx_2_sel_mask; 395 unsigned int compander1_reg_offset; 396 unsigned int softclip0_reg_base; 397 unsigned int softclip1_reg_offset; 398 }; 399 400 struct wsa_macro { 401 struct device *dev; 402 int comp_enabled[WSA_MACRO_COMP_MAX]; 403 int ec_hq[WSA_MACRO_RX1 + 1]; 404 u16 prim_int_users[WSA_MACRO_RX1 + 1]; 405 u16 wsa_mclk_users; 406 enum lpass_codec_version codec_version; 407 const struct wsa_reg_layout *reg_layout; 408 unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS]; 409 unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS]; 410 int rx_port_value[WSA_MACRO_RX_MAX]; 411 int ear_spkr_gain; 412 int spkr_gain_offset; 413 int spkr_mode; 414 u32 pcm_rate_vi; 415 int is_softclip_on[WSA_MACRO_SOFTCLIP_MAX]; 416 int softclip_clk_users[WSA_MACRO_SOFTCLIP_MAX]; 417 struct regmap *regmap; 418 struct clk *mclk; 419 struct clk *npl; 420 struct clk *macro; 421 struct clk *dcodec; 422 struct clk *fsgen; 423 struct clk_hw hw; 424 }; 425 #define to_wsa_macro(_hw) container_of(_hw, struct wsa_macro, hw) 426 427 static const struct wsa_reg_layout wsa_codec_v2_1 = { 428 .rx_intx_1_mix_inp0_sel_mask = GENMASK(2, 0), 429 .rx_intx_1_mix_inp1_sel_mask = GENMASK(5, 3), 430 .rx_intx_1_mix_inp2_sel_mask = GENMASK(5, 3), 431 .rx_intx_2_sel_mask = GENMASK(2, 0), 432 .compander1_reg_offset = 0x40, 433 .softclip0_reg_base = 0x600, 434 .softclip1_reg_offset = 0x40, 435 }; 436 437 static const struct wsa_reg_layout wsa_codec_v2_5 = { 438 .rx_intx_1_mix_inp0_sel_mask = GENMASK(3, 0), 439 .rx_intx_1_mix_inp1_sel_mask = GENMASK(7, 4), 440 .rx_intx_1_mix_inp2_sel_mask = GENMASK(7, 4), 441 .rx_intx_2_sel_mask = GENMASK(3, 0), 442 .compander1_reg_offset = 0x60, 443 .softclip0_reg_base = 0x640, 444 .softclip1_reg_offset = 0x20, 445 }; 446 447 static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); 448 449 static const char *const rx_text_v2_1[] = { 450 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1" 451 }; 452 453 static const char *const rx_text_v2_5[] = { 454 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "RX4", "RX5", "RX6", "RX7", "RX8", "DEC0", "DEC1" 455 }; 456 457 static const char *const rx_mix_text_v2_1[] = { 458 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1" 459 }; 460 461 static const char *const rx_mix_text_v2_5[] = { 462 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "RX4", "RX5", "RX6", "RX7", "RX8" 463 }; 464 465 static const char *const rx_mix_ec_text[] = { 466 "ZERO", "RX_MIX_TX0", "RX_MIX_TX1" 467 }; 468 469 static const char *const rx_mux_text[] = { 470 "ZERO", "AIF1_PB", "AIF_MIX1_PB" 471 }; 472 473 static const char *const rx_sidetone_mix_text[] = { 474 "ZERO", "SRC0" 475 }; 476 477 static 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 482 static SOC_ENUM_SINGLE_EXT_DECL(wsa_macro_ear_spkr_pa_gain_enum, 483 wsa_macro_ear_spkr_pa_gain_text); 484 485 /* RX INT0 */ 486 static 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 490 static 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 494 static 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 498 static 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 502 static 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 506 static 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 510 static 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 514 static 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 518 static const struct soc_enum rx0_sidetone_mix_enum = 519 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text); 520 521 static 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 524 static 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 527 static 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 530 static 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 533 static 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 536 static 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 539 static 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 542 static 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 545 static 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 */ 549 static 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 553 static 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 557 static 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 561 static 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 565 static 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 569 static 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 573 static 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 577 static 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 581 static 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 584 static 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 587 static 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 590 static 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 593 static 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 596 static 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 599 static 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 602 static 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 605 static 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 609 static 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 613 static const struct snd_kcontrol_new rx_mix_ec0_mux = 614 SOC_DAPM_ENUM("WSA RX_MIX EC0_Mux", rx_mix_ec0_enum); 615 616 static const struct snd_kcontrol_new rx_mix_ec1_mux = 617 SOC_DAPM_ENUM("WSA RX_MIX EC1_Mux", rx_mix_ec1_enum); 618 619 static 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 730 static 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 753 static 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 803 static 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 816 static 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 836 static 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 883 static 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 997 static 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 1008 static 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 1018 static 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 1028 static 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 1058 static 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 1068 static 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 1078 static 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 1106 static 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 */ 1128 int 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 } 1154 EXPORT_SYMBOL(wsa_macro_set_spkr_mode); 1155 1156 static 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 if ((int_1_mix1_inp < WSA_MACRO_RX0) || (int_1_mix1_inp > WSA_MACRO_RX_MIX1)) { 1171 dev_err(component->dev, "%s: Invalid RX port, Dai ID is %d\n", 1172 __func__, dai->id); 1173 return -EINVAL; 1174 } 1175 1176 int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0; 1177 1178 /* 1179 * Loop through all interpolator MUX inputs and find out 1180 * to which interpolator input, the cdc_dma rx port 1181 * is connected 1182 */ 1183 for (j = 0; j < NUM_INTERPOLATORS; j++) { 1184 int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET; 1185 inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0, 1186 wsa->reg_layout->rx_intx_1_mix_inp0_sel_mask); 1187 inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0, 1188 wsa->reg_layout->rx_intx_1_mix_inp1_sel_mask); 1189 inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1, 1190 wsa->reg_layout->rx_intx_1_mix_inp2_sel_mask); 1191 1192 if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || 1193 (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || 1194 (inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) { 1195 int_fs_reg = CDC_WSA_RX0_RX_PATH_CTL + 1196 WSA_MACRO_RX_PATH_OFFSET * j; 1197 /* sample_rate is in Hz */ 1198 snd_soc_component_update_bits(component, int_fs_reg, 1199 WSA_MACRO_FS_RATE_MASK, 1200 int_prim_fs_rate_reg_val); 1201 } 1202 int_mux_cfg0 += WSA_MACRO_MUX_CFG_OFFSET; 1203 } 1204 } 1205 1206 return 0; 1207 } 1208 1209 static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai, 1210 u8 int_mix_fs_rate_reg_val, 1211 u32 sample_rate) 1212 { 1213 u8 int_2_inp; 1214 u32 j, port; 1215 u16 int_mux_cfg1, int_fs_reg; 1216 u8 int_mux_cfg1_val; 1217 struct snd_soc_component *component = dai->component; 1218 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1219 1220 for_each_set_bit(port, &wsa->active_ch_mask[dai->id], WSA_MACRO_RX_MAX) { 1221 int_2_inp = port; 1222 if ((int_2_inp < WSA_MACRO_RX0) || (int_2_inp > WSA_MACRO_RX_MIX1)) { 1223 dev_err(component->dev, "%s: Invalid RX port, Dai ID is %d\n", 1224 __func__, dai->id); 1225 return -EINVAL; 1226 } 1227 1228 int_mux_cfg1 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG1; 1229 for (j = 0; j < NUM_INTERPOLATORS; j++) { 1230 int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1, 1231 wsa->reg_layout->rx_intx_2_sel_mask); 1232 1233 if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) { 1234 int_fs_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL + 1235 WSA_MACRO_RX_PATH_OFFSET * j; 1236 1237 snd_soc_component_update_bits(component, 1238 int_fs_reg, 1239 WSA_MACRO_FS_RATE_MASK, 1240 int_mix_fs_rate_reg_val); 1241 } 1242 int_mux_cfg1 += WSA_MACRO_MUX_CFG_OFFSET; 1243 } 1244 } 1245 return 0; 1246 } 1247 1248 static int wsa_macro_set_interpolator_rate(struct snd_soc_dai *dai, 1249 u32 sample_rate) 1250 { 1251 int rate_val = 0; 1252 int i, ret; 1253 1254 /* set mixing path rate */ 1255 for (i = 0; i < ARRAY_SIZE(int_mix_sample_rate_val); i++) { 1256 if (sample_rate == int_mix_sample_rate_val[i].sample_rate) { 1257 rate_val = int_mix_sample_rate_val[i].rate_val; 1258 break; 1259 } 1260 } 1261 if ((i == ARRAY_SIZE(int_mix_sample_rate_val)) || (rate_val < 0)) 1262 goto prim_rate; 1263 1264 ret = wsa_macro_set_mix_interpolator_rate(dai, (u8) rate_val, sample_rate); 1265 if (ret < 0) 1266 return ret; 1267 prim_rate: 1268 /* set primary path sample rate */ 1269 for (i = 0; i < ARRAY_SIZE(int_prim_sample_rate_val); i++) { 1270 if (sample_rate == int_prim_sample_rate_val[i].sample_rate) { 1271 rate_val = int_prim_sample_rate_val[i].rate_val; 1272 break; 1273 } 1274 } 1275 if ((i == ARRAY_SIZE(int_prim_sample_rate_val)) || (rate_val < 0)) 1276 return -EINVAL; 1277 1278 ret = wsa_macro_set_prim_interpolator_rate(dai, (u8) rate_val, sample_rate); 1279 1280 return ret; 1281 } 1282 1283 static int wsa_macro_hw_params(struct snd_pcm_substream *substream, 1284 struct snd_pcm_hw_params *params, 1285 struct snd_soc_dai *dai) 1286 { 1287 struct snd_soc_component *component = dai->component; 1288 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1289 int ret; 1290 1291 switch (substream->stream) { 1292 case SNDRV_PCM_STREAM_PLAYBACK: 1293 ret = wsa_macro_set_interpolator_rate(dai, params_rate(params)); 1294 if (ret) { 1295 dev_err(component->dev, 1296 "%s: cannot set sample rate: %u\n", 1297 __func__, params_rate(params)); 1298 return ret; 1299 } 1300 break; 1301 case SNDRV_PCM_STREAM_CAPTURE: 1302 if (dai->id == WSA_MACRO_AIF_VI) 1303 wsa->pcm_rate_vi = params_rate(params); 1304 1305 break; 1306 default: 1307 break; 1308 } 1309 return 0; 1310 } 1311 1312 static int wsa_macro_get_channel_map(const struct snd_soc_dai *dai, 1313 unsigned int *tx_num, unsigned int *tx_slot, 1314 unsigned int *rx_num, unsigned int *rx_slot) 1315 { 1316 struct snd_soc_component *component = dai->component; 1317 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1318 u16 val, mask = 0, cnt = 0, temp; 1319 1320 switch (dai->id) { 1321 case WSA_MACRO_AIF_VI: 1322 *tx_slot = wsa->active_ch_mask[dai->id]; 1323 *tx_num = wsa->active_ch_cnt[dai->id]; 1324 break; 1325 case WSA_MACRO_AIF1_PB: 1326 case WSA_MACRO_AIF_MIX1_PB: 1327 for_each_set_bit(temp, &wsa->active_ch_mask[dai->id], 1328 WSA_MACRO_RX_MAX) { 1329 mask |= (1 << temp); 1330 if (++cnt == WSA_MACRO_MAX_DMA_CH_PER_PORT) 1331 break; 1332 } 1333 if (mask & 0x0C) 1334 mask = mask >> 0x2; 1335 *rx_slot = mask; 1336 *rx_num = cnt; 1337 break; 1338 case WSA_MACRO_AIF_ECHO: 1339 val = snd_soc_component_read(component, CDC_WSA_RX_INP_MUX_RX_MIX_CFG0); 1340 if (val & WSA_MACRO_EC_MIX_TX1_MASK) { 1341 mask |= 0x2; 1342 cnt++; 1343 } 1344 if (val & WSA_MACRO_EC_MIX_TX0_MASK) { 1345 mask |= 0x1; 1346 cnt++; 1347 } 1348 *tx_slot = mask; 1349 *tx_num = cnt; 1350 break; 1351 default: 1352 dev_err(component->dev, "%s: Invalid AIF\n", __func__); 1353 break; 1354 } 1355 return 0; 1356 } 1357 1358 static const struct snd_soc_dai_ops wsa_macro_dai_ops = { 1359 .hw_params = wsa_macro_hw_params, 1360 .get_channel_map = wsa_macro_get_channel_map, 1361 }; 1362 1363 static struct snd_soc_dai_driver wsa_macro_dai[] = { 1364 { 1365 .name = "wsa_macro_rx1", 1366 .id = WSA_MACRO_AIF1_PB, 1367 .playback = { 1368 .stream_name = "WSA_AIF1 Playback", 1369 .rates = WSA_MACRO_RX_RATES, 1370 .formats = WSA_MACRO_RX_FORMATS, 1371 .rate_max = 384000, 1372 .rate_min = 8000, 1373 .channels_min = 1, 1374 .channels_max = 2, 1375 }, 1376 .ops = &wsa_macro_dai_ops, 1377 }, 1378 { 1379 .name = "wsa_macro_rx_mix", 1380 .id = WSA_MACRO_AIF_MIX1_PB, 1381 .playback = { 1382 .stream_name = "WSA_AIF_MIX1 Playback", 1383 .rates = WSA_MACRO_RX_MIX_RATES, 1384 .formats = WSA_MACRO_RX_FORMATS, 1385 .rate_max = 192000, 1386 .rate_min = 48000, 1387 .channels_min = 1, 1388 .channels_max = 2, 1389 }, 1390 .ops = &wsa_macro_dai_ops, 1391 }, 1392 { 1393 .name = "wsa_macro_vifeedback", 1394 .id = WSA_MACRO_AIF_VI, 1395 .capture = { 1396 .stream_name = "WSA_AIF_VI Capture", 1397 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000, 1398 .formats = WSA_MACRO_RX_FORMATS, 1399 .rate_max = 48000, 1400 .rate_min = 8000, 1401 .channels_min = 1, 1402 .channels_max = 4, 1403 }, 1404 .ops = &wsa_macro_dai_ops, 1405 }, 1406 { 1407 .name = "wsa_macro_echo", 1408 .id = WSA_MACRO_AIF_ECHO, 1409 .capture = { 1410 .stream_name = "WSA_AIF_ECHO Capture", 1411 .rates = WSA_MACRO_ECHO_RATES, 1412 .formats = WSA_MACRO_ECHO_FORMATS, 1413 .rate_max = 48000, 1414 .rate_min = 8000, 1415 .channels_min = 1, 1416 .channels_max = 2, 1417 }, 1418 .ops = &wsa_macro_dai_ops, 1419 }, 1420 }; 1421 1422 static void wsa_macro_mclk_enable(struct wsa_macro *wsa, bool mclk_enable) 1423 { 1424 struct regmap *regmap = wsa->regmap; 1425 1426 if (mclk_enable) { 1427 if (wsa->wsa_mclk_users == 0) { 1428 regcache_mark_dirty(regmap); 1429 regcache_sync(regmap); 1430 /* 9.6MHz MCLK, set value 0x00 if other frequency */ 1431 regmap_update_bits(regmap, CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01); 1432 regmap_update_bits(regmap, 1433 CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL, 1434 CDC_WSA_MCLK_EN_MASK, 1435 CDC_WSA_MCLK_ENABLE); 1436 regmap_update_bits(regmap, 1437 CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL, 1438 CDC_WSA_FS_CNT_EN_MASK, 1439 CDC_WSA_FS_CNT_ENABLE); 1440 } 1441 wsa->wsa_mclk_users++; 1442 } else { 1443 if (wsa->wsa_mclk_users <= 0) { 1444 dev_err(wsa->dev, "clock already disabled\n"); 1445 wsa->wsa_mclk_users = 0; 1446 return; 1447 } 1448 wsa->wsa_mclk_users--; 1449 if (wsa->wsa_mclk_users == 0) { 1450 regmap_update_bits(regmap, 1451 CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL, 1452 CDC_WSA_FS_CNT_EN_MASK, 1453 CDC_WSA_FS_CNT_DISABLE); 1454 regmap_update_bits(regmap, 1455 CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL, 1456 CDC_WSA_MCLK_EN_MASK, 1457 CDC_WSA_MCLK_DISABLE); 1458 } 1459 } 1460 } 1461 1462 static void wsa_macro_enable_disable_vi_sense(struct snd_soc_component *component, bool enable, 1463 u32 tx_reg0, u32 tx_reg1, u32 val) 1464 { 1465 if (enable) { 1466 /* Enable V&I sensing */ 1467 snd_soc_component_update_bits(component, tx_reg0, 1468 CDC_WSA_TX_SPKR_PROT_RESET_MASK, 1469 CDC_WSA_TX_SPKR_PROT_RESET); 1470 snd_soc_component_update_bits(component, tx_reg1, 1471 CDC_WSA_TX_SPKR_PROT_RESET_MASK, 1472 CDC_WSA_TX_SPKR_PROT_RESET); 1473 snd_soc_component_update_bits(component, tx_reg0, 1474 CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK, 1475 val); 1476 snd_soc_component_update_bits(component, tx_reg1, 1477 CDC_WSA_TX_SPKR_PROT_PCM_RATE_MASK, 1478 val); 1479 snd_soc_component_update_bits(component, tx_reg0, 1480 CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK, 1481 CDC_WSA_TX_SPKR_PROT_CLK_ENABLE); 1482 snd_soc_component_update_bits(component, tx_reg1, 1483 CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK, 1484 CDC_WSA_TX_SPKR_PROT_CLK_ENABLE); 1485 snd_soc_component_update_bits(component, tx_reg0, 1486 CDC_WSA_TX_SPKR_PROT_RESET_MASK, 1487 CDC_WSA_TX_SPKR_PROT_NO_RESET); 1488 snd_soc_component_update_bits(component, tx_reg1, 1489 CDC_WSA_TX_SPKR_PROT_RESET_MASK, 1490 CDC_WSA_TX_SPKR_PROT_NO_RESET); 1491 } else { 1492 snd_soc_component_update_bits(component, tx_reg0, 1493 CDC_WSA_TX_SPKR_PROT_RESET_MASK, 1494 CDC_WSA_TX_SPKR_PROT_RESET); 1495 snd_soc_component_update_bits(component, tx_reg1, 1496 CDC_WSA_TX_SPKR_PROT_RESET_MASK, 1497 CDC_WSA_TX_SPKR_PROT_RESET); 1498 snd_soc_component_update_bits(component, tx_reg0, 1499 CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK, 1500 CDC_WSA_TX_SPKR_PROT_CLK_DISABLE); 1501 snd_soc_component_update_bits(component, tx_reg1, 1502 CDC_WSA_TX_SPKR_PROT_CLK_EN_MASK, 1503 CDC_WSA_TX_SPKR_PROT_CLK_DISABLE); 1504 } 1505 } 1506 1507 static void wsa_macro_enable_disable_vi_feedback(struct snd_soc_component *component, 1508 bool enable, u32 rate) 1509 { 1510 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1511 1512 if (test_bit(WSA_MACRO_TX0, &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) 1513 wsa_macro_enable_disable_vi_sense(component, enable, 1514 CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 1515 CDC_WSA_TX1_SPKR_PROT_PATH_CTL, rate); 1516 1517 if (test_bit(WSA_MACRO_TX1, &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) 1518 wsa_macro_enable_disable_vi_sense(component, enable, 1519 CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 1520 CDC_WSA_TX3_SPKR_PROT_PATH_CTL, rate); 1521 } 1522 1523 static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w, 1524 struct snd_kcontrol *kcontrol, 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 1529 wsa_macro_mclk_enable(wsa, event == SND_SOC_DAPM_PRE_PMU); 1530 return 0; 1531 } 1532 1533 static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w, 1534 struct snd_kcontrol *kcontrol, 1535 int event) 1536 { 1537 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 1538 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1539 u32 rate_val; 1540 1541 switch (wsa->pcm_rate_vi) { 1542 case 8000: 1543 rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K; 1544 break; 1545 case 16000: 1546 rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_16K; 1547 break; 1548 case 24000: 1549 rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_24K; 1550 break; 1551 case 32000: 1552 rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_32K; 1553 break; 1554 case 48000: 1555 rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_48K; 1556 break; 1557 default: 1558 rate_val = CDC_WSA_TX_SPKR_PROT_PCM_RATE_8K; 1559 break; 1560 } 1561 1562 switch (event) { 1563 case SND_SOC_DAPM_POST_PMU: 1564 /* Enable V&I sensing */ 1565 wsa_macro_enable_disable_vi_feedback(component, true, rate_val); 1566 break; 1567 case SND_SOC_DAPM_POST_PMD: 1568 /* Disable V&I sensing */ 1569 wsa_macro_enable_disable_vi_feedback(component, false, rate_val); 1570 break; 1571 } 1572 1573 return 0; 1574 } 1575 1576 static int wsa_macro_enable_mix_path(struct snd_soc_dapm_widget *w, 1577 struct snd_kcontrol *kcontrol, int event) 1578 { 1579 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 1580 u16 path_reg, gain_reg; 1581 int val; 1582 1583 switch (w->shift) { 1584 case WSA_MACRO_RX_MIX0: 1585 path_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL; 1586 gain_reg = CDC_WSA_RX0_RX_VOL_MIX_CTL; 1587 break; 1588 case WSA_MACRO_RX_MIX1: 1589 path_reg = CDC_WSA_RX1_RX_PATH_MIX_CTL; 1590 gain_reg = CDC_WSA_RX1_RX_VOL_MIX_CTL; 1591 break; 1592 default: 1593 return 0; 1594 } 1595 1596 switch (event) { 1597 case SND_SOC_DAPM_POST_PMU: 1598 val = snd_soc_component_read(component, gain_reg); 1599 snd_soc_component_write(component, gain_reg, val); 1600 break; 1601 case SND_SOC_DAPM_POST_PMD: 1602 snd_soc_component_update_bits(component, path_reg, 1603 CDC_WSA_RX_PATH_MIX_CLK_EN_MASK, 1604 CDC_WSA_RX_PATH_MIX_CLK_DISABLE); 1605 break; 1606 } 1607 1608 return 0; 1609 } 1610 1611 static void wsa_macro_hd2_control(struct snd_soc_component *component, 1612 u16 reg, int event) 1613 { 1614 u16 hd2_scale_reg; 1615 u16 hd2_enable_reg; 1616 1617 if (reg == CDC_WSA_RX0_RX_PATH_CTL) { 1618 hd2_scale_reg = CDC_WSA_RX0_RX_PATH_SEC3; 1619 hd2_enable_reg = CDC_WSA_RX0_RX_PATH_CFG0; 1620 } 1621 if (reg == CDC_WSA_RX1_RX_PATH_CTL) { 1622 hd2_scale_reg = CDC_WSA_RX1_RX_PATH_SEC3; 1623 hd2_enable_reg = CDC_WSA_RX1_RX_PATH_CFG0; 1624 } 1625 1626 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { 1627 snd_soc_component_update_bits(component, hd2_scale_reg, 1628 CDC_WSA_RX_PATH_HD2_ALPHA_MASK, 1629 0x10); 1630 snd_soc_component_update_bits(component, hd2_scale_reg, 1631 CDC_WSA_RX_PATH_HD2_SCALE_MASK, 1632 0x1); 1633 snd_soc_component_update_bits(component, hd2_enable_reg, 1634 CDC_WSA_RX_PATH_HD2_EN_MASK, 1635 CDC_WSA_RX_PATH_HD2_ENABLE); 1636 } 1637 1638 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { 1639 snd_soc_component_update_bits(component, hd2_enable_reg, 1640 CDC_WSA_RX_PATH_HD2_EN_MASK, 0); 1641 snd_soc_component_update_bits(component, hd2_scale_reg, 1642 CDC_WSA_RX_PATH_HD2_SCALE_MASK, 1643 0); 1644 snd_soc_component_update_bits(component, hd2_scale_reg, 1645 CDC_WSA_RX_PATH_HD2_ALPHA_MASK, 1646 0); 1647 } 1648 } 1649 1650 static int wsa_macro_config_compander(struct snd_soc_component *component, 1651 int comp, int event) 1652 { 1653 u16 comp_ctl0_reg, rx_path_cfg0_reg; 1654 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1655 1656 if (!wsa->comp_enabled[comp]) 1657 return 0; 1658 1659 comp_ctl0_reg = CDC_WSA_COMPANDER0_CTL0 + 1660 (comp * wsa->reg_layout->compander1_reg_offset); 1661 rx_path_cfg0_reg = CDC_WSA_RX0_RX_PATH_CFG0 + 1662 (comp * WSA_MACRO_RX_PATH_OFFSET); 1663 1664 if (SND_SOC_DAPM_EVENT_ON(event)) { 1665 /* Enable Compander Clock */ 1666 snd_soc_component_update_bits(component, comp_ctl0_reg, 1667 CDC_WSA_COMPANDER_CLK_EN_MASK, 1668 CDC_WSA_COMPANDER_CLK_ENABLE); 1669 snd_soc_component_update_bits(component, comp_ctl0_reg, 1670 CDC_WSA_COMPANDER_SOFT_RST_MASK, 1671 CDC_WSA_COMPANDER_SOFT_RST_ENABLE); 1672 snd_soc_component_update_bits(component, comp_ctl0_reg, 1673 CDC_WSA_COMPANDER_SOFT_RST_MASK, 1674 0); 1675 snd_soc_component_update_bits(component, rx_path_cfg0_reg, 1676 CDC_WSA_RX_PATH_COMP_EN_MASK, 1677 CDC_WSA_RX_PATH_COMP_ENABLE); 1678 } 1679 1680 if (SND_SOC_DAPM_EVENT_OFF(event)) { 1681 snd_soc_component_update_bits(component, comp_ctl0_reg, 1682 CDC_WSA_COMPANDER_HALT_MASK, 1683 CDC_WSA_COMPANDER_HALT); 1684 snd_soc_component_update_bits(component, rx_path_cfg0_reg, 1685 CDC_WSA_RX_PATH_COMP_EN_MASK, 0); 1686 snd_soc_component_update_bits(component, comp_ctl0_reg, 1687 CDC_WSA_COMPANDER_SOFT_RST_MASK, 1688 CDC_WSA_COMPANDER_SOFT_RST_ENABLE); 1689 snd_soc_component_update_bits(component, comp_ctl0_reg, 1690 CDC_WSA_COMPANDER_SOFT_RST_MASK, 1691 0); 1692 snd_soc_component_update_bits(component, comp_ctl0_reg, 1693 CDC_WSA_COMPANDER_CLK_EN_MASK, 0); 1694 snd_soc_component_update_bits(component, comp_ctl0_reg, 1695 CDC_WSA_COMPANDER_HALT_MASK, 0); 1696 } 1697 1698 return 0; 1699 } 1700 1701 static void wsa_macro_enable_softclip_clk(struct snd_soc_component *component, 1702 struct wsa_macro *wsa, 1703 int path, 1704 bool enable) 1705 { 1706 u16 softclip_clk_reg = wsa->reg_layout->softclip0_reg_base + 1707 (path * wsa->reg_layout->softclip1_reg_offset); 1708 u8 softclip_mux_mask = (1 << path); 1709 u8 softclip_mux_value = (1 << path); 1710 1711 if (enable) { 1712 if (wsa->softclip_clk_users[path] == 0) { 1713 snd_soc_component_update_bits(component, 1714 softclip_clk_reg, 1715 CDC_WSA_SOFTCLIP_CLK_EN_MASK, 1716 CDC_WSA_SOFTCLIP_CLK_ENABLE); 1717 snd_soc_component_update_bits(component, 1718 CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, 1719 softclip_mux_mask, softclip_mux_value); 1720 } 1721 wsa->softclip_clk_users[path]++; 1722 } else { 1723 wsa->softclip_clk_users[path]--; 1724 if (wsa->softclip_clk_users[path] == 0) { 1725 snd_soc_component_update_bits(component, 1726 softclip_clk_reg, 1727 CDC_WSA_SOFTCLIP_CLK_EN_MASK, 1728 0); 1729 snd_soc_component_update_bits(component, 1730 CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, 1731 softclip_mux_mask, 0x00); 1732 } 1733 } 1734 } 1735 1736 static int wsa_macro_config_softclip(struct snd_soc_component *component, 1737 int path, int event) 1738 { 1739 u16 softclip_ctrl_reg; 1740 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1741 int softclip_path = 0; 1742 1743 if (path == WSA_MACRO_COMP1) 1744 softclip_path = WSA_MACRO_SOFTCLIP0; 1745 else if (path == WSA_MACRO_COMP2) 1746 softclip_path = WSA_MACRO_SOFTCLIP1; 1747 1748 if (!wsa->is_softclip_on[softclip_path]) 1749 return 0; 1750 1751 softclip_ctrl_reg = CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL + 1752 (softclip_path * wsa->reg_layout->softclip1_reg_offset); 1753 1754 if (SND_SOC_DAPM_EVENT_ON(event)) { 1755 /* Enable Softclip clock and mux */ 1756 wsa_macro_enable_softclip_clk(component, wsa, softclip_path, 1757 true); 1758 /* Enable Softclip control */ 1759 snd_soc_component_update_bits(component, softclip_ctrl_reg, 1760 CDC_WSA_SOFTCLIP_EN_MASK, 1761 CDC_WSA_SOFTCLIP_ENABLE); 1762 } 1763 1764 if (SND_SOC_DAPM_EVENT_OFF(event)) { 1765 snd_soc_component_update_bits(component, softclip_ctrl_reg, 1766 CDC_WSA_SOFTCLIP_EN_MASK, 0); 1767 wsa_macro_enable_softclip_clk(component, wsa, softclip_path, 1768 false); 1769 } 1770 1771 return 0; 1772 } 1773 1774 static bool wsa_macro_adie_lb(struct snd_soc_component *component, 1775 int interp_idx) 1776 { 1777 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1778 u16 int_mux_cfg0, int_mux_cfg1; 1779 u8 int_n_inp0, int_n_inp1, int_n_inp2; 1780 1781 int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8; 1782 int_mux_cfg1 = int_mux_cfg0 + 4; 1783 1784 int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0, 1785 wsa->reg_layout->rx_intx_1_mix_inp0_sel_mask); 1786 if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || 1787 int_n_inp0 == INTn_1_INP_SEL_DEC1) 1788 return true; 1789 1790 int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0, 1791 wsa->reg_layout->rx_intx_1_mix_inp1_sel_mask); 1792 if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || 1793 int_n_inp1 == INTn_1_INP_SEL_DEC1) 1794 return true; 1795 1796 int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1, 1797 wsa->reg_layout->rx_intx_1_mix_inp2_sel_mask); 1798 if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || 1799 int_n_inp2 == INTn_1_INP_SEL_DEC1) 1800 return true; 1801 1802 return false; 1803 } 1804 1805 static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w, 1806 struct snd_kcontrol *kcontrol, 1807 int event) 1808 { 1809 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 1810 u16 reg; 1811 1812 reg = CDC_WSA_RX0_RX_PATH_CTL + WSA_MACRO_RX_PATH_OFFSET * w->shift; 1813 switch (event) { 1814 case SND_SOC_DAPM_PRE_PMU: 1815 if (wsa_macro_adie_lb(component, w->shift)) { 1816 snd_soc_component_update_bits(component, reg, 1817 CDC_WSA_RX_PATH_CLK_EN_MASK, 1818 CDC_WSA_RX_PATH_CLK_ENABLE); 1819 } 1820 break; 1821 default: 1822 break; 1823 } 1824 return 0; 1825 } 1826 1827 static int wsa_macro_interp_get_primary_reg(u16 reg, u16 *ind) 1828 { 1829 u16 prim_int_reg = 0; 1830 1831 switch (reg) { 1832 case CDC_WSA_RX0_RX_PATH_CTL: 1833 case CDC_WSA_RX0_RX_PATH_MIX_CTL: 1834 prim_int_reg = CDC_WSA_RX0_RX_PATH_CTL; 1835 *ind = 0; 1836 break; 1837 case CDC_WSA_RX1_RX_PATH_CTL: 1838 case CDC_WSA_RX1_RX_PATH_MIX_CTL: 1839 prim_int_reg = CDC_WSA_RX1_RX_PATH_CTL; 1840 *ind = 1; 1841 break; 1842 } 1843 1844 return prim_int_reg; 1845 } 1846 1847 static int wsa_macro_enable_prim_interpolator(struct snd_soc_component *component, 1848 u16 reg, int event) 1849 { 1850 u16 prim_int_reg; 1851 u16 ind = 0; 1852 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1853 1854 prim_int_reg = wsa_macro_interp_get_primary_reg(reg, &ind); 1855 1856 switch (event) { 1857 case SND_SOC_DAPM_PRE_PMU: 1858 wsa->prim_int_users[ind]++; 1859 if (wsa->prim_int_users[ind] == 1) { 1860 snd_soc_component_update_bits(component, 1861 prim_int_reg + WSA_MACRO_RX_PATH_CFG3_OFFSET, 1862 CDC_WSA_RX_DC_DCOEFF_MASK, 1863 0x3); 1864 snd_soc_component_update_bits(component, prim_int_reg, 1865 CDC_WSA_RX_PATH_PGA_MUTE_EN_MASK, 1866 CDC_WSA_RX_PATH_PGA_MUTE_ENABLE); 1867 wsa_macro_hd2_control(component, prim_int_reg, event); 1868 snd_soc_component_update_bits(component, 1869 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET, 1870 CDC_WSA_RX_DSMDEM_CLK_EN_MASK, 1871 CDC_WSA_RX_DSMDEM_CLK_ENABLE); 1872 } 1873 if ((reg != prim_int_reg) && 1874 ((snd_soc_component_read( 1875 component, prim_int_reg)) & 0x10)) 1876 snd_soc_component_update_bits(component, reg, 1877 0x10, 0x10); 1878 break; 1879 case SND_SOC_DAPM_POST_PMD: 1880 wsa->prim_int_users[ind]--; 1881 if (wsa->prim_int_users[ind] == 0) { 1882 snd_soc_component_update_bits(component, 1883 prim_int_reg + WSA_MACRO_RX_PATH_DSMDEM_OFFSET, 1884 CDC_WSA_RX_DSMDEM_CLK_EN_MASK, 0); 1885 wsa_macro_hd2_control(component, prim_int_reg, event); 1886 } 1887 break; 1888 } 1889 1890 return 0; 1891 } 1892 1893 static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component, 1894 struct wsa_macro *wsa, 1895 int event, int gain_reg) 1896 { 1897 int comp_gain_offset, val; 1898 1899 switch (wsa->spkr_mode) { 1900 /* Compander gain in WSA_MACRO_SPKR_MODE1 case is 12 dB */ 1901 case WSA_MACRO_SPKR_MODE_1: 1902 comp_gain_offset = -12; 1903 break; 1904 /* Default case compander gain is 15 dB */ 1905 default: 1906 comp_gain_offset = -15; 1907 break; 1908 } 1909 1910 switch (event) { 1911 case SND_SOC_DAPM_POST_PMU: 1912 /* Apply ear spkr gain only if compander is enabled */ 1913 if (wsa->comp_enabled[WSA_MACRO_COMP1] && 1914 (gain_reg == CDC_WSA_RX0_RX_VOL_CTL) && 1915 (wsa->ear_spkr_gain != 0)) { 1916 /* For example, val is -8(-12+5-1) for 4dB of gain */ 1917 val = comp_gain_offset + wsa->ear_spkr_gain - 1; 1918 snd_soc_component_write(component, gain_reg, val); 1919 } 1920 break; 1921 case SND_SOC_DAPM_POST_PMD: 1922 /* 1923 * Reset RX0 volume to 0 dB if compander is enabled and 1924 * ear_spkr_gain is non-zero. 1925 */ 1926 if (wsa->comp_enabled[WSA_MACRO_COMP1] && 1927 (gain_reg == CDC_WSA_RX0_RX_VOL_CTL) && 1928 (wsa->ear_spkr_gain != 0)) { 1929 snd_soc_component_write(component, gain_reg, 0x0); 1930 } 1931 break; 1932 } 1933 1934 return 0; 1935 } 1936 1937 static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, 1938 struct snd_kcontrol *kcontrol, 1939 int event) 1940 { 1941 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 1942 u16 gain_reg; 1943 u16 reg; 1944 int val; 1945 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1946 1947 if (w->shift == WSA_MACRO_COMP1) { 1948 reg = CDC_WSA_RX0_RX_PATH_CTL; 1949 gain_reg = CDC_WSA_RX0_RX_VOL_CTL; 1950 } else if (w->shift == WSA_MACRO_COMP2) { 1951 reg = CDC_WSA_RX1_RX_PATH_CTL; 1952 gain_reg = CDC_WSA_RX1_RX_VOL_CTL; 1953 } 1954 1955 switch (event) { 1956 case SND_SOC_DAPM_PRE_PMU: 1957 /* Reset if needed */ 1958 wsa_macro_enable_prim_interpolator(component, reg, event); 1959 break; 1960 case SND_SOC_DAPM_POST_PMU: 1961 wsa_macro_config_compander(component, w->shift, event); 1962 wsa_macro_config_softclip(component, w->shift, event); 1963 /* apply gain after int clk is enabled */ 1964 if ((wsa->spkr_gain_offset == WSA_MACRO_GAIN_OFFSET_M1P5_DB) && 1965 (wsa->comp_enabled[WSA_MACRO_COMP1] || 1966 wsa->comp_enabled[WSA_MACRO_COMP2])) { 1967 snd_soc_component_update_bits(component, 1968 CDC_WSA_RX0_RX_PATH_SEC1, 1969 CDC_WSA_RX_PGA_HALF_DB_MASK, 1970 CDC_WSA_RX_PGA_HALF_DB_ENABLE); 1971 snd_soc_component_update_bits(component, 1972 CDC_WSA_RX0_RX_PATH_MIX_SEC0, 1973 CDC_WSA_RX_PGA_HALF_DB_MASK, 1974 CDC_WSA_RX_PGA_HALF_DB_ENABLE); 1975 snd_soc_component_update_bits(component, 1976 CDC_WSA_RX1_RX_PATH_SEC1, 1977 CDC_WSA_RX_PGA_HALF_DB_MASK, 1978 CDC_WSA_RX_PGA_HALF_DB_ENABLE); 1979 snd_soc_component_update_bits(component, 1980 CDC_WSA_RX1_RX_PATH_MIX_SEC0, 1981 CDC_WSA_RX_PGA_HALF_DB_MASK, 1982 CDC_WSA_RX_PGA_HALF_DB_ENABLE); 1983 } 1984 val = snd_soc_component_read(component, gain_reg); 1985 snd_soc_component_write(component, gain_reg, val); 1986 wsa_macro_config_ear_spkr_gain(component, wsa, 1987 event, gain_reg); 1988 break; 1989 case SND_SOC_DAPM_POST_PMD: 1990 wsa_macro_config_compander(component, w->shift, event); 1991 wsa_macro_config_softclip(component, w->shift, event); 1992 wsa_macro_enable_prim_interpolator(component, reg, event); 1993 if ((wsa->spkr_gain_offset == WSA_MACRO_GAIN_OFFSET_M1P5_DB) && 1994 (wsa->comp_enabled[WSA_MACRO_COMP1] || 1995 wsa->comp_enabled[WSA_MACRO_COMP2])) { 1996 snd_soc_component_update_bits(component, 1997 CDC_WSA_RX0_RX_PATH_SEC1, 1998 CDC_WSA_RX_PGA_HALF_DB_MASK, 1999 CDC_WSA_RX_PGA_HALF_DB_DISABLE); 2000 snd_soc_component_update_bits(component, 2001 CDC_WSA_RX0_RX_PATH_MIX_SEC0, 2002 CDC_WSA_RX_PGA_HALF_DB_MASK, 2003 CDC_WSA_RX_PGA_HALF_DB_DISABLE); 2004 snd_soc_component_update_bits(component, 2005 CDC_WSA_RX1_RX_PATH_SEC1, 2006 CDC_WSA_RX_PGA_HALF_DB_MASK, 2007 CDC_WSA_RX_PGA_HALF_DB_DISABLE); 2008 snd_soc_component_update_bits(component, 2009 CDC_WSA_RX1_RX_PATH_MIX_SEC0, 2010 CDC_WSA_RX_PGA_HALF_DB_MASK, 2011 CDC_WSA_RX_PGA_HALF_DB_DISABLE); 2012 } 2013 wsa_macro_config_ear_spkr_gain(component, wsa, 2014 event, gain_reg); 2015 break; 2016 } 2017 2018 return 0; 2019 } 2020 2021 static int wsa_macro_spk_boost_event(struct snd_soc_dapm_widget *w, 2022 struct snd_kcontrol *kcontrol, 2023 int event) 2024 { 2025 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 2026 u16 boost_path_ctl, boost_path_cfg1; 2027 u16 reg, reg_mix; 2028 2029 if (!snd_soc_dapm_widget_name_cmp(w, "WSA_RX INT0 CHAIN")) { 2030 boost_path_ctl = CDC_WSA_BOOST0_BOOST_PATH_CTL; 2031 boost_path_cfg1 = CDC_WSA_RX0_RX_PATH_CFG1; 2032 reg = CDC_WSA_RX0_RX_PATH_CTL; 2033 reg_mix = CDC_WSA_RX0_RX_PATH_MIX_CTL; 2034 } else if (!snd_soc_dapm_widget_name_cmp(w, "WSA_RX INT1 CHAIN")) { 2035 boost_path_ctl = CDC_WSA_BOOST1_BOOST_PATH_CTL; 2036 boost_path_cfg1 = CDC_WSA_RX1_RX_PATH_CFG1; 2037 reg = CDC_WSA_RX1_RX_PATH_CTL; 2038 reg_mix = CDC_WSA_RX1_RX_PATH_MIX_CTL; 2039 } else { 2040 dev_warn(component->dev, "Incorrect widget name in the driver\n"); 2041 return -EINVAL; 2042 } 2043 2044 switch (event) { 2045 case SND_SOC_DAPM_PRE_PMU: 2046 snd_soc_component_update_bits(component, boost_path_cfg1, 2047 CDC_WSA_RX_PATH_SMART_BST_EN_MASK, 2048 CDC_WSA_RX_PATH_SMART_BST_ENABLE); 2049 snd_soc_component_update_bits(component, boost_path_ctl, 2050 CDC_WSA_BOOST_PATH_CLK_EN_MASK, 2051 CDC_WSA_BOOST_PATH_CLK_ENABLE); 2052 if ((snd_soc_component_read(component, reg_mix)) & 0x10) 2053 snd_soc_component_update_bits(component, reg_mix, 2054 0x10, 0x00); 2055 break; 2056 case SND_SOC_DAPM_POST_PMU: 2057 snd_soc_component_update_bits(component, reg, 0x10, 0x00); 2058 break; 2059 case SND_SOC_DAPM_POST_PMD: 2060 snd_soc_component_update_bits(component, boost_path_ctl, 2061 CDC_WSA_BOOST_PATH_CLK_EN_MASK, 2062 CDC_WSA_BOOST_PATH_CLK_DISABLE); 2063 snd_soc_component_update_bits(component, boost_path_cfg1, 2064 CDC_WSA_RX_PATH_SMART_BST_EN_MASK, 2065 CDC_WSA_RX_PATH_SMART_BST_DISABLE); 2066 break; 2067 } 2068 2069 return 0; 2070 } 2071 2072 static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w, 2073 struct snd_kcontrol *kcontrol, 2074 int event) 2075 { 2076 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 2077 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2078 u16 val, ec_tx, ec_hq_reg; 2079 2080 val = snd_soc_component_read(component, CDC_WSA_RX_INP_MUX_RX_MIX_CFG0); 2081 2082 switch (w->shift) { 2083 case WSA_MACRO_EC0_MUX: 2084 val = val & CDC_WSA_RX_MIX_TX0_SEL_MASK; 2085 ec_tx = val - 1; 2086 break; 2087 case WSA_MACRO_EC1_MUX: 2088 val = val & CDC_WSA_RX_MIX_TX1_SEL_MASK; 2089 ec_tx = (val >> CDC_WSA_RX_MIX_TX1_SEL_SHFT) - 1; 2090 break; 2091 default: 2092 dev_err(component->dev, "%s: Invalid shift %u\n", 2093 __func__, w->shift); 2094 return -EINVAL; 2095 } 2096 2097 if (wsa->ec_hq[ec_tx]) { 2098 ec_hq_reg = CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL + 0x40 * ec_tx; 2099 snd_soc_component_update_bits(component, ec_hq_reg, 2100 CDC_WSA_EC_HQ_EC_CLK_EN_MASK, 2101 CDC_WSA_EC_HQ_EC_CLK_ENABLE); 2102 ec_hq_reg = CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 + 0x40 * ec_tx; 2103 /* default set to 48k */ 2104 snd_soc_component_update_bits(component, ec_hq_reg, 2105 CDC_WSA_EC_HQ_EC_REF_PCM_RATE_MASK, 2106 CDC_WSA_EC_HQ_EC_REF_PCM_RATE_48K); 2107 } 2108 2109 return 0; 2110 } 2111 2112 static int wsa_macro_get_ec_hq(struct snd_kcontrol *kcontrol, 2113 struct snd_ctl_elem_value *ucontrol) 2114 { 2115 2116 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 2117 int ec_tx = ((struct soc_mixer_control *) kcontrol->private_value)->shift; 2118 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2119 2120 ucontrol->value.integer.value[0] = wsa->ec_hq[ec_tx]; 2121 2122 return 0; 2123 } 2124 2125 static int wsa_macro_set_ec_hq(struct snd_kcontrol *kcontrol, 2126 struct snd_ctl_elem_value *ucontrol) 2127 { 2128 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 2129 int ec_tx = ((struct soc_mixer_control *) kcontrol->private_value)->shift; 2130 int value = ucontrol->value.integer.value[0]; 2131 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2132 2133 wsa->ec_hq[ec_tx] = value; 2134 2135 return 0; 2136 } 2137 2138 static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol, 2139 struct snd_ctl_elem_value *ucontrol) 2140 { 2141 2142 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 2143 int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift; 2144 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2145 2146 ucontrol->value.integer.value[0] = wsa->comp_enabled[comp]; 2147 return 0; 2148 } 2149 2150 static int wsa_macro_set_compander(struct snd_kcontrol *kcontrol, 2151 struct snd_ctl_elem_value *ucontrol) 2152 { 2153 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 2154 int comp = ((struct soc_mixer_control *) kcontrol->private_value)->shift; 2155 int value = ucontrol->value.integer.value[0]; 2156 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2157 2158 wsa->comp_enabled[comp] = value; 2159 2160 return 0; 2161 } 2162 2163 static int wsa_macro_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol, 2164 struct snd_ctl_elem_value *ucontrol) 2165 { 2166 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 2167 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2168 2169 ucontrol->value.integer.value[0] = wsa->ear_spkr_gain; 2170 2171 return 0; 2172 } 2173 2174 static int wsa_macro_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol, 2175 struct snd_ctl_elem_value *ucontrol) 2176 { 2177 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 2178 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2179 2180 wsa->ear_spkr_gain = ucontrol->value.integer.value[0]; 2181 2182 return 0; 2183 } 2184 2185 static int wsa_macro_rx_mux_get(struct snd_kcontrol *kcontrol, 2186 struct snd_ctl_elem_value *ucontrol) 2187 { 2188 struct snd_soc_dapm_widget *widget = 2189 snd_soc_dapm_kcontrol_widget(kcontrol); 2190 struct snd_soc_component *component = 2191 snd_soc_dapm_to_component(widget->dapm); 2192 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2193 2194 ucontrol->value.integer.value[0] = 2195 wsa->rx_port_value[widget->shift]; 2196 return 0; 2197 } 2198 2199 static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol, 2200 struct snd_ctl_elem_value *ucontrol) 2201 { 2202 struct snd_soc_dapm_widget *widget = 2203 snd_soc_dapm_kcontrol_widget(kcontrol); 2204 struct snd_soc_component *component = 2205 snd_soc_dapm_to_component(widget->dapm); 2206 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2207 struct snd_soc_dapm_update *update = NULL; 2208 u32 rx_port_value = ucontrol->value.integer.value[0]; 2209 u32 bit_input; 2210 u32 aif_rst; 2211 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2212 2213 aif_rst = wsa->rx_port_value[widget->shift]; 2214 if (!rx_port_value) { 2215 if (aif_rst == 0) 2216 return 0; 2217 if (aif_rst >= WSA_MACRO_RX_MAX) { 2218 dev_err(component->dev, "%s: Invalid AIF reset\n", __func__); 2219 return 0; 2220 } 2221 } 2222 wsa->rx_port_value[widget->shift] = rx_port_value; 2223 2224 bit_input = widget->shift; 2225 2226 switch (rx_port_value) { 2227 case 0: 2228 if (wsa->active_ch_cnt[aif_rst]) { 2229 clear_bit(bit_input, 2230 &wsa->active_ch_mask[aif_rst]); 2231 wsa->active_ch_cnt[aif_rst]--; 2232 } 2233 break; 2234 case 1: 2235 case 2: 2236 set_bit(bit_input, 2237 &wsa->active_ch_mask[rx_port_value]); 2238 wsa->active_ch_cnt[rx_port_value]++; 2239 break; 2240 default: 2241 dev_err(component->dev, 2242 "%s: Invalid AIF_ID for WSA RX MUX %d\n", 2243 __func__, rx_port_value); 2244 return -EINVAL; 2245 } 2246 2247 snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, 2248 rx_port_value, e, update); 2249 return 0; 2250 } 2251 2252 static int wsa_macro_soft_clip_enable_get(struct snd_kcontrol *kcontrol, 2253 struct snd_ctl_elem_value *ucontrol) 2254 { 2255 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 2256 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2257 int path = ((struct soc_mixer_control *)kcontrol->private_value)->shift; 2258 2259 ucontrol->value.integer.value[0] = wsa->is_softclip_on[path]; 2260 2261 return 0; 2262 } 2263 2264 static int wsa_macro_soft_clip_enable_put(struct snd_kcontrol *kcontrol, 2265 struct snd_ctl_elem_value *ucontrol) 2266 { 2267 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 2268 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2269 int path = ((struct soc_mixer_control *) kcontrol->private_value)->shift; 2270 2271 wsa->is_softclip_on[path] = ucontrol->value.integer.value[0]; 2272 2273 return 0; 2274 } 2275 2276 static const struct snd_kcontrol_new wsa_macro_snd_controls[] = { 2277 SOC_ENUM_EXT("EAR SPKR PA Gain", wsa_macro_ear_spkr_pa_gain_enum, 2278 wsa_macro_ear_spkr_pa_gain_get, 2279 wsa_macro_ear_spkr_pa_gain_put), 2280 SOC_SINGLE_EXT("WSA_Softclip0 Enable", SND_SOC_NOPM, 2281 WSA_MACRO_SOFTCLIP0, 1, 0, 2282 wsa_macro_soft_clip_enable_get, 2283 wsa_macro_soft_clip_enable_put), 2284 SOC_SINGLE_EXT("WSA_Softclip1 Enable", SND_SOC_NOPM, 2285 WSA_MACRO_SOFTCLIP1, 1, 0, 2286 wsa_macro_soft_clip_enable_get, 2287 wsa_macro_soft_clip_enable_put), 2288 2289 SOC_SINGLE_S8_TLV("WSA_RX0 Digital Volume", CDC_WSA_RX0_RX_VOL_CTL, 2290 -84, 40, digital_gain), 2291 SOC_SINGLE_S8_TLV("WSA_RX1 Digital Volume", CDC_WSA_RX1_RX_VOL_CTL, 2292 -84, 40, digital_gain), 2293 2294 SOC_SINGLE("WSA_RX0 Digital Mute", CDC_WSA_RX0_RX_PATH_CTL, 4, 1, 0), 2295 SOC_SINGLE("WSA_RX1 Digital Mute", CDC_WSA_RX1_RX_PATH_CTL, 4, 1, 0), 2296 SOC_SINGLE("WSA_RX0_MIX Digital Mute", CDC_WSA_RX0_RX_PATH_MIX_CTL, 4, 2297 1, 0), 2298 SOC_SINGLE("WSA_RX1_MIX Digital Mute", CDC_WSA_RX1_RX_PATH_MIX_CTL, 4, 2299 1, 0), 2300 SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0, 2301 wsa_macro_get_compander, wsa_macro_set_compander), 2302 SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0, 2303 wsa_macro_get_compander, wsa_macro_set_compander), 2304 SOC_SINGLE_EXT("WSA_RX0 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX0, 1, 0, 2305 wsa_macro_get_ec_hq, wsa_macro_set_ec_hq), 2306 SOC_SINGLE_EXT("WSA_RX1 EC_HQ Switch", SND_SOC_NOPM, WSA_MACRO_RX1, 1, 0, 2307 wsa_macro_get_ec_hq, wsa_macro_set_ec_hq), 2308 }; 2309 2310 static const struct soc_enum rx_mux_enum = 2311 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_mux_text), rx_mux_text); 2312 2313 static const struct snd_kcontrol_new rx_mux[WSA_MACRO_RX_MAX] = { 2314 SOC_DAPM_ENUM_EXT("WSA RX0 Mux", rx_mux_enum, 2315 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put), 2316 SOC_DAPM_ENUM_EXT("WSA RX1 Mux", rx_mux_enum, 2317 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put), 2318 SOC_DAPM_ENUM_EXT("WSA RX_MIX0 Mux", rx_mux_enum, 2319 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put), 2320 SOC_DAPM_ENUM_EXT("WSA RX_MIX1 Mux", rx_mux_enum, 2321 wsa_macro_rx_mux_get, wsa_macro_rx_mux_put), 2322 }; 2323 2324 static int wsa_macro_vi_feed_mixer_get(struct snd_kcontrol *kcontrol, 2325 struct snd_ctl_elem_value *ucontrol) 2326 { 2327 struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); 2328 struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); 2329 struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; 2330 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2331 u32 spk_tx_id = mixer->shift; 2332 u32 dai_id = widget->shift; 2333 2334 if (test_bit(spk_tx_id, &wsa->active_ch_mask[dai_id])) 2335 ucontrol->value.integer.value[0] = 1; 2336 else 2337 ucontrol->value.integer.value[0] = 0; 2338 2339 return 0; 2340 } 2341 2342 static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol, 2343 struct snd_ctl_elem_value *ucontrol) 2344 { 2345 struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kcontrol); 2346 struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); 2347 struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; 2348 struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 2349 u32 enable = ucontrol->value.integer.value[0]; 2350 u32 spk_tx_id = mixer->shift; 2351 u32 dai_id = widget->shift; 2352 2353 if (enable) { 2354 if (spk_tx_id == WSA_MACRO_TX0 && 2355 !test_bit(WSA_MACRO_TX0, 2356 &wsa->active_ch_mask[dai_id])) { 2357 set_bit(WSA_MACRO_TX0, 2358 &wsa->active_ch_mask[dai_id]); 2359 wsa->active_ch_cnt[dai_id]++; 2360 } 2361 if (spk_tx_id == WSA_MACRO_TX1 && 2362 !test_bit(WSA_MACRO_TX1, 2363 &wsa->active_ch_mask[dai_id])) { 2364 set_bit(WSA_MACRO_TX1, 2365 &wsa->active_ch_mask[dai_id]); 2366 wsa->active_ch_cnt[dai_id]++; 2367 } 2368 } else { 2369 if (spk_tx_id == WSA_MACRO_TX0 && 2370 test_bit(WSA_MACRO_TX0, 2371 &wsa->active_ch_mask[dai_id])) { 2372 clear_bit(WSA_MACRO_TX0, 2373 &wsa->active_ch_mask[dai_id]); 2374 wsa->active_ch_cnt[dai_id]--; 2375 } 2376 if (spk_tx_id == WSA_MACRO_TX1 && 2377 test_bit(WSA_MACRO_TX1, 2378 &wsa->active_ch_mask[dai_id])) { 2379 clear_bit(WSA_MACRO_TX1, 2380 &wsa->active_ch_mask[dai_id]); 2381 wsa->active_ch_cnt[dai_id]--; 2382 } 2383 } 2384 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL); 2385 2386 return 0; 2387 } 2388 2389 static const struct snd_kcontrol_new aif_vi_mixer[] = { 2390 SOC_SINGLE_EXT("WSA_SPKR_VI_1", SND_SOC_NOPM, WSA_MACRO_TX0, 1, 0, 2391 wsa_macro_vi_feed_mixer_get, 2392 wsa_macro_vi_feed_mixer_put), 2393 SOC_SINGLE_EXT("WSA_SPKR_VI_2", SND_SOC_NOPM, WSA_MACRO_TX1, 1, 0, 2394 wsa_macro_vi_feed_mixer_get, 2395 wsa_macro_vi_feed_mixer_put), 2396 }; 2397 2398 static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets[] = { 2399 SND_SOC_DAPM_AIF_IN("WSA AIF1 PB", "WSA_AIF1 Playback", 0, 2400 SND_SOC_NOPM, 0, 0), 2401 SND_SOC_DAPM_AIF_IN("WSA AIF_MIX1 PB", "WSA_AIF_MIX1 Playback", 0, 2402 SND_SOC_NOPM, 0, 0), 2403 2404 SND_SOC_DAPM_AIF_OUT_E("WSA AIF_VI", "WSA_AIF_VI Capture", 0, 2405 SND_SOC_NOPM, WSA_MACRO_AIF_VI, 0, 2406 wsa_macro_enable_vi_feedback, 2407 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 2408 SND_SOC_DAPM_AIF_OUT("WSA AIF_ECHO", "WSA_AIF_ECHO Capture", 0, 2409 SND_SOC_NOPM, 0, 0), 2410 2411 SND_SOC_DAPM_MIXER("WSA_AIF_VI Mixer", SND_SOC_NOPM, WSA_MACRO_AIF_VI, 2412 0, aif_vi_mixer, ARRAY_SIZE(aif_vi_mixer)), 2413 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC0_MUX", SND_SOC_NOPM, 2414 WSA_MACRO_EC0_MUX, 0, 2415 &rx_mix_ec0_mux, wsa_macro_enable_echo, 2416 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2417 SND_SOC_DAPM_MUX_E("WSA RX_MIX EC1_MUX", SND_SOC_NOPM, 2418 WSA_MACRO_EC1_MUX, 0, 2419 &rx_mix_ec1_mux, wsa_macro_enable_echo, 2420 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2421 2422 SND_SOC_DAPM_MUX("WSA RX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX0, 0, 2423 &rx_mux[WSA_MACRO_RX0]), 2424 SND_SOC_DAPM_MUX("WSA RX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX1, 0, 2425 &rx_mux[WSA_MACRO_RX1]), 2426 SND_SOC_DAPM_MUX("WSA RX_MIX0 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 0, 2427 &rx_mux[WSA_MACRO_RX_MIX0]), 2428 SND_SOC_DAPM_MUX("WSA RX_MIX1 MUX", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 0, 2429 &rx_mux[WSA_MACRO_RX_MIX1]), 2430 2431 SND_SOC_DAPM_MIXER("WSA RX0", SND_SOC_NOPM, 0, 0, NULL, 0), 2432 SND_SOC_DAPM_MIXER("WSA RX1", SND_SOC_NOPM, 0, 0, NULL, 0), 2433 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0), 2434 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 2435 2436 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0, 2437 wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU), 2438 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM, 1, 0, NULL, 0, 2439 wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU), 2440 2441 SND_SOC_DAPM_MIXER("WSA_RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 2442 SND_SOC_DAPM_MIXER("WSA_RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 2443 2444 SND_SOC_DAPM_MUX("WSA_RX0 INT0 SIDETONE MIX", CDC_WSA_RX0_RX_PATH_CFG1, 2445 4, 0, &rx0_sidetone_mix_mux), 2446 2447 SND_SOC_DAPM_INPUT("WSA SRC0_INP"), 2448 SND_SOC_DAPM_INPUT("WSA_TX DEC0_INP"), 2449 SND_SOC_DAPM_INPUT("WSA_TX DEC1_INP"), 2450 2451 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 INTERP", SND_SOC_NOPM, 2452 WSA_MACRO_COMP1, 0, NULL, 0, 2453 wsa_macro_enable_interpolator, 2454 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2455 SND_SOC_DAPM_POST_PMD), 2456 2457 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 INTERP", SND_SOC_NOPM, 2458 WSA_MACRO_COMP2, 0, NULL, 0, 2459 wsa_macro_enable_interpolator, 2460 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2461 SND_SOC_DAPM_POST_PMD), 2462 2463 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 CHAIN", SND_SOC_NOPM, 0, 0, 2464 NULL, 0, wsa_macro_spk_boost_event, 2465 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2466 SND_SOC_DAPM_POST_PMD), 2467 2468 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 CHAIN", SND_SOC_NOPM, 0, 0, 2469 NULL, 0, wsa_macro_spk_boost_event, 2470 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 2471 SND_SOC_DAPM_POST_PMD), 2472 2473 SND_SOC_DAPM_INPUT("VIINPUT_WSA"), 2474 SND_SOC_DAPM_OUTPUT("WSA_SPK1 OUT"), 2475 SND_SOC_DAPM_OUTPUT("WSA_SPK2 OUT"), 2476 2477 SND_SOC_DAPM_SUPPLY("WSA_RX0_CLK", CDC_WSA_RX0_RX_PATH_CTL, 5, 0, NULL, 0), 2478 SND_SOC_DAPM_SUPPLY("WSA_RX1_CLK", CDC_WSA_RX1_RX_PATH_CTL, 5, 0, NULL, 0), 2479 SND_SOC_DAPM_SUPPLY("WSA_RX_MIX0_CLK", CDC_WSA_RX0_RX_PATH_MIX_CTL, 5, 0, NULL, 0), 2480 SND_SOC_DAPM_SUPPLY("WSA_RX_MIX1_CLK", CDC_WSA_RX1_RX_PATH_MIX_CTL, 5, 0, NULL, 0), 2481 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0, 2482 wsa_macro_mclk_event, 2483 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2484 }; 2485 2486 static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets_v2_1[] = { 2487 SND_SOC_DAPM_MUX("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0, &rx0_prim_inp0_mux_v2_1), 2488 SND_SOC_DAPM_MUX("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0, &rx0_prim_inp1_mux_v2_1), 2489 SND_SOC_DAPM_MUX("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux_v2_1), 2490 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 2491 0, &rx0_mix_mux_v2_1, wsa_macro_enable_mix_path, 2492 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2493 SND_SOC_DAPM_MUX("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, &rx1_prim_inp0_mux_v2_1), 2494 SND_SOC_DAPM_MUX("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0, &rx1_prim_inp1_mux_v2_1), 2495 SND_SOC_DAPM_MUX("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux_v2_1), 2496 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 2497 0, &rx1_mix_mux_v2_1, wsa_macro_enable_mix_path, 2498 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2499 }; 2500 2501 static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets_v2_5[] = { 2502 SND_SOC_DAPM_MUX("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0, &rx0_prim_inp0_mux_v2_5), 2503 SND_SOC_DAPM_MUX("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0, &rx0_prim_inp1_mux_v2_5), 2504 SND_SOC_DAPM_MUX("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux_v2_5), 2505 SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 2506 0, &rx0_mix_mux_v2_5, wsa_macro_enable_mix_path, 2507 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2508 SND_SOC_DAPM_MUX("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, &rx1_prim_inp0_mux_v2_5), 2509 SND_SOC_DAPM_MUX("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0, &rx1_prim_inp1_mux_v2_5), 2510 SND_SOC_DAPM_MUX("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux_v2_5), 2511 SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 2512 0, &rx1_mix_mux_v2_5, wsa_macro_enable_mix_path, 2513 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2514 }; 2515 2516 static const struct snd_soc_dapm_route wsa_audio_map[] = { 2517 /* VI Feedback */ 2518 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_1", "VIINPUT_WSA"}, 2519 {"WSA_AIF_VI Mixer", "WSA_SPKR_VI_2", "VIINPUT_WSA"}, 2520 {"WSA AIF_VI", NULL, "WSA_AIF_VI Mixer"}, 2521 {"WSA AIF_VI", NULL, "WSA_MCLK"}, 2522 2523 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"}, 2524 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX0", "WSA_RX INT0 SEC MIX"}, 2525 {"WSA RX_MIX EC0_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"}, 2526 {"WSA RX_MIX EC1_MUX", "RX_MIX_TX1", "WSA_RX INT1 SEC MIX"}, 2527 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC0_MUX"}, 2528 {"WSA AIF_ECHO", NULL, "WSA RX_MIX EC1_MUX"}, 2529 {"WSA AIF_ECHO", NULL, "WSA_MCLK"}, 2530 2531 {"WSA AIF1 PB", NULL, "WSA_MCLK"}, 2532 {"WSA AIF_MIX1 PB", NULL, "WSA_MCLK"}, 2533 2534 {"WSA RX0 MUX", "AIF1_PB", "WSA AIF1 PB"}, 2535 {"WSA RX1 MUX", "AIF1_PB", "WSA AIF1 PB"}, 2536 {"WSA RX_MIX0 MUX", "AIF1_PB", "WSA AIF1 PB"}, 2537 {"WSA RX_MIX1 MUX", "AIF1_PB", "WSA AIF1 PB"}, 2538 2539 {"WSA RX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"}, 2540 {"WSA RX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"}, 2541 {"WSA RX_MIX0 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"}, 2542 {"WSA RX_MIX1 MUX", "AIF_MIX1_PB", "WSA AIF_MIX1 PB"}, 2543 2544 {"WSA RX0", NULL, "WSA RX0 MUX"}, 2545 {"WSA RX1", NULL, "WSA RX1 MUX"}, 2546 {"WSA RX_MIX0", NULL, "WSA RX_MIX0 MUX"}, 2547 {"WSA RX_MIX1", NULL, "WSA RX_MIX1 MUX"}, 2548 2549 {"WSA RX0", NULL, "WSA_RX0_CLK"}, 2550 {"WSA RX1", NULL, "WSA_RX1_CLK"}, 2551 {"WSA RX_MIX0", NULL, "WSA_RX_MIX0_CLK"}, 2552 {"WSA RX_MIX1", NULL, "WSA_RX_MIX1_CLK"}, 2553 2554 {"WSA_RX0 INP0", "RX0", "WSA RX0"}, 2555 {"WSA_RX0 INP0", "RX1", "WSA RX1"}, 2556 {"WSA_RX0 INP0", "RX_MIX0", "WSA RX_MIX0"}, 2557 {"WSA_RX0 INP0", "RX_MIX1", "WSA RX_MIX1"}, 2558 {"WSA_RX0 INP0", "DEC0", "WSA_TX DEC0_INP"}, 2559 {"WSA_RX0 INP0", "DEC1", "WSA_TX DEC1_INP"}, 2560 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP0"}, 2561 2562 {"WSA_RX0 INP1", "RX0", "WSA RX0"}, 2563 {"WSA_RX0 INP1", "RX1", "WSA RX1"}, 2564 {"WSA_RX0 INP1", "RX_MIX0", "WSA RX_MIX0"}, 2565 {"WSA_RX0 INP1", "RX_MIX1", "WSA RX_MIX1"}, 2566 {"WSA_RX0 INP1", "DEC0", "WSA_TX DEC0_INP"}, 2567 {"WSA_RX0 INP1", "DEC1", "WSA_TX DEC1_INP"}, 2568 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP1"}, 2569 2570 {"WSA_RX0 INP2", "RX0", "WSA RX0"}, 2571 {"WSA_RX0 INP2", "RX1", "WSA RX1"}, 2572 {"WSA_RX0 INP2", "RX_MIX0", "WSA RX_MIX0"}, 2573 {"WSA_RX0 INP2", "RX_MIX1", "WSA RX_MIX1"}, 2574 {"WSA_RX0 INP2", "DEC0", "WSA_TX DEC0_INP"}, 2575 {"WSA_RX0 INP2", "DEC1", "WSA_TX DEC1_INP"}, 2576 {"WSA_RX INT0 MIX", NULL, "WSA_RX0 INP2"}, 2577 2578 {"WSA_RX0 MIX INP", "RX0", "WSA RX0"}, 2579 {"WSA_RX0 MIX INP", "RX1", "WSA RX1"}, 2580 {"WSA_RX0 MIX INP", "RX_MIX0", "WSA RX_MIX0"}, 2581 {"WSA_RX0 MIX INP", "RX_MIX1", "WSA RX_MIX1"}, 2582 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX0 MIX INP"}, 2583 2584 {"WSA_RX INT0 SEC MIX", NULL, "WSA_RX INT0 MIX"}, 2585 {"WSA_RX INT0 INTERP", NULL, "WSA_RX INT0 SEC MIX"}, 2586 {"WSA_RX0 INT0 SIDETONE MIX", "SRC0", "WSA SRC0_INP"}, 2587 {"WSA_RX INT0 INTERP", NULL, "WSA_RX0 INT0 SIDETONE MIX"}, 2588 {"WSA_RX INT0 CHAIN", NULL, "WSA_RX INT0 INTERP"}, 2589 2590 {"WSA_SPK1 OUT", NULL, "WSA_RX INT0 CHAIN"}, 2591 {"WSA_SPK1 OUT", NULL, "WSA_MCLK"}, 2592 2593 {"WSA_RX1 INP0", "RX0", "WSA RX0"}, 2594 {"WSA_RX1 INP0", "RX1", "WSA RX1"}, 2595 {"WSA_RX1 INP0", "RX_MIX0", "WSA RX_MIX0"}, 2596 {"WSA_RX1 INP0", "RX_MIX1", "WSA RX_MIX1"}, 2597 {"WSA_RX1 INP0", "DEC0", "WSA_TX DEC0_INP"}, 2598 {"WSA_RX1 INP0", "DEC1", "WSA_TX DEC1_INP"}, 2599 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP0"}, 2600 2601 {"WSA_RX1 INP1", "RX0", "WSA RX0"}, 2602 {"WSA_RX1 INP1", "RX1", "WSA RX1"}, 2603 {"WSA_RX1 INP1", "RX_MIX0", "WSA RX_MIX0"}, 2604 {"WSA_RX1 INP1", "RX_MIX1", "WSA RX_MIX1"}, 2605 {"WSA_RX1 INP1", "DEC0", "WSA_TX DEC0_INP"}, 2606 {"WSA_RX1 INP1", "DEC1", "WSA_TX DEC1_INP"}, 2607 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP1"}, 2608 2609 {"WSA_RX1 INP2", "RX0", "WSA RX0"}, 2610 {"WSA_RX1 INP2", "RX1", "WSA RX1"}, 2611 {"WSA_RX1 INP2", "RX_MIX0", "WSA RX_MIX0"}, 2612 {"WSA_RX1 INP2", "RX_MIX1", "WSA RX_MIX1"}, 2613 {"WSA_RX1 INP2", "DEC0", "WSA_TX DEC0_INP"}, 2614 {"WSA_RX1 INP2", "DEC1", "WSA_TX DEC1_INP"}, 2615 {"WSA_RX INT1 MIX", NULL, "WSA_RX1 INP2"}, 2616 2617 {"WSA_RX1 MIX INP", "RX0", "WSA RX0"}, 2618 {"WSA_RX1 MIX INP", "RX1", "WSA RX1"}, 2619 {"WSA_RX1 MIX INP", "RX_MIX0", "WSA RX_MIX0"}, 2620 {"WSA_RX1 MIX INP", "RX_MIX1", "WSA RX_MIX1"}, 2621 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX1 MIX INP"}, 2622 2623 {"WSA_RX INT1 SEC MIX", NULL, "WSA_RX INT1 MIX"}, 2624 {"WSA_RX INT1 INTERP", NULL, "WSA_RX INT1 SEC MIX"}, 2625 2626 {"WSA_RX INT1 CHAIN", NULL, "WSA_RX INT1 INTERP"}, 2627 {"WSA_SPK2 OUT", NULL, "WSA_RX INT1 CHAIN"}, 2628 {"WSA_SPK2 OUT", NULL, "WSA_MCLK"}, 2629 }; 2630 2631 static int wsa_swrm_clock(struct wsa_macro *wsa, bool enable) 2632 { 2633 struct regmap *regmap = wsa->regmap; 2634 2635 if (enable) { 2636 int ret; 2637 2638 ret = clk_prepare_enable(wsa->mclk); 2639 if (ret) { 2640 dev_err(wsa->dev, "failed to enable mclk\n"); 2641 return ret; 2642 } 2643 wsa_macro_mclk_enable(wsa, true); 2644 2645 regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 2646 CDC_WSA_SWR_CLK_EN_MASK, 2647 CDC_WSA_SWR_CLK_ENABLE); 2648 2649 } else { 2650 regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 2651 CDC_WSA_SWR_CLK_EN_MASK, 0); 2652 wsa_macro_mclk_enable(wsa, false); 2653 clk_disable_unprepare(wsa->mclk); 2654 } 2655 2656 return 0; 2657 } 2658 2659 static int wsa_macro_component_probe(struct snd_soc_component *comp) 2660 { 2661 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(comp); 2662 struct wsa_macro *wsa = snd_soc_component_get_drvdata(comp); 2663 const struct snd_soc_dapm_widget *widgets; 2664 unsigned int num_widgets; 2665 2666 snd_soc_component_init_regmap(comp, wsa->regmap); 2667 2668 wsa->spkr_gain_offset = WSA_MACRO_GAIN_OFFSET_M1P5_DB; 2669 2670 /* set SPKR rate to FS_2P4_3P072 */ 2671 snd_soc_component_update_bits(comp, CDC_WSA_RX0_RX_PATH_CFG1, 2672 CDC_WSA_RX_PATH_SPKR_RATE_MASK, 2673 CDC_WSA_RX_PATH_SPKR_RATE_FS_2P4_3P072); 2674 2675 snd_soc_component_update_bits(comp, CDC_WSA_RX1_RX_PATH_CFG1, 2676 CDC_WSA_RX_PATH_SPKR_RATE_MASK, 2677 CDC_WSA_RX_PATH_SPKR_RATE_FS_2P4_3P072); 2678 2679 wsa_macro_set_spkr_mode(comp, WSA_MACRO_SPKR_MODE_1); 2680 2681 switch (wsa->codec_version) { 2682 case LPASS_CODEC_VERSION_1_0: 2683 case LPASS_CODEC_VERSION_1_1: 2684 case LPASS_CODEC_VERSION_1_2: 2685 case LPASS_CODEC_VERSION_2_0: 2686 case LPASS_CODEC_VERSION_2_1: 2687 widgets = wsa_macro_dapm_widgets_v2_1; 2688 num_widgets = ARRAY_SIZE(wsa_macro_dapm_widgets_v2_1); 2689 break; 2690 case LPASS_CODEC_VERSION_2_5: 2691 case LPASS_CODEC_VERSION_2_6: 2692 case LPASS_CODEC_VERSION_2_7: 2693 case LPASS_CODEC_VERSION_2_8: 2694 widgets = wsa_macro_dapm_widgets_v2_5; 2695 num_widgets = ARRAY_SIZE(wsa_macro_dapm_widgets_v2_5); 2696 break; 2697 default: 2698 return -EINVAL; 2699 } 2700 2701 return snd_soc_dapm_new_controls(dapm, widgets, num_widgets); 2702 } 2703 2704 static int swclk_gate_enable(struct clk_hw *hw) 2705 { 2706 return wsa_swrm_clock(to_wsa_macro(hw), true); 2707 } 2708 2709 static void swclk_gate_disable(struct clk_hw *hw) 2710 { 2711 wsa_swrm_clock(to_wsa_macro(hw), false); 2712 } 2713 2714 static int swclk_gate_is_enabled(struct clk_hw *hw) 2715 { 2716 struct wsa_macro *wsa = to_wsa_macro(hw); 2717 int ret, val; 2718 2719 regmap_read(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, &val); 2720 ret = val & BIT(0); 2721 2722 return ret; 2723 } 2724 2725 static unsigned long swclk_recalc_rate(struct clk_hw *hw, 2726 unsigned long parent_rate) 2727 { 2728 return parent_rate / 2; 2729 } 2730 2731 static const struct clk_ops swclk_gate_ops = { 2732 .prepare = swclk_gate_enable, 2733 .unprepare = swclk_gate_disable, 2734 .is_enabled = swclk_gate_is_enabled, 2735 .recalc_rate = swclk_recalc_rate, 2736 }; 2737 2738 static int wsa_macro_register_mclk_output(struct wsa_macro *wsa) 2739 { 2740 struct device *dev = wsa->dev; 2741 const char *parent_clk_name; 2742 struct clk_hw *hw; 2743 struct clk_init_data init; 2744 int ret; 2745 2746 if (wsa->npl) 2747 parent_clk_name = __clk_get_name(wsa->npl); 2748 else 2749 parent_clk_name = __clk_get_name(wsa->mclk); 2750 2751 init.name = "mclk"; 2752 of_property_read_string(dev_of_node(dev), "clock-output-names", 2753 &init.name); 2754 init.ops = &swclk_gate_ops; 2755 init.flags = 0; 2756 init.parent_names = &parent_clk_name; 2757 init.num_parents = 1; 2758 wsa->hw.init = &init; 2759 hw = &wsa->hw; 2760 ret = clk_hw_register(wsa->dev, hw); 2761 if (ret) 2762 return ret; 2763 2764 return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw); 2765 } 2766 2767 static const struct snd_soc_component_driver wsa_macro_component_drv = { 2768 .name = "WSA MACRO", 2769 .probe = wsa_macro_component_probe, 2770 .controls = wsa_macro_snd_controls, 2771 .num_controls = ARRAY_SIZE(wsa_macro_snd_controls), 2772 .dapm_widgets = wsa_macro_dapm_widgets, 2773 .num_dapm_widgets = ARRAY_SIZE(wsa_macro_dapm_widgets), 2774 .dapm_routes = wsa_audio_map, 2775 .num_dapm_routes = ARRAY_SIZE(wsa_audio_map), 2776 }; 2777 2778 static int wsa_macro_probe(struct platform_device *pdev) 2779 { 2780 struct device *dev = &pdev->dev; 2781 struct wsa_macro *wsa; 2782 kernel_ulong_t flags; 2783 void __iomem *base; 2784 int ret, def_count; 2785 2786 flags = (kernel_ulong_t)device_get_match_data(dev); 2787 2788 wsa = devm_kzalloc(dev, sizeof(*wsa), GFP_KERNEL); 2789 if (!wsa) 2790 return -ENOMEM; 2791 2792 wsa->macro = devm_clk_get_optional(dev, "macro"); 2793 if (IS_ERR(wsa->macro)) 2794 return dev_err_probe(dev, PTR_ERR(wsa->macro), "unable to get macro clock\n"); 2795 2796 wsa->dcodec = devm_clk_get_optional(dev, "dcodec"); 2797 if (IS_ERR(wsa->dcodec)) 2798 return dev_err_probe(dev, PTR_ERR(wsa->dcodec), "unable to get dcodec clock\n"); 2799 2800 wsa->mclk = devm_clk_get(dev, "mclk"); 2801 if (IS_ERR(wsa->mclk)) 2802 return dev_err_probe(dev, PTR_ERR(wsa->mclk), "unable to get mclk clock\n"); 2803 2804 if (flags & LPASS_MACRO_FLAG_HAS_NPL_CLOCK) { 2805 wsa->npl = devm_clk_get(dev, "npl"); 2806 if (IS_ERR(wsa->npl)) 2807 return dev_err_probe(dev, PTR_ERR(wsa->npl), "unable to get npl clock\n"); 2808 } 2809 2810 wsa->fsgen = devm_clk_get(dev, "fsgen"); 2811 if (IS_ERR(wsa->fsgen)) 2812 return dev_err_probe(dev, PTR_ERR(wsa->fsgen), "unable to get fsgen clock\n"); 2813 2814 base = devm_platform_ioremap_resource(pdev, 0); 2815 if (IS_ERR(base)) 2816 return PTR_ERR(base); 2817 2818 wsa->codec_version = lpass_macro_get_codec_version(); 2819 struct reg_default *reg_defaults __free(kfree) = NULL; 2820 2821 switch (wsa->codec_version) { 2822 case LPASS_CODEC_VERSION_1_0: 2823 case LPASS_CODEC_VERSION_1_1: 2824 case LPASS_CODEC_VERSION_1_2: 2825 case LPASS_CODEC_VERSION_2_0: 2826 case LPASS_CODEC_VERSION_2_1: 2827 wsa->reg_layout = &wsa_codec_v2_1; 2828 def_count = ARRAY_SIZE(wsa_defaults) + ARRAY_SIZE(wsa_defaults_v2_1); 2829 reg_defaults = kmalloc_array(def_count, sizeof(*reg_defaults), 2830 GFP_KERNEL); 2831 if (!reg_defaults) 2832 return -ENOMEM; 2833 memcpy(®_defaults[0], wsa_defaults, sizeof(wsa_defaults)); 2834 memcpy(®_defaults[ARRAY_SIZE(wsa_defaults)], 2835 wsa_defaults_v2_1, sizeof(wsa_defaults_v2_1)); 2836 break; 2837 2838 case LPASS_CODEC_VERSION_2_5: 2839 case LPASS_CODEC_VERSION_2_6: 2840 case LPASS_CODEC_VERSION_2_7: 2841 case LPASS_CODEC_VERSION_2_8: 2842 wsa->reg_layout = &wsa_codec_v2_5; 2843 def_count = ARRAY_SIZE(wsa_defaults) + ARRAY_SIZE(wsa_defaults_v2_5); 2844 reg_defaults = kmalloc_array(def_count, sizeof(*reg_defaults), 2845 GFP_KERNEL); 2846 if (!reg_defaults) 2847 return -ENOMEM; 2848 memcpy(®_defaults[0], wsa_defaults, sizeof(wsa_defaults)); 2849 memcpy(®_defaults[ARRAY_SIZE(wsa_defaults)], 2850 wsa_defaults_v2_5, sizeof(wsa_defaults_v2_5)); 2851 break; 2852 2853 default: 2854 dev_err(dev, "Unsupported Codec version (%d)\n", wsa->codec_version); 2855 return -EINVAL; 2856 } 2857 2858 struct regmap_config *reg_config __free(kfree) = kmemdup(&wsa_regmap_config, 2859 sizeof(*reg_config), 2860 GFP_KERNEL); 2861 if (!reg_config) 2862 return -ENOMEM; 2863 2864 reg_config->reg_defaults = reg_defaults; 2865 reg_config->num_reg_defaults = def_count; 2866 2867 wsa->regmap = devm_regmap_init_mmio(dev, base, reg_config); 2868 if (IS_ERR(wsa->regmap)) 2869 return PTR_ERR(wsa->regmap); 2870 2871 dev_set_drvdata(dev, wsa); 2872 2873 wsa->dev = dev; 2874 2875 /* set MCLK and NPL rates */ 2876 clk_set_rate(wsa->mclk, WSA_MACRO_MCLK_FREQ); 2877 clk_set_rate(wsa->npl, WSA_MACRO_MCLK_FREQ); 2878 2879 ret = clk_prepare_enable(wsa->macro); 2880 if (ret) 2881 goto err; 2882 2883 ret = clk_prepare_enable(wsa->dcodec); 2884 if (ret) 2885 goto err_dcodec; 2886 2887 ret = clk_prepare_enable(wsa->mclk); 2888 if (ret) 2889 goto err_mclk; 2890 2891 ret = clk_prepare_enable(wsa->npl); 2892 if (ret) 2893 goto err_npl; 2894 2895 ret = clk_prepare_enable(wsa->fsgen); 2896 if (ret) 2897 goto err_fsgen; 2898 2899 /* reset swr ip */ 2900 regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 2901 CDC_WSA_SWR_RST_EN_MASK, CDC_WSA_SWR_RST_ENABLE); 2902 2903 regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 2904 CDC_WSA_SWR_CLK_EN_MASK, CDC_WSA_SWR_CLK_ENABLE); 2905 2906 /* Bring out of reset */ 2907 regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 2908 CDC_WSA_SWR_RST_EN_MASK, CDC_WSA_SWR_RST_DISABLE); 2909 2910 ret = devm_snd_soc_register_component(dev, &wsa_macro_component_drv, 2911 wsa_macro_dai, 2912 ARRAY_SIZE(wsa_macro_dai)); 2913 if (ret) 2914 goto err_clkout; 2915 2916 pm_runtime_set_autosuspend_delay(dev, 3000); 2917 pm_runtime_use_autosuspend(dev); 2918 pm_runtime_mark_last_busy(dev); 2919 pm_runtime_set_active(dev); 2920 pm_runtime_enable(dev); 2921 2922 ret = wsa_macro_register_mclk_output(wsa); 2923 if (ret) 2924 goto err_clkout; 2925 2926 return 0; 2927 2928 err_clkout: 2929 clk_disable_unprepare(wsa->fsgen); 2930 err_fsgen: 2931 clk_disable_unprepare(wsa->npl); 2932 err_npl: 2933 clk_disable_unprepare(wsa->mclk); 2934 err_mclk: 2935 clk_disable_unprepare(wsa->dcodec); 2936 err_dcodec: 2937 clk_disable_unprepare(wsa->macro); 2938 err: 2939 return ret; 2940 2941 } 2942 2943 static void wsa_macro_remove(struct platform_device *pdev) 2944 { 2945 struct wsa_macro *wsa = dev_get_drvdata(&pdev->dev); 2946 2947 clk_disable_unprepare(wsa->macro); 2948 clk_disable_unprepare(wsa->dcodec); 2949 clk_disable_unprepare(wsa->mclk); 2950 clk_disable_unprepare(wsa->npl); 2951 clk_disable_unprepare(wsa->fsgen); 2952 } 2953 2954 static int wsa_macro_runtime_suspend(struct device *dev) 2955 { 2956 struct wsa_macro *wsa = dev_get_drvdata(dev); 2957 2958 regcache_cache_only(wsa->regmap, true); 2959 regcache_mark_dirty(wsa->regmap); 2960 2961 clk_disable_unprepare(wsa->fsgen); 2962 clk_disable_unprepare(wsa->npl); 2963 clk_disable_unprepare(wsa->mclk); 2964 2965 return 0; 2966 } 2967 2968 static int wsa_macro_runtime_resume(struct device *dev) 2969 { 2970 struct wsa_macro *wsa = dev_get_drvdata(dev); 2971 int ret; 2972 2973 ret = clk_prepare_enable(wsa->mclk); 2974 if (ret) { 2975 dev_err(dev, "unable to prepare mclk\n"); 2976 return ret; 2977 } 2978 2979 ret = clk_prepare_enable(wsa->npl); 2980 if (ret) { 2981 dev_err(dev, "unable to prepare mclkx2\n"); 2982 goto err_npl; 2983 } 2984 2985 ret = clk_prepare_enable(wsa->fsgen); 2986 if (ret) { 2987 dev_err(dev, "unable to prepare fsgen\n"); 2988 goto err_fsgen; 2989 } 2990 2991 regcache_cache_only(wsa->regmap, false); 2992 regcache_sync(wsa->regmap); 2993 2994 return 0; 2995 err_fsgen: 2996 clk_disable_unprepare(wsa->npl); 2997 err_npl: 2998 clk_disable_unprepare(wsa->mclk); 2999 3000 return ret; 3001 } 3002 3003 static const struct dev_pm_ops wsa_macro_pm_ops = { 3004 RUNTIME_PM_OPS(wsa_macro_runtime_suspend, wsa_macro_runtime_resume, NULL) 3005 }; 3006 3007 static const struct of_device_id wsa_macro_dt_match[] = { 3008 { 3009 .compatible = "qcom,sc7280-lpass-wsa-macro", 3010 .data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK, 3011 }, { 3012 .compatible = "qcom,sm8250-lpass-wsa-macro", 3013 .data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK, 3014 }, { 3015 .compatible = "qcom,sm8450-lpass-wsa-macro", 3016 .data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK, 3017 }, { 3018 .compatible = "qcom,sm8550-lpass-wsa-macro", 3019 }, { 3020 .compatible = "qcom,sc8280xp-lpass-wsa-macro", 3021 .data = (void *)LPASS_MACRO_FLAG_HAS_NPL_CLOCK, 3022 }, 3023 {} 3024 }; 3025 MODULE_DEVICE_TABLE(of, wsa_macro_dt_match); 3026 3027 static struct platform_driver wsa_macro_driver = { 3028 .driver = { 3029 .name = "wsa_macro", 3030 .of_match_table = wsa_macro_dt_match, 3031 .pm = pm_ptr(&wsa_macro_pm_ops), 3032 }, 3033 .probe = wsa_macro_probe, 3034 .remove = wsa_macro_remove, 3035 }; 3036 3037 module_platform_driver(wsa_macro_driver); 3038 MODULE_DESCRIPTION("WSA macro driver"); 3039 MODULE_LICENSE("GPL"); 3040