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 .probe = axg_tdm_iface_probe_dai, 399 .remove = axg_tdm_iface_remove_dai, 400 .set_sysclk = axg_tdm_iface_set_sysclk, 401 .set_fmt = axg_tdm_iface_set_fmt, 402 .startup = axg_tdm_iface_startup, 403 .hw_params = axg_tdm_iface_hw_params, 404 .prepare = axg_tdm_iface_prepare, 405 .hw_free = axg_tdm_iface_hw_free, 406 }; 407 408 /* TDM Backend DAIs */ 409 static const struct snd_soc_dai_driver axg_tdm_iface_dai_drv[] = { 410 [TDM_IFACE_PAD] = { 411 .name = "TDM Pad", 412 .playback = { 413 .stream_name = "Playback", 414 .channels_min = 1, 415 .channels_max = AXG_TDM_CHANNEL_MAX, 416 .rates = AXG_TDM_RATES, 417 .formats = AXG_TDM_FORMATS, 418 }, 419 .capture = { 420 .stream_name = "Capture", 421 .channels_min = 1, 422 .channels_max = AXG_TDM_CHANNEL_MAX, 423 .rates = AXG_TDM_RATES, 424 .formats = AXG_TDM_FORMATS, 425 }, 426 .id = TDM_IFACE_PAD, 427 .ops = &axg_tdm_iface_ops, 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 }, 441 }; 442 443 static int axg_tdm_iface_set_bias_level(struct snd_soc_component *component, 444 enum snd_soc_bias_level level) 445 { 446 struct axg_tdm_iface *iface = snd_soc_component_get_drvdata(component); 447 enum snd_soc_bias_level now = 448 snd_soc_component_get_bias_level(component); 449 int ret = 0; 450 451 switch (level) { 452 case SND_SOC_BIAS_PREPARE: 453 if (now == SND_SOC_BIAS_STANDBY) 454 ret = clk_prepare_enable(iface->mclk); 455 break; 456 457 case SND_SOC_BIAS_STANDBY: 458 if (now == SND_SOC_BIAS_PREPARE) 459 clk_disable_unprepare(iface->mclk); 460 break; 461 462 case SND_SOC_BIAS_OFF: 463 case SND_SOC_BIAS_ON: 464 break; 465 } 466 467 return ret; 468 } 469 470 static const struct snd_soc_dapm_widget axg_tdm_iface_dapm_widgets[] = { 471 SND_SOC_DAPM_SIGGEN("Playback Signal"), 472 }; 473 474 static const struct snd_soc_dapm_route axg_tdm_iface_dapm_routes[] = { 475 { "Loopback", NULL, "Playback Signal" }, 476 }; 477 478 static const struct snd_soc_component_driver axg_tdm_iface_component_drv = { 479 .dapm_widgets = axg_tdm_iface_dapm_widgets, 480 .num_dapm_widgets = ARRAY_SIZE(axg_tdm_iface_dapm_widgets), 481 .dapm_routes = axg_tdm_iface_dapm_routes, 482 .num_dapm_routes = ARRAY_SIZE(axg_tdm_iface_dapm_routes), 483 .set_bias_level = axg_tdm_iface_set_bias_level, 484 }; 485 486 static const struct of_device_id axg_tdm_iface_of_match[] = { 487 { .compatible = "amlogic,axg-tdm-iface", }, 488 {} 489 }; 490 MODULE_DEVICE_TABLE(of, axg_tdm_iface_of_match); 491 492 static int axg_tdm_iface_probe(struct platform_device *pdev) 493 { 494 struct device *dev = &pdev->dev; 495 struct snd_soc_dai_driver *dai_drv; 496 struct axg_tdm_iface *iface; 497 int i; 498 499 iface = devm_kzalloc(dev, sizeof(*iface), GFP_KERNEL); 500 if (!iface) 501 return -ENOMEM; 502 platform_set_drvdata(pdev, iface); 503 504 /* 505 * Duplicate dai driver: depending on the slot masks configuration 506 * We'll change the number of channel provided by DAI stream, so dpcm 507 * channel merge can be done properly 508 */ 509 dai_drv = devm_kcalloc(dev, ARRAY_SIZE(axg_tdm_iface_dai_drv), 510 sizeof(*dai_drv), GFP_KERNEL); 511 if (!dai_drv) 512 return -ENOMEM; 513 514 for (i = 0; i < ARRAY_SIZE(axg_tdm_iface_dai_drv); i++) 515 memcpy(&dai_drv[i], &axg_tdm_iface_dai_drv[i], 516 sizeof(*dai_drv)); 517 518 /* Bit clock provided on the pad */ 519 iface->sclk = devm_clk_get(dev, "sclk"); 520 if (IS_ERR(iface->sclk)) 521 return dev_err_probe(dev, PTR_ERR(iface->sclk), "failed to get sclk\n"); 522 523 /* Sample clock provided on the pad */ 524 iface->lrclk = devm_clk_get(dev, "lrclk"); 525 if (IS_ERR(iface->lrclk)) 526 return dev_err_probe(dev, PTR_ERR(iface->lrclk), "failed to get lrclk\n"); 527 528 /* 529 * mclk maybe be missing when the cpu dai is in slave mode and 530 * the codec does not require it to provide a master clock. 531 * At this point, ignore the error if mclk is missing. We'll 532 * throw an error if the cpu dai is master and mclk is missing 533 */ 534 iface->mclk = devm_clk_get_optional(dev, "mclk"); 535 if (IS_ERR(iface->mclk)) 536 return dev_err_probe(dev, PTR_ERR(iface->mclk), "failed to get mclk\n"); 537 538 return devm_snd_soc_register_component(dev, 539 &axg_tdm_iface_component_drv, dai_drv, 540 ARRAY_SIZE(axg_tdm_iface_dai_drv)); 541 } 542 543 static struct platform_driver axg_tdm_iface_pdrv = { 544 .probe = axg_tdm_iface_probe, 545 .driver = { 546 .name = "axg-tdm-iface", 547 .of_match_table = axg_tdm_iface_of_match, 548 }, 549 }; 550 module_platform_driver(axg_tdm_iface_pdrv); 551 552 MODULE_DESCRIPTION("Amlogic AXG TDM interface driver"); 553 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 554 MODULE_LICENSE("GPL v2"); 555