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