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