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