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