1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Cirrus Logic CS42448/CS42888 Audio CODEC Digital Audio Interface (DAI) driver 4 * 5 * Copyright (C) 2014 Freescale Semiconductor, Inc. 6 * 7 * Author: Nicolin Chen <Guangyu.Chen@freescale.com> 8 */ 9 10 #include <linux/clk.h> 11 #include <linux/delay.h> 12 #include <linux/module.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/pm_runtime.h> 15 #include <linux/regulator/consumer.h> 16 #include <sound/pcm_params.h> 17 #include <sound/soc.h> 18 #include <sound/tlv.h> 19 20 #include "cs42xx8.h" 21 22 #define CS42XX8_NUM_SUPPLIES 4 23 static const char *const cs42xx8_supply_names[CS42XX8_NUM_SUPPLIES] = { 24 "VA", 25 "VD", 26 "VLS", 27 "VLC", 28 }; 29 30 #define CS42XX8_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 31 SNDRV_PCM_FMTBIT_S20_3LE | \ 32 SNDRV_PCM_FMTBIT_S24_LE | \ 33 SNDRV_PCM_FMTBIT_S32_LE) 34 35 /* codec private data */ 36 struct cs42xx8_priv { 37 struct regulator_bulk_data supplies[CS42XX8_NUM_SUPPLIES]; 38 const struct cs42xx8_driver_data *drvdata; 39 struct regmap *regmap; 40 struct clk *clk; 41 42 bool slave_mode; 43 bool is_tdm_mode; 44 unsigned long sysclk; 45 u32 tx_channels; 46 struct gpio_desc *gpiod_reset; 47 u32 rate[2]; 48 }; 49 50 /* -127.5dB to 0dB with step of 0.5dB */ 51 static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); 52 /* -64dB to 24dB with step of 0.5dB */ 53 static const DECLARE_TLV_DB_SCALE(adc_tlv, -6400, 50, 0); 54 55 static const char *const cs42xx8_adc_single[] = { "Differential", "Single-Ended" }; 56 static const char *const cs42xx8_szc[] = { "Immediate Change", "Zero Cross", 57 "Soft Ramp", "Soft Ramp on Zero Cross" }; 58 59 static const struct soc_enum adc1_single_enum = 60 SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 4, 2, cs42xx8_adc_single); 61 static const struct soc_enum adc2_single_enum = 62 SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 3, 2, cs42xx8_adc_single); 63 static const struct soc_enum adc3_single_enum = 64 SOC_ENUM_SINGLE(CS42XX8_ADCCTL, 2, 2, cs42xx8_adc_single); 65 static const struct soc_enum dac_szc_enum = 66 SOC_ENUM_SINGLE(CS42XX8_TXCTL, 5, 4, cs42xx8_szc); 67 static const struct soc_enum adc_szc_enum = 68 SOC_ENUM_SINGLE(CS42XX8_TXCTL, 0, 4, cs42xx8_szc); 69 70 static const struct snd_kcontrol_new cs42xx8_snd_controls[] = { 71 SOC_DOUBLE_R_TLV("DAC1 Playback Volume", CS42XX8_VOLAOUT1, 72 CS42XX8_VOLAOUT2, 0, 0xff, 1, dac_tlv), 73 SOC_DOUBLE_R_TLV("DAC2 Playback Volume", CS42XX8_VOLAOUT3, 74 CS42XX8_VOLAOUT4, 0, 0xff, 1, dac_tlv), 75 SOC_DOUBLE_R_TLV("DAC3 Playback Volume", CS42XX8_VOLAOUT5, 76 CS42XX8_VOLAOUT6, 0, 0xff, 1, dac_tlv), 77 SOC_DOUBLE_R_TLV("DAC4 Playback Volume", CS42XX8_VOLAOUT7, 78 CS42XX8_VOLAOUT8, 0, 0xff, 1, dac_tlv), 79 SOC_DOUBLE_R_S_TLV("ADC1 Capture Volume", CS42XX8_VOLAIN1, 80 CS42XX8_VOLAIN2, 0, -0x80, 0x30, 7, 0, adc_tlv), 81 SOC_DOUBLE_R_S_TLV("ADC2 Capture Volume", CS42XX8_VOLAIN3, 82 CS42XX8_VOLAIN4, 0, -0x80, 0x30, 7, 0, adc_tlv), 83 SOC_DOUBLE("DAC1 Invert Switch", CS42XX8_DACINV, 0, 1, 1, 0), 84 SOC_DOUBLE("DAC2 Invert Switch", CS42XX8_DACINV, 2, 3, 1, 0), 85 SOC_DOUBLE("DAC3 Invert Switch", CS42XX8_DACINV, 4, 5, 1, 0), 86 SOC_DOUBLE("DAC4 Invert Switch", CS42XX8_DACINV, 6, 7, 1, 0), 87 SOC_DOUBLE("ADC1 Invert Switch", CS42XX8_ADCINV, 0, 1, 1, 0), 88 SOC_DOUBLE("ADC2 Invert Switch", CS42XX8_ADCINV, 2, 3, 1, 0), 89 SOC_SINGLE("ADC High-Pass Filter Switch", CS42XX8_ADCCTL, 7, 1, 1), 90 SOC_SINGLE("DAC De-emphasis Switch", CS42XX8_ADCCTL, 5, 1, 0), 91 SOC_ENUM("ADC1 Single Ended Mode Switch", adc1_single_enum), 92 SOC_ENUM("ADC2 Single Ended Mode Switch", adc2_single_enum), 93 SOC_SINGLE("DAC Single Volume Control Switch", CS42XX8_TXCTL, 7, 1, 0), 94 SOC_ENUM("DAC Soft Ramp & Zero Cross Control Switch", dac_szc_enum), 95 SOC_SINGLE("DAC Auto Mute Switch", CS42XX8_TXCTL, 4, 1, 0), 96 SOC_SINGLE("Mute ADC Serial Port Switch", CS42XX8_TXCTL, 3, 1, 0), 97 SOC_SINGLE("ADC Single Volume Control Switch", CS42XX8_TXCTL, 2, 1, 0), 98 SOC_ENUM("ADC Soft Ramp & Zero Cross Control Switch", adc_szc_enum), 99 }; 100 101 static const struct snd_kcontrol_new cs42xx8_adc3_snd_controls[] = { 102 SOC_DOUBLE_R_S_TLV("ADC3 Capture Volume", CS42XX8_VOLAIN5, 103 CS42XX8_VOLAIN6, 0, -0x80, 0x30, 7, 0, adc_tlv), 104 SOC_DOUBLE("ADC3 Invert Switch", CS42XX8_ADCINV, 4, 5, 1, 0), 105 SOC_ENUM("ADC3 Single Ended Mode Switch", adc3_single_enum), 106 }; 107 108 static const struct snd_soc_dapm_widget cs42xx8_dapm_widgets[] = { 109 SND_SOC_DAPM_DAC("DAC1", "Playback", CS42XX8_PWRCTL, 1, 1), 110 SND_SOC_DAPM_DAC("DAC2", "Playback", CS42XX8_PWRCTL, 2, 1), 111 SND_SOC_DAPM_DAC("DAC3", "Playback", CS42XX8_PWRCTL, 3, 1), 112 SND_SOC_DAPM_DAC("DAC4", "Playback", CS42XX8_PWRCTL, 4, 1), 113 114 SND_SOC_DAPM_OUTPUT("AOUT1L"), 115 SND_SOC_DAPM_OUTPUT("AOUT1R"), 116 SND_SOC_DAPM_OUTPUT("AOUT2L"), 117 SND_SOC_DAPM_OUTPUT("AOUT2R"), 118 SND_SOC_DAPM_OUTPUT("AOUT3L"), 119 SND_SOC_DAPM_OUTPUT("AOUT3R"), 120 SND_SOC_DAPM_OUTPUT("AOUT4L"), 121 SND_SOC_DAPM_OUTPUT("AOUT4R"), 122 123 SND_SOC_DAPM_ADC("ADC1", "Capture", CS42XX8_PWRCTL, 5, 1), 124 SND_SOC_DAPM_ADC("ADC2", "Capture", CS42XX8_PWRCTL, 6, 1), 125 126 SND_SOC_DAPM_INPUT("AIN1L"), 127 SND_SOC_DAPM_INPUT("AIN1R"), 128 SND_SOC_DAPM_INPUT("AIN2L"), 129 SND_SOC_DAPM_INPUT("AIN2R"), 130 131 SND_SOC_DAPM_SUPPLY("PWR", CS42XX8_PWRCTL, 0, 1, NULL, 0), 132 }; 133 134 static const struct snd_soc_dapm_widget cs42xx8_adc3_dapm_widgets[] = { 135 SND_SOC_DAPM_ADC("ADC3", "Capture", CS42XX8_PWRCTL, 7, 1), 136 137 SND_SOC_DAPM_INPUT("AIN3L"), 138 SND_SOC_DAPM_INPUT("AIN3R"), 139 }; 140 141 static const struct snd_soc_dapm_route cs42xx8_dapm_routes[] = { 142 /* Playback */ 143 { "AOUT1L", NULL, "DAC1" }, 144 { "AOUT1R", NULL, "DAC1" }, 145 { "DAC1", NULL, "PWR" }, 146 147 { "AOUT2L", NULL, "DAC2" }, 148 { "AOUT2R", NULL, "DAC2" }, 149 { "DAC2", NULL, "PWR" }, 150 151 { "AOUT3L", NULL, "DAC3" }, 152 { "AOUT3R", NULL, "DAC3" }, 153 { "DAC3", NULL, "PWR" }, 154 155 { "AOUT4L", NULL, "DAC4" }, 156 { "AOUT4R", NULL, "DAC4" }, 157 { "DAC4", NULL, "PWR" }, 158 159 /* Capture */ 160 { "ADC1", NULL, "AIN1L" }, 161 { "ADC1", NULL, "AIN1R" }, 162 { "ADC1", NULL, "PWR" }, 163 164 { "ADC2", NULL, "AIN2L" }, 165 { "ADC2", NULL, "AIN2R" }, 166 { "ADC2", NULL, "PWR" }, 167 }; 168 169 static const struct snd_soc_dapm_route cs42xx8_adc3_dapm_routes[] = { 170 /* Capture */ 171 { "ADC3", NULL, "AIN3L" }, 172 { "ADC3", NULL, "AIN3R" }, 173 { "ADC3", NULL, "PWR" }, 174 }; 175 176 struct cs42xx8_ratios { 177 unsigned int mfreq; 178 unsigned int min_mclk; 179 unsigned int max_mclk; 180 unsigned int ratio[3]; 181 }; 182 183 /* 184 * According to reference mannual, define the cs42xx8_ratio struct 185 * MFreq2 | MFreq1 | MFreq0 | Description | SSM | DSM | QSM | 186 * 0 | 0 | 0 |1.029MHz to 12.8MHz | 256 | 128 | 64 | 187 * 0 | 0 | 1 |1.536MHz to 19.2MHz | 384 | 192 | 96 | 188 * 0 | 1 | 0 |2.048MHz to 25.6MHz | 512 | 256 | 128 | 189 * 0 | 1 | 1 |3.072MHz to 38.4MHz | 768 | 384 | 192 | 190 * 1 | x | x |4.096MHz to 51.2MHz |1024 | 512 | 256 | 191 */ 192 static const struct cs42xx8_ratios cs42xx8_ratios[] = { 193 { 0, 1029000, 12800000, {256, 128, 64} }, 194 { 2, 1536000, 19200000, {384, 192, 96} }, 195 { 4, 2048000, 25600000, {512, 256, 128} }, 196 { 6, 3072000, 38400000, {768, 384, 192} }, 197 { 8, 4096000, 51200000, {1024, 512, 256} }, 198 }; 199 200 static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai, 201 int clk_id, unsigned int freq, int dir) 202 { 203 struct snd_soc_component *component = codec_dai->component; 204 struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component); 205 206 cs42xx8->sysclk = freq; 207 208 return 0; 209 } 210 211 static int cs42xx8_set_dai_fmt(struct snd_soc_dai *codec_dai, 212 unsigned int format) 213 { 214 struct snd_soc_component *component = codec_dai->component; 215 struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component); 216 u32 val; 217 218 cs42xx8->is_tdm_mode = false; 219 220 /* Set DAI format */ 221 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 222 case SND_SOC_DAIFMT_LEFT_J: 223 val = CS42XX8_INTF_DAC_DIF_LEFTJ | CS42XX8_INTF_ADC_DIF_LEFTJ; 224 break; 225 case SND_SOC_DAIFMT_I2S: 226 val = CS42XX8_INTF_DAC_DIF_I2S | CS42XX8_INTF_ADC_DIF_I2S; 227 break; 228 case SND_SOC_DAIFMT_RIGHT_J: 229 val = CS42XX8_INTF_DAC_DIF_RIGHTJ | CS42XX8_INTF_ADC_DIF_RIGHTJ; 230 break; 231 case SND_SOC_DAIFMT_DSP_A: 232 val = CS42XX8_INTF_DAC_DIF_TDM | CS42XX8_INTF_ADC_DIF_TDM; 233 cs42xx8->is_tdm_mode = true; 234 break; 235 default: 236 dev_err(component->dev, "unsupported dai format\n"); 237 return -EINVAL; 238 } 239 240 regmap_update_bits(cs42xx8->regmap, CS42XX8_INTF, 241 CS42XX8_INTF_DAC_DIF_MASK | 242 CS42XX8_INTF_ADC_DIF_MASK, val); 243 244 /* Set master/slave audio interface */ 245 switch (format & SND_SOC_DAIFMT_MASTER_MASK) { 246 case SND_SOC_DAIFMT_CBC_CFC: 247 cs42xx8->slave_mode = true; 248 break; 249 case SND_SOC_DAIFMT_CBP_CFP: 250 cs42xx8->slave_mode = false; 251 break; 252 default: 253 dev_err(component->dev, "unsupported master/slave mode\n"); 254 return -EINVAL; 255 } 256 257 if (cs42xx8->is_tdm_mode && !cs42xx8->slave_mode) { 258 dev_err(component->dev, "TDM mode is supported only in slave mode\n"); 259 return -EINVAL; 260 } 261 262 return 0; 263 } 264 265 static int cs42xx8_hw_params(struct snd_pcm_substream *substream, 266 struct snd_pcm_hw_params *params, 267 struct snd_soc_dai *dai) 268 { 269 struct snd_soc_component *component = dai->component; 270 struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component); 271 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 272 u32 ratio[2]; 273 u32 rate[2]; 274 u32 fm[2]; 275 u32 i, val, mask; 276 bool condition1, condition2; 277 278 if (tx) 279 cs42xx8->tx_channels = params_channels(params); 280 281 rate[tx] = params_rate(params); 282 rate[!tx] = cs42xx8->rate[!tx]; 283 284 ratio[tx] = rate[tx] > 0 ? cs42xx8->sysclk / rate[tx] : 0; 285 ratio[!tx] = rate[!tx] > 0 ? cs42xx8->sysclk / rate[!tx] : 0; 286 287 /* Get functional mode for tx and rx according to rate */ 288 for (i = 0; i < 2; i++) { 289 if (cs42xx8->slave_mode) { 290 fm[i] = CS42XX8_FM_AUTO; 291 } else { 292 if (rate[i] < 50000) { 293 fm[i] = CS42XX8_FM_SINGLE; 294 } else if (rate[i] > 50000 && rate[i] < 100000) { 295 fm[i] = CS42XX8_FM_DOUBLE; 296 } else if (rate[i] > 100000 && rate[i] < 200000) { 297 fm[i] = CS42XX8_FM_QUAD; 298 } else { 299 dev_err(component->dev, 300 "unsupported sample rate\n"); 301 return -EINVAL; 302 } 303 } 304 } 305 306 for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) { 307 /* Is the ratio[tx] valid ? */ 308 condition1 = ((fm[tx] == CS42XX8_FM_AUTO) ? 309 (cs42xx8_ratios[i].ratio[0] == ratio[tx] || 310 cs42xx8_ratios[i].ratio[1] == ratio[tx] || 311 cs42xx8_ratios[i].ratio[2] == ratio[tx]) : 312 (cs42xx8_ratios[i].ratio[fm[tx]] == ratio[tx])) && 313 cs42xx8->sysclk >= cs42xx8_ratios[i].min_mclk && 314 cs42xx8->sysclk <= cs42xx8_ratios[i].max_mclk; 315 316 if (!ratio[tx]) 317 condition1 = true; 318 319 /* Is the ratio[!tx] valid ? */ 320 condition2 = ((fm[!tx] == CS42XX8_FM_AUTO) ? 321 (cs42xx8_ratios[i].ratio[0] == ratio[!tx] || 322 cs42xx8_ratios[i].ratio[1] == ratio[!tx] || 323 cs42xx8_ratios[i].ratio[2] == ratio[!tx]) : 324 (cs42xx8_ratios[i].ratio[fm[!tx]] == ratio[!tx])); 325 326 if (!ratio[!tx]) 327 condition2 = true; 328 329 /* 330 * Both ratio[tx] and ratio[!tx] is valid, then we get 331 * a proper MFreq. 332 */ 333 if (condition1 && condition2) 334 break; 335 } 336 337 if (i == ARRAY_SIZE(cs42xx8_ratios)) { 338 dev_err(component->dev, "unsupported sysclk ratio\n"); 339 return -EINVAL; 340 } 341 342 cs42xx8->rate[tx] = params_rate(params); 343 344 if (cs42xx8->is_tdm_mode) { 345 if (cs42xx8->sysclk < 256 * cs42xx8->rate[tx]) { 346 dev_err(component->dev, "Unsupported sysclk in TDM mode\n"); 347 return -EINVAL; 348 } 349 350 if (!tx && cs42xx8->rate[tx] > 100000) { 351 dev_err(component->dev, 352 "ADC does not support Quad-Speed Mode in TDM mode\n"); 353 return -EINVAL; 354 } 355 } 356 357 mask = CS42XX8_FUNCMOD_MFREQ_MASK; 358 val = cs42xx8_ratios[i].mfreq; 359 360 regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD, 361 CS42XX8_FUNCMOD_xC_FM_MASK(tx) | mask, 362 CS42XX8_FUNCMOD_xC_FM(tx, fm[tx]) | val); 363 364 return 0; 365 } 366 367 static int cs42xx8_hw_free(struct snd_pcm_substream *substream, 368 struct snd_soc_dai *dai) 369 { 370 struct snd_soc_component *component = dai->component; 371 struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component); 372 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 373 374 /* Clear stored rate */ 375 cs42xx8->rate[tx] = 0; 376 377 regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD, 378 CS42XX8_FUNCMOD_xC_FM_MASK(tx), 379 CS42XX8_FUNCMOD_xC_FM(tx, CS42XX8_FM_AUTO)); 380 return 0; 381 } 382 383 static int cs42xx8_mute(struct snd_soc_dai *dai, int mute, int direction) 384 { 385 struct snd_soc_component *component = dai->component; 386 struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component); 387 u8 dac_unmute = cs42xx8->tx_channels ? 388 ~((0x1 << cs42xx8->tx_channels) - 1) : 0; 389 390 regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE, 391 mute ? CS42XX8_DACMUTE_ALL : dac_unmute); 392 393 return 0; 394 } 395 396 static const struct snd_soc_dai_ops cs42xx8_dai_ops = { 397 .set_fmt = cs42xx8_set_dai_fmt, 398 .set_sysclk = cs42xx8_set_dai_sysclk, 399 .hw_params = cs42xx8_hw_params, 400 .hw_free = cs42xx8_hw_free, 401 .mute_stream = cs42xx8_mute, 402 .no_capture_mute = 1, 403 }; 404 405 static struct snd_soc_dai_driver cs42xx8_dai = { 406 .playback = { 407 .stream_name = "Playback", 408 .channels_min = 1, 409 .channels_max = 8, 410 .rates = SNDRV_PCM_RATE_8000_192000, 411 .formats = CS42XX8_FORMATS, 412 }, 413 .capture = { 414 .stream_name = "Capture", 415 .channels_min = 1, 416 .rates = SNDRV_PCM_RATE_8000_192000, 417 .formats = CS42XX8_FORMATS, 418 }, 419 .ops = &cs42xx8_dai_ops, 420 }; 421 422 static const struct reg_default cs42xx8_reg[] = { 423 { 0x02, 0x00 }, /* Power Control */ 424 { 0x03, 0xF0 }, /* Functional Mode */ 425 { 0x04, 0x46 }, /* Interface Formats */ 426 { 0x05, 0x00 }, /* ADC Control & DAC De-Emphasis */ 427 { 0x06, 0x10 }, /* Transition Control */ 428 { 0x07, 0x00 }, /* DAC Channel Mute */ 429 { 0x08, 0x00 }, /* Volume Control AOUT1 */ 430 { 0x09, 0x00 }, /* Volume Control AOUT2 */ 431 { 0x0a, 0x00 }, /* Volume Control AOUT3 */ 432 { 0x0b, 0x00 }, /* Volume Control AOUT4 */ 433 { 0x0c, 0x00 }, /* Volume Control AOUT5 */ 434 { 0x0d, 0x00 }, /* Volume Control AOUT6 */ 435 { 0x0e, 0x00 }, /* Volume Control AOUT7 */ 436 { 0x0f, 0x00 }, /* Volume Control AOUT8 */ 437 { 0x10, 0x00 }, /* DAC Channel Invert */ 438 { 0x11, 0x00 }, /* Volume Control AIN1 */ 439 { 0x12, 0x00 }, /* Volume Control AIN2 */ 440 { 0x13, 0x00 }, /* Volume Control AIN3 */ 441 { 0x14, 0x00 }, /* Volume Control AIN4 */ 442 { 0x15, 0x00 }, /* Volume Control AIN5 */ 443 { 0x16, 0x00 }, /* Volume Control AIN6 */ 444 { 0x17, 0x00 }, /* ADC Channel Invert */ 445 { 0x18, 0x00 }, /* Status Control */ 446 { 0x1a, 0x00 }, /* Status Mask */ 447 { 0x1b, 0x00 }, /* MUTEC Pin Control */ 448 }; 449 450 static bool cs42xx8_volatile_register(struct device *dev, unsigned int reg) 451 { 452 switch (reg) { 453 case CS42XX8_STATUS: 454 return true; 455 default: 456 return false; 457 } 458 } 459 460 static bool cs42xx8_writeable_register(struct device *dev, unsigned int reg) 461 { 462 switch (reg) { 463 case CS42XX8_CHIPID: 464 case CS42XX8_STATUS: 465 return false; 466 default: 467 return true; 468 } 469 } 470 471 const struct regmap_config cs42xx8_regmap_config = { 472 .reg_bits = 8, 473 .val_bits = 8, 474 475 .max_register = CS42XX8_LASTREG, 476 .reg_defaults = cs42xx8_reg, 477 .num_reg_defaults = ARRAY_SIZE(cs42xx8_reg), 478 .volatile_reg = cs42xx8_volatile_register, 479 .writeable_reg = cs42xx8_writeable_register, 480 .cache_type = REGCACHE_MAPLE, 481 }; 482 EXPORT_SYMBOL_GPL(cs42xx8_regmap_config); 483 484 static int cs42xx8_component_probe(struct snd_soc_component *component) 485 { 486 struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component); 487 struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); 488 489 switch (cs42xx8->drvdata->num_adcs) { 490 case 3: 491 snd_soc_add_component_controls(component, cs42xx8_adc3_snd_controls, 492 ARRAY_SIZE(cs42xx8_adc3_snd_controls)); 493 snd_soc_dapm_new_controls(dapm, cs42xx8_adc3_dapm_widgets, 494 ARRAY_SIZE(cs42xx8_adc3_dapm_widgets)); 495 snd_soc_dapm_add_routes(dapm, cs42xx8_adc3_dapm_routes, 496 ARRAY_SIZE(cs42xx8_adc3_dapm_routes)); 497 break; 498 default: 499 break; 500 } 501 502 /* Mute all DAC channels */ 503 regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE, CS42XX8_DACMUTE_ALL); 504 505 return 0; 506 } 507 508 static const struct snd_soc_component_driver cs42xx8_driver = { 509 .probe = cs42xx8_component_probe, 510 .controls = cs42xx8_snd_controls, 511 .num_controls = ARRAY_SIZE(cs42xx8_snd_controls), 512 .dapm_widgets = cs42xx8_dapm_widgets, 513 .num_dapm_widgets = ARRAY_SIZE(cs42xx8_dapm_widgets), 514 .dapm_routes = cs42xx8_dapm_routes, 515 .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes), 516 .use_pmdown_time = 1, 517 .endianness = 1, 518 }; 519 520 const struct cs42xx8_driver_data cs42448_data = { 521 .name = "cs42448", 522 .num_adcs = 3, 523 }; 524 EXPORT_SYMBOL_GPL(cs42448_data); 525 526 const struct cs42xx8_driver_data cs42888_data = { 527 .name = "cs42888", 528 .num_adcs = 2, 529 }; 530 EXPORT_SYMBOL_GPL(cs42888_data); 531 532 int cs42xx8_probe(struct device *dev, struct regmap *regmap, struct cs42xx8_driver_data *drvdata) 533 { 534 struct cs42xx8_priv *cs42xx8; 535 int ret, val, i; 536 537 if (IS_ERR(regmap)) { 538 ret = PTR_ERR(regmap); 539 dev_err(dev, "failed to allocate regmap: %d\n", ret); 540 return ret; 541 } 542 543 cs42xx8 = devm_kzalloc(dev, sizeof(*cs42xx8), GFP_KERNEL); 544 if (cs42xx8 == NULL) 545 return -ENOMEM; 546 547 dev_set_drvdata(dev, cs42xx8); 548 549 cs42xx8->regmap = regmap; 550 551 cs42xx8->drvdata = drvdata; 552 553 cs42xx8->gpiod_reset = devm_gpiod_get_optional(dev, "reset", 554 GPIOD_OUT_HIGH); 555 if (IS_ERR(cs42xx8->gpiod_reset)) 556 return PTR_ERR(cs42xx8->gpiod_reset); 557 558 gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 0); 559 560 cs42xx8->clk = devm_clk_get(dev, "mclk"); 561 if (IS_ERR(cs42xx8->clk)) { 562 dev_err(dev, "failed to get the clock: %ld\n", 563 PTR_ERR(cs42xx8->clk)); 564 return -EINVAL; 565 } 566 567 cs42xx8->sysclk = clk_get_rate(cs42xx8->clk); 568 569 for (i = 0; i < ARRAY_SIZE(cs42xx8->supplies); i++) 570 cs42xx8->supplies[i].supply = cs42xx8_supply_names[i]; 571 572 ret = devm_regulator_bulk_get(dev, 573 ARRAY_SIZE(cs42xx8->supplies), cs42xx8->supplies); 574 if (ret) { 575 dev_err(dev, "failed to request supplies: %d\n", ret); 576 return ret; 577 } 578 579 ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies), 580 cs42xx8->supplies); 581 if (ret) { 582 dev_err(dev, "failed to enable supplies: %d\n", ret); 583 return ret; 584 } 585 586 /* Make sure hardware reset done */ 587 msleep(5); 588 589 /* Validate the chip ID */ 590 ret = regmap_read(cs42xx8->regmap, CS42XX8_CHIPID, &val); 591 if (ret < 0) { 592 dev_err(dev, "failed to get device ID, ret = %d", ret); 593 goto err_enable; 594 } 595 596 /* The top four bits of the chip ID should be 0000 */ 597 if (((val & CS42XX8_CHIPID_CHIP_ID_MASK) >> 4) != 0x00) { 598 dev_err(dev, "unmatched chip ID: %d\n", 599 (val & CS42XX8_CHIPID_CHIP_ID_MASK) >> 4); 600 ret = -EINVAL; 601 goto err_enable; 602 } 603 604 dev_info(dev, "found device, revision %X\n", 605 val & CS42XX8_CHIPID_REV_ID_MASK); 606 607 cs42xx8_dai.name = cs42xx8->drvdata->name; 608 609 /* Each adc supports stereo input */ 610 cs42xx8_dai.capture.channels_max = cs42xx8->drvdata->num_adcs * 2; 611 612 ret = devm_snd_soc_register_component(dev, &cs42xx8_driver, &cs42xx8_dai, 1); 613 if (ret) { 614 dev_err(dev, "failed to register component:%d\n", ret); 615 goto err_enable; 616 } 617 618 regcache_cache_only(cs42xx8->regmap, true); 619 620 err_enable: 621 regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies), 622 cs42xx8->supplies); 623 624 return ret; 625 } 626 EXPORT_SYMBOL_GPL(cs42xx8_probe); 627 628 static int cs42xx8_runtime_resume(struct device *dev) 629 { 630 struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev); 631 int ret; 632 633 ret = clk_prepare_enable(cs42xx8->clk); 634 if (ret) { 635 dev_err(dev, "failed to enable mclk: %d\n", ret); 636 return ret; 637 } 638 639 gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 0); 640 641 ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies), 642 cs42xx8->supplies); 643 if (ret) { 644 dev_err(dev, "failed to enable supplies: %d\n", ret); 645 goto err_clk; 646 } 647 648 /* Make sure hardware reset done */ 649 msleep(5); 650 651 regcache_cache_only(cs42xx8->regmap, false); 652 regcache_mark_dirty(cs42xx8->regmap); 653 654 ret = regcache_sync(cs42xx8->regmap); 655 if (ret) { 656 dev_err(dev, "failed to sync regmap: %d\n", ret); 657 goto err_bulk; 658 } 659 660 return 0; 661 662 err_bulk: 663 regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies), 664 cs42xx8->supplies); 665 err_clk: 666 clk_disable_unprepare(cs42xx8->clk); 667 668 return ret; 669 } 670 671 static int cs42xx8_runtime_suspend(struct device *dev) 672 { 673 struct cs42xx8_priv *cs42xx8 = dev_get_drvdata(dev); 674 675 regcache_cache_only(cs42xx8->regmap, true); 676 677 regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies), 678 cs42xx8->supplies); 679 680 gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 1); 681 682 clk_disable_unprepare(cs42xx8->clk); 683 684 return 0; 685 } 686 687 EXPORT_GPL_DEV_PM_OPS(cs42xx8_pm) = { 688 SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) 689 RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL) 690 }; 691 692 MODULE_DESCRIPTION("Cirrus Logic CS42448/CS42888 ALSA SoC Codec Driver"); 693 MODULE_AUTHOR("Freescale Semiconductor, Inc."); 694 MODULE_LICENSE("GPL"); 695