1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // tegra210_dmic.c - Tegra210 DMIC driver 4 // 5 // Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. 6 7 #include <linux/clk.h> 8 #include <linux/device.h> 9 #include <linux/math64.h> 10 #include <linux/module.h> 11 #include <linux/of_device.h> 12 #include <linux/platform_device.h> 13 #include <linux/pm_runtime.h> 14 #include <linux/regmap.h> 15 #include <sound/core.h> 16 #include <sound/pcm_params.h> 17 #include <sound/soc.h> 18 #include "tegra210_dmic.h" 19 #include "tegra_cif.h" 20 21 static const struct reg_default tegra210_dmic_reg_defaults[] = { 22 { TEGRA210_DMIC_TX_INT_MASK, 0x00000001 }, 23 { TEGRA210_DMIC_TX_CIF_CTRL, 0x00007700 }, 24 { TEGRA210_DMIC_CG, 0x1 }, 25 { TEGRA210_DMIC_CTRL, 0x00000301 }, 26 /* Below enables all filters - DCR, LP and SC */ 27 { TEGRA210_DMIC_DBG_CTRL, 0xe }, 28 /* Below as per latest POR value */ 29 { TEGRA210_DMIC_DCR_BIQUAD_0_COEF_4, 0x0 }, 30 /* LP filter is configured for pass through and used to apply gain */ 31 { TEGRA210_DMIC_LP_BIQUAD_0_COEF_0, 0x00800000 }, 32 { TEGRA210_DMIC_LP_BIQUAD_0_COEF_1, 0x0 }, 33 { TEGRA210_DMIC_LP_BIQUAD_0_COEF_2, 0x0 }, 34 { TEGRA210_DMIC_LP_BIQUAD_0_COEF_3, 0x0 }, 35 { TEGRA210_DMIC_LP_BIQUAD_0_COEF_4, 0x0 }, 36 { TEGRA210_DMIC_LP_BIQUAD_1_COEF_0, 0x00800000 }, 37 { TEGRA210_DMIC_LP_BIQUAD_1_COEF_1, 0x0 }, 38 { TEGRA210_DMIC_LP_BIQUAD_1_COEF_2, 0x0 }, 39 { TEGRA210_DMIC_LP_BIQUAD_1_COEF_3, 0x0 }, 40 { TEGRA210_DMIC_LP_BIQUAD_1_COEF_4, 0x0 }, 41 }; 42 43 static int __maybe_unused tegra210_dmic_runtime_suspend(struct device *dev) 44 { 45 struct tegra210_dmic *dmic = dev_get_drvdata(dev); 46 47 regcache_cache_only(dmic->regmap, true); 48 regcache_mark_dirty(dmic->regmap); 49 50 clk_disable_unprepare(dmic->clk_dmic); 51 52 return 0; 53 } 54 55 static int __maybe_unused tegra210_dmic_runtime_resume(struct device *dev) 56 { 57 struct tegra210_dmic *dmic = dev_get_drvdata(dev); 58 int err; 59 60 err = clk_prepare_enable(dmic->clk_dmic); 61 if (err) { 62 dev_err(dev, "failed to enable DMIC clock, err: %d\n", err); 63 return err; 64 } 65 66 regcache_cache_only(dmic->regmap, false); 67 regcache_sync(dmic->regmap); 68 69 return 0; 70 } 71 72 static int tegra210_dmic_hw_params(struct snd_pcm_substream *substream, 73 struct snd_pcm_hw_params *params, 74 struct snd_soc_dai *dai) 75 { 76 struct tegra210_dmic *dmic = snd_soc_dai_get_drvdata(dai); 77 unsigned int srate, clk_rate, channels; 78 struct tegra_cif_conf cif_conf; 79 unsigned long long gain_q23 = DEFAULT_GAIN_Q23; 80 int err; 81 82 memset(&cif_conf, 0, sizeof(struct tegra_cif_conf)); 83 84 channels = params_channels(params); 85 86 cif_conf.audio_ch = channels; 87 88 switch (dmic->ch_select) { 89 case DMIC_CH_SELECT_LEFT: 90 case DMIC_CH_SELECT_RIGHT: 91 cif_conf.client_ch = 1; 92 break; 93 case DMIC_CH_SELECT_STEREO: 94 cif_conf.client_ch = 2; 95 break; 96 default: 97 dev_err(dai->dev, "invalid DMIC client channels\n"); 98 return -EINVAL; 99 } 100 101 srate = params_rate(params); 102 103 /* 104 * DMIC clock rate is a multiple of 'Over Sampling Ratio' and 105 * 'Sample Rate'. The supported OSR values are 64, 128 and 256. 106 */ 107 clk_rate = (DMIC_OSR_FACTOR << dmic->osr_val) * srate; 108 109 err = clk_set_rate(dmic->clk_dmic, clk_rate); 110 if (err) { 111 dev_err(dai->dev, "can't set DMIC clock rate %u, err: %d\n", 112 clk_rate, err); 113 return err; 114 } 115 116 regmap_update_bits(dmic->regmap, 117 /* Reg */ 118 TEGRA210_DMIC_CTRL, 119 /* Mask */ 120 TEGRA210_DMIC_CTRL_LRSEL_POLARITY_MASK | 121 TEGRA210_DMIC_CTRL_OSR_MASK | 122 TEGRA210_DMIC_CTRL_CHANNEL_SELECT_MASK, 123 /* Value */ 124 (dmic->lrsel << LRSEL_POL_SHIFT) | 125 (dmic->osr_val << OSR_SHIFT) | 126 ((dmic->ch_select + 1) << CH_SEL_SHIFT)); 127 128 /* 129 * Use LP filter gain register to apply boost. 130 * Boost Gain Volume control has 100x factor. 131 */ 132 if (dmic->boost_gain) 133 gain_q23 = div_u64(gain_q23 * dmic->boost_gain, 100); 134 135 regmap_write(dmic->regmap, TEGRA210_DMIC_LP_FILTER_GAIN, 136 (unsigned int)gain_q23); 137 138 switch (params_format(params)) { 139 case SNDRV_PCM_FORMAT_S16_LE: 140 cif_conf.audio_bits = TEGRA_ACIF_BITS_16; 141 break; 142 case SNDRV_PCM_FORMAT_S32_LE: 143 cif_conf.audio_bits = TEGRA_ACIF_BITS_32; 144 break; 145 default: 146 dev_err(dai->dev, "unsupported format!\n"); 147 return -EOPNOTSUPP; 148 } 149 150 cif_conf.client_bits = TEGRA_ACIF_BITS_24; 151 cif_conf.mono_conv = dmic->mono_to_stereo; 152 cif_conf.stereo_conv = dmic->stereo_to_mono; 153 154 tegra_set_cif(dmic->regmap, TEGRA210_DMIC_TX_CIF_CTRL, &cif_conf); 155 156 return 0; 157 } 158 159 static int tegra210_dmic_get_boost_gain(struct snd_kcontrol *kcontrol, 160 struct snd_ctl_elem_value *ucontrol) 161 { 162 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 163 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 164 165 ucontrol->value.integer.value[0] = dmic->boost_gain; 166 167 return 0; 168 } 169 170 static int tegra210_dmic_put_boost_gain(struct snd_kcontrol *kcontrol, 171 struct snd_ctl_elem_value *ucontrol) 172 { 173 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 174 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 175 int value = ucontrol->value.integer.value[0]; 176 177 if (value == dmic->boost_gain) 178 return 0; 179 180 dmic->boost_gain = value; 181 182 return 1; 183 } 184 185 static int tegra210_dmic_get_ch_select(struct snd_kcontrol *kcontrol, 186 struct snd_ctl_elem_value *ucontrol) 187 { 188 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 189 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 190 191 ucontrol->value.enumerated.item[0] = dmic->ch_select; 192 193 return 0; 194 } 195 196 static int tegra210_dmic_put_ch_select(struct snd_kcontrol *kcontrol, 197 struct snd_ctl_elem_value *ucontrol) 198 { 199 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 200 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 201 unsigned int value = ucontrol->value.enumerated.item[0]; 202 203 if (value == dmic->ch_select) 204 return 0; 205 206 dmic->ch_select = value; 207 208 return 1; 209 } 210 211 static int tegra210_dmic_get_mono_to_stereo(struct snd_kcontrol *kcontrol, 212 struct snd_ctl_elem_value *ucontrol) 213 { 214 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 215 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 216 217 ucontrol->value.enumerated.item[0] = dmic->mono_to_stereo; 218 219 return 0; 220 } 221 222 static int tegra210_dmic_put_mono_to_stereo(struct snd_kcontrol *kcontrol, 223 struct snd_ctl_elem_value *ucontrol) 224 { 225 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 226 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 227 unsigned int value = ucontrol->value.enumerated.item[0]; 228 229 if (value == dmic->mono_to_stereo) 230 return 0; 231 232 dmic->mono_to_stereo = value; 233 234 return 1; 235 } 236 237 static int tegra210_dmic_get_stereo_to_mono(struct snd_kcontrol *kcontrol, 238 struct snd_ctl_elem_value *ucontrol) 239 { 240 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 241 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 242 243 ucontrol->value.enumerated.item[0] = dmic->stereo_to_mono; 244 245 return 0; 246 } 247 248 static int tegra210_dmic_put_stereo_to_mono(struct snd_kcontrol *kcontrol, 249 struct snd_ctl_elem_value *ucontrol) 250 { 251 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 252 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 253 unsigned int value = ucontrol->value.enumerated.item[0]; 254 255 if (value == dmic->stereo_to_mono) 256 return 0; 257 258 dmic->stereo_to_mono = value; 259 260 return 1; 261 } 262 263 static int tegra210_dmic_get_osr_val(struct snd_kcontrol *kcontrol, 264 struct snd_ctl_elem_value *ucontrol) 265 { 266 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 267 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 268 269 ucontrol->value.enumerated.item[0] = dmic->osr_val; 270 271 return 0; 272 } 273 274 static int tegra210_dmic_put_osr_val(struct snd_kcontrol *kcontrol, 275 struct snd_ctl_elem_value *ucontrol) 276 { 277 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 278 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 279 unsigned int value = ucontrol->value.enumerated.item[0]; 280 281 if (value == dmic->osr_val) 282 return 0; 283 284 dmic->osr_val = value; 285 286 return 1; 287 } 288 289 static int tegra210_dmic_get_pol_sel(struct snd_kcontrol *kcontrol, 290 struct snd_ctl_elem_value *ucontrol) 291 { 292 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 293 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 294 295 ucontrol->value.enumerated.item[0] = dmic->lrsel; 296 297 return 0; 298 } 299 300 static int tegra210_dmic_put_pol_sel(struct snd_kcontrol *kcontrol, 301 struct snd_ctl_elem_value *ucontrol) 302 { 303 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 304 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 305 unsigned int value = ucontrol->value.enumerated.item[0]; 306 307 if (value == dmic->lrsel) 308 return 0; 309 310 dmic->lrsel = value; 311 312 return 1; 313 } 314 315 static const struct snd_soc_dai_ops tegra210_dmic_dai_ops = { 316 .hw_params = tegra210_dmic_hw_params, 317 }; 318 319 static struct snd_soc_dai_driver tegra210_dmic_dais[] = { 320 { 321 .name = "DMIC-CIF", 322 .capture = { 323 .stream_name = "CIF-Capture", 324 .channels_min = 1, 325 .channels_max = 2, 326 .rates = SNDRV_PCM_RATE_8000_48000, 327 .formats = SNDRV_PCM_FMTBIT_S16_LE | 328 SNDRV_PCM_FMTBIT_S32_LE, 329 }, 330 }, 331 { 332 .name = "DMIC-DAP", 333 .capture = { 334 .stream_name = "DAP-Capture", 335 .channels_min = 1, 336 .channels_max = 2, 337 .rates = SNDRV_PCM_RATE_8000_48000, 338 .formats = SNDRV_PCM_FMTBIT_S16_LE | 339 SNDRV_PCM_FMTBIT_S32_LE, 340 }, 341 .ops = &tegra210_dmic_dai_ops, 342 .symmetric_rate = 1, 343 }, 344 }; 345 346 static const struct snd_soc_dapm_widget tegra210_dmic_widgets[] = { 347 SND_SOC_DAPM_AIF_OUT("TX", NULL, 0, TEGRA210_DMIC_ENABLE, 0, 0), 348 SND_SOC_DAPM_MIC("MIC", NULL), 349 }; 350 351 static const struct snd_soc_dapm_route tegra210_dmic_routes[] = { 352 { "XBAR-RX", NULL, "XBAR-Capture" }, 353 { "XBAR-Capture", NULL, "CIF-Capture" }, 354 { "CIF-Capture", NULL, "TX" }, 355 { "TX", NULL, "DAP-Capture" }, 356 { "DAP-Capture", NULL, "MIC" }, 357 }; 358 359 static const char * const tegra210_dmic_ch_select[] = { 360 "Left", "Right", "Stereo", 361 }; 362 363 static const struct soc_enum tegra210_dmic_ch_enum = 364 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(tegra210_dmic_ch_select), 365 tegra210_dmic_ch_select); 366 367 static const char * const tegra210_dmic_mono_conv_text[] = { 368 "Zero", "Copy", 369 }; 370 371 static const char * const tegra210_dmic_stereo_conv_text[] = { 372 "CH0", "CH1", "AVG", 373 }; 374 375 static const struct soc_enum tegra210_dmic_mono_conv_enum = 376 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(tegra210_dmic_mono_conv_text), 377 tegra210_dmic_mono_conv_text); 378 379 static const struct soc_enum tegra210_dmic_stereo_conv_enum = 380 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(tegra210_dmic_stereo_conv_text), 381 tegra210_dmic_stereo_conv_text); 382 383 static const char * const tegra210_dmic_osr_text[] = { 384 "OSR_64", "OSR_128", "OSR_256", 385 }; 386 387 static const struct soc_enum tegra210_dmic_osr_enum = 388 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(tegra210_dmic_osr_text), 389 tegra210_dmic_osr_text); 390 391 static const char * const tegra210_dmic_lrsel_text[] = { 392 "Left", "Right", 393 }; 394 395 static const struct soc_enum tegra210_dmic_lrsel_enum = 396 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(tegra210_dmic_lrsel_text), 397 tegra210_dmic_lrsel_text); 398 399 static const struct snd_kcontrol_new tegra210_dmic_controls[] = { 400 SOC_SINGLE_EXT("Boost Gain Volume", 0, 0, MAX_BOOST_GAIN, 0, 401 tegra210_dmic_get_boost_gain, 402 tegra210_dmic_put_boost_gain), 403 SOC_ENUM_EXT("Channel Select", tegra210_dmic_ch_enum, 404 tegra210_dmic_get_ch_select, tegra210_dmic_put_ch_select), 405 SOC_ENUM_EXT("Mono To Stereo", 406 tegra210_dmic_mono_conv_enum, 407 tegra210_dmic_get_mono_to_stereo, 408 tegra210_dmic_put_mono_to_stereo), 409 SOC_ENUM_EXT("Stereo To Mono", 410 tegra210_dmic_stereo_conv_enum, 411 tegra210_dmic_get_stereo_to_mono, 412 tegra210_dmic_put_stereo_to_mono), 413 SOC_ENUM_EXT("OSR Value", tegra210_dmic_osr_enum, 414 tegra210_dmic_get_osr_val, tegra210_dmic_put_osr_val), 415 SOC_ENUM_EXT("LR Polarity Select", tegra210_dmic_lrsel_enum, 416 tegra210_dmic_get_pol_sel, tegra210_dmic_put_pol_sel), 417 }; 418 419 static const struct snd_soc_component_driver tegra210_dmic_compnt = { 420 .dapm_widgets = tegra210_dmic_widgets, 421 .num_dapm_widgets = ARRAY_SIZE(tegra210_dmic_widgets), 422 .dapm_routes = tegra210_dmic_routes, 423 .num_dapm_routes = ARRAY_SIZE(tegra210_dmic_routes), 424 .controls = tegra210_dmic_controls, 425 .num_controls = ARRAY_SIZE(tegra210_dmic_controls), 426 }; 427 428 static bool tegra210_dmic_wr_reg(struct device *dev, unsigned int reg) 429 { 430 switch (reg) { 431 case TEGRA210_DMIC_TX_INT_MASK ... TEGRA210_DMIC_TX_CIF_CTRL: 432 case TEGRA210_DMIC_ENABLE ... TEGRA210_DMIC_CG: 433 case TEGRA210_DMIC_CTRL: 434 case TEGRA210_DMIC_DBG_CTRL: 435 case TEGRA210_DMIC_DCR_BIQUAD_0_COEF_4 ... TEGRA210_DMIC_LP_BIQUAD_1_COEF_4: 436 return true; 437 default: 438 return false; 439 } 440 } 441 442 static bool tegra210_dmic_rd_reg(struct device *dev, unsigned int reg) 443 { 444 if (tegra210_dmic_wr_reg(dev, reg)) 445 return true; 446 447 switch (reg) { 448 case TEGRA210_DMIC_TX_STATUS: 449 case TEGRA210_DMIC_TX_INT_STATUS: 450 case TEGRA210_DMIC_STATUS: 451 case TEGRA210_DMIC_INT_STATUS: 452 return true; 453 default: 454 return false; 455 } 456 } 457 458 static bool tegra210_dmic_volatile_reg(struct device *dev, unsigned int reg) 459 { 460 switch (reg) { 461 case TEGRA210_DMIC_TX_STATUS: 462 case TEGRA210_DMIC_TX_INT_STATUS: 463 case TEGRA210_DMIC_TX_INT_SET: 464 case TEGRA210_DMIC_SOFT_RESET: 465 case TEGRA210_DMIC_STATUS: 466 case TEGRA210_DMIC_INT_STATUS: 467 return true; 468 default: 469 return false; 470 } 471 } 472 473 static const struct regmap_config tegra210_dmic_regmap_config = { 474 .reg_bits = 32, 475 .reg_stride = 4, 476 .val_bits = 32, 477 .max_register = TEGRA210_DMIC_LP_BIQUAD_1_COEF_4, 478 .writeable_reg = tegra210_dmic_wr_reg, 479 .readable_reg = tegra210_dmic_rd_reg, 480 .volatile_reg = tegra210_dmic_volatile_reg, 481 .reg_defaults = tegra210_dmic_reg_defaults, 482 .num_reg_defaults = ARRAY_SIZE(tegra210_dmic_reg_defaults), 483 .cache_type = REGCACHE_FLAT, 484 }; 485 486 static int tegra210_dmic_probe(struct platform_device *pdev) 487 { 488 struct device *dev = &pdev->dev; 489 struct tegra210_dmic *dmic; 490 void __iomem *regs; 491 int err; 492 493 dmic = devm_kzalloc(dev, sizeof(*dmic), GFP_KERNEL); 494 if (!dmic) 495 return -ENOMEM; 496 497 dmic->osr_val = DMIC_OSR_64; 498 dmic->ch_select = DMIC_CH_SELECT_STEREO; 499 dmic->lrsel = DMIC_LRSEL_LEFT; 500 dmic->boost_gain = 0; 501 dmic->stereo_to_mono = 0; /* "CH0" */ 502 503 dev_set_drvdata(dev, dmic); 504 505 dmic->clk_dmic = devm_clk_get(dev, "dmic"); 506 if (IS_ERR(dmic->clk_dmic)) { 507 dev_err(dev, "can't retrieve DMIC clock\n"); 508 return PTR_ERR(dmic->clk_dmic); 509 } 510 511 regs = devm_platform_ioremap_resource(pdev, 0); 512 if (IS_ERR(regs)) 513 return PTR_ERR(regs); 514 515 dmic->regmap = devm_regmap_init_mmio(dev, regs, 516 &tegra210_dmic_regmap_config); 517 if (IS_ERR(dmic->regmap)) { 518 dev_err(dev, "regmap init failed\n"); 519 return PTR_ERR(dmic->regmap); 520 } 521 522 regcache_cache_only(dmic->regmap, true); 523 524 err = devm_snd_soc_register_component(dev, &tegra210_dmic_compnt, 525 tegra210_dmic_dais, 526 ARRAY_SIZE(tegra210_dmic_dais)); 527 if (err) { 528 dev_err(dev, "can't register DMIC component, err: %d\n", err); 529 return err; 530 } 531 532 pm_runtime_enable(dev); 533 534 return 0; 535 } 536 537 static int tegra210_dmic_remove(struct platform_device *pdev) 538 { 539 pm_runtime_disable(&pdev->dev); 540 541 return 0; 542 } 543 544 static const struct dev_pm_ops tegra210_dmic_pm_ops = { 545 SET_RUNTIME_PM_OPS(tegra210_dmic_runtime_suspend, 546 tegra210_dmic_runtime_resume, NULL) 547 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 548 pm_runtime_force_resume) 549 }; 550 551 static const struct of_device_id tegra210_dmic_of_match[] = { 552 { .compatible = "nvidia,tegra210-dmic" }, 553 {}, 554 }; 555 MODULE_DEVICE_TABLE(of, tegra210_dmic_of_match); 556 557 static struct platform_driver tegra210_dmic_driver = { 558 .driver = { 559 .name = "tegra210-dmic", 560 .of_match_table = tegra210_dmic_of_match, 561 .pm = &tegra210_dmic_pm_ops, 562 }, 563 .probe = tegra210_dmic_probe, 564 .remove = tegra210_dmic_remove, 565 }; 566 module_platform_driver(tegra210_dmic_driver) 567 568 MODULE_AUTHOR("Rahul Mittal <rmittal@nvidia.com>"); 569 MODULE_DESCRIPTION("Tegra210 ASoC DMIC driver"); 570 MODULE_LICENSE("GPL v2"); 571