1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * cs42l73.c -- CS42L73 ALSA Soc Audio driver 4 * 5 * Copyright 2011 Cirrus Logic, Inc. 6 * 7 * Authors: Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com> 8 * Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com> 9 */ 10 11 #include <linux/module.h> 12 #include <linux/moduleparam.h> 13 #include <linux/kernel.h> 14 #include <linux/init.h> 15 #include <linux/delay.h> 16 #include <linux/of_gpio.h> 17 #include <linux/pm.h> 18 #include <linux/i2c.h> 19 #include <linux/regmap.h> 20 #include <linux/slab.h> 21 #include <sound/core.h> 22 #include <sound/pcm.h> 23 #include <sound/pcm_params.h> 24 #include <sound/soc.h> 25 #include <sound/soc-dapm.h> 26 #include <sound/initval.h> 27 #include <sound/tlv.h> 28 #include <sound/cs42l73.h> 29 #include "cs42l73.h" 30 31 struct sp_config { 32 u8 spc, mmcc, spfs; 33 u32 srate; 34 }; 35 struct cs42l73_private { 36 struct cs42l73_platform_data pdata; 37 struct sp_config config[3]; 38 struct regmap *regmap; 39 u32 sysclk; 40 u8 mclksel; 41 u32 mclk; 42 int shutdwn_delay; 43 }; 44 45 static const struct reg_default cs42l73_reg_defaults[] = { 46 { 6, 0xF1 }, /* r06 - Power Ctl 1 */ 47 { 7, 0xDF }, /* r07 - Power Ctl 2 */ 48 { 8, 0x3F }, /* r08 - Power Ctl 3 */ 49 { 9, 0x50 }, /* r09 - Charge Pump Freq */ 50 { 10, 0x53 }, /* r0A - Output Load MicBias Short Detect */ 51 { 11, 0x00 }, /* r0B - DMIC Master Clock Ctl */ 52 { 12, 0x00 }, /* r0C - Aux PCM Ctl */ 53 { 13, 0x15 }, /* r0D - Aux PCM Master Clock Ctl */ 54 { 14, 0x00 }, /* r0E - Audio PCM Ctl */ 55 { 15, 0x15 }, /* r0F - Audio PCM Master Clock Ctl */ 56 { 16, 0x00 }, /* r10 - Voice PCM Ctl */ 57 { 17, 0x15 }, /* r11 - Voice PCM Master Clock Ctl */ 58 { 18, 0x00 }, /* r12 - Voice/Aux Sample Rate */ 59 { 19, 0x06 }, /* r13 - Misc I/O Path Ctl */ 60 { 20, 0x00 }, /* r14 - ADC Input Path Ctl */ 61 { 21, 0x00 }, /* r15 - MICA Preamp, PGA Volume */ 62 { 22, 0x00 }, /* r16 - MICB Preamp, PGA Volume */ 63 { 23, 0x00 }, /* r17 - Input Path A Digital Volume */ 64 { 24, 0x00 }, /* r18 - Input Path B Digital Volume */ 65 { 25, 0x00 }, /* r19 - Playback Digital Ctl */ 66 { 26, 0x00 }, /* r1A - HP/LO Left Digital Volume */ 67 { 27, 0x00 }, /* r1B - HP/LO Right Digital Volume */ 68 { 28, 0x00 }, /* r1C - Speakerphone Digital Volume */ 69 { 29, 0x00 }, /* r1D - Ear/SPKLO Digital Volume */ 70 { 30, 0x00 }, /* r1E - HP Left Analog Volume */ 71 { 31, 0x00 }, /* r1F - HP Right Analog Volume */ 72 { 32, 0x00 }, /* r20 - LO Left Analog Volume */ 73 { 33, 0x00 }, /* r21 - LO Right Analog Volume */ 74 { 34, 0x00 }, /* r22 - Stereo Input Path Advisory Volume */ 75 { 35, 0x00 }, /* r23 - Aux PCM Input Advisory Volume */ 76 { 36, 0x00 }, /* r24 - Audio PCM Input Advisory Volume */ 77 { 37, 0x00 }, /* r25 - Voice PCM Input Advisory Volume */ 78 { 38, 0x00 }, /* r26 - Limiter Attack Rate HP/LO */ 79 { 39, 0x7F }, /* r27 - Limter Ctl, Release Rate HP/LO */ 80 { 40, 0x00 }, /* r28 - Limter Threshold HP/LO */ 81 { 41, 0x00 }, /* r29 - Limiter Attack Rate Speakerphone */ 82 { 42, 0x3F }, /* r2A - Limter Ctl, Release Rate Speakerphone */ 83 { 43, 0x00 }, /* r2B - Limter Threshold Speakerphone */ 84 { 44, 0x00 }, /* r2C - Limiter Attack Rate Ear/SPKLO */ 85 { 45, 0x3F }, /* r2D - Limter Ctl, Release Rate Ear/SPKLO */ 86 { 46, 0x00 }, /* r2E - Limter Threshold Ear/SPKLO */ 87 { 47, 0x00 }, /* r2F - ALC Enable, Attack Rate Left/Right */ 88 { 48, 0x3F }, /* r30 - ALC Release Rate Left/Right */ 89 { 49, 0x00 }, /* r31 - ALC Threshold Left/Right */ 90 { 50, 0x00 }, /* r32 - Noise Gate Ctl Left/Right */ 91 { 51, 0x00 }, /* r33 - ALC/NG Misc Ctl */ 92 { 52, 0x18 }, /* r34 - Mixer Ctl */ 93 { 53, 0x3F }, /* r35 - HP/LO Left Mixer Input Path Volume */ 94 { 54, 0x3F }, /* r36 - HP/LO Right Mixer Input Path Volume */ 95 { 55, 0x3F }, /* r37 - HP/LO Left Mixer Aux PCM Volume */ 96 { 56, 0x3F }, /* r38 - HP/LO Right Mixer Aux PCM Volume */ 97 { 57, 0x3F }, /* r39 - HP/LO Left Mixer Audio PCM Volume */ 98 { 58, 0x3F }, /* r3A - HP/LO Right Mixer Audio PCM Volume */ 99 { 59, 0x3F }, /* r3B - HP/LO Left Mixer Voice PCM Mono Volume */ 100 { 60, 0x3F }, /* r3C - HP/LO Right Mixer Voice PCM Mono Volume */ 101 { 61, 0x3F }, /* r3D - Aux PCM Left Mixer Input Path Volume */ 102 { 62, 0x3F }, /* r3E - Aux PCM Right Mixer Input Path Volume */ 103 { 63, 0x3F }, /* r3F - Aux PCM Left Mixer Volume */ 104 { 64, 0x3F }, /* r40 - Aux PCM Left Mixer Volume */ 105 { 65, 0x3F }, /* r41 - Aux PCM Left Mixer Audio PCM L Volume */ 106 { 66, 0x3F }, /* r42 - Aux PCM Right Mixer Audio PCM R Volume */ 107 { 67, 0x3F }, /* r43 - Aux PCM Left Mixer Voice PCM Volume */ 108 { 68, 0x3F }, /* r44 - Aux PCM Right Mixer Voice PCM Volume */ 109 { 69, 0x3F }, /* r45 - Audio PCM Left Input Path Volume */ 110 { 70, 0x3F }, /* r46 - Audio PCM Right Input Path Volume */ 111 { 71, 0x3F }, /* r47 - Audio PCM Left Mixer Aux PCM L Volume */ 112 { 72, 0x3F }, /* r48 - Audio PCM Right Mixer Aux PCM R Volume */ 113 { 73, 0x3F }, /* r49 - Audio PCM Left Mixer Volume */ 114 { 74, 0x3F }, /* r4A - Audio PCM Right Mixer Volume */ 115 { 75, 0x3F }, /* r4B - Audio PCM Left Mixer Voice PCM Volume */ 116 { 76, 0x3F }, /* r4C - Audio PCM Right Mixer Voice PCM Volume */ 117 { 77, 0x3F }, /* r4D - Voice PCM Left Input Path Volume */ 118 { 78, 0x3F }, /* r4E - Voice PCM Right Input Path Volume */ 119 { 79, 0x3F }, /* r4F - Voice PCM Left Mixer Aux PCM L Volume */ 120 { 80, 0x3F }, /* r50 - Voice PCM Right Mixer Aux PCM R Volume */ 121 { 81, 0x3F }, /* r51 - Voice PCM Left Mixer Audio PCM L Volume */ 122 { 82, 0x3F }, /* r52 - Voice PCM Right Mixer Audio PCM R Volume */ 123 { 83, 0x3F }, /* r53 - Voice PCM Left Mixer Voice PCM Volume */ 124 { 84, 0x3F }, /* r54 - Voice PCM Right Mixer Voice PCM Volume */ 125 { 85, 0xAA }, /* r55 - Mono Mixer Ctl */ 126 { 86, 0x3F }, /* r56 - SPK Mono Mixer Input Path Volume */ 127 { 87, 0x3F }, /* r57 - SPK Mono Mixer Aux PCM Mono/L/R Volume */ 128 { 88, 0x3F }, /* r58 - SPK Mono Mixer Audio PCM Mono/L/R Volume */ 129 { 89, 0x3F }, /* r59 - SPK Mono Mixer Voice PCM Mono Volume */ 130 { 90, 0x3F }, /* r5A - SPKLO Mono Mixer Input Path Mono Volume */ 131 { 91, 0x3F }, /* r5B - SPKLO Mono Mixer Aux Mono/L/R Volume */ 132 { 92, 0x3F }, /* r5C - SPKLO Mono Mixer Audio Mono/L/R Volume */ 133 { 93, 0x3F }, /* r5D - SPKLO Mono Mixer Voice Mono Volume */ 134 { 94, 0x00 }, /* r5E - Interrupt Mask 1 */ 135 { 95, 0x00 }, /* r5F - Interrupt Mask 2 */ 136 }; 137 138 static bool cs42l73_volatile_register(struct device *dev, unsigned int reg) 139 { 140 switch (reg) { 141 case CS42L73_IS1: 142 case CS42L73_IS2: 143 return true; 144 default: 145 return false; 146 } 147 } 148 149 static bool cs42l73_readable_register(struct device *dev, unsigned int reg) 150 { 151 switch (reg) { 152 case CS42L73_DEVID_AB ... CS42L73_DEVID_E: 153 case CS42L73_REVID ... CS42L73_IM2: 154 return true; 155 default: 156 return false; 157 } 158 } 159 160 static const DECLARE_TLV_DB_RANGE(hpaloa_tlv, 161 0, 13, TLV_DB_SCALE_ITEM(-7600, 200, 0), 162 14, 75, TLV_DB_SCALE_ITEM(-4900, 100, 0) 163 ); 164 165 static DECLARE_TLV_DB_SCALE(adc_boost_tlv, 0, 2500, 0); 166 167 static DECLARE_TLV_DB_SCALE(hl_tlv, -10200, 50, 0); 168 169 static DECLARE_TLV_DB_SCALE(ipd_tlv, -9600, 100, 0); 170 171 static DECLARE_TLV_DB_SCALE(micpga_tlv, -600, 50, 0); 172 173 static const DECLARE_TLV_DB_RANGE(limiter_tlv, 174 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0), 175 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0) 176 ); 177 178 static const DECLARE_TLV_DB_SCALE(attn_tlv, -6300, 100, 1); 179 180 static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" }; 181 static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" }; 182 183 static SOC_ENUM_SINGLE_DECL(pgaa_enum, 184 CS42L73_ADCIPC, 3, 185 cs42l73_pgaa_text); 186 187 static SOC_ENUM_SINGLE_DECL(pgab_enum, 188 CS42L73_ADCIPC, 7, 189 cs42l73_pgab_text); 190 191 static const struct snd_kcontrol_new pgaa_mux = 192 SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum); 193 194 static const struct snd_kcontrol_new pgab_mux = 195 SOC_DAPM_ENUM("Right Analog Input Capture Mux", pgab_enum); 196 197 static const struct snd_kcontrol_new input_left_mixer[] = { 198 SOC_DAPM_SINGLE("ADC Left Input", CS42L73_PWRCTL1, 199 5, 1, 1), 200 SOC_DAPM_SINGLE("DMIC Left Input", CS42L73_PWRCTL1, 201 4, 1, 1), 202 }; 203 204 static const struct snd_kcontrol_new input_right_mixer[] = { 205 SOC_DAPM_SINGLE("ADC Right Input", CS42L73_PWRCTL1, 206 7, 1, 1), 207 SOC_DAPM_SINGLE("DMIC Right Input", CS42L73_PWRCTL1, 208 6, 1, 1), 209 }; 210 211 static const char * const cs42l73_ng_delay_text[] = { 212 "50ms", "100ms", "150ms", "200ms" }; 213 214 static SOC_ENUM_SINGLE_DECL(ng_delay_enum, 215 CS42L73_NGCAB, 0, 216 cs42l73_ng_delay_text); 217 218 static const char * const cs42l73_mono_mix_texts[] = { 219 "Left", "Right", "Mono Mix"}; 220 221 static const unsigned int cs42l73_mono_mix_values[] = { 0, 1, 2 }; 222 223 static const struct soc_enum spk_asp_enum = 224 SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 3, 225 ARRAY_SIZE(cs42l73_mono_mix_texts), 226 cs42l73_mono_mix_texts, 227 cs42l73_mono_mix_values); 228 229 static const struct snd_kcontrol_new spk_asp_mixer = 230 SOC_DAPM_ENUM("Route", spk_asp_enum); 231 232 static const struct soc_enum spk_xsp_enum = 233 SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 4, 3, 234 ARRAY_SIZE(cs42l73_mono_mix_texts), 235 cs42l73_mono_mix_texts, 236 cs42l73_mono_mix_values); 237 238 static const struct snd_kcontrol_new spk_xsp_mixer = 239 SOC_DAPM_ENUM("Route", spk_xsp_enum); 240 241 static const struct soc_enum esl_asp_enum = 242 SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 3, 243 ARRAY_SIZE(cs42l73_mono_mix_texts), 244 cs42l73_mono_mix_texts, 245 cs42l73_mono_mix_values); 246 247 static const struct snd_kcontrol_new esl_asp_mixer = 248 SOC_DAPM_ENUM("Route", esl_asp_enum); 249 250 static const struct soc_enum esl_xsp_enum = 251 SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 3, 252 ARRAY_SIZE(cs42l73_mono_mix_texts), 253 cs42l73_mono_mix_texts, 254 cs42l73_mono_mix_values); 255 256 static const struct snd_kcontrol_new esl_xsp_mixer = 257 SOC_DAPM_ENUM("Route", esl_xsp_enum); 258 259 static const char * const cs42l73_ip_swap_text[] = { 260 "Stereo", "Mono A", "Mono B", "Swap A-B"}; 261 262 static SOC_ENUM_SINGLE_DECL(ip_swap_enum, 263 CS42L73_MIOPC, 6, 264 cs42l73_ip_swap_text); 265 266 static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"}; 267 268 static SOC_ENUM_SINGLE_DECL(vsp_output_mux_enum, 269 CS42L73_MIXERCTL, 5, 270 cs42l73_spo_mixer_text); 271 272 static SOC_ENUM_SINGLE_DECL(xsp_output_mux_enum, 273 CS42L73_MIXERCTL, 4, 274 cs42l73_spo_mixer_text); 275 276 static const struct snd_kcontrol_new hp_amp_ctl = 277 SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 0, 1, 1); 278 279 static const struct snd_kcontrol_new lo_amp_ctl = 280 SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 1, 1, 1); 281 282 static const struct snd_kcontrol_new spk_amp_ctl = 283 SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 2, 1, 1); 284 285 static const struct snd_kcontrol_new spklo_amp_ctl = 286 SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 4, 1, 1); 287 288 static const struct snd_kcontrol_new ear_amp_ctl = 289 SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 3, 1, 1); 290 291 static const struct snd_kcontrol_new cs42l73_snd_controls[] = { 292 SOC_DOUBLE_R_SX_TLV("Headphone Analog Playback Volume", 293 CS42L73_HPAAVOL, CS42L73_HPBAVOL, 0, 294 0x41, 0x4B, hpaloa_tlv), 295 296 SOC_DOUBLE_R_SX_TLV("LineOut Analog Playback Volume", CS42L73_LOAAVOL, 297 CS42L73_LOBAVOL, 0, 0x41, 0x4B, hpaloa_tlv), 298 299 SOC_DOUBLE_R_SX_TLV("Input PGA Analog Volume", CS42L73_MICAPREPGAAVOL, 300 CS42L73_MICBPREPGABVOL, 0, 0x34, 301 0x24, micpga_tlv), 302 303 SOC_DOUBLE_R("MIC Preamp Switch", CS42L73_MICAPREPGAAVOL, 304 CS42L73_MICBPREPGABVOL, 6, 1, 1), 305 306 SOC_DOUBLE_R_SX_TLV("Input Path Digital Volume", CS42L73_IPADVOL, 307 CS42L73_IPBDVOL, 0, 0xA0, 0x6C, ipd_tlv), 308 309 SOC_DOUBLE_R_SX_TLV("HL Digital Playback Volume", 310 CS42L73_HLADVOL, CS42L73_HLBDVOL, 311 0, 0x34, 0xE4, hl_tlv), 312 313 SOC_SINGLE_TLV("ADC A Boost Volume", 314 CS42L73_ADCIPC, 2, 0x01, 1, adc_boost_tlv), 315 316 SOC_SINGLE_TLV("ADC B Boost Volume", 317 CS42L73_ADCIPC, 6, 0x01, 1, adc_boost_tlv), 318 319 SOC_SINGLE_SX_TLV("Speakerphone Digital Volume", 320 CS42L73_SPKDVOL, 0, 0x34, 0xE4, hl_tlv), 321 322 SOC_SINGLE_SX_TLV("Ear Speaker Digital Volume", 323 CS42L73_ESLDVOL, 0, 0x34, 0xE4, hl_tlv), 324 325 SOC_DOUBLE_R("Headphone Analog Playback Switch", CS42L73_HPAAVOL, 326 CS42L73_HPBAVOL, 7, 1, 1), 327 328 SOC_DOUBLE_R("LineOut Analog Playback Switch", CS42L73_LOAAVOL, 329 CS42L73_LOBAVOL, 7, 1, 1), 330 SOC_DOUBLE("Input Path Digital Switch", CS42L73_ADCIPC, 0, 4, 1, 1), 331 SOC_DOUBLE("HL Digital Playback Switch", CS42L73_PBDC, 0, 332 1, 1, 1), 333 SOC_SINGLE("Speakerphone Digital Playback Switch", CS42L73_PBDC, 2, 1, 334 1), 335 SOC_SINGLE("Ear Speaker Digital Playback Switch", CS42L73_PBDC, 3, 1, 336 1), 337 338 SOC_SINGLE("PGA Soft-Ramp Switch", CS42L73_MIOPC, 3, 1, 0), 339 SOC_SINGLE("Analog Zero Cross Switch", CS42L73_MIOPC, 2, 1, 0), 340 SOC_SINGLE("Digital Soft-Ramp Switch", CS42L73_MIOPC, 1, 1, 0), 341 SOC_SINGLE("Analog Output Soft-Ramp Switch", CS42L73_MIOPC, 0, 1, 0), 342 343 SOC_DOUBLE("ADC Signal Polarity Switch", CS42L73_ADCIPC, 1, 5, 1, 344 0), 345 346 SOC_SINGLE("HL Limiter Attack Rate", CS42L73_LIMARATEHL, 0, 0x3F, 347 0), 348 SOC_SINGLE("HL Limiter Release Rate", CS42L73_LIMRRATEHL, 0, 349 0x3F, 0), 350 351 352 SOC_SINGLE("HL Limiter Switch", CS42L73_LIMRRATEHL, 7, 1, 0), 353 SOC_SINGLE("HL Limiter All Channels Switch", CS42L73_LIMRRATEHL, 6, 1, 354 0), 355 356 SOC_SINGLE_TLV("HL Limiter Max Threshold Volume", CS42L73_LMAXHL, 5, 7, 357 1, limiter_tlv), 358 359 SOC_SINGLE_TLV("HL Limiter Cushion Volume", CS42L73_LMAXHL, 2, 7, 1, 360 limiter_tlv), 361 362 SOC_SINGLE("SPK Limiter Attack Rate Volume", CS42L73_LIMARATESPK, 0, 363 0x3F, 0), 364 SOC_SINGLE("SPK Limiter Release Rate Volume", CS42L73_LIMRRATESPK, 0, 365 0x3F, 0), 366 SOC_SINGLE("SPK Limiter Switch", CS42L73_LIMRRATESPK, 7, 1, 0), 367 SOC_SINGLE("SPK Limiter All Channels Switch", CS42L73_LIMRRATESPK, 368 6, 1, 0), 369 SOC_SINGLE_TLV("SPK Limiter Max Threshold Volume", CS42L73_LMAXSPK, 5, 370 7, 1, limiter_tlv), 371 372 SOC_SINGLE_TLV("SPK Limiter Cushion Volume", CS42L73_LMAXSPK, 2, 7, 1, 373 limiter_tlv), 374 375 SOC_SINGLE("ESL Limiter Attack Rate Volume", CS42L73_LIMARATEESL, 0, 376 0x3F, 0), 377 SOC_SINGLE("ESL Limiter Release Rate Volume", CS42L73_LIMRRATEESL, 0, 378 0x3F, 0), 379 SOC_SINGLE("ESL Limiter Switch", CS42L73_LIMRRATEESL, 7, 1, 0), 380 SOC_SINGLE_TLV("ESL Limiter Max Threshold Volume", CS42L73_LMAXESL, 5, 381 7, 1, limiter_tlv), 382 383 SOC_SINGLE_TLV("ESL Limiter Cushion Volume", CS42L73_LMAXESL, 2, 7, 1, 384 limiter_tlv), 385 386 SOC_SINGLE("ALC Attack Rate Volume", CS42L73_ALCARATE, 0, 0x3F, 0), 387 SOC_SINGLE("ALC Release Rate Volume", CS42L73_ALCRRATE, 0, 0x3F, 0), 388 SOC_DOUBLE("ALC Switch", CS42L73_ALCARATE, 6, 7, 1, 0), 389 SOC_SINGLE_TLV("ALC Max Threshold Volume", CS42L73_ALCMINMAX, 5, 7, 0, 390 limiter_tlv), 391 SOC_SINGLE_TLV("ALC Min Threshold Volume", CS42L73_ALCMINMAX, 2, 7, 0, 392 limiter_tlv), 393 394 SOC_DOUBLE("NG Enable Switch", CS42L73_NGCAB, 6, 7, 1, 0), 395 SOC_SINGLE("NG Boost Switch", CS42L73_NGCAB, 5, 1, 0), 396 /* 397 NG Threshold depends on NG_BOOTSAB, which selects 398 between two threshold scales in decibels. 399 Set linear values for now .. 400 */ 401 SOC_SINGLE("NG Threshold", CS42L73_NGCAB, 2, 7, 0), 402 SOC_ENUM("NG Delay", ng_delay_enum), 403 404 SOC_DOUBLE_R_TLV("XSP-IP Volume", 405 CS42L73_XSPAIPAA, CS42L73_XSPBIPBA, 0, 0x3F, 1, 406 attn_tlv), 407 SOC_DOUBLE_R_TLV("XSP-XSP Volume", 408 CS42L73_XSPAXSPAA, CS42L73_XSPBXSPBA, 0, 0x3F, 1, 409 attn_tlv), 410 SOC_DOUBLE_R_TLV("XSP-ASP Volume", 411 CS42L73_XSPAASPAA, CS42L73_XSPAASPBA, 0, 0x3F, 1, 412 attn_tlv), 413 SOC_DOUBLE_R_TLV("XSP-VSP Volume", 414 CS42L73_XSPAVSPMA, CS42L73_XSPBVSPMA, 0, 0x3F, 1, 415 attn_tlv), 416 417 SOC_DOUBLE_R_TLV("ASP-IP Volume", 418 CS42L73_ASPAIPAA, CS42L73_ASPBIPBA, 0, 0x3F, 1, 419 attn_tlv), 420 SOC_DOUBLE_R_TLV("ASP-XSP Volume", 421 CS42L73_ASPAXSPAA, CS42L73_ASPBXSPBA, 0, 0x3F, 1, 422 attn_tlv), 423 SOC_DOUBLE_R_TLV("ASP-ASP Volume", 424 CS42L73_ASPAASPAA, CS42L73_ASPBASPBA, 0, 0x3F, 1, 425 attn_tlv), 426 SOC_DOUBLE_R_TLV("ASP-VSP Volume", 427 CS42L73_ASPAVSPMA, CS42L73_ASPBVSPMA, 0, 0x3F, 1, 428 attn_tlv), 429 430 SOC_DOUBLE_R_TLV("VSP-IP Volume", 431 CS42L73_VSPAIPAA, CS42L73_VSPBIPBA, 0, 0x3F, 1, 432 attn_tlv), 433 SOC_DOUBLE_R_TLV("VSP-XSP Volume", 434 CS42L73_VSPAXSPAA, CS42L73_VSPBXSPBA, 0, 0x3F, 1, 435 attn_tlv), 436 SOC_DOUBLE_R_TLV("VSP-ASP Volume", 437 CS42L73_VSPAASPAA, CS42L73_VSPBASPBA, 0, 0x3F, 1, 438 attn_tlv), 439 SOC_DOUBLE_R_TLV("VSP-VSP Volume", 440 CS42L73_VSPAVSPMA, CS42L73_VSPBVSPMA, 0, 0x3F, 1, 441 attn_tlv), 442 443 SOC_DOUBLE_R_TLV("HL-IP Volume", 444 CS42L73_HLAIPAA, CS42L73_HLBIPBA, 0, 0x3F, 1, 445 attn_tlv), 446 SOC_DOUBLE_R_TLV("HL-XSP Volume", 447 CS42L73_HLAXSPAA, CS42L73_HLBXSPBA, 0, 0x3F, 1, 448 attn_tlv), 449 SOC_DOUBLE_R_TLV("HL-ASP Volume", 450 CS42L73_HLAASPAA, CS42L73_HLBASPBA, 0, 0x3F, 1, 451 attn_tlv), 452 SOC_DOUBLE_R_TLV("HL-VSP Volume", 453 CS42L73_HLAVSPMA, CS42L73_HLBVSPMA, 0, 0x3F, 1, 454 attn_tlv), 455 456 SOC_SINGLE_TLV("SPK-IP Mono Volume", 457 CS42L73_SPKMIPMA, 0, 0x3F, 1, attn_tlv), 458 SOC_SINGLE_TLV("SPK-XSP Mono Volume", 459 CS42L73_SPKMXSPA, 0, 0x3F, 1, attn_tlv), 460 SOC_SINGLE_TLV("SPK-ASP Mono Volume", 461 CS42L73_SPKMASPA, 0, 0x3F, 1, attn_tlv), 462 SOC_SINGLE_TLV("SPK-VSP Mono Volume", 463 CS42L73_SPKMVSPMA, 0, 0x3F, 1, attn_tlv), 464 465 SOC_SINGLE_TLV("ESL-IP Mono Volume", 466 CS42L73_ESLMIPMA, 0, 0x3F, 1, attn_tlv), 467 SOC_SINGLE_TLV("ESL-XSP Mono Volume", 468 CS42L73_ESLMXSPA, 0, 0x3F, 1, attn_tlv), 469 SOC_SINGLE_TLV("ESL-ASP Mono Volume", 470 CS42L73_ESLMASPA, 0, 0x3F, 1, attn_tlv), 471 SOC_SINGLE_TLV("ESL-VSP Mono Volume", 472 CS42L73_ESLMVSPMA, 0, 0x3F, 1, attn_tlv), 473 474 SOC_ENUM("IP Digital Swap/Mono Select", ip_swap_enum), 475 476 SOC_ENUM("VSPOUT Mono/Stereo Select", vsp_output_mux_enum), 477 SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum), 478 }; 479 480 static int cs42l73_spklo_spk_amp_event(struct snd_soc_dapm_widget *w, 481 struct snd_kcontrol *kcontrol, int event) 482 { 483 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 484 struct cs42l73_private *priv = snd_soc_component_get_drvdata(component); 485 switch (event) { 486 case SND_SOC_DAPM_POST_PMD: 487 /* 150 ms delay between setting PDN and MCLKDIS */ 488 priv->shutdwn_delay = 150; 489 break; 490 default: 491 pr_err("Invalid event = 0x%x\n", event); 492 } 493 return 0; 494 } 495 496 static int cs42l73_ear_amp_event(struct snd_soc_dapm_widget *w, 497 struct snd_kcontrol *kcontrol, int event) 498 { 499 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 500 struct cs42l73_private *priv = snd_soc_component_get_drvdata(component); 501 switch (event) { 502 case SND_SOC_DAPM_POST_PMD: 503 /* 50 ms delay between setting PDN and MCLKDIS */ 504 if (priv->shutdwn_delay < 50) 505 priv->shutdwn_delay = 50; 506 break; 507 default: 508 pr_err("Invalid event = 0x%x\n", event); 509 } 510 return 0; 511 } 512 513 514 static int cs42l73_hp_amp_event(struct snd_soc_dapm_widget *w, 515 struct snd_kcontrol *kcontrol, int event) 516 { 517 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 518 struct cs42l73_private *priv = snd_soc_component_get_drvdata(component); 519 switch (event) { 520 case SND_SOC_DAPM_POST_PMD: 521 /* 30 ms delay between setting PDN and MCLKDIS */ 522 if (priv->shutdwn_delay < 30) 523 priv->shutdwn_delay = 30; 524 break; 525 default: 526 pr_err("Invalid event = 0x%x\n", event); 527 } 528 return 0; 529 } 530 531 static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { 532 SND_SOC_DAPM_INPUT("DMICA"), 533 SND_SOC_DAPM_INPUT("DMICB"), 534 SND_SOC_DAPM_INPUT("LINEINA"), 535 SND_SOC_DAPM_INPUT("LINEINB"), 536 SND_SOC_DAPM_INPUT("MIC1"), 537 SND_SOC_DAPM_SUPPLY("MIC1 Bias", CS42L73_PWRCTL2, 6, 1, NULL, 0), 538 SND_SOC_DAPM_INPUT("MIC2"), 539 SND_SOC_DAPM_SUPPLY("MIC2 Bias", CS42L73_PWRCTL2, 7, 1, NULL, 0), 540 541 SND_SOC_DAPM_AIF_OUT("XSPOUTL", NULL, 0, 542 CS42L73_PWRCTL2, 1, 1), 543 SND_SOC_DAPM_AIF_OUT("XSPOUTR", NULL, 0, 544 CS42L73_PWRCTL2, 1, 1), 545 SND_SOC_DAPM_AIF_OUT("ASPOUTL", NULL, 0, 546 CS42L73_PWRCTL2, 3, 1), 547 SND_SOC_DAPM_AIF_OUT("ASPOUTR", NULL, 0, 548 CS42L73_PWRCTL2, 3, 1), 549 SND_SOC_DAPM_AIF_OUT("VSPINOUT", NULL, 0, 550 CS42L73_PWRCTL2, 4, 1), 551 552 SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0), 553 SND_SOC_DAPM_PGA("PGA Right", SND_SOC_NOPM, 0, 0, NULL, 0), 554 555 SND_SOC_DAPM_MUX("PGA Left Mux", SND_SOC_NOPM, 0, 0, &pgaa_mux), 556 SND_SOC_DAPM_MUX("PGA Right Mux", SND_SOC_NOPM, 0, 0, &pgab_mux), 557 558 SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L73_PWRCTL1, 7, 1), 559 SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L73_PWRCTL1, 5, 1), 560 SND_SOC_DAPM_ADC("DMIC Left", NULL, CS42L73_PWRCTL1, 6, 1), 561 SND_SOC_DAPM_ADC("DMIC Right", NULL, CS42L73_PWRCTL1, 4, 1), 562 563 SND_SOC_DAPM_MIXER_NAMED_CTL("Input Left Capture", SND_SOC_NOPM, 564 0, 0, input_left_mixer, 565 ARRAY_SIZE(input_left_mixer)), 566 567 SND_SOC_DAPM_MIXER_NAMED_CTL("Input Right Capture", SND_SOC_NOPM, 568 0, 0, input_right_mixer, 569 ARRAY_SIZE(input_right_mixer)), 570 571 SND_SOC_DAPM_MIXER("ASPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 572 SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 573 SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 574 SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 575 SND_SOC_DAPM_MIXER("VSP Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 576 577 SND_SOC_DAPM_AIF_IN("XSPINL", NULL, 0, 578 CS42L73_PWRCTL2, 0, 1), 579 SND_SOC_DAPM_AIF_IN("XSPINR", NULL, 0, 580 CS42L73_PWRCTL2, 0, 1), 581 SND_SOC_DAPM_AIF_IN("XSPINM", NULL, 0, 582 CS42L73_PWRCTL2, 0, 1), 583 584 SND_SOC_DAPM_AIF_IN("ASPINL", NULL, 0, 585 CS42L73_PWRCTL2, 2, 1), 586 SND_SOC_DAPM_AIF_IN("ASPINR", NULL, 0, 587 CS42L73_PWRCTL2, 2, 1), 588 SND_SOC_DAPM_AIF_IN("ASPINM", NULL, 0, 589 CS42L73_PWRCTL2, 2, 1), 590 591 SND_SOC_DAPM_AIF_IN("VSPINOUT", NULL, 0, 592 CS42L73_PWRCTL2, 4, 1), 593 594 SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 595 SND_SOC_DAPM_MIXER("HL Right Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 596 SND_SOC_DAPM_MIXER("SPK Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 597 SND_SOC_DAPM_MIXER("ESL Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 598 599 SND_SOC_DAPM_MUX("ESL-XSP Mux", SND_SOC_NOPM, 600 0, 0, &esl_xsp_mixer), 601 602 SND_SOC_DAPM_MUX("ESL-ASP Mux", SND_SOC_NOPM, 603 0, 0, &esl_asp_mixer), 604 605 SND_SOC_DAPM_MUX("SPK-ASP Mux", SND_SOC_NOPM, 606 0, 0, &spk_asp_mixer), 607 608 SND_SOC_DAPM_MUX("SPK-XSP Mux", SND_SOC_NOPM, 609 0, 0, &spk_xsp_mixer), 610 611 SND_SOC_DAPM_PGA("HL Left DAC", SND_SOC_NOPM, 0, 0, NULL, 0), 612 SND_SOC_DAPM_PGA("HL Right DAC", SND_SOC_NOPM, 0, 0, NULL, 0), 613 SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0), 614 SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0), 615 616 SND_SOC_DAPM_SWITCH_E("HP Amp", CS42L73_PWRCTL3, 0, 1, 617 &hp_amp_ctl, cs42l73_hp_amp_event, 618 SND_SOC_DAPM_POST_PMD), 619 SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1, 620 &lo_amp_ctl), 621 SND_SOC_DAPM_SWITCH_E("SPK Amp", CS42L73_PWRCTL3, 2, 1, 622 &spk_amp_ctl, cs42l73_spklo_spk_amp_event, 623 SND_SOC_DAPM_POST_PMD), 624 SND_SOC_DAPM_SWITCH_E("EAR Amp", CS42L73_PWRCTL3, 3, 1, 625 &ear_amp_ctl, cs42l73_ear_amp_event, 626 SND_SOC_DAPM_POST_PMD), 627 SND_SOC_DAPM_SWITCH_E("SPKLO Amp", CS42L73_PWRCTL3, 4, 1, 628 &spklo_amp_ctl, cs42l73_spklo_spk_amp_event, 629 SND_SOC_DAPM_POST_PMD), 630 631 SND_SOC_DAPM_OUTPUT("HPOUTA"), 632 SND_SOC_DAPM_OUTPUT("HPOUTB"), 633 SND_SOC_DAPM_OUTPUT("LINEOUTA"), 634 SND_SOC_DAPM_OUTPUT("LINEOUTB"), 635 SND_SOC_DAPM_OUTPUT("EAROUT"), 636 SND_SOC_DAPM_OUTPUT("SPKOUT"), 637 SND_SOC_DAPM_OUTPUT("SPKLINEOUT"), 638 }; 639 640 static const struct snd_soc_dapm_route cs42l73_audio_map[] = { 641 642 /* SPKLO EARSPK Paths */ 643 {"EAROUT", NULL, "EAR Amp"}, 644 {"SPKLINEOUT", NULL, "SPKLO Amp"}, 645 646 {"EAR Amp", "Switch", "ESL DAC"}, 647 {"SPKLO Amp", "Switch", "ESL DAC"}, 648 649 {"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"}, 650 {"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"}, 651 {"ESL DAC", "ESL-VSP Mono Volume", "VSPINOUT"}, 652 /* Loopback */ 653 {"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"}, 654 {"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"}, 655 656 {"ESL Mixer", NULL, "ESL-ASP Mux"}, 657 {"ESL Mixer", NULL, "ESL-XSP Mux"}, 658 659 {"ESL-ASP Mux", "Left", "ASPINL"}, 660 {"ESL-ASP Mux", "Right", "ASPINR"}, 661 {"ESL-ASP Mux", "Mono Mix", "ASPINM"}, 662 663 {"ESL-XSP Mux", "Left", "XSPINL"}, 664 {"ESL-XSP Mux", "Right", "XSPINR"}, 665 {"ESL-XSP Mux", "Mono Mix", "XSPINM"}, 666 667 /* Speakerphone Paths */ 668 {"SPKOUT", NULL, "SPK Amp"}, 669 {"SPK Amp", "Switch", "SPK DAC"}, 670 671 {"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"}, 672 {"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"}, 673 {"SPK DAC", "SPK-VSP Mono Volume", "VSPINOUT"}, 674 /* Loopback */ 675 {"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"}, 676 {"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"}, 677 678 {"SPK Mixer", NULL, "SPK-ASP Mux"}, 679 {"SPK Mixer", NULL, "SPK-XSP Mux"}, 680 681 {"SPK-ASP Mux", "Left", "ASPINL"}, 682 {"SPK-ASP Mux", "Mono Mix", "ASPINM"}, 683 {"SPK-ASP Mux", "Right", "ASPINR"}, 684 685 {"SPK-XSP Mux", "Left", "XSPINL"}, 686 {"SPK-XSP Mux", "Mono Mix", "XSPINM"}, 687 {"SPK-XSP Mux", "Right", "XSPINR"}, 688 689 /* HP LineOUT Paths */ 690 {"HPOUTA", NULL, "HP Amp"}, 691 {"HPOUTB", NULL, "HP Amp"}, 692 {"LINEOUTA", NULL, "LO Amp"}, 693 {"LINEOUTB", NULL, "LO Amp"}, 694 695 {"HP Amp", "Switch", "HL Left DAC"}, 696 {"HP Amp", "Switch", "HL Right DAC"}, 697 {"LO Amp", "Switch", "HL Left DAC"}, 698 {"LO Amp", "Switch", "HL Right DAC"}, 699 700 {"HL Left DAC", "HL-XSP Volume", "HL Left Mixer"}, 701 {"HL Right DAC", "HL-XSP Volume", "HL Right Mixer"}, 702 {"HL Left DAC", "HL-ASP Volume", "HL Left Mixer"}, 703 {"HL Right DAC", "HL-ASP Volume", "HL Right Mixer"}, 704 {"HL Left DAC", "HL-VSP Volume", "HL Left Mixer"}, 705 {"HL Right DAC", "HL-VSP Volume", "HL Right Mixer"}, 706 /* Loopback */ 707 {"HL Left DAC", "HL-IP Volume", "HL Left Mixer"}, 708 {"HL Right DAC", "HL-IP Volume", "HL Right Mixer"}, 709 {"HL Left Mixer", NULL, "Input Left Capture"}, 710 {"HL Right Mixer", NULL, "Input Right Capture"}, 711 712 {"HL Left Mixer", NULL, "ASPINL"}, 713 {"HL Right Mixer", NULL, "ASPINR"}, 714 {"HL Left Mixer", NULL, "XSPINL"}, 715 {"HL Right Mixer", NULL, "XSPINR"}, 716 {"HL Left Mixer", NULL, "VSPINOUT"}, 717 {"HL Right Mixer", NULL, "VSPINOUT"}, 718 719 {"ASPINL", NULL, "ASP Playback"}, 720 {"ASPINM", NULL, "ASP Playback"}, 721 {"ASPINR", NULL, "ASP Playback"}, 722 {"XSPINL", NULL, "XSP Playback"}, 723 {"XSPINM", NULL, "XSP Playback"}, 724 {"XSPINR", NULL, "XSP Playback"}, 725 {"VSPINOUT", NULL, "VSP Playback"}, 726 727 /* Capture Paths */ 728 {"MIC1", NULL, "MIC1 Bias"}, 729 {"PGA Left Mux", "Mic 1", "MIC1"}, 730 {"MIC2", NULL, "MIC2 Bias"}, 731 {"PGA Right Mux", "Mic 2", "MIC2"}, 732 733 {"PGA Left Mux", "Line A", "LINEINA"}, 734 {"PGA Right Mux", "Line B", "LINEINB"}, 735 736 {"PGA Left", NULL, "PGA Left Mux"}, 737 {"PGA Right", NULL, "PGA Right Mux"}, 738 739 {"ADC Left", NULL, "PGA Left"}, 740 {"ADC Right", NULL, "PGA Right"}, 741 {"DMIC Left", NULL, "DMICA"}, 742 {"DMIC Right", NULL, "DMICB"}, 743 744 {"Input Left Capture", "ADC Left Input", "ADC Left"}, 745 {"Input Right Capture", "ADC Right Input", "ADC Right"}, 746 {"Input Left Capture", "DMIC Left Input", "DMIC Left"}, 747 {"Input Right Capture", "DMIC Right Input", "DMIC Right"}, 748 749 /* Audio Capture */ 750 {"ASPL Output Mixer", NULL, "Input Left Capture"}, 751 {"ASPR Output Mixer", NULL, "Input Right Capture"}, 752 753 {"ASPOUTL", "ASP-IP Volume", "ASPL Output Mixer"}, 754 {"ASPOUTR", "ASP-IP Volume", "ASPR Output Mixer"}, 755 756 /* Auxillary Capture */ 757 {"XSPL Output Mixer", NULL, "Input Left Capture"}, 758 {"XSPR Output Mixer", NULL, "Input Right Capture"}, 759 760 {"XSPOUTL", "XSP-IP Volume", "XSPL Output Mixer"}, 761 {"XSPOUTR", "XSP-IP Volume", "XSPR Output Mixer"}, 762 763 {"XSPOUTL", NULL, "XSPL Output Mixer"}, 764 {"XSPOUTR", NULL, "XSPR Output Mixer"}, 765 766 /* Voice Capture */ 767 {"VSP Output Mixer", NULL, "Input Left Capture"}, 768 {"VSP Output Mixer", NULL, "Input Right Capture"}, 769 770 {"VSPINOUT", "VSP-IP Volume", "VSP Output Mixer"}, 771 772 {"VSPINOUT", NULL, "VSP Output Mixer"}, 773 774 {"ASP Capture", NULL, "ASPOUTL"}, 775 {"ASP Capture", NULL, "ASPOUTR"}, 776 {"XSP Capture", NULL, "XSPOUTL"}, 777 {"XSP Capture", NULL, "XSPOUTR"}, 778 {"VSP Capture", NULL, "VSPINOUT"}, 779 }; 780 781 struct cs42l73_mclk_div { 782 u32 mclk; 783 u32 srate; 784 u8 mmcc; 785 }; 786 787 static const struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = { 788 /* MCLK, Sample Rate, xMMCC[5:0] */ 789 {5644800, 11025, 0x30}, 790 {5644800, 22050, 0x20}, 791 {5644800, 44100, 0x10}, 792 793 {6000000, 8000, 0x39}, 794 {6000000, 11025, 0x33}, 795 {6000000, 12000, 0x31}, 796 {6000000, 16000, 0x29}, 797 {6000000, 22050, 0x23}, 798 {6000000, 24000, 0x21}, 799 {6000000, 32000, 0x19}, 800 {6000000, 44100, 0x13}, 801 {6000000, 48000, 0x11}, 802 803 {6144000, 8000, 0x38}, 804 {6144000, 12000, 0x30}, 805 {6144000, 16000, 0x28}, 806 {6144000, 24000, 0x20}, 807 {6144000, 32000, 0x18}, 808 {6144000, 48000, 0x10}, 809 810 {6500000, 8000, 0x3C}, 811 {6500000, 11025, 0x35}, 812 {6500000, 12000, 0x34}, 813 {6500000, 16000, 0x2C}, 814 {6500000, 22050, 0x25}, 815 {6500000, 24000, 0x24}, 816 {6500000, 32000, 0x1C}, 817 {6500000, 44100, 0x15}, 818 {6500000, 48000, 0x14}, 819 820 {6400000, 8000, 0x3E}, 821 {6400000, 11025, 0x37}, 822 {6400000, 12000, 0x36}, 823 {6400000, 16000, 0x2E}, 824 {6400000, 22050, 0x27}, 825 {6400000, 24000, 0x26}, 826 {6400000, 32000, 0x1E}, 827 {6400000, 44100, 0x17}, 828 {6400000, 48000, 0x16}, 829 }; 830 831 struct cs42l73_mclkx_div { 832 u32 mclkx; 833 u8 ratio; 834 u8 mclkdiv; 835 }; 836 837 static const struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = { 838 {5644800, 1, 0}, /* 5644800 */ 839 {6000000, 1, 0}, /* 6000000 */ 840 {6144000, 1, 0}, /* 6144000 */ 841 {11289600, 2, 2}, /* 5644800 */ 842 {12288000, 2, 2}, /* 6144000 */ 843 {12000000, 2, 2}, /* 6000000 */ 844 {13000000, 2, 2}, /* 6500000 */ 845 {19200000, 3, 3}, /* 6400000 */ 846 {24000000, 4, 4}, /* 6000000 */ 847 {26000000, 4, 4}, /* 6500000 */ 848 {38400000, 6, 5} /* 6400000 */ 849 }; 850 851 static int cs42l73_get_mclkx_coeff(int mclkx) 852 { 853 int i; 854 855 for (i = 0; i < ARRAY_SIZE(cs42l73_mclkx_coeffs); i++) { 856 if (cs42l73_mclkx_coeffs[i].mclkx == mclkx) 857 return i; 858 } 859 return -EINVAL; 860 } 861 862 static int cs42l73_get_mclk_coeff(int mclk, int srate) 863 { 864 int i; 865 866 for (i = 0; i < ARRAY_SIZE(cs42l73_mclk_coeffs); i++) { 867 if (cs42l73_mclk_coeffs[i].mclk == mclk && 868 cs42l73_mclk_coeffs[i].srate == srate) 869 return i; 870 } 871 return -EINVAL; 872 873 } 874 875 static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq) 876 { 877 struct snd_soc_component *component = dai->component; 878 struct cs42l73_private *priv = snd_soc_component_get_drvdata(component); 879 880 int mclkx_coeff; 881 u32 mclk = 0; 882 u8 dmmcc = 0; 883 884 /* MCLKX -> MCLK */ 885 mclkx_coeff = cs42l73_get_mclkx_coeff(freq); 886 if (mclkx_coeff < 0) 887 return mclkx_coeff; 888 889 mclk = cs42l73_mclkx_coeffs[mclkx_coeff].mclkx / 890 cs42l73_mclkx_coeffs[mclkx_coeff].ratio; 891 892 dev_dbg(component->dev, "MCLK%u %u <-> internal MCLK %u\n", 893 priv->mclksel + 1, cs42l73_mclkx_coeffs[mclkx_coeff].mclkx, 894 mclk); 895 896 dmmcc = (priv->mclksel << 4) | 897 (cs42l73_mclkx_coeffs[mclkx_coeff].mclkdiv << 1); 898 899 snd_soc_component_write(component, CS42L73_DMMCC, dmmcc); 900 901 priv->sysclk = mclkx_coeff; 902 priv->mclk = mclk; 903 904 return 0; 905 } 906 907 static int cs42l73_set_sysclk(struct snd_soc_dai *dai, 908 int clk_id, unsigned int freq, int dir) 909 { 910 struct snd_soc_component *component = dai->component; 911 struct cs42l73_private *priv = snd_soc_component_get_drvdata(component); 912 913 switch (clk_id) { 914 case CS42L73_CLKID_MCLK1: 915 break; 916 case CS42L73_CLKID_MCLK2: 917 break; 918 default: 919 return -EINVAL; 920 } 921 922 if ((cs42l73_set_mclk(dai, freq)) < 0) { 923 dev_err(component->dev, "Unable to set MCLK for dai %s\n", 924 dai->name); 925 return -EINVAL; 926 } 927 928 priv->mclksel = clk_id; 929 930 return 0; 931 } 932 933 static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 934 { 935 struct snd_soc_component *component = codec_dai->component; 936 struct cs42l73_private *priv = snd_soc_component_get_drvdata(component); 937 u8 id = codec_dai->id; 938 unsigned int inv, format; 939 u8 spc, mmcc; 940 941 spc = snd_soc_component_read(component, CS42L73_SPC(id)); 942 mmcc = snd_soc_component_read(component, CS42L73_MMCC(id)); 943 944 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 945 case SND_SOC_DAIFMT_CBM_CFM: 946 mmcc |= CS42L73_MS_MASTER; 947 break; 948 949 case SND_SOC_DAIFMT_CBS_CFS: 950 mmcc &= ~CS42L73_MS_MASTER; 951 break; 952 953 default: 954 return -EINVAL; 955 } 956 957 format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK); 958 inv = (fmt & SND_SOC_DAIFMT_INV_MASK); 959 960 switch (format) { 961 case SND_SOC_DAIFMT_I2S: 962 spc &= ~CS42L73_SPDIF_PCM; 963 break; 964 case SND_SOC_DAIFMT_DSP_A: 965 case SND_SOC_DAIFMT_DSP_B: 966 if (mmcc & CS42L73_MS_MASTER) { 967 dev_err(component->dev, 968 "PCM format in slave mode only\n"); 969 return -EINVAL; 970 } 971 if (id == CS42L73_ASP) { 972 dev_err(component->dev, 973 "PCM format is not supported on ASP port\n"); 974 return -EINVAL; 975 } 976 spc |= CS42L73_SPDIF_PCM; 977 break; 978 default: 979 return -EINVAL; 980 } 981 982 if (spc & CS42L73_SPDIF_PCM) { 983 /* Clear PCM mode, clear PCM_BIT_ORDER bit for MSB->LSB */ 984 spc &= ~(CS42L73_PCM_MODE_MASK | CS42L73_PCM_BIT_ORDER); 985 switch (format) { 986 case SND_SOC_DAIFMT_DSP_B: 987 if (inv == SND_SOC_DAIFMT_IB_IF) 988 spc |= CS42L73_PCM_MODE0; 989 if (inv == SND_SOC_DAIFMT_IB_NF) 990 spc |= CS42L73_PCM_MODE1; 991 break; 992 case SND_SOC_DAIFMT_DSP_A: 993 if (inv == SND_SOC_DAIFMT_IB_IF) 994 spc |= CS42L73_PCM_MODE1; 995 break; 996 default: 997 return -EINVAL; 998 } 999 } 1000 1001 priv->config[id].spc = spc; 1002 priv->config[id].mmcc = mmcc; 1003 1004 return 0; 1005 } 1006 1007 static const unsigned int cs42l73_asrc_rates[] = { 1008 8000, 11025, 12000, 16000, 22050, 1009 24000, 32000, 44100, 48000 1010 }; 1011 1012 static unsigned int cs42l73_get_xspfs_coeff(u32 rate) 1013 { 1014 int i; 1015 for (i = 0; i < ARRAY_SIZE(cs42l73_asrc_rates); i++) { 1016 if (cs42l73_asrc_rates[i] == rate) 1017 return i + 1; 1018 } 1019 return 0; /* 0 = Don't know */ 1020 } 1021 1022 static void cs42l73_update_asrc(struct snd_soc_component *component, int id, int srate) 1023 { 1024 u8 spfs = 0; 1025 1026 if (srate > 0) 1027 spfs = cs42l73_get_xspfs_coeff(srate); 1028 1029 switch (id) { 1030 case CS42L73_XSP: 1031 snd_soc_component_update_bits(component, CS42L73_VXSPFS, 0x0f, spfs); 1032 break; 1033 case CS42L73_ASP: 1034 snd_soc_component_update_bits(component, CS42L73_ASPC, 0x3c, spfs << 2); 1035 break; 1036 case CS42L73_VSP: 1037 snd_soc_component_update_bits(component, CS42L73_VXSPFS, 0xf0, spfs << 4); 1038 break; 1039 default: 1040 break; 1041 } 1042 } 1043 1044 static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream, 1045 struct snd_pcm_hw_params *params, 1046 struct snd_soc_dai *dai) 1047 { 1048 struct snd_soc_component *component = dai->component; 1049 struct cs42l73_private *priv = snd_soc_component_get_drvdata(component); 1050 int id = dai->id; 1051 int mclk_coeff; 1052 int srate = params_rate(params); 1053 1054 if (priv->config[id].mmcc & CS42L73_MS_MASTER) { 1055 /* CS42L73 Master */ 1056 /* MCLK -> srate */ 1057 mclk_coeff = 1058 cs42l73_get_mclk_coeff(priv->mclk, srate); 1059 1060 if (mclk_coeff < 0) 1061 return -EINVAL; 1062 1063 dev_dbg(component->dev, 1064 "DAI[%d]: MCLK %u, srate %u, MMCC[5:0] = %x\n", 1065 id, priv->mclk, srate, 1066 cs42l73_mclk_coeffs[mclk_coeff].mmcc); 1067 1068 priv->config[id].mmcc &= 0xC0; 1069 priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; 1070 priv->config[id].spc &= 0xFC; 1071 /* Use SCLK=64*Fs if internal MCLK >= 6.4MHz */ 1072 if (priv->mclk >= 6400000) 1073 priv->config[id].spc |= CS42L73_MCK_SCLK_64FS; 1074 else 1075 priv->config[id].spc |= CS42L73_MCK_SCLK_MCLK; 1076 } else { 1077 /* CS42L73 Slave */ 1078 priv->config[id].spc &= 0xFC; 1079 priv->config[id].spc |= CS42L73_MCK_SCLK_64FS; 1080 } 1081 /* Update ASRCs */ 1082 priv->config[id].srate = srate; 1083 1084 snd_soc_component_write(component, CS42L73_SPC(id), priv->config[id].spc); 1085 snd_soc_component_write(component, CS42L73_MMCC(id), priv->config[id].mmcc); 1086 1087 cs42l73_update_asrc(component, id, srate); 1088 1089 return 0; 1090 } 1091 1092 static int cs42l73_set_bias_level(struct snd_soc_component *component, 1093 enum snd_soc_bias_level level) 1094 { 1095 struct cs42l73_private *cs42l73 = snd_soc_component_get_drvdata(component); 1096 1097 switch (level) { 1098 case SND_SOC_BIAS_ON: 1099 snd_soc_component_update_bits(component, CS42L73_DMMCC, CS42L73_MCLKDIS, 0); 1100 snd_soc_component_update_bits(component, CS42L73_PWRCTL1, CS42L73_PDN, 0); 1101 break; 1102 1103 case SND_SOC_BIAS_PREPARE: 1104 break; 1105 1106 case SND_SOC_BIAS_STANDBY: 1107 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { 1108 regcache_cache_only(cs42l73->regmap, false); 1109 regcache_sync(cs42l73->regmap); 1110 } 1111 snd_soc_component_update_bits(component, CS42L73_PWRCTL1, CS42L73_PDN, 1); 1112 break; 1113 1114 case SND_SOC_BIAS_OFF: 1115 snd_soc_component_update_bits(component, CS42L73_PWRCTL1, CS42L73_PDN, 1); 1116 if (cs42l73->shutdwn_delay > 0) { 1117 mdelay(cs42l73->shutdwn_delay); 1118 cs42l73->shutdwn_delay = 0; 1119 } else { 1120 mdelay(15); /* Min amount of time requred to power 1121 * down. 1122 */ 1123 } 1124 snd_soc_component_update_bits(component, CS42L73_DMMCC, CS42L73_MCLKDIS, 1); 1125 break; 1126 } 1127 return 0; 1128 } 1129 1130 static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate) 1131 { 1132 struct snd_soc_component *component = dai->component; 1133 int id = dai->id; 1134 1135 return snd_soc_component_update_bits(component, CS42L73_SPC(id), CS42L73_SP_3ST, 1136 tristate << 7); 1137 } 1138 1139 static const struct snd_pcm_hw_constraint_list constraints_12_24 = { 1140 .count = ARRAY_SIZE(cs42l73_asrc_rates), 1141 .list = cs42l73_asrc_rates, 1142 }; 1143 1144 static int cs42l73_pcm_startup(struct snd_pcm_substream *substream, 1145 struct snd_soc_dai *dai) 1146 { 1147 snd_pcm_hw_constraint_list(substream->runtime, 0, 1148 SNDRV_PCM_HW_PARAM_RATE, 1149 &constraints_12_24); 1150 return 0; 1151 } 1152 1153 1154 #define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 1155 SNDRV_PCM_FMTBIT_S24_LE) 1156 1157 static const struct snd_soc_dai_ops cs42l73_ops = { 1158 .startup = cs42l73_pcm_startup, 1159 .hw_params = cs42l73_pcm_hw_params, 1160 .set_fmt = cs42l73_set_dai_fmt, 1161 .set_sysclk = cs42l73_set_sysclk, 1162 .set_tristate = cs42l73_set_tristate, 1163 }; 1164 1165 static struct snd_soc_dai_driver cs42l73_dai[] = { 1166 { 1167 .name = "cs42l73-xsp", 1168 .id = CS42L73_XSP, 1169 .playback = { 1170 .stream_name = "XSP Playback", 1171 .channels_min = 1, 1172 .channels_max = 2, 1173 .rates = SNDRV_PCM_RATE_KNOT, 1174 .formats = CS42L73_FORMATS, 1175 }, 1176 .capture = { 1177 .stream_name = "XSP Capture", 1178 .channels_min = 1, 1179 .channels_max = 2, 1180 .rates = SNDRV_PCM_RATE_KNOT, 1181 .formats = CS42L73_FORMATS, 1182 }, 1183 .ops = &cs42l73_ops, 1184 .symmetric_rate = 1, 1185 }, 1186 { 1187 .name = "cs42l73-asp", 1188 .id = CS42L73_ASP, 1189 .playback = { 1190 .stream_name = "ASP Playback", 1191 .channels_min = 2, 1192 .channels_max = 2, 1193 .rates = SNDRV_PCM_RATE_KNOT, 1194 .formats = CS42L73_FORMATS, 1195 }, 1196 .capture = { 1197 .stream_name = "ASP Capture", 1198 .channels_min = 2, 1199 .channels_max = 2, 1200 .rates = SNDRV_PCM_RATE_KNOT, 1201 .formats = CS42L73_FORMATS, 1202 }, 1203 .ops = &cs42l73_ops, 1204 .symmetric_rate = 1, 1205 }, 1206 { 1207 .name = "cs42l73-vsp", 1208 .id = CS42L73_VSP, 1209 .playback = { 1210 .stream_name = "VSP Playback", 1211 .channels_min = 1, 1212 .channels_max = 2, 1213 .rates = SNDRV_PCM_RATE_KNOT, 1214 .formats = CS42L73_FORMATS, 1215 }, 1216 .capture = { 1217 .stream_name = "VSP Capture", 1218 .channels_min = 1, 1219 .channels_max = 2, 1220 .rates = SNDRV_PCM_RATE_KNOT, 1221 .formats = CS42L73_FORMATS, 1222 }, 1223 .ops = &cs42l73_ops, 1224 .symmetric_rate = 1, 1225 } 1226 }; 1227 1228 static int cs42l73_probe(struct snd_soc_component *component) 1229 { 1230 struct cs42l73_private *cs42l73 = snd_soc_component_get_drvdata(component); 1231 1232 /* Set Charge Pump Frequency */ 1233 if (cs42l73->pdata.chgfreq) 1234 snd_soc_component_update_bits(component, CS42L73_CPFCHC, 1235 CS42L73_CHARGEPUMP_MASK, 1236 cs42l73->pdata.chgfreq << 4); 1237 1238 /* MCLK1 as master clk */ 1239 cs42l73->mclksel = CS42L73_CLKID_MCLK1; 1240 cs42l73->mclk = 0; 1241 1242 return 0; 1243 } 1244 1245 static const struct snd_soc_component_driver soc_component_dev_cs42l73 = { 1246 .probe = cs42l73_probe, 1247 .set_bias_level = cs42l73_set_bias_level, 1248 .controls = cs42l73_snd_controls, 1249 .num_controls = ARRAY_SIZE(cs42l73_snd_controls), 1250 .dapm_widgets = cs42l73_dapm_widgets, 1251 .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets), 1252 .dapm_routes = cs42l73_audio_map, 1253 .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map), 1254 .suspend_bias_off = 1, 1255 .idle_bias_on = 1, 1256 .use_pmdown_time = 1, 1257 .endianness = 1, 1258 .non_legacy_dai_naming = 1, 1259 }; 1260 1261 static const struct regmap_config cs42l73_regmap = { 1262 .reg_bits = 8, 1263 .val_bits = 8, 1264 1265 .max_register = CS42L73_MAX_REGISTER, 1266 .reg_defaults = cs42l73_reg_defaults, 1267 .num_reg_defaults = ARRAY_SIZE(cs42l73_reg_defaults), 1268 .volatile_reg = cs42l73_volatile_register, 1269 .readable_reg = cs42l73_readable_register, 1270 .cache_type = REGCACHE_RBTREE, 1271 1272 .use_single_read = true, 1273 .use_single_write = true, 1274 }; 1275 1276 static int cs42l73_i2c_probe(struct i2c_client *i2c_client, 1277 const struct i2c_device_id *id) 1278 { 1279 struct cs42l73_private *cs42l73; 1280 struct cs42l73_platform_data *pdata = dev_get_platdata(&i2c_client->dev); 1281 int ret; 1282 unsigned int devid = 0; 1283 unsigned int reg; 1284 u32 val32; 1285 1286 cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(*cs42l73), GFP_KERNEL); 1287 if (!cs42l73) 1288 return -ENOMEM; 1289 1290 cs42l73->regmap = devm_regmap_init_i2c(i2c_client, &cs42l73_regmap); 1291 if (IS_ERR(cs42l73->regmap)) { 1292 ret = PTR_ERR(cs42l73->regmap); 1293 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); 1294 return ret; 1295 } 1296 1297 if (pdata) { 1298 cs42l73->pdata = *pdata; 1299 } else { 1300 pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata), 1301 GFP_KERNEL); 1302 if (!pdata) 1303 return -ENOMEM; 1304 1305 if (i2c_client->dev.of_node) { 1306 if (of_property_read_u32(i2c_client->dev.of_node, 1307 "chgfreq", &val32) >= 0) 1308 pdata->chgfreq = val32; 1309 } 1310 pdata->reset_gpio = of_get_named_gpio(i2c_client->dev.of_node, 1311 "reset-gpio", 0); 1312 cs42l73->pdata = *pdata; 1313 } 1314 1315 i2c_set_clientdata(i2c_client, cs42l73); 1316 1317 if (cs42l73->pdata.reset_gpio) { 1318 ret = devm_gpio_request_one(&i2c_client->dev, 1319 cs42l73->pdata.reset_gpio, 1320 GPIOF_OUT_INIT_HIGH, 1321 "CS42L73 /RST"); 1322 if (ret < 0) { 1323 dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n", 1324 cs42l73->pdata.reset_gpio, ret); 1325 return ret; 1326 } 1327 gpio_set_value_cansleep(cs42l73->pdata.reset_gpio, 0); 1328 gpio_set_value_cansleep(cs42l73->pdata.reset_gpio, 1); 1329 } 1330 1331 /* initialize codec */ 1332 ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®); 1333 devid = (reg & 0xFF) << 12; 1334 1335 ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_CD, ®); 1336 devid |= (reg & 0xFF) << 4; 1337 1338 ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, ®); 1339 devid |= (reg & 0xF0) >> 4; 1340 1341 if (devid != CS42L73_DEVID) { 1342 ret = -ENODEV; 1343 dev_err(&i2c_client->dev, 1344 "CS42L73 Device ID (%X). Expected %X\n", 1345 devid, CS42L73_DEVID); 1346 return ret; 1347 } 1348 1349 ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); 1350 if (ret < 0) { 1351 dev_err(&i2c_client->dev, "Get Revision ID failed\n"); 1352 return ret; 1353 } 1354 1355 dev_info(&i2c_client->dev, 1356 "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF); 1357 1358 ret = devm_snd_soc_register_component(&i2c_client->dev, 1359 &soc_component_dev_cs42l73, cs42l73_dai, 1360 ARRAY_SIZE(cs42l73_dai)); 1361 if (ret < 0) 1362 return ret; 1363 return 0; 1364 } 1365 1366 static const struct of_device_id cs42l73_of_match[] = { 1367 { .compatible = "cirrus,cs42l73", }, 1368 {}, 1369 }; 1370 MODULE_DEVICE_TABLE(of, cs42l73_of_match); 1371 1372 static const struct i2c_device_id cs42l73_id[] = { 1373 {"cs42l73", 0}, 1374 {} 1375 }; 1376 1377 MODULE_DEVICE_TABLE(i2c, cs42l73_id); 1378 1379 static struct i2c_driver cs42l73_i2c_driver = { 1380 .driver = { 1381 .name = "cs42l73", 1382 .of_match_table = cs42l73_of_match, 1383 }, 1384 .id_table = cs42l73_id, 1385 .probe = cs42l73_i2c_probe, 1386 1387 }; 1388 1389 module_i2c_driver(cs42l73_i2c_driver); 1390 1391 MODULE_DESCRIPTION("ASoC CS42L73 driver"); 1392 MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>"); 1393 MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>"); 1394 MODULE_LICENSE("GPL"); 1395