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