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 struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); 339 int ret = 0; 340 341 dev_dbg(st->dev, "Set bias level %d\n", level); 342 343 switch (level) { 344 case SND_SOC_BIAS_ON: 345 case SND_SOC_BIAS_PREPARE: 346 break; 347 348 case SND_SOC_BIAS_STANDBY: 349 if (snd_soc_dapm_get_bias_level(dapm) == 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 = snd_soc_component_to_dapm(component); 397 int ret = 0; 398 399 if (st->hw_mode) { 400 ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_hw, 401 ARRAY_SIZE(adau7118_widgets_hw)); 402 if (ret) 403 return ret; 404 405 ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_hw, 406 ARRAY_SIZE(adau7118_routes_hw)); 407 } else { 408 snd_soc_component_init_regmap(component, st->map); 409 ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_sw, 410 ARRAY_SIZE(adau7118_widgets_sw)); 411 if (ret) 412 return ret; 413 414 ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_sw, 415 ARRAY_SIZE(adau7118_routes_sw)); 416 } 417 418 return ret; 419 } 420 421 static const struct snd_soc_dai_ops adau7118_ops = { 422 .hw_params = adau7118_hw_params, 423 .set_channel_map = adau7118_set_channel_map, 424 .set_fmt = adau7118_set_fmt, 425 .set_tdm_slot = adau7118_set_tdm_slot, 426 .set_tristate = adau7118_set_tristate, 427 }; 428 429 static struct snd_soc_dai_driver adau7118_dai = { 430 .name = "adau7118-hifi-capture", 431 .capture = { 432 .stream_name = "Capture", 433 .channels_min = 1, 434 .channels_max = 8, 435 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | 436 SNDRV_PCM_FMTBIT_S20_LE | SNDRV_PCM_FMTBIT_S24_LE | 437 SNDRV_PCM_FMTBIT_S24_3LE, 438 .rates = SNDRV_PCM_RATE_CONTINUOUS, 439 .rate_min = 4000, 440 .rate_max = 192000, 441 .sig_bits = 24, 442 }, 443 }; 444 445 static const struct snd_soc_component_driver adau7118_component_driver = { 446 .probe = adau7118_component_probe, 447 .set_bias_level = adau7118_set_bias_level, 448 .dapm_widgets = adau7118_widgets, 449 .num_dapm_widgets = ARRAY_SIZE(adau7118_widgets), 450 .use_pmdown_time = 1, 451 .endianness = 1, 452 }; 453 454 static int adau7118_regulator_setup(struct adau7118_data *st) 455 { 456 st->iovdd = devm_regulator_get(st->dev, "iovdd"); 457 if (IS_ERR(st->iovdd)) { 458 dev_err(st->dev, "Could not get iovdd: %ld\n", 459 PTR_ERR(st->iovdd)); 460 return PTR_ERR(st->iovdd); 461 } 462 463 st->dvdd = devm_regulator_get(st->dev, "dvdd"); 464 if (IS_ERR(st->dvdd)) { 465 dev_err(st->dev, "Could not get dvdd: %ld\n", 466 PTR_ERR(st->dvdd)); 467 return PTR_ERR(st->dvdd); 468 } 469 /* just assume the device is in reset */ 470 if (!st->hw_mode) { 471 regcache_mark_dirty(st->map); 472 regcache_cache_only(st->map, true); 473 } 474 475 return 0; 476 } 477 478 static int adau7118_parset_dt(const struct adau7118_data *st) 479 { 480 int ret; 481 u32 dec_ratio = 0; 482 /* 4 inputs */ 483 u32 clk_map[4], regval; 484 485 if (st->hw_mode) 486 return 0; 487 488 ret = device_property_read_u32(st->dev, "adi,decimation-ratio", 489 &dec_ratio); 490 if (!ret) { 491 switch (dec_ratio) { 492 case 64: 493 regval = ADAU7118_DEC_RATIO(0); 494 break; 495 case 32: 496 regval = ADAU7118_DEC_RATIO(1); 497 break; 498 case 16: 499 regval = ADAU7118_DEC_RATIO(2); 500 break; 501 default: 502 dev_err(st->dev, "Invalid dec ratio: %u", dec_ratio); 503 return -EINVAL; 504 } 505 506 ret = regmap_update_bits(st->map, 507 ADAU7118_REG_DEC_RATIO_CLK_MAP, 508 ADAU7118_DEC_RATIO_MASK, regval); 509 if (ret) 510 return ret; 511 } 512 513 ret = device_property_read_u32_array(st->dev, "adi,pdm-clk-map", 514 clk_map, ARRAY_SIZE(clk_map)); 515 if (!ret) { 516 int pdm; 517 u32 _clk_map = 0; 518 519 for (pdm = 0; pdm < ARRAY_SIZE(clk_map); pdm++) 520 _clk_map |= (clk_map[pdm] << (pdm + 4)); 521 522 ret = regmap_update_bits(st->map, 523 ADAU7118_REG_DEC_RATIO_CLK_MAP, 524 ADAU7118_CLK_MAP_MASK, _clk_map); 525 if (ret) 526 return ret; 527 } 528 529 return 0; 530 } 531 532 int adau7118_probe(struct device *dev, struct regmap *map, bool hw_mode) 533 { 534 struct adau7118_data *st; 535 int ret; 536 537 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 538 if (!st) 539 return -ENOMEM; 540 541 st->dev = dev; 542 st->hw_mode = hw_mode; 543 dev_set_drvdata(dev, st); 544 545 if (!hw_mode) { 546 st->map = map; 547 adau7118_dai.ops = &adau7118_ops; 548 /* 549 * Perform a full soft reset. This will set all register's 550 * with their reset values. 551 */ 552 ret = regmap_update_bits(map, ADAU7118_REG_RESET, 553 ADAU7118_FULL_SOFT_R_MASK, 554 ADAU7118_FULL_SOFT_R(1)); 555 if (ret) 556 return ret; 557 } 558 559 ret = adau7118_parset_dt(st); 560 if (ret) 561 return ret; 562 563 ret = adau7118_regulator_setup(st); 564 if (ret) 565 return ret; 566 567 return devm_snd_soc_register_component(dev, 568 &adau7118_component_driver, 569 &adau7118_dai, 1); 570 } 571 EXPORT_SYMBOL_GPL(adau7118_probe); 572 573 MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>"); 574 MODULE_DESCRIPTION("ADAU7118 8 channel PDM-to-I2S/TDM Converter driver"); 575 MODULE_LICENSE("GPL"); 576