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