1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * cs42l51.c 4 * 5 * ASoC Driver for Cirrus Logic CS42L51 codecs 6 * 7 * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com> 8 * 9 * Based on cs4270.c - Copyright (c) Freescale Semiconductor 10 * 11 * For now: 12 * - Only I2C is support. Not SPI 13 * - master mode *NOT* supported 14 */ 15 16 #include <linux/clk.h> 17 #include <linux/module.h> 18 #include <linux/slab.h> 19 #include <sound/core.h> 20 #include <sound/soc.h> 21 #include <sound/tlv.h> 22 #include <sound/initval.h> 23 #include <sound/pcm_params.h> 24 #include <sound/pcm.h> 25 #include <linux/gpio/consumer.h> 26 #include <linux/regmap.h> 27 #include <linux/regulator/consumer.h> 28 29 #include "cs42l51.h" 30 31 enum master_slave_mode { 32 MODE_SLAVE, 33 MODE_SLAVE_AUTO, 34 MODE_MASTER, 35 }; 36 37 static const char * const cs42l51_supply_names[] = { 38 "VL", 39 "VD", 40 "VA", 41 "VAHP", 42 }; 43 44 struct cs42l51_private { 45 unsigned int mclk; 46 struct clk *mclk_handle; 47 unsigned int audio_mode; /* The mode (I2S or left-justified) */ 48 enum master_slave_mode func; 49 struct regulator_bulk_data supplies[ARRAY_SIZE(cs42l51_supply_names)]; 50 struct gpio_desc *reset_gpio; 51 struct regmap *regmap; 52 }; 53 54 #define CS42L51_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \ 55 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) 56 57 static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, 58 struct snd_ctl_elem_value *ucontrol) 59 { 60 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 61 unsigned long value = snd_soc_component_read(component, CS42L51_PCM_MIXER)&3; 62 63 switch (value) { 64 default: 65 case 0: 66 ucontrol->value.enumerated.item[0] = 0; 67 break; 68 /* same value : (L+R)/2 and (R+L)/2 */ 69 case 1: 70 case 2: 71 ucontrol->value.enumerated.item[0] = 1; 72 break; 73 case 3: 74 ucontrol->value.enumerated.item[0] = 2; 75 break; 76 } 77 78 return 0; 79 } 80 81 #define CHAN_MIX_NORMAL 0x00 82 #define CHAN_MIX_BOTH 0x55 83 #define CHAN_MIX_SWAP 0xFF 84 85 static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol, 86 struct snd_ctl_elem_value *ucontrol) 87 { 88 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 89 unsigned char val; 90 91 switch (ucontrol->value.enumerated.item[0]) { 92 default: 93 case 0: 94 val = CHAN_MIX_NORMAL; 95 break; 96 case 1: 97 val = CHAN_MIX_BOTH; 98 break; 99 case 2: 100 val = CHAN_MIX_SWAP; 101 break; 102 } 103 104 snd_soc_component_write(component, CS42L51_PCM_MIXER, val); 105 106 return 1; 107 } 108 109 static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0); 110 static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0); 111 112 static const DECLARE_TLV_DB_SCALE(aout_tlv, -10200, 50, 0); 113 114 static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0); 115 static const DECLARE_TLV_DB_SCALE(adc_boost_tlv, 2000, 2000, 0); 116 static const char *chan_mix[] = { 117 "L R", 118 "L+R", 119 "R L", 120 }; 121 122 static const DECLARE_TLV_DB_SCALE(pga_tlv, -300, 50, 0); 123 static const DECLARE_TLV_DB_SCALE(adc_att_tlv, -9600, 100, 0); 124 125 static SOC_ENUM_SINGLE_EXT_DECL(cs42l51_chan_mix, chan_mix); 126 127 static const struct snd_kcontrol_new cs42l51_snd_controls[] = { 128 SOC_DOUBLE_R_SX_TLV("PCM Playback Volume", 129 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 130 0, 0x19, 0x7F, adc_pcm_tlv), 131 SOC_DOUBLE_R("PCM Playback Switch", 132 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1), 133 SOC_DOUBLE_R_SX_TLV("Analog Playback Volume", 134 CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL, 135 0, 0x34, 0xE4, aout_tlv), 136 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", 137 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 138 0, 0x19, 0x7F, adc_pcm_tlv), 139 SOC_DOUBLE_R("ADC Mixer Switch", 140 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1), 141 SOC_DOUBLE_R_SX_TLV("ADC Attenuator Volume", 142 CS42L51_ADCA_ATT, CS42L51_ADCB_ATT, 143 0, 0xA0, 96, adc_att_tlv), 144 SOC_DOUBLE_R_SX_TLV("PGA Volume", 145 CS42L51_ALC_PGA_CTL, CS42L51_ALC_PGB_CTL, 146 0, 0x1A, 30, pga_tlv), 147 SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0), 148 SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0), 149 SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0), 150 SOC_SINGLE("Zero Cross Switch", CS42L51_DAC_CTL, 0, 0, 0), 151 SOC_DOUBLE_TLV("Mic Boost Volume", 152 CS42L51_MIC_CTL, 0, 1, 1, 0, boost_tlv), 153 SOC_DOUBLE_TLV("ADC Boost Volume", 154 CS42L51_MIC_CTL, 5, 6, 1, 0, adc_boost_tlv), 155 SOC_SINGLE_TLV("Bass Volume", CS42L51_TONE_CTL, 0, 0xf, 1, tone_tlv), 156 SOC_SINGLE_TLV("Treble Volume", CS42L51_TONE_CTL, 4, 0xf, 1, tone_tlv), 157 SOC_ENUM_EXT("PCM channel mixer", 158 cs42l51_chan_mix, 159 cs42l51_get_chan_mix, cs42l51_set_chan_mix), 160 }; 161 162 /* 163 * to power down, one must: 164 * 1.) Enable the PDN bit 165 * 2.) enable power-down for the select channels 166 * 3.) disable the PDN bit. 167 */ 168 static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w, 169 struct snd_kcontrol *kcontrol, int event) 170 { 171 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 172 173 switch (event) { 174 case SND_SOC_DAPM_PRE_PMD: 175 snd_soc_component_update_bits(component, CS42L51_POWER_CTL1, 176 CS42L51_POWER_CTL1_PDN, 177 CS42L51_POWER_CTL1_PDN); 178 break; 179 default: 180 case SND_SOC_DAPM_POST_PMD: 181 snd_soc_component_update_bits(component, CS42L51_POWER_CTL1, 182 CS42L51_POWER_CTL1_PDN, 0); 183 break; 184 } 185 186 return 0; 187 } 188 189 static const char *cs42l51_dac_names[] = {"Direct PCM", 190 "DSP PCM", "ADC"}; 191 static SOC_ENUM_SINGLE_DECL(cs42l51_dac_mux_enum, 192 CS42L51_DAC_CTL, 6, cs42l51_dac_names); 193 static const struct snd_kcontrol_new cs42l51_dac_mux_controls = 194 SOC_DAPM_ENUM("Route", cs42l51_dac_mux_enum); 195 196 static const char *cs42l51_adcl_names[] = {"AIN1 Left", "AIN2 Left", 197 "MIC Left", "MIC+preamp Left"}; 198 static SOC_ENUM_SINGLE_DECL(cs42l51_adcl_mux_enum, 199 CS42L51_ADC_INPUT, 4, cs42l51_adcl_names); 200 static const struct snd_kcontrol_new cs42l51_adcl_mux_controls = 201 SOC_DAPM_ENUM("Route", cs42l51_adcl_mux_enum); 202 203 static const char *cs42l51_adcr_names[] = {"AIN1 Right", "AIN2 Right", 204 "MIC Right", "MIC+preamp Right"}; 205 static SOC_ENUM_SINGLE_DECL(cs42l51_adcr_mux_enum, 206 CS42L51_ADC_INPUT, 6, cs42l51_adcr_names); 207 static const struct snd_kcontrol_new cs42l51_adcr_mux_controls = 208 SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum); 209 210 static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = { 211 SND_SOC_DAPM_SUPPLY("Mic Bias", CS42L51_MIC_POWER_CTL, 1, 1, NULL, 212 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 213 SND_SOC_DAPM_PGA_E("Left PGA", CS42L51_POWER_CTL1, 3, 1, NULL, 0, 214 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 215 SND_SOC_DAPM_PGA_E("Right PGA", CS42L51_POWER_CTL1, 4, 1, NULL, 0, 216 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 217 SND_SOC_DAPM_ADC_E("Left ADC", "Left HiFi Capture", 218 CS42L51_POWER_CTL1, 1, 1, 219 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 220 SND_SOC_DAPM_ADC_E("Right ADC", "Right HiFi Capture", 221 CS42L51_POWER_CTL1, 2, 1, 222 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 223 SND_SOC_DAPM_DAC_E("Left DAC", NULL, CS42L51_POWER_CTL1, 5, 1, 224 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 225 SND_SOC_DAPM_DAC_E("Right DAC", NULL, CS42L51_POWER_CTL1, 6, 1, 226 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 227 228 /* analog/mic */ 229 SND_SOC_DAPM_INPUT("AIN1L"), 230 SND_SOC_DAPM_INPUT("AIN1R"), 231 SND_SOC_DAPM_INPUT("AIN2L"), 232 SND_SOC_DAPM_INPUT("AIN2R"), 233 SND_SOC_DAPM_INPUT("MICL"), 234 SND_SOC_DAPM_INPUT("MICR"), 235 236 SND_SOC_DAPM_MIXER("Mic Preamp Left", 237 CS42L51_MIC_POWER_CTL, 2, 1, NULL, 0), 238 SND_SOC_DAPM_MIXER("Mic Preamp Right", 239 CS42L51_MIC_POWER_CTL, 3, 1, NULL, 0), 240 241 /* HP */ 242 SND_SOC_DAPM_OUTPUT("HPL"), 243 SND_SOC_DAPM_OUTPUT("HPR"), 244 245 /* mux */ 246 SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0, 247 &cs42l51_dac_mux_controls), 248 SND_SOC_DAPM_MUX("PGA-ADC Mux Left", SND_SOC_NOPM, 0, 0, 249 &cs42l51_adcl_mux_controls), 250 SND_SOC_DAPM_MUX("PGA-ADC Mux Right", SND_SOC_NOPM, 0, 0, 251 &cs42l51_adcr_mux_controls), 252 }; 253 254 static int mclk_event(struct snd_soc_dapm_widget *w, 255 struct snd_kcontrol *kcontrol, int event) 256 { 257 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 258 struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(comp); 259 260 switch (event) { 261 case SND_SOC_DAPM_PRE_PMU: 262 return clk_prepare_enable(cs42l51->mclk_handle); 263 case SND_SOC_DAPM_POST_PMD: 264 /* Delay mclk shutdown to fulfill power-down sequence requirements */ 265 msleep(20); 266 clk_disable_unprepare(cs42l51->mclk_handle); 267 break; 268 } 269 270 return 0; 271 } 272 273 static const struct snd_soc_dapm_widget cs42l51_dapm_mclk_widgets[] = { 274 SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, mclk_event, 275 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 276 }; 277 278 static const struct snd_soc_dapm_route cs42l51_routes[] = { 279 {"HPL", NULL, "Left DAC"}, 280 {"HPR", NULL, "Right DAC"}, 281 282 {"Right DAC", NULL, "DAC Mux"}, 283 {"Left DAC", NULL, "DAC Mux"}, 284 285 {"DAC Mux", "Direct PCM", "Playback"}, 286 {"DAC Mux", "DSP PCM", "Playback"}, 287 288 {"Left ADC", NULL, "Left PGA"}, 289 {"Right ADC", NULL, "Right PGA"}, 290 291 {"Mic Preamp Left", NULL, "MICL"}, 292 {"Mic Preamp Right", NULL, "MICR"}, 293 294 {"PGA-ADC Mux Left", "AIN1 Left", "AIN1L" }, 295 {"PGA-ADC Mux Left", "AIN2 Left", "AIN2L" }, 296 {"PGA-ADC Mux Left", "MIC Left", "MICL" }, 297 {"PGA-ADC Mux Left", "MIC+preamp Left", "Mic Preamp Left" }, 298 {"PGA-ADC Mux Right", "AIN1 Right", "AIN1R" }, 299 {"PGA-ADC Mux Right", "AIN2 Right", "AIN2R" }, 300 {"PGA-ADC Mux Right", "MIC Right", "MICR" }, 301 {"PGA-ADC Mux Right", "MIC+preamp Right", "Mic Preamp Right" }, 302 303 {"Left PGA", NULL, "PGA-ADC Mux Left"}, 304 {"Right PGA", NULL, "PGA-ADC Mux Right"}, 305 }; 306 307 static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai, 308 unsigned int format) 309 { 310 struct snd_soc_component *component = codec_dai->component; 311 struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component); 312 313 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 314 case SND_SOC_DAIFMT_I2S: 315 case SND_SOC_DAIFMT_LEFT_J: 316 case SND_SOC_DAIFMT_RIGHT_J: 317 cs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK; 318 break; 319 default: 320 dev_err(component->dev, "invalid DAI format\n"); 321 return -EINVAL; 322 } 323 324 switch (format & SND_SOC_DAIFMT_MASTER_MASK) { 325 case SND_SOC_DAIFMT_CBM_CFM: 326 cs42l51->func = MODE_MASTER; 327 break; 328 case SND_SOC_DAIFMT_CBS_CFS: 329 cs42l51->func = MODE_SLAVE_AUTO; 330 break; 331 default: 332 dev_err(component->dev, "Unknown master/slave configuration\n"); 333 return -EINVAL; 334 } 335 336 return 0; 337 } 338 339 struct cs42l51_ratios { 340 unsigned int ratio; 341 unsigned char speed_mode; 342 unsigned char mclk; 343 }; 344 345 static struct cs42l51_ratios slave_ratios[] = { 346 { 512, CS42L51_QSM_MODE, 0 }, { 768, CS42L51_QSM_MODE, 0 }, 347 { 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 }, 348 { 2048, CS42L51_QSM_MODE, 0 }, { 3072, CS42L51_QSM_MODE, 0 }, 349 { 256, CS42L51_HSM_MODE, 0 }, { 384, CS42L51_HSM_MODE, 0 }, 350 { 512, CS42L51_HSM_MODE, 0 }, { 768, CS42L51_HSM_MODE, 0 }, 351 { 1024, CS42L51_HSM_MODE, 0 }, { 1536, CS42L51_HSM_MODE, 0 }, 352 { 128, CS42L51_SSM_MODE, 0 }, { 192, CS42L51_SSM_MODE, 0 }, 353 { 256, CS42L51_SSM_MODE, 0 }, { 384, CS42L51_SSM_MODE, 0 }, 354 { 512, CS42L51_SSM_MODE, 0 }, { 768, CS42L51_SSM_MODE, 0 }, 355 { 128, CS42L51_DSM_MODE, 0 }, { 192, CS42L51_DSM_MODE, 0 }, 356 { 256, CS42L51_DSM_MODE, 0 }, { 384, CS42L51_DSM_MODE, 0 }, 357 }; 358 359 static struct cs42l51_ratios slave_auto_ratios[] = { 360 { 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 }, 361 { 2048, CS42L51_QSM_MODE, 1 }, { 3072, CS42L51_QSM_MODE, 1 }, 362 { 512, CS42L51_HSM_MODE, 0 }, { 768, CS42L51_HSM_MODE, 0 }, 363 { 1024, CS42L51_HSM_MODE, 1 }, { 1536, CS42L51_HSM_MODE, 1 }, 364 { 256, CS42L51_SSM_MODE, 0 }, { 384, CS42L51_SSM_MODE, 0 }, 365 { 512, CS42L51_SSM_MODE, 1 }, { 768, CS42L51_SSM_MODE, 1 }, 366 { 128, CS42L51_DSM_MODE, 0 }, { 192, CS42L51_DSM_MODE, 0 }, 367 { 256, CS42L51_DSM_MODE, 1 }, { 384, CS42L51_DSM_MODE, 1 }, 368 }; 369 370 /* 371 * Master mode mclk/fs ratios. 372 * Recommended configurations are SSM for 4-50khz and DSM for 50-100kHz ranges 373 * The table below provides support of following ratios: 374 * 128: SSM (%128) with div2 disabled 375 * 256: SSM (%128) with div2 enabled 376 * In both cases, if sampling rate is above 50kHz, SSM is overridden 377 * with DSM (%128) configuration 378 */ 379 static struct cs42l51_ratios master_ratios[] = { 380 { 128, CS42L51_SSM_MODE, 0 }, { 256, CS42L51_SSM_MODE, 1 }, 381 }; 382 383 static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai, 384 int clk_id, unsigned int freq, int dir) 385 { 386 struct snd_soc_component *component = codec_dai->component; 387 struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component); 388 389 cs42l51->mclk = freq; 390 return 0; 391 } 392 393 static int cs42l51_hw_params(struct snd_pcm_substream *substream, 394 struct snd_pcm_hw_params *params, 395 struct snd_soc_dai *dai) 396 { 397 struct snd_soc_component *component = dai->component; 398 struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component); 399 int ret; 400 unsigned int i; 401 unsigned int rate; 402 unsigned int ratio; 403 struct cs42l51_ratios *ratios = NULL; 404 int nr_ratios = 0; 405 int intf_ctl, power_ctl, fmt, mode; 406 407 switch (cs42l51->func) { 408 case MODE_MASTER: 409 ratios = master_ratios; 410 nr_ratios = ARRAY_SIZE(master_ratios); 411 break; 412 case MODE_SLAVE: 413 ratios = slave_ratios; 414 nr_ratios = ARRAY_SIZE(slave_ratios); 415 break; 416 case MODE_SLAVE_AUTO: 417 ratios = slave_auto_ratios; 418 nr_ratios = ARRAY_SIZE(slave_auto_ratios); 419 break; 420 } 421 422 /* Figure out which MCLK/LRCK ratio to use */ 423 rate = params_rate(params); /* Sampling rate, in Hz */ 424 ratio = cs42l51->mclk / rate; /* MCLK/LRCK ratio */ 425 for (i = 0; i < nr_ratios; i++) { 426 if (ratios[i].ratio == ratio) 427 break; 428 } 429 430 if (i == nr_ratios) { 431 /* We did not find a matching ratio */ 432 dev_err(component->dev, "could not find matching ratio\n"); 433 return -EINVAL; 434 } 435 436 intf_ctl = snd_soc_component_read(component, CS42L51_INTF_CTL); 437 power_ctl = snd_soc_component_read(component, CS42L51_MIC_POWER_CTL); 438 439 intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S 440 | CS42L51_INTF_CTL_DAC_FORMAT(7)); 441 power_ctl &= ~(CS42L51_MIC_POWER_CTL_SPEED(3) 442 | CS42L51_MIC_POWER_CTL_MCLK_DIV2); 443 444 switch (cs42l51->func) { 445 case MODE_MASTER: 446 intf_ctl |= CS42L51_INTF_CTL_MASTER; 447 mode = ratios[i].speed_mode; 448 /* Force DSM mode if sampling rate is above 50kHz */ 449 if (rate > 50000) 450 mode = CS42L51_DSM_MODE; 451 power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(mode); 452 /* 453 * Auto detect mode is not applicable for master mode and has to 454 * be disabled. Otherwise SPEED[1:0] bits will be ignored. 455 */ 456 power_ctl &= ~CS42L51_MIC_POWER_CTL_AUTO; 457 break; 458 case MODE_SLAVE: 459 power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode); 460 break; 461 case MODE_SLAVE_AUTO: 462 power_ctl |= CS42L51_MIC_POWER_CTL_AUTO; 463 break; 464 } 465 466 switch (cs42l51->audio_mode) { 467 case SND_SOC_DAIFMT_I2S: 468 intf_ctl |= CS42L51_INTF_CTL_ADC_I2S; 469 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_I2S); 470 break; 471 case SND_SOC_DAIFMT_LEFT_J: 472 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24); 473 break; 474 case SND_SOC_DAIFMT_RIGHT_J: 475 switch (params_width(params)) { 476 case 16: 477 fmt = CS42L51_DAC_DIF_RJ16; 478 break; 479 case 18: 480 fmt = CS42L51_DAC_DIF_RJ18; 481 break; 482 case 20: 483 fmt = CS42L51_DAC_DIF_RJ20; 484 break; 485 case 24: 486 fmt = CS42L51_DAC_DIF_RJ24; 487 break; 488 default: 489 dev_err(component->dev, "unknown format\n"); 490 return -EINVAL; 491 } 492 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt); 493 break; 494 default: 495 dev_err(component->dev, "unknown format\n"); 496 return -EINVAL; 497 } 498 499 if (ratios[i].mclk) 500 power_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2; 501 502 ret = snd_soc_component_write(component, CS42L51_INTF_CTL, intf_ctl); 503 if (ret < 0) 504 return ret; 505 506 ret = snd_soc_component_write(component, CS42L51_MIC_POWER_CTL, power_ctl); 507 if (ret < 0) 508 return ret; 509 510 return 0; 511 } 512 513 static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute, int direction) 514 { 515 struct snd_soc_component *component = dai->component; 516 int reg; 517 int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE; 518 519 reg = snd_soc_component_read(component, CS42L51_DAC_OUT_CTL); 520 521 if (mute) 522 reg |= mask; 523 else 524 reg &= ~mask; 525 526 return snd_soc_component_write(component, CS42L51_DAC_OUT_CTL, reg); 527 } 528 529 static int cs42l51_of_xlate_dai_id(struct snd_soc_component *component, 530 struct device_node *endpoint) 531 { 532 /* return dai id 0, whatever the endpoint index */ 533 return 0; 534 } 535 536 static const struct snd_soc_dai_ops cs42l51_dai_ops = { 537 .hw_params = cs42l51_hw_params, 538 .set_sysclk = cs42l51_set_dai_sysclk, 539 .set_fmt = cs42l51_set_dai_fmt, 540 .mute_stream = cs42l51_dai_mute, 541 .no_capture_mute = 1, 542 }; 543 544 static struct snd_soc_dai_driver cs42l51_dai = { 545 .name = "cs42l51-hifi", 546 .playback = { 547 .stream_name = "Playback", 548 .channels_min = 1, 549 .channels_max = 2, 550 .rates = SNDRV_PCM_RATE_8000_96000, 551 .formats = CS42L51_FORMATS, 552 }, 553 .capture = { 554 .stream_name = "Capture", 555 .channels_min = 1, 556 .channels_max = 2, 557 .rates = SNDRV_PCM_RATE_8000_96000, 558 .formats = CS42L51_FORMATS, 559 }, 560 .ops = &cs42l51_dai_ops, 561 }; 562 563 static int cs42l51_component_probe(struct snd_soc_component *component) 564 { 565 int ret, reg; 566 struct snd_soc_dapm_context *dapm; 567 struct cs42l51_private *cs42l51; 568 569 cs42l51 = snd_soc_component_get_drvdata(component); 570 dapm = snd_soc_component_get_dapm(component); 571 572 if (cs42l51->mclk_handle) 573 snd_soc_dapm_new_controls(dapm, cs42l51_dapm_mclk_widgets, 1); 574 575 /* 576 * DAC configuration 577 * - Use signal processor 578 * - auto mute 579 * - vol changes immediate 580 * - no de-emphasize 581 */ 582 reg = CS42L51_DAC_CTL_DATA_SEL(1) 583 | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0); 584 ret = snd_soc_component_write(component, CS42L51_DAC_CTL, reg); 585 if (ret < 0) 586 return ret; 587 588 return 0; 589 } 590 591 static const struct snd_soc_component_driver soc_component_device_cs42l51 = { 592 .probe = cs42l51_component_probe, 593 .controls = cs42l51_snd_controls, 594 .num_controls = ARRAY_SIZE(cs42l51_snd_controls), 595 .dapm_widgets = cs42l51_dapm_widgets, 596 .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets), 597 .dapm_routes = cs42l51_routes, 598 .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), 599 .of_xlate_dai_id = cs42l51_of_xlate_dai_id, 600 .idle_bias_on = 1, 601 .use_pmdown_time = 1, 602 .endianness = 1, 603 }; 604 605 static bool cs42l51_writeable_reg(struct device *dev, unsigned int reg) 606 { 607 switch (reg) { 608 case CS42L51_POWER_CTL1: 609 case CS42L51_MIC_POWER_CTL: 610 case CS42L51_INTF_CTL: 611 case CS42L51_MIC_CTL: 612 case CS42L51_ADC_CTL: 613 case CS42L51_ADC_INPUT: 614 case CS42L51_DAC_OUT_CTL: 615 case CS42L51_DAC_CTL: 616 case CS42L51_ALC_PGA_CTL: 617 case CS42L51_ALC_PGB_CTL: 618 case CS42L51_ADCA_ATT: 619 case CS42L51_ADCB_ATT: 620 case CS42L51_ADCA_VOL: 621 case CS42L51_ADCB_VOL: 622 case CS42L51_PCMA_VOL: 623 case CS42L51_PCMB_VOL: 624 case CS42L51_BEEP_FREQ: 625 case CS42L51_BEEP_VOL: 626 case CS42L51_BEEP_CONF: 627 case CS42L51_TONE_CTL: 628 case CS42L51_AOUTA_VOL: 629 case CS42L51_AOUTB_VOL: 630 case CS42L51_PCM_MIXER: 631 case CS42L51_LIMIT_THRES_DIS: 632 case CS42L51_LIMIT_REL: 633 case CS42L51_LIMIT_ATT: 634 case CS42L51_ALC_EN: 635 case CS42L51_ALC_REL: 636 case CS42L51_ALC_THRES: 637 case CS42L51_NOISE_CONF: 638 case CS42L51_CHARGE_FREQ: 639 return true; 640 default: 641 return false; 642 } 643 } 644 645 static bool cs42l51_volatile_reg(struct device *dev, unsigned int reg) 646 { 647 switch (reg) { 648 case CS42L51_STATUS: 649 return true; 650 default: 651 return false; 652 } 653 } 654 655 static bool cs42l51_readable_reg(struct device *dev, unsigned int reg) 656 { 657 switch (reg) { 658 case CS42L51_CHIP_REV_ID: 659 case CS42L51_POWER_CTL1: 660 case CS42L51_MIC_POWER_CTL: 661 case CS42L51_INTF_CTL: 662 case CS42L51_MIC_CTL: 663 case CS42L51_ADC_CTL: 664 case CS42L51_ADC_INPUT: 665 case CS42L51_DAC_OUT_CTL: 666 case CS42L51_DAC_CTL: 667 case CS42L51_ALC_PGA_CTL: 668 case CS42L51_ALC_PGB_CTL: 669 case CS42L51_ADCA_ATT: 670 case CS42L51_ADCB_ATT: 671 case CS42L51_ADCA_VOL: 672 case CS42L51_ADCB_VOL: 673 case CS42L51_PCMA_VOL: 674 case CS42L51_PCMB_VOL: 675 case CS42L51_BEEP_FREQ: 676 case CS42L51_BEEP_VOL: 677 case CS42L51_BEEP_CONF: 678 case CS42L51_TONE_CTL: 679 case CS42L51_AOUTA_VOL: 680 case CS42L51_AOUTB_VOL: 681 case CS42L51_PCM_MIXER: 682 case CS42L51_LIMIT_THRES_DIS: 683 case CS42L51_LIMIT_REL: 684 case CS42L51_LIMIT_ATT: 685 case CS42L51_ALC_EN: 686 case CS42L51_ALC_REL: 687 case CS42L51_ALC_THRES: 688 case CS42L51_NOISE_CONF: 689 case CS42L51_STATUS: 690 case CS42L51_CHARGE_FREQ: 691 return true; 692 default: 693 return false; 694 } 695 } 696 697 const struct regmap_config cs42l51_regmap = { 698 .reg_bits = 8, 699 .reg_stride = 1, 700 .val_bits = 8, 701 .use_single_write = true, 702 .readable_reg = cs42l51_readable_reg, 703 .volatile_reg = cs42l51_volatile_reg, 704 .writeable_reg = cs42l51_writeable_reg, 705 .max_register = CS42L51_CHARGE_FREQ, 706 .cache_type = REGCACHE_MAPLE, 707 }; 708 EXPORT_SYMBOL_GPL(cs42l51_regmap); 709 710 int cs42l51_probe(struct device *dev, struct regmap *regmap) 711 { 712 struct cs42l51_private *cs42l51; 713 unsigned int val; 714 int ret, i; 715 716 if (IS_ERR(regmap)) 717 return PTR_ERR(regmap); 718 719 cs42l51 = devm_kzalloc(dev, sizeof(struct cs42l51_private), 720 GFP_KERNEL); 721 if (!cs42l51) 722 return -ENOMEM; 723 724 dev_set_drvdata(dev, cs42l51); 725 cs42l51->regmap = regmap; 726 727 cs42l51->mclk_handle = devm_clk_get_optional(dev, "MCLK"); 728 if (IS_ERR(cs42l51->mclk_handle)) 729 return PTR_ERR(cs42l51->mclk_handle); 730 731 for (i = 0; i < ARRAY_SIZE(cs42l51->supplies); i++) 732 cs42l51->supplies[i].supply = cs42l51_supply_names[i]; 733 734 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs42l51->supplies), 735 cs42l51->supplies); 736 if (ret != 0) { 737 dev_err(dev, "Failed to request supplies: %d\n", ret); 738 return ret; 739 } 740 741 ret = regulator_bulk_enable(ARRAY_SIZE(cs42l51->supplies), 742 cs42l51->supplies); 743 if (ret != 0) { 744 dev_err(dev, "Failed to enable supplies: %d\n", ret); 745 return ret; 746 } 747 748 cs42l51->reset_gpio = devm_gpiod_get_optional(dev, "reset", 749 GPIOD_OUT_LOW); 750 if (IS_ERR(cs42l51->reset_gpio)) 751 return PTR_ERR(cs42l51->reset_gpio); 752 753 if (cs42l51->reset_gpio) { 754 dev_dbg(dev, "Release reset gpio\n"); 755 gpiod_set_value_cansleep(cs42l51->reset_gpio, 0); 756 mdelay(2); 757 } 758 759 /* Verify that we have a CS42L51 */ 760 ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val); 761 if (ret < 0) { 762 dev_err(dev, "failed to read I2C\n"); 763 goto error; 764 } 765 766 if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && 767 (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { 768 dev_err(dev, "Invalid chip id: %x\n", val); 769 ret = -ENODEV; 770 goto error; 771 } 772 dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n", 773 val & CS42L51_CHIP_REV_MASK); 774 775 ret = devm_snd_soc_register_component(dev, 776 &soc_component_device_cs42l51, &cs42l51_dai, 1); 777 if (ret < 0) 778 goto error; 779 780 return 0; 781 782 error: 783 regulator_bulk_disable(ARRAY_SIZE(cs42l51->supplies), 784 cs42l51->supplies); 785 return ret; 786 } 787 EXPORT_SYMBOL_GPL(cs42l51_probe); 788 789 void cs42l51_remove(struct device *dev) 790 { 791 struct cs42l51_private *cs42l51 = dev_get_drvdata(dev); 792 int ret; 793 794 gpiod_set_value_cansleep(cs42l51->reset_gpio, 1); 795 796 ret = regulator_bulk_disable(ARRAY_SIZE(cs42l51->supplies), 797 cs42l51->supplies); 798 if (ret) 799 dev_warn(dev, "Failed to disable all regulators (%pe)\n", 800 ERR_PTR(ret)); 801 802 } 803 EXPORT_SYMBOL_GPL(cs42l51_remove); 804 805 int __maybe_unused cs42l51_suspend(struct device *dev) 806 { 807 struct cs42l51_private *cs42l51 = dev_get_drvdata(dev); 808 809 regcache_cache_only(cs42l51->regmap, true); 810 regcache_mark_dirty(cs42l51->regmap); 811 812 return 0; 813 } 814 EXPORT_SYMBOL_GPL(cs42l51_suspend); 815 816 int __maybe_unused cs42l51_resume(struct device *dev) 817 { 818 struct cs42l51_private *cs42l51 = dev_get_drvdata(dev); 819 820 regcache_cache_only(cs42l51->regmap, false); 821 822 return regcache_sync(cs42l51->regmap); 823 } 824 EXPORT_SYMBOL_GPL(cs42l51_resume); 825 826 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); 827 MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); 828 MODULE_LICENSE("GPL"); 829
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.