1 // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 // 3 // Copyright (c) 2018 BayLibre, SAS. 4 // Author: Jerome Brunet <jbrunet@baylibre.com> 5 6 #include <linux/clk.h> 7 #include <linux/module.h> 8 #include <linux/of_platform.h> 9 #include <sound/pcm_params.h> 10 #include <sound/soc.h> 11 #include <sound/soc-dai.h> 12 13 #include "axg-tdm.h" 14 15 enum { 16 TDM_IFACE_PAD, 17 TDM_IFACE_LOOPBACK, 18 }; 19 20 static unsigned int axg_tdm_slots_total(u32 *mask) 21 { 22 unsigned int slots = 0; 23 int i; 24 25 if (!mask) 26 return 0; 27 28 /* Count the total number of slots provided by all 4 lanes */ 29 for (i = 0; i < AXG_TDM_NUM_LANES; i++) 30 slots += hweight32(mask[i]); 31 32 return slots; 33 } 34 35 int axg_tdm_set_tdm_slots(struct snd_soc_dai *dai, u32 *tx_mask, 36 u32 *rx_mask, unsigned int slots, 37 unsigned int slot_width) 38 { 39 struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); 40 struct axg_tdm_stream *tx = snd_soc_dai_dma_data_get_playback(dai); 41 struct axg_tdm_stream *rx = snd_soc_dai_dma_data_get_capture(dai); 42 unsigned int tx_slots, rx_slots; 43 unsigned int fmt = 0; 44 45 tx_slots = axg_tdm_slots_total(tx_mask); 46 rx_slots = axg_tdm_slots_total(rx_mask); 47 48 /* We should at least have a slot for a valid interface */ 49 if (!tx_slots && !rx_slots) { 50 dev_err(dai->dev, "interface has no slot\n"); 51 return -EINVAL; 52 } 53 54 iface->slots = slots; 55 56 switch (slot_width) { 57 case 0: 58 slot_width = 32; 59 fallthrough; 60 case 32: 61 fmt |= SNDRV_PCM_FMTBIT_S32_LE; 62 fallthrough; 63 case 24: 64 fmt |= SNDRV_PCM_FMTBIT_S24_LE; 65 fmt |= SNDRV_PCM_FMTBIT_S20_LE; 66 fallthrough; 67 case 16: 68 fmt |= SNDRV_PCM_FMTBIT_S16_LE; 69 fallthrough; 70 case 8: 71 fmt |= SNDRV_PCM_FMTBIT_S8; 72 break; 73 default: 74 dev_err(dai->dev, "unsupported slot width: %d\n", slot_width); 75 return -EINVAL; 76 } 77 78 iface->slot_width = slot_width; 79 80 /* Amend the dai driver and let dpcm merge do its job */ 81 if (tx) { 82 tx->mask = tx_mask; 83 dai->driver->playback.channels_max = tx_slots; 84 dai->driver->playback.formats = fmt; 85 } 86 87 if (rx) { 88 rx->mask = rx_mask; 89 dai->driver->capture.channels_max = rx_slots; 90 dai->driver->capture.formats = fmt; 91 } 92 93 return 0; 94 } 95 EXPORT_SYMBOL_GPL(axg_tdm_set_tdm_slots); 96 97 static int axg_tdm_iface_set_sysclk(struct snd_soc_dai *dai, int clk_id, 98 unsigned int freq, int dir) 99 { 100 struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); 101 int ret = -ENOTSUPP; 102 103 if (dir == SND_SOC_CLOCK_OUT && clk_id == 0) { 104 if (!iface->mclk) { 105 dev_warn(dai->dev, "master clock not provided\n"); 106 } else { 107 ret = clk_set_rate(iface->mclk, freq); 108 if (!ret) 109 iface->mclk_rate = freq; 110 } 111 } 112 113 return ret; 114 } 115 116 static int axg_tdm_iface_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 117 { 118 struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); 119 120 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 121 case SND_SOC_DAIFMT_BP_FP: 122 if (!iface->mclk) { 123 dev_err(dai->dev, "cpu clock master: mclk missing\n"); 124 return -ENODEV; 125 } 126 break; 127 128 case SND_SOC_DAIFMT_BC_FC: 129 break; 130 131 case SND_SOC_DAIFMT_BP_FC: 132 case SND_SOC_DAIFMT_BC_FP: 133 dev_err(dai->dev, "only CBS_CFS and CBM_CFM are supported\n"); 134 fallthrough; 135 default: 136 return -EINVAL; 137 } 138 139 iface->fmt = fmt; 140 return 0; 141 } 142 143 static int axg_tdm_iface_startup(struct snd_pcm_substream *substream, 144 struct snd_soc_dai *dai) 145 { 146 struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); 147 struct axg_tdm_stream *ts = 148 snd_soc_dai_get_dma_data(dai, substream); 149 int ret; 150 151 if (!axg_tdm_slots_total(ts->mask)) { 152 dev_err(dai->dev, "interface has not slots\n"); 153 return -EINVAL; 154 } 155 156 /* Apply component wide rate symmetry */ 157 if (snd_soc_component_active(dai->component)) { 158 ret = snd_pcm_hw_constraint_single(substream->runtime, 159 SNDRV_PCM_HW_PARAM_RATE, 160 iface->rate); 161 if (ret < 0) { 162 dev_err(dai->dev, 163 "can't set iface rate constraint\n"); 164 return ret; 165 } 166 } 167 168 return 0; 169 } 170 171 static int axg_tdm_iface_set_stream(struct snd_pcm_substream *substream, 172 struct snd_pcm_hw_params *params, 173 struct snd_soc_dai *dai) 174 { 175 struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); 176 struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); 177 unsigned int channels = params_channels(params); 178 unsigned int width = params_width(params); 179 180 /* Save rate and sample_bits for component symmetry */ 181 iface->rate = params_rate(params); 182 183 /* Make sure this interface can cope with the stream */ 184 if (axg_tdm_slots_total(ts->mask) < channels) { 185 dev_err(dai->dev, "not enough slots for channels\n"); 186 return -EINVAL; 187 } 188 189 if (iface->slot_width < width) { 190 dev_err(dai->dev, "incompatible slots width for stream\n"); 191 return -EINVAL; 192 } 193 194 /* Save the parameter for tdmout/tdmin widgets */ 195 ts->physical_width = params_physical_width(params); 196 ts->width = params_width(params); 197 ts->channels = params_channels(params); 198 199 return 0; 200 } 201 202 static int axg_tdm_iface_set_lrclk(struct snd_soc_dai *dai, 203 struct snd_pcm_hw_params *params) 204 { 205 struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); 206 unsigned int ratio_num; 207 int ret; 208 209 ret = clk_set_rate(iface->lrclk, params_rate(params)); 210 if (ret) { 211 dev_err(dai->dev, "setting sample clock failed: %d\n", ret); 212 return ret; 213 } 214 215 switch (iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 216 case SND_SOC_DAIFMT_I2S: 217 case SND_SOC_DAIFMT_LEFT_J: 218 case SND_SOC_DAIFMT_RIGHT_J: 219 /* 50% duty cycle ratio */ 220 ratio_num = 1; 221 break; 222 223 case SND_SOC_DAIFMT_DSP_A: 224 case SND_SOC_DAIFMT_DSP_B: 225 /* 226 * A zero duty cycle ratio will result in setting the mininum 227 * ratio possible which, for this clock, is 1 cycle of the 228 * parent bclk clock high and the rest low, This is exactly 229 * what we want here. 230 */ 231 ratio_num = 0; 232 break; 233 234 default: 235 return -EINVAL; 236 } 237 238 ret = clk_set_duty_cycle(iface->lrclk, ratio_num, 2); 239 if (ret) { 240 dev_err(dai->dev, 241 "setting sample clock duty cycle failed: %d\n", ret); 242 return ret; 243 } 244 245 /* Set sample clock inversion */ 246 ret = clk_set_phase(iface->lrclk, 247 axg_tdm_lrclk_invert(iface->fmt) ? 180 : 0); 248 if (ret) { 249 dev_err(dai->dev, 250 "setting sample clock phase failed: %d\n", ret); 251 return ret; 252 } 253 254 return 0; 255 } 256 257 static int axg_tdm_iface_set_sclk(struct snd_soc_dai *dai, 258 struct snd_pcm_hw_params *params) 259 { 260 struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); 261 unsigned long srate; 262 int ret; 263 264 srate = iface->slots * iface->slot_width * params_rate(params); 265 266 if (!iface->mclk_rate) { 267 /* If no specific mclk is requested, default to bit clock * 4 */ 268 clk_set_rate(iface->mclk, 4 * srate); 269 } else { 270 /* Check if we can actually get the bit clock from mclk */ 271 if (iface->mclk_rate % srate) { 272 dev_err(dai->dev, 273 "can't derive sclk %lu from mclk %lu\n", 274 srate, iface->mclk_rate); 275 return -EINVAL; 276 } 277 } 278 279 ret = clk_set_rate(iface->sclk, srate); 280 if (ret) { 281 dev_err(dai->dev, "setting bit clock failed: %d\n", ret); 282 return ret; 283 } 284 285 /* Set the bit clock inversion */ 286 ret = clk_set_phase(iface->sclk, 287 axg_tdm_sclk_invert(iface->fmt) ? 0 : 180); 288 if (ret) { 289 dev_err(dai->dev, "setting bit clock phase failed: %d\n", ret); 290 return ret; 291 } 292 293 return ret; 294 } 295 296 static int axg_tdm_iface_hw_params(struct snd_pcm_substream *substream, 297 struct snd_pcm_hw_params *params, 298 struct snd_soc_dai *dai) 299 { 300 struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); 301 int ret; 302 303 switch (iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 304 case SND_SOC_DAIFMT_I2S: 305 case SND_SOC_DAIFMT_LEFT_J: 306 case SND_SOC_DAIFMT_RIGHT_J: 307 if (iface->slots > 2) { 308 dev_err(dai->dev, "bad slot number for format: %d\n", 309 iface->slots); 310 return -EINVAL; 311 } 312 break; 313 314 case SND_SOC_DAIFMT_DSP_A: 315 case SND_SOC_DAIFMT_DSP_B: 316 break; 317 318 default: 319 dev_err(dai->dev, "unsupported dai format\n"); 320 return -EINVAL; 321 } 322 323 ret = axg_tdm_iface_set_stream(substream, params, dai); 324 if (ret) 325 return ret; 326 327 if ((iface->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) == 328 SND_SOC_DAIFMT_BP_FP) { 329 ret = axg_tdm_iface_set_sclk(dai, params); 330 if (ret) 331 return ret; 332 333 ret = axg_tdm_iface_set_lrclk(dai, params); 334 if (ret) 335 return ret; 336 } 337 338 return 0; 339 } 340 341 static int axg_tdm_iface_hw_free(struct snd_pcm_substream *substream, 342 struct snd_soc_dai *dai) 343 { 344 struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); 345 346 /* Stop all attached formatters */ 347 axg_tdm_stream_stop(ts); 348 349 return 0; 350 } 351 352 static int axg_tdm_iface_prepare(struct snd_pcm_substream *substream, 353 struct snd_soc_dai *dai) 354 { 355 struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); 356 357 /* Force all attached formatters to update */ 358 return axg_tdm_stream_reset(ts); 359 } 360 361 static int axg_tdm_iface_remove_dai(struct snd_soc_dai *dai) 362 { 363 int stream; 364 365 for_each_pcm_streams(stream) { 366 struct axg_tdm_stream *ts = snd_soc_dai_dma_data_get(dai, stream); 367 368 if (ts) 369 axg_tdm_stream_free(ts); 370 } 371 372 return 0; 373 } 374 375 static int axg_tdm_iface_probe_dai(struct snd_soc_dai *dai) 376 { 377 struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); 378 int stream; 379 380 for_each_pcm_streams(stream) { 381 struct axg_tdm_stream *ts; 382 383 if (!snd_soc_dai_get_widget(dai, stream)) 384 continue; 385 386 ts = axg_tdm_stream_alloc(iface); 387 if (!ts) { 388 axg_tdm_iface_remove_dai(dai); 389 return -ENOMEM; 390 } 391 snd_soc_dai_dma_data_set(dai, stream, ts); 392 } 393 394 return 0; 395 } 396 397 static const struct snd_soc_dai_ops axg_tdm_iface_ops = { 398 .set_sysclk = axg_tdm_iface_set_sysclk, 399 .set_fmt = axg_tdm_iface_set_fmt, 400 .startup = axg_tdm_iface_startup, 401 .hw_params = axg_tdm_iface_hw_params, 402 .prepare = axg_tdm_iface_prepare, 403 .hw_free = axg_tdm_iface_hw_free, 404 }; 405 406 /* TDM Backend DAIs */ 407 static const struct snd_soc_dai_driver axg_tdm_iface_dai_drv[] = { 408 [TDM_IFACE_PAD] = { 409 .name = "TDM Pad", 410 .playback = { 411 .stream_name = "Playback", 412 .channels_min = 1, 413 .channels_max = AXG_TDM_CHANNEL_MAX, 414 .rates = AXG_TDM_RATES, 415 .formats = AXG_TDM_FORMATS, 416 }, 417 .capture = { 418 .stream_name = "Capture", 419 .channels_min = 1, 420 .channels_max = AXG_TDM_CHANNEL_MAX, 421 .rates = AXG_TDM_RATES, 422 .formats = AXG_TDM_FORMATS, 423 }, 424 .id = TDM_IFACE_PAD, 425 .ops = &axg_tdm_iface_ops, 426 .probe = axg_tdm_iface_probe_dai, 427 .remove = axg_tdm_iface_remove_dai, 428 }, 429 [TDM_IFACE_LOOPBACK] = { 430 .name = "TDM Loopback", 431 .capture = { 432 .stream_name = "Loopback", 433 .channels_min = 1, 434 .channels_max = AXG_TDM_CHANNEL_MAX, 435 .rates = AXG_TDM_RATES, 436 .formats = AXG_TDM_FORMATS, 437 }, 438 .id = TDM_IFACE_LOOPBACK, 439 .ops = &axg_tdm_iface_ops, 440 .probe = axg_tdm_iface_probe_dai, 441 .remove = axg_tdm_iface_remove_dai, 442 }, 443 }; 444 445 static int axg_tdm_iface_set_bias_level(struct snd_soc_component *component, 446 enum snd_soc_bias_level level) 447 { 448 struct axg_tdm_iface *iface = snd_soc_component_get_drvdata(component); 449 enum snd_soc_bias_level now = 450 snd_soc_component_get_bias_level(component); 451 int ret = 0; 452 453 switch (level) { 454 case SND_SOC_BIAS_PREPARE: 455 if (now == SND_SOC_BIAS_STANDBY) 456 ret = clk_prepare_enable(iface->mclk); 457 break; 458 459 case SND_SOC_BIAS_STANDBY: 460 if (now == SND_SOC_BIAS_PREPARE) 461 clk_disable_unprepare(iface->mclk); 462 break; 463 464 case SND_SOC_BIAS_OFF: 465 case SND_SOC_BIAS_ON: 466 break; 467 } 468 469 return ret; 470 } 471 472 static const struct snd_soc_dapm_widget axg_tdm_iface_dapm_widgets[] = { 473 SND_SOC_DAPM_SIGGEN("Playback Signal"), 474 }; 475 476 static const struct snd_soc_dapm_route axg_tdm_iface_dapm_routes[] = { 477 { "Loopback", NULL, "Playback Signal" }, 478 }; 479 480 static const struct snd_soc_component_driver axg_tdm_iface_component_drv = { 481 .dapm_widgets = axg_tdm_iface_dapm_widgets, 482 .num_dapm_widgets = ARRAY_SIZE(axg_tdm_iface_dapm_widgets), 483 .dapm_routes = axg_tdm_iface_dapm_routes, 484 .num_dapm_routes = ARRAY_SIZE(axg_tdm_iface_dapm_routes), 485 .set_bias_level = axg_tdm_iface_set_bias_level, 486 }; 487 488 static const struct of_device_id axg_tdm_iface_of_match[] = { 489 { .compatible = "amlogic,axg-tdm-iface", }, 490 {} 491 }; 492 MODULE_DEVICE_TABLE(of, axg_tdm_iface_of_match); 493 494 static int axg_tdm_iface_probe(struct platform_device *pdev) 495 { 496 struct device *dev = &pdev->dev; 497 struct snd_soc_dai_driver *dai_drv; 498 struct axg_tdm_iface *iface; 499 int i; 500 501 iface = devm_kzalloc(dev, sizeof(*iface), GFP_KERNEL); 502 if (!iface) 503 return -ENOMEM; 504 platform_set_drvdata(pdev, iface); 505 506 /* 507 * Duplicate dai driver: depending on the slot masks configuration 508 * We'll change the number of channel provided by DAI stream, so dpcm 509 * channel merge can be done properly 510 */ 511 dai_drv = devm_kcalloc(dev, ARRAY_SIZE(axg_tdm_iface_dai_drv), 512 sizeof(*dai_drv), GFP_KERNEL); 513 if (!dai_drv) 514 return -ENOMEM; 515 516 for (i = 0; i < ARRAY_SIZE(axg_tdm_iface_dai_drv); i++) 517 memcpy(&dai_drv[i], &axg_tdm_iface_dai_drv[i], 518 sizeof(*dai_drv)); 519 520 /* Bit clock provided on the pad */ 521 iface->sclk = devm_clk_get(dev, "sclk"); 522 if (IS_ERR(iface->sclk)) 523 return dev_err_probe(dev, PTR_ERR(iface->sclk), "failed to get sclk\n"); 524 525 /* Sample clock provided on the pad */ 526 iface->lrclk = devm_clk_get(dev, "lrclk"); 527 if (IS_ERR(iface->lrclk)) 528 return dev_err_probe(dev, PTR_ERR(iface->lrclk), "failed to get lrclk\n"); 529 530 /* 531 * mclk maybe be missing when the cpu dai is in slave mode and 532 * the codec does not require it to provide a master clock. 533 * At this point, ignore the error if mclk is missing. We'll 534 * throw an error if the cpu dai is master and mclk is missing 535 */ 536 iface->mclk = devm_clk_get_optional(dev, "mclk"); 537 if (IS_ERR(iface->mclk)) 538 return dev_err_probe(dev, PTR_ERR(iface->mclk), "failed to get mclk\n"); 539 540 return devm_snd_soc_register_component(dev, 541 &axg_tdm_iface_component_drv, dai_drv, 542 ARRAY_SIZE(axg_tdm_iface_dai_drv)); 543 } 544 545 static struct platform_driver axg_tdm_iface_pdrv = { 546 .probe = axg_tdm_iface_probe, 547 .driver = { 548 .name = "axg-tdm-iface", 549 .of_match_table = axg_tdm_iface_of_match, 550 }, 551 }; 552 module_platform_driver(axg_tdm_iface_pdrv); 553 554 MODULE_DESCRIPTION("Amlogic AXG TDM interface driver"); 555 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 556 MODULE_LICENSE("GPL v2"); 557