1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Analog Devices ADAU7118 8 channel PDM-to-I2S/TDM Converter driver 4 // 5 // Copyright 2019 Analog Devices Inc. 6 7 #include <linux/bitfield.h> 8 #include <linux/module.h> 9 #include <linux/regmap.h> 10 #include <linux/regulator/consumer.h> 11 #include <sound/pcm_params.h> 12 #include <sound/soc.h> 13 14 #include "adau7118.h" 15 16 #define ADAU7118_DEC_RATIO_MASK GENMASK(1, 0) 17 #define ADAU7118_DEC_RATIO(x) FIELD_PREP(ADAU7118_DEC_RATIO_MASK, x) 18 #define ADAU7118_CLK_MAP_MASK GENMASK(7, 4) 19 #define ADAU7118_SLOT_WIDTH_MASK GENMASK(5, 4) 20 #define ADAU7118_SLOT_WIDTH(x) FIELD_PREP(ADAU7118_SLOT_WIDTH_MASK, x) 21 #define ADAU7118_TRISTATE_MASK BIT(6) 22 #define ADAU7118_TRISTATE(x) FIELD_PREP(ADAU7118_TRISTATE_MASK, x) 23 #define ADAU7118_DATA_FMT_MASK GENMASK(3, 1) 24 #define ADAU7118_DATA_FMT(x) FIELD_PREP(ADAU7118_DATA_FMT_MASK, x) 25 #define ADAU7118_SAI_MODE_MASK BIT(0) 26 #define ADAU7118_SAI_MODE(x) FIELD_PREP(ADAU7118_SAI_MODE_MASK, x) 27 #define ADAU7118_LRCLK_BCLK_POL_MASK GENMASK(1, 0) 28 #define ADAU7118_LRCLK_BCLK_POL(x) \ 29 FIELD_PREP(ADAU7118_LRCLK_BCLK_POL_MASK, x) 30 #define ADAU7118_SPT_SLOT_MASK GENMASK(7, 4) 31 #define ADAU7118_SPT_SLOT(x) FIELD_PREP(ADAU7118_SPT_SLOT_MASK, x) 32 #define ADAU7118_FULL_SOFT_R_MASK BIT(1) 33 #define ADAU7118_FULL_SOFT_R(x) FIELD_PREP(ADAU7118_FULL_SOFT_R_MASK, x) 34 35 struct adau7118_data { 36 struct regmap *map; 37 struct device *dev; 38 struct regulator *iovdd; 39 struct regulator *dvdd; 40 u32 slot_width; 41 u32 slots; 42 bool hw_mode; 43 bool right_j; 44 }; 45 46 /* Input Enable */ 47 static const struct snd_kcontrol_new adau7118_dapm_pdm_control[4] = { 48 SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 0, 1, 0), 49 SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 1, 1, 0), 50 SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 2, 1, 0), 51 SOC_DAPM_SINGLE("Capture Switch", ADAU7118_REG_ENABLES, 3, 1, 0), 52 }; 53 54 static const struct snd_soc_dapm_widget adau7118_widgets_sw[] = { 55 /* Input Enable Switches */ 56 SND_SOC_DAPM_SWITCH("PDM0", SND_SOC_NOPM, 0, 0, 57 &adau7118_dapm_pdm_control[0]), 58 SND_SOC_DAPM_SWITCH("PDM1", SND_SOC_NOPM, 0, 0, 59 &adau7118_dapm_pdm_control[1]), 60 SND_SOC_DAPM_SWITCH("PDM2", SND_SOC_NOPM, 0, 0, 61 &adau7118_dapm_pdm_control[2]), 62 SND_SOC_DAPM_SWITCH("PDM3", SND_SOC_NOPM, 0, 0, 63 &adau7118_dapm_pdm_control[3]), 64 65 /* PDM Clocks */ 66 SND_SOC_DAPM_SUPPLY("PDM_CLK0", ADAU7118_REG_ENABLES, 4, 0, NULL, 0), 67 SND_SOC_DAPM_SUPPLY("PDM_CLK1", ADAU7118_REG_ENABLES, 5, 0, NULL, 0), 68 69 /* Output channels */ 70 SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, ADAU7118_REG_SPT_CX(0), 71 0, 0), 72 SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 0, ADAU7118_REG_SPT_CX(1), 73 0, 0), 74 SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 0, ADAU7118_REG_SPT_CX(2), 75 0, 0), 76 SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 0, ADAU7118_REG_SPT_CX(3), 77 0, 0), 78 SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 0, ADAU7118_REG_SPT_CX(4), 79 0, 0), 80 SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 0, ADAU7118_REG_SPT_CX(5), 81 0, 0), 82 SND_SOC_DAPM_AIF_OUT("AIF1TX7", "Capture", 0, ADAU7118_REG_SPT_CX(6), 83 0, 0), 84 SND_SOC_DAPM_AIF_OUT("AIF1TX8", "Capture", 0, ADAU7118_REG_SPT_CX(7), 85 0, 0), 86 }; 87 88 static const struct snd_soc_dapm_route adau7118_routes_sw[] = { 89 { "PDM0", "Capture Switch", "PDM_DAT0" }, 90 { "PDM1", "Capture Switch", "PDM_DAT1" }, 91 { "PDM2", "Capture Switch", "PDM_DAT2" }, 92 { "PDM3", "Capture Switch", "PDM_DAT3" }, 93 { "AIF1TX1", NULL, "PDM0" }, 94 { "AIF1TX2", NULL, "PDM0" }, 95 { "AIF1TX3", NULL, "PDM1" }, 96 { "AIF1TX4", NULL, "PDM1" }, 97 { "AIF1TX5", NULL, "PDM2" }, 98 { "AIF1TX6", NULL, "PDM2" }, 99 { "AIF1TX7", NULL, "PDM3" }, 100 { "AIF1TX8", NULL, "PDM3" }, 101 { "Capture", NULL, "PDM_CLK0" }, 102 { "Capture", NULL, "PDM_CLK1" }, 103 }; 104 105 static const struct snd_soc_dapm_widget adau7118_widgets_hw[] = { 106 SND_SOC_DAPM_AIF_OUT("AIF1TX", "Capture", 0, SND_SOC_NOPM, 0, 0), 107 }; 108 109 static const struct snd_soc_dapm_route adau7118_routes_hw[] = { 110 { "AIF1TX", NULL, "PDM_DAT0" }, 111 { "AIF1TX", NULL, "PDM_DAT1" }, 112 { "AIF1TX", NULL, "PDM_DAT2" }, 113 { "AIF1TX", NULL, "PDM_DAT3" }, 114 }; 115 116 static const struct snd_soc_dapm_widget adau7118_widgets[] = { 117 SND_SOC_DAPM_INPUT("PDM_DAT0"), 118 SND_SOC_DAPM_INPUT("PDM_DAT1"), 119 SND_SOC_DAPM_INPUT("PDM_DAT2"), 120 SND_SOC_DAPM_INPUT("PDM_DAT3"), 121 }; 122 123 static int adau7118_set_channel_map(struct snd_soc_dai *dai, 124 unsigned int tx_num, 125 const unsigned int *tx_slot, 126 unsigned int rx_num, 127 const unsigned int *rx_slot) 128 { 129 struct adau7118_data *st = 130 snd_soc_component_get_drvdata(dai->component); 131 int chan, ret; 132 133 dev_dbg(st->dev, "Set channel map, %d", tx_num); 134 135 for (chan = 0; chan < tx_num; chan++) { 136 ret = snd_soc_component_update_bits(dai->component, 137 ADAU7118_REG_SPT_CX(chan), 138 ADAU7118_SPT_SLOT_MASK, 139 ADAU7118_SPT_SLOT(tx_slot[chan])); 140 if (ret < 0) 141 return ret; 142 } 143 144 return 0; 145 } 146 147 static int adau7118_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 148 { 149 struct adau7118_data *st = 150 snd_soc_component_get_drvdata(dai->component); 151 int ret = 0; 152 u32 regval; 153 154 dev_dbg(st->dev, "Set format, fmt:%d\n", fmt); 155 156 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 157 case SND_SOC_DAIFMT_I2S: 158 ret = snd_soc_component_update_bits(dai->component, 159 ADAU7118_REG_SPT_CTRL1, 160 ADAU7118_DATA_FMT_MASK, 161 ADAU7118_DATA_FMT(0)); 162 break; 163 case SND_SOC_DAIFMT_LEFT_J: 164 ret = snd_soc_component_update_bits(dai->component, 165 ADAU7118_REG_SPT_CTRL1, 166 ADAU7118_DATA_FMT_MASK, 167 ADAU7118_DATA_FMT(1)); 168 break; 169 case SND_SOC_DAIFMT_RIGHT_J: 170 st->right_j = true; 171 break; 172 case SND_SOC_DAIFMT_DSP_A: 173 ret = snd_soc_component_update_bits(dai->component, 174 ADAU7118_REG_SPT_CTRL1, 175 ADAU7118_DATA_FMT_MASK, 176 ADAU7118_DATA_FMT(1)); 177 break; 178 default: 179 dev_err(st->dev, "Invalid format %d", 180 fmt & SND_SOC_DAIFMT_FORMAT_MASK); 181 return -EINVAL; 182 } 183 184 if (ret < 0) 185 return ret; 186 187 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 188 case SND_SOC_DAIFMT_NB_NF: 189 regval = ADAU7118_LRCLK_BCLK_POL(0); 190 break; 191 case SND_SOC_DAIFMT_NB_IF: 192 regval = ADAU7118_LRCLK_BCLK_POL(2); 193 break; 194 case SND_SOC_DAIFMT_IB_NF: 195 regval = ADAU7118_LRCLK_BCLK_POL(1); 196 break; 197 case SND_SOC_DAIFMT_IB_IF: 198 regval = ADAU7118_LRCLK_BCLK_POL(3); 199 break; 200 default: 201 dev_err(st->dev, "Invalid Inv mask %d", 202 fmt & SND_SOC_DAIFMT_INV_MASK); 203 return -EINVAL; 204 } 205 206 ret = snd_soc_component_update_bits(dai->component, 207 ADAU7118_REG_SPT_CTRL2, 208 ADAU7118_LRCLK_BCLK_POL_MASK, 209 regval); 210 if (ret < 0) 211 return ret; 212 213 return 0; 214 } 215 216 static int adau7118_set_tristate(struct snd_soc_dai *dai, int tristate) 217 { 218 struct adau7118_data *st = 219 snd_soc_component_get_drvdata(dai->component); 220 int ret; 221 222 dev_dbg(st->dev, "Set tristate, %d\n", tristate); 223 224 ret = snd_soc_component_update_bits(dai->component, 225 ADAU7118_REG_SPT_CTRL1, 226 ADAU7118_TRISTATE_MASK, 227 ADAU7118_TRISTATE(tristate)); 228 if (ret < 0) 229 return ret; 230 231 return 0; 232 } 233 234 static int adau7118_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 235 unsigned int rx_mask, int slots, 236 int slot_width) 237 { 238 struct adau7118_data *st = 239 snd_soc_component_get_drvdata(dai->component); 240 int ret = 0; 241 u32 regval; 242 243 dev_dbg(st->dev, "Set tdm, slots:%d width:%d\n", slots, slot_width); 244 245 switch (slot_width) { 246 case 32: 247 regval = ADAU7118_SLOT_WIDTH(0); 248 break; 249 case 24: 250 regval = ADAU7118_SLOT_WIDTH(2); 251 break; 252 case 16: 253 regval = ADAU7118_SLOT_WIDTH(1); 254 break; 255 default: 256 dev_err(st->dev, "Invalid slot width:%d\n", slot_width); 257 return -EINVAL; 258 } 259 260 ret = snd_soc_component_update_bits(dai->component, 261 ADAU7118_REG_SPT_CTRL1, 262 ADAU7118_SLOT_WIDTH_MASK, regval); 263 if (ret < 0) 264 return ret; 265 266 st->slot_width = slot_width; 267 st->slots = slots; 268 269 return 0; 270 } 271 272 static int adau7118_hw_params(struct snd_pcm_substream *substream, 273 struct snd_pcm_hw_params *params, 274 struct snd_soc_dai *dai) 275 { 276 struct adau7118_data *st = 277 snd_soc_component_get_drvdata(dai->component); 278 u32 data_width = params_width(params), slots_width; 279 int ret; 280 u32 regval; 281 282 if (!st->slots) { 283 /* set stereo mode */ 284 ret = snd_soc_component_update_bits(dai->component, 285 ADAU7118_REG_SPT_CTRL1, 286 ADAU7118_SAI_MODE_MASK, 287 ADAU7118_SAI_MODE(0)); 288 if (ret < 0) 289 return ret; 290 291 slots_width = 32; 292 } else { 293 slots_width = st->slot_width; 294 } 295 296 if (data_width > slots_width) { 297 dev_err(st->dev, "Invalid data_width:%d, slots_width:%d", 298 data_width, slots_width); 299 return -EINVAL; 300 } 301 302 if (st->right_j) { 303 switch (slots_width - data_width) { 304 case 8: 305 /* delay bclck by 8 */ 306 regval = ADAU7118_DATA_FMT(2); 307 break; 308 case 12: 309 /* delay bclck by 12 */ 310 regval = ADAU7118_DATA_FMT(3); 311 break; 312 case 16: 313 /* delay bclck by 16 */ 314 regval = ADAU7118_DATA_FMT(4); 315 break; 316 default: 317 dev_err(st->dev, 318 "Cannot set right_j setting, slot_w:%d, data_w:%d\n", 319 slots_width, data_width); 320 return -EINVAL; 321 } 322 323 ret = snd_soc_component_update_bits(dai->component, 324 ADAU7118_REG_SPT_CTRL1, 325 ADAU7118_DATA_FMT_MASK, 326 regval); 327 if (ret < 0) 328 return ret; 329 } 330 331 return 0; 332 } 333 334 static int adau7118_set_bias_level(struct snd_soc_component *component, 335 enum snd_soc_bias_level level) 336 { 337 struct adau7118_data *st = snd_soc_component_get_drvdata(component); 338 int ret = 0; 339 340 dev_dbg(st->dev, "Set bias level %d\n", level); 341 342 switch (level) { 343 case SND_SOC_BIAS_ON: 344 case SND_SOC_BIAS_PREPARE: 345 break; 346 347 case SND_SOC_BIAS_STANDBY: 348 if (snd_soc_component_get_bias_level(component) == 349 SND_SOC_BIAS_OFF) { 350 /* power on */ 351 ret = regulator_enable(st->iovdd); 352 if (ret) 353 return ret; 354 355 /* there's no timing constraints before enabling dvdd */ 356 ret = regulator_enable(st->dvdd); 357 if (ret) { 358 regulator_disable(st->iovdd); 359 return ret; 360 } 361 362 if (st->hw_mode) 363 return 0; 364 365 regcache_cache_only(st->map, false); 366 /* sync cache */ 367 ret = snd_soc_component_cache_sync(component); 368 } 369 break; 370 case SND_SOC_BIAS_OFF: 371 /* power off */ 372 ret = regulator_disable(st->dvdd); 373 if (ret) 374 return ret; 375 376 ret = regulator_disable(st->iovdd); 377 if (ret) 378 return ret; 379 380 if (st->hw_mode) 381 return 0; 382 383 /* cache only */ 384 regcache_mark_dirty(st->map); 385 regcache_cache_only(st->map, true); 386 387 break; 388 } 389 390 return ret; 391 } 392 393 static int adau7118_component_probe(struct snd_soc_component *component) 394 { 395 struct adau7118_data *st = snd_soc_component_get_drvdata(component); 396 struct snd_soc_dapm_context *dapm = 397 snd_soc_component_get_dapm(component); 398 int ret = 0; 399 400 if (st->hw_mode) { 401 ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_hw, 402 ARRAY_SIZE(adau7118_widgets_hw)); 403 if (ret) 404 return ret; 405 406 ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_hw, 407 ARRAY_SIZE(adau7118_routes_hw)); 408 } else { 409 snd_soc_component_init_regmap(component, st->map); 410 ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_sw, 411 ARRAY_SIZE(adau7118_widgets_sw)); 412 if (ret) 413 return ret; 414 415 ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_sw, 416 ARRAY_SIZE(adau7118_routes_sw)); 417 } 418 419 return ret; 420 } 421 422 static const struct snd_soc_dai_ops adau7118_ops = { 423 .hw_params = adau7118_hw_params, 424 .set_channel_map = adau7118_set_channel_map, 425 .set_fmt = adau7118_set_fmt, 426 .set_tdm_slot = adau7118_set_tdm_slot, 427 .set_tristate = adau7118_set_tristate, 428 }; 429 430 static struct snd_soc_dai_driver adau7118_dai = { 431 .name = "adau7118-hifi-capture", 432 .capture = { 433 .stream_name = "Capture", 434 .channels_min = 1, 435 .channels_max = 8, 436 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | 437 SNDRV_PCM_FMTBIT_S20_LE | SNDRV_PCM_FMTBIT_S24_LE | 438 SNDRV_PCM_FMTBIT_S24_3LE, 439 .rates = SNDRV_PCM_RATE_CONTINUOUS, 440 .rate_min = 4000, 441 .rate_max = 192000, 442 .sig_bits = 24, 443 }, 444 }; 445 446 static const struct snd_soc_component_driver adau7118_component_driver = { 447 .probe = adau7118_component_probe, 448 .set_bias_level = adau7118_set_bias_level, 449 .dapm_widgets = adau7118_widgets, 450 .num_dapm_widgets = ARRAY_SIZE(adau7118_widgets), 451 .use_pmdown_time = 1, 452 .endianness = 1, 453 }; 454 455 static int adau7118_regulator_setup(struct adau7118_data *st) 456 { 457 st->iovdd = devm_regulator_get(st->dev, "iovdd"); 458 if (IS_ERR(st->iovdd)) { 459 dev_err(st->dev, "Could not get iovdd: %ld\n", 460 PTR_ERR(st->iovdd)); 461 return PTR_ERR(st->iovdd); 462 } 463 464 st->dvdd = devm_regulator_get(st->dev, "dvdd"); 465 if (IS_ERR(st->dvdd)) { 466 dev_err(st->dev, "Could not get dvdd: %ld\n", 467 PTR_ERR(st->dvdd)); 468 return PTR_ERR(st->dvdd); 469 } 470 /* just assume the device is in reset */ 471 if (!st->hw_mode) { 472 regcache_mark_dirty(st->map); 473 regcache_cache_only(st->map, true); 474 } 475 476 return 0; 477 } 478 479 static int adau7118_parset_dt(const struct adau7118_data *st) 480 { 481 int ret; 482 u32 dec_ratio = 0; 483 /* 4 inputs */ 484 u32 clk_map[4], regval; 485 486 if (st->hw_mode) 487 return 0; 488 489 ret = device_property_read_u32(st->dev, "adi,decimation-ratio", 490 &dec_ratio); 491 if (!ret) { 492 switch (dec_ratio) { 493 case 64: 494 regval = ADAU7118_DEC_RATIO(0); 495 break; 496 case 32: 497 regval = ADAU7118_DEC_RATIO(1); 498 break; 499 case 16: 500 regval = ADAU7118_DEC_RATIO(2); 501 break; 502 default: 503 dev_err(st->dev, "Invalid dec ratio: %u", dec_ratio); 504 return -EINVAL; 505 } 506 507 ret = regmap_update_bits(st->map, 508 ADAU7118_REG_DEC_RATIO_CLK_MAP, 509 ADAU7118_DEC_RATIO_MASK, regval); 510 if (ret) 511 return ret; 512 } 513 514 ret = device_property_read_u32_array(st->dev, "adi,pdm-clk-map", 515 clk_map, ARRAY_SIZE(clk_map)); 516 if (!ret) { 517 int pdm; 518 u32 _clk_map = 0; 519 520 for (pdm = 0; pdm < ARRAY_SIZE(clk_map); pdm++) 521 _clk_map |= (clk_map[pdm] << (pdm + 4)); 522 523 ret = regmap_update_bits(st->map, 524 ADAU7118_REG_DEC_RATIO_CLK_MAP, 525 ADAU7118_CLK_MAP_MASK, _clk_map); 526 if (ret) 527 return ret; 528 } 529 530 return 0; 531 } 532 533 int adau7118_probe(struct device *dev, struct regmap *map, bool hw_mode) 534 { 535 struct adau7118_data *st; 536 int ret; 537 538 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 539 if (!st) 540 return -ENOMEM; 541 542 st->dev = dev; 543 st->hw_mode = hw_mode; 544 dev_set_drvdata(dev, st); 545 546 if (!hw_mode) { 547 st->map = map; 548 adau7118_dai.ops = &adau7118_ops; 549 /* 550 * Perform a full soft reset. This will set all register's 551 * with their reset values. 552 */ 553 ret = regmap_update_bits(map, ADAU7118_REG_RESET, 554 ADAU7118_FULL_SOFT_R_MASK, 555 ADAU7118_FULL_SOFT_R(1)); 556 if (ret) 557 return ret; 558 } 559 560 ret = adau7118_parset_dt(st); 561 if (ret) 562 return ret; 563 564 ret = adau7118_regulator_setup(st); 565 if (ret) 566 return ret; 567 568 return devm_snd_soc_register_component(dev, 569 &adau7118_component_driver, 570 &adau7118_dai, 1); 571 } 572 EXPORT_SYMBOL_GPL(adau7118_probe); 573 574 MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>"); 575 MODULE_DESCRIPTION("ADAU7118 8 channel PDM-to-I2S/TDM Converter driver"); 576 MODULE_LICENSE("GPL"); 577