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