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 default: 173 dev_err(st->dev, "Invalid format %d", 174 fmt & SND_SOC_DAIFMT_FORMAT_MASK); 175 return -EINVAL; 176 } 177 178 if (ret < 0) 179 return ret; 180 181 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 182 case SND_SOC_DAIFMT_NB_NF: 183 regval = ADAU7118_LRCLK_BCLK_POL(0); 184 break; 185 case SND_SOC_DAIFMT_NB_IF: 186 regval = ADAU7118_LRCLK_BCLK_POL(2); 187 break; 188 case SND_SOC_DAIFMT_IB_NF: 189 regval = ADAU7118_LRCLK_BCLK_POL(1); 190 break; 191 case SND_SOC_DAIFMT_IB_IF: 192 regval = ADAU7118_LRCLK_BCLK_POL(3); 193 break; 194 default: 195 dev_err(st->dev, "Invalid Inv mask %d", 196 fmt & SND_SOC_DAIFMT_INV_MASK); 197 return -EINVAL; 198 } 199 200 ret = snd_soc_component_update_bits(dai->component, 201 ADAU7118_REG_SPT_CTRL2, 202 ADAU7118_LRCLK_BCLK_POL_MASK, 203 regval); 204 if (ret < 0) 205 return ret; 206 207 return 0; 208 } 209 210 static int adau7118_set_tristate(struct snd_soc_dai *dai, int tristate) 211 { 212 struct adau7118_data *st = 213 snd_soc_component_get_drvdata(dai->component); 214 int ret; 215 216 dev_dbg(st->dev, "Set tristate, %d\n", tristate); 217 218 ret = snd_soc_component_update_bits(dai->component, 219 ADAU7118_REG_SPT_CTRL1, 220 ADAU7118_TRISTATE_MASK, 221 ADAU7118_TRISTATE(tristate)); 222 if (ret < 0) 223 return ret; 224 225 return 0; 226 } 227 228 static int adau7118_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 229 unsigned int rx_mask, int slots, 230 int slot_width) 231 { 232 struct adau7118_data *st = 233 snd_soc_component_get_drvdata(dai->component); 234 int ret = 0; 235 u32 regval; 236 237 dev_dbg(st->dev, "Set tdm, slots:%d width:%d\n", slots, slot_width); 238 239 switch (slot_width) { 240 case 32: 241 regval = ADAU7118_SLOT_WIDTH(0); 242 break; 243 case 24: 244 regval = ADAU7118_SLOT_WIDTH(2); 245 break; 246 case 16: 247 regval = ADAU7118_SLOT_WIDTH(1); 248 break; 249 default: 250 dev_err(st->dev, "Invalid slot width:%d\n", slot_width); 251 return -EINVAL; 252 } 253 254 ret = snd_soc_component_update_bits(dai->component, 255 ADAU7118_REG_SPT_CTRL1, 256 ADAU7118_SLOT_WIDTH_MASK, regval); 257 if (ret < 0) 258 return ret; 259 260 st->slot_width = slot_width; 261 st->slots = slots; 262 263 return 0; 264 } 265 266 static int adau7118_hw_params(struct snd_pcm_substream *substream, 267 struct snd_pcm_hw_params *params, 268 struct snd_soc_dai *dai) 269 { 270 struct adau7118_data *st = 271 snd_soc_component_get_drvdata(dai->component); 272 u32 data_width = params_width(params), slots_width; 273 int ret; 274 u32 regval; 275 276 if (!st->slots) { 277 /* set stereo mode */ 278 ret = snd_soc_component_update_bits(dai->component, 279 ADAU7118_REG_SPT_CTRL1, 280 ADAU7118_SAI_MODE_MASK, 281 ADAU7118_SAI_MODE(0)); 282 if (ret < 0) 283 return ret; 284 285 slots_width = 32; 286 } else { 287 slots_width = st->slot_width; 288 } 289 290 if (data_width > slots_width) { 291 dev_err(st->dev, "Invalid data_width:%d, slots_width:%d", 292 data_width, slots_width); 293 return -EINVAL; 294 } 295 296 if (st->right_j) { 297 switch (slots_width - data_width) { 298 case 8: 299 /* delay bclck by 8 */ 300 regval = ADAU7118_DATA_FMT(2); 301 break; 302 case 12: 303 /* delay bclck by 12 */ 304 regval = ADAU7118_DATA_FMT(3); 305 break; 306 case 16: 307 /* delay bclck by 16 */ 308 regval = ADAU7118_DATA_FMT(4); 309 break; 310 default: 311 dev_err(st->dev, 312 "Cannot set right_j setting, slot_w:%d, data_w:%d\n", 313 slots_width, data_width); 314 return -EINVAL; 315 } 316 317 ret = snd_soc_component_update_bits(dai->component, 318 ADAU7118_REG_SPT_CTRL1, 319 ADAU7118_DATA_FMT_MASK, 320 regval); 321 if (ret < 0) 322 return ret; 323 } 324 325 return 0; 326 } 327 328 static int adau7118_set_bias_level(struct snd_soc_component *component, 329 enum snd_soc_bias_level level) 330 { 331 struct adau7118_data *st = snd_soc_component_get_drvdata(component); 332 int ret = 0; 333 334 dev_dbg(st->dev, "Set bias level %d\n", level); 335 336 switch (level) { 337 case SND_SOC_BIAS_ON: 338 case SND_SOC_BIAS_PREPARE: 339 break; 340 341 case SND_SOC_BIAS_STANDBY: 342 if (snd_soc_component_get_bias_level(component) == 343 SND_SOC_BIAS_OFF) { 344 /* power on */ 345 ret = regulator_enable(st->iovdd); 346 if (ret) 347 return ret; 348 349 /* there's no timing constraints before enabling dvdd */ 350 ret = regulator_enable(st->dvdd); 351 if (ret) { 352 regulator_disable(st->iovdd); 353 return ret; 354 } 355 356 if (st->hw_mode) 357 return 0; 358 359 regcache_cache_only(st->map, false); 360 /* sync cache */ 361 ret = snd_soc_component_cache_sync(component); 362 } 363 break; 364 case SND_SOC_BIAS_OFF: 365 /* power off */ 366 ret = regulator_disable(st->dvdd); 367 if (ret) 368 return ret; 369 370 ret = regulator_disable(st->iovdd); 371 if (ret) 372 return ret; 373 374 if (st->hw_mode) 375 return 0; 376 377 /* cache only */ 378 regcache_mark_dirty(st->map); 379 regcache_cache_only(st->map, true); 380 381 break; 382 } 383 384 return ret; 385 } 386 387 static int adau7118_component_probe(struct snd_soc_component *component) 388 { 389 struct adau7118_data *st = snd_soc_component_get_drvdata(component); 390 struct snd_soc_dapm_context *dapm = 391 snd_soc_component_get_dapm(component); 392 int ret = 0; 393 394 if (st->hw_mode) { 395 ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_hw, 396 ARRAY_SIZE(adau7118_widgets_hw)); 397 if (ret) 398 return ret; 399 400 ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_hw, 401 ARRAY_SIZE(adau7118_routes_hw)); 402 } else { 403 snd_soc_component_init_regmap(component, st->map); 404 ret = snd_soc_dapm_new_controls(dapm, adau7118_widgets_sw, 405 ARRAY_SIZE(adau7118_widgets_sw)); 406 if (ret) 407 return ret; 408 409 ret = snd_soc_dapm_add_routes(dapm, adau7118_routes_sw, 410 ARRAY_SIZE(adau7118_routes_sw)); 411 } 412 413 return ret; 414 } 415 416 static const struct snd_soc_dai_ops adau7118_ops = { 417 .hw_params = adau7118_hw_params, 418 .set_channel_map = adau7118_set_channel_map, 419 .set_fmt = adau7118_set_fmt, 420 .set_tdm_slot = adau7118_set_tdm_slot, 421 .set_tristate = adau7118_set_tristate, 422 }; 423 424 static struct snd_soc_dai_driver adau7118_dai = { 425 .name = "adau7118-hifi-capture", 426 .capture = { 427 .stream_name = "Capture", 428 .channels_min = 1, 429 .channels_max = 8, 430 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | 431 SNDRV_PCM_FMTBIT_S20_LE | SNDRV_PCM_FMTBIT_S24_LE | 432 SNDRV_PCM_FMTBIT_S24_3LE, 433 .rates = SNDRV_PCM_RATE_CONTINUOUS, 434 .rate_min = 4000, 435 .rate_max = 192000, 436 .sig_bits = 24, 437 }, 438 }; 439 440 static const struct snd_soc_component_driver adau7118_component_driver = { 441 .probe = adau7118_component_probe, 442 .set_bias_level = adau7118_set_bias_level, 443 .dapm_widgets = adau7118_widgets, 444 .num_dapm_widgets = ARRAY_SIZE(adau7118_widgets), 445 .use_pmdown_time = 1, 446 .endianness = 1, 447 }; 448 449 static int adau7118_regulator_setup(struct adau7118_data *st) 450 { 451 st->iovdd = devm_regulator_get(st->dev, "iovdd"); 452 if (IS_ERR(st->iovdd)) { 453 dev_err(st->dev, "Could not get iovdd: %ld\n", 454 PTR_ERR(st->iovdd)); 455 return PTR_ERR(st->iovdd); 456 } 457 458 st->dvdd = devm_regulator_get(st->dev, "dvdd"); 459 if (IS_ERR(st->dvdd)) { 460 dev_err(st->dev, "Could not get dvdd: %ld\n", 461 PTR_ERR(st->dvdd)); 462 return PTR_ERR(st->dvdd); 463 } 464 /* just assume the device is in reset */ 465 if (!st->hw_mode) { 466 regcache_mark_dirty(st->map); 467 regcache_cache_only(st->map, true); 468 } 469 470 return 0; 471 } 472 473 static int adau7118_parset_dt(const struct adau7118_data *st) 474 { 475 int ret; 476 u32 dec_ratio = 0; 477 /* 4 inputs */ 478 u32 clk_map[4], regval; 479 480 if (st->hw_mode) 481 return 0; 482 483 ret = device_property_read_u32(st->dev, "adi,decimation-ratio", 484 &dec_ratio); 485 if (!ret) { 486 switch (dec_ratio) { 487 case 64: 488 regval = ADAU7118_DEC_RATIO(0); 489 break; 490 case 32: 491 regval = ADAU7118_DEC_RATIO(1); 492 break; 493 case 16: 494 regval = ADAU7118_DEC_RATIO(2); 495 break; 496 default: 497 dev_err(st->dev, "Invalid dec ratio: %u", dec_ratio); 498 return -EINVAL; 499 } 500 501 ret = regmap_update_bits(st->map, 502 ADAU7118_REG_DEC_RATIO_CLK_MAP, 503 ADAU7118_DEC_RATIO_MASK, regval); 504 if (ret) 505 return ret; 506 } 507 508 ret = device_property_read_u32_array(st->dev, "adi,pdm-clk-map", 509 clk_map, ARRAY_SIZE(clk_map)); 510 if (!ret) { 511 int pdm; 512 u32 _clk_map = 0; 513 514 for (pdm = 0; pdm < ARRAY_SIZE(clk_map); pdm++) 515 _clk_map |= (clk_map[pdm] << (pdm + 4)); 516 517 ret = regmap_update_bits(st->map, 518 ADAU7118_REG_DEC_RATIO_CLK_MAP, 519 ADAU7118_CLK_MAP_MASK, _clk_map); 520 if (ret) 521 return ret; 522 } 523 524 return 0; 525 } 526 527 int adau7118_probe(struct device *dev, struct regmap *map, bool hw_mode) 528 { 529 struct adau7118_data *st; 530 int ret; 531 532 st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 533 if (!st) 534 return -ENOMEM; 535 536 st->dev = dev; 537 st->hw_mode = hw_mode; 538 dev_set_drvdata(dev, st); 539 540 if (!hw_mode) { 541 st->map = map; 542 adau7118_dai.ops = &adau7118_ops; 543 /* 544 * Perform a full soft reset. This will set all register's 545 * with their reset values. 546 */ 547 ret = regmap_update_bits(map, ADAU7118_REG_RESET, 548 ADAU7118_FULL_SOFT_R_MASK, 549 ADAU7118_FULL_SOFT_R(1)); 550 if (ret) 551 return ret; 552 } 553 554 ret = adau7118_parset_dt(st); 555 if (ret) 556 return ret; 557 558 ret = adau7118_regulator_setup(st); 559 if (ret) 560 return ret; 561 562 return devm_snd_soc_register_component(dev, 563 &adau7118_component_driver, 564 &adau7118_dai, 1); 565 } 566 EXPORT_SYMBOL_GPL(adau7118_probe); 567 568 MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>"); 569 MODULE_DESCRIPTION("ADAU7118 8 channel PDM-to-I2S/TDM Converter driver"); 570 MODULE_LICENSE("GPL"); 571