1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // simple-card-utils.c 4 // 5 // Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6 7 #include <dt-bindings/sound/audio-graph.h> 8 #include <linux/cleanup.h> 9 #include <linux/clk.h> 10 #include <linux/gpio/consumer.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/of_graph.h> 14 #include <sound/jack.h> 15 #include <sound/pcm_params.h> 16 #include <sound/simple_card_utils.h> 17 18 #define simple_ret(priv, ret) _simple_ret(priv, __func__, ret) 19 static inline int _simple_ret(struct simple_util_priv *priv, 20 const char *func, int ret) 21 { 22 return snd_soc_ret(simple_priv_to_dev(priv), ret, "at %s()\n", func); 23 } 24 25 int simple_util_get_sample_fmt(struct simple_util_data *data) 26 { 27 int i; 28 int val = -EINVAL; 29 30 struct { 31 char *fmt; 32 u32 val; 33 } of_sample_fmt_table[] = { 34 { "s8", SNDRV_PCM_FORMAT_S8}, 35 { "s16_le", SNDRV_PCM_FORMAT_S16_LE}, 36 { "s24_le", SNDRV_PCM_FORMAT_S24_LE}, 37 { "s24_3le", SNDRV_PCM_FORMAT_S24_3LE}, 38 { "s32_le", SNDRV_PCM_FORMAT_S32_LE}, 39 }; 40 41 for (i = 0; i < ARRAY_SIZE(of_sample_fmt_table); i++) { 42 if (!strcmp(data->convert_sample_format, 43 of_sample_fmt_table[i].fmt)) { 44 val = of_sample_fmt_table[i].val; 45 break; 46 } 47 } 48 return val; 49 } 50 EXPORT_SYMBOL_GPL(simple_util_get_sample_fmt); 51 52 static void simple_fixup_sample_fmt(struct simple_util_data *data, 53 struct snd_pcm_hw_params *params) 54 { 55 int val; 56 struct snd_mask *mask = hw_param_mask(params, 57 SNDRV_PCM_HW_PARAM_FORMAT); 58 59 val = simple_util_get_sample_fmt(data); 60 if (val >= 0) { 61 snd_mask_none(mask); 62 snd_mask_set(mask, val); 63 } 64 } 65 66 void simple_util_parse_convert(struct device_node *np, 67 char *prefix, 68 struct simple_util_data *data) 69 { 70 char prop[128]; 71 72 if (!np) 73 return; 74 75 if (!prefix) 76 prefix = ""; 77 78 /* sampling rate convert */ 79 snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-rate"); 80 of_property_read_u32(np, prop, &data->convert_rate); 81 82 /* channels transfer */ 83 snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-channels"); 84 of_property_read_u32(np, prop, &data->convert_channels); 85 86 /* convert sample format */ 87 snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-sample-format"); 88 of_property_read_string(np, prop, &data->convert_sample_format); 89 } 90 EXPORT_SYMBOL_GPL(simple_util_parse_convert); 91 92 /** 93 * simple_util_is_convert_required() - Query if HW param conversion was requested 94 * @data: Link data. 95 * 96 * Returns true if any HW param conversion was requested for this DAI link with 97 * any "convert-xxx" properties. 98 */ 99 bool simple_util_is_convert_required(const struct simple_util_data *data) 100 { 101 return data->convert_rate || 102 data->convert_channels || 103 data->convert_sample_format; 104 } 105 EXPORT_SYMBOL_GPL(simple_util_is_convert_required); 106 107 int simple_util_parse_daifmt(struct device *dev, 108 struct device_node *node, 109 struct device_node *codec, 110 char *prefix, 111 unsigned int *retfmt) 112 { 113 struct device_node *bitclkmaster = NULL; 114 struct device_node *framemaster = NULL; 115 unsigned int daifmt; 116 117 daifmt = snd_soc_daifmt_parse_format(node, prefix); 118 119 snd_soc_daifmt_parse_clock_provider_as_phandle(node, prefix, &bitclkmaster, &framemaster); 120 if (!bitclkmaster && !framemaster) { 121 /* 122 * No dai-link level and master setting was not found from 123 * sound node level, revert back to legacy DT parsing and 124 * take the settings from codec node. 125 */ 126 dev_dbg(dev, "Revert to legacy daifmt parsing\n"); 127 128 daifmt |= snd_soc_daifmt_parse_clock_provider_as_flag(codec, NULL); 129 } else { 130 daifmt |= snd_soc_daifmt_clock_provider_from_bitmap( 131 ((codec == bitclkmaster) << 4) | (codec == framemaster)); 132 } 133 134 of_node_put(bitclkmaster); 135 of_node_put(framemaster); 136 137 *retfmt = daifmt; 138 139 return 0; 140 } 141 EXPORT_SYMBOL_GPL(simple_util_parse_daifmt); 142 143 int simple_util_parse_tdm_width_map(struct simple_util_priv *priv, struct device_node *np, 144 struct simple_util_dai *dai) 145 { 146 struct device *dev = simple_priv_to_dev(priv); 147 int n, i, ret; 148 u32 *p; 149 150 /* 151 * NOTE 152 * 153 * Clang doesn't allow to use "goto end" before calling __free(), 154 * because it bypasses the initialization. Use simple_ret() directly. 155 */ 156 157 n = of_property_count_elems_of_size(np, "dai-tdm-slot-width-map", sizeof(u32)); 158 if (n <= 0) 159 return 0; 160 161 if (n % 3) { 162 dev_err(dev, "Invalid number of cells for dai-tdm-slot-width-map\n"); 163 return simple_ret(priv, -EINVAL); /* see NOTE */ 164 } 165 166 ret = -ENOMEM; 167 dai->tdm_width_map = devm_kcalloc(dev, n, sizeof(*dai->tdm_width_map), GFP_KERNEL); 168 if (!dai->tdm_width_map) 169 return simple_ret(priv, ret); /* see NOTE */ 170 171 u32 *array_values __free(kfree) = kcalloc(n, sizeof(*array_values), GFP_KERNEL); 172 if (!array_values) 173 goto end; 174 175 ret = of_property_read_u32_array(np, "dai-tdm-slot-width-map", array_values, n); 176 if (ret < 0) { 177 dev_err(dev, "Could not read dai-tdm-slot-width-map: %d\n", ret); 178 goto end; 179 } 180 181 p = array_values; 182 for (i = 0; i < n / 3; ++i) { 183 dai->tdm_width_map[i].sample_bits = *p++; 184 dai->tdm_width_map[i].slot_width = *p++; 185 dai->tdm_width_map[i].slot_count = *p++; 186 } 187 188 dai->n_tdm_widths = i; 189 ret = 0; 190 end: 191 return simple_ret(priv, ret); 192 } 193 EXPORT_SYMBOL_GPL(simple_util_parse_tdm_width_map); 194 195 int simple_util_set_dailink_name(struct simple_util_priv *priv, 196 struct snd_soc_dai_link *dai_link, 197 const char *fmt, ...) 198 { 199 struct device *dev = simple_priv_to_dev(priv); 200 va_list ap; 201 char *name = NULL; 202 int ret = -ENOMEM; 203 204 va_start(ap, fmt); 205 name = devm_kvasprintf(dev, GFP_KERNEL, fmt, ap); 206 va_end(ap); 207 208 if (name) { 209 ret = 0; 210 211 dai_link->name = name; 212 dai_link->stream_name = name; 213 } 214 215 return simple_ret(priv, ret); 216 } 217 EXPORT_SYMBOL_GPL(simple_util_set_dailink_name); 218 219 int simple_util_parse_property(struct simple_util_priv *priv, 220 int (*func)(struct snd_soc_card *card, const char *propname), 221 char *prefix, char *property) 222 { 223 struct snd_soc_card *card = simple_priv_to_card(priv); 224 struct device_node *node = card->dev->of_node; 225 char prop[128]; 226 227 if (!prefix) 228 prefix = ""; 229 230 snprintf(prop, sizeof(prop), "%s%s", prefix, property); 231 232 /* no property is not error */ 233 if (!of_property_present(node, prop)) 234 return 0; 235 236 return func(card, prop); 237 } 238 EXPORT_SYMBOL_GPL(simple_util_parse_property); 239 240 int simple_util_parse_card_name(struct simple_util_priv *priv, 241 char *prefix) 242 { 243 struct snd_soc_card *card = simple_priv_to_card(priv); 244 int ret; 245 246 if (!prefix) 247 prefix = ""; 248 249 /* Parse the card name from DT */ 250 ret = snd_soc_of_parse_card_name(card, "label"); 251 if (ret < 0 || !card->name) { 252 char prop[128]; 253 254 snprintf(prop, sizeof(prop), "%sname", prefix); 255 ret = snd_soc_of_parse_card_name(card, prop); 256 if (ret < 0) 257 goto end; 258 } 259 260 if (!card->name && card->dai_link) 261 card->name = card->dai_link->name; 262 end: 263 return simple_ret(priv, ret); 264 } 265 EXPORT_SYMBOL_GPL(simple_util_parse_card_name); 266 267 static int simple_clk_enable(struct simple_util_dai *dai) 268 { 269 if (dai) 270 return clk_prepare_enable(dai->clk); 271 272 return 0; 273 } 274 275 static void simple_clk_disable(struct simple_util_dai *dai) 276 { 277 if (dai) 278 clk_disable_unprepare(dai->clk); 279 } 280 281 int simple_util_parse_clk(struct device *dev, 282 struct device_node *node, 283 struct simple_util_dai *simple_dai, 284 struct snd_soc_dai_link_component *dlc) 285 { 286 struct clk *clk; 287 u32 val; 288 289 /* 290 * Parse dai->sysclk come from "clocks = <&xxx>" 291 * (if system has common clock) 292 * or "system-clock-frequency = <xxx>" 293 * or device's module clock. 294 */ 295 clk = devm_get_clk_from_child(dev, node, NULL); 296 simple_dai->clk_fixed = of_property_read_bool( 297 node, "system-clock-fixed"); 298 if (!IS_ERR(clk)) { 299 simple_dai->sysclk = clk_get_rate(clk); 300 301 simple_dai->clk = clk; 302 } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) { 303 simple_dai->sysclk = val; 304 simple_dai->clk_fixed = true; 305 } else { 306 clk = devm_get_clk_from_child(dev, dlc->of_node, NULL); 307 if (!IS_ERR(clk)) 308 simple_dai->sysclk = clk_get_rate(clk); 309 } 310 311 if (of_property_read_bool(node, "system-clock-direction-out")) 312 simple_dai->clk_direction = SND_SOC_CLOCK_OUT; 313 314 return 0; 315 } 316 EXPORT_SYMBOL_GPL(simple_util_parse_clk); 317 318 static int simple_check_fixed_sysclk(struct device *dev, 319 struct simple_util_dai *dai, 320 unsigned int *fixed_sysclk) 321 { 322 if (dai->clk_fixed) { 323 if (*fixed_sysclk && *fixed_sysclk != dai->sysclk) { 324 dev_err(dev, "inconsistent fixed sysclk rates (%u vs %u)\n", 325 *fixed_sysclk, dai->sysclk); 326 return -EINVAL; 327 } 328 *fixed_sysclk = dai->sysclk; 329 } 330 331 return 0; 332 } 333 334 int simple_util_startup(struct snd_pcm_substream *substream) 335 { 336 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 337 struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card); 338 struct simple_dai_props *props = runtime_simple_priv_to_props(priv, rtd); 339 struct simple_util_dai *dai; 340 unsigned int fixed_sysclk = 0; 341 int i1, i2, i; 342 int ret; 343 344 for_each_prop_dai_cpu(props, i1, dai) { 345 ret = simple_clk_enable(dai); 346 if (ret) 347 goto cpu_err; 348 ret = simple_check_fixed_sysclk(rtd->dev, dai, &fixed_sysclk); 349 if (ret) 350 goto cpu_err; 351 } 352 353 for_each_prop_dai_codec(props, i2, dai) { 354 ret = simple_clk_enable(dai); 355 if (ret) 356 goto codec_err; 357 ret = simple_check_fixed_sysclk(rtd->dev, dai, &fixed_sysclk); 358 if (ret) 359 goto codec_err; 360 } 361 362 if (fixed_sysclk && props->mclk_fs) { 363 unsigned int fixed_rate = fixed_sysclk / props->mclk_fs; 364 365 if (fixed_sysclk % props->mclk_fs) { 366 dev_err(rtd->dev, "fixed sysclk %u not divisible by mclk_fs %u\n", 367 fixed_sysclk, props->mclk_fs); 368 ret = -EINVAL; 369 goto codec_err; 370 } 371 ret = snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, 372 fixed_rate, fixed_rate); 373 if (ret < 0) 374 goto codec_err; 375 } 376 377 return 0; 378 379 codec_err: 380 for_each_prop_dai_codec(props, i, dai) { 381 if (i >= i2) 382 break; 383 simple_clk_disable(dai); 384 } 385 cpu_err: 386 for_each_prop_dai_cpu(props, i, dai) { 387 if (i >= i1) 388 break; 389 simple_clk_disable(dai); 390 } 391 392 return simple_ret(priv, ret); 393 } 394 EXPORT_SYMBOL_GPL(simple_util_startup); 395 396 void simple_util_shutdown(struct snd_pcm_substream *substream) 397 { 398 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 399 struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card); 400 struct simple_dai_props *props = runtime_simple_priv_to_props(priv, rtd); 401 struct simple_util_dai *dai; 402 int i; 403 404 for_each_prop_dai_cpu(props, i, dai) { 405 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, i); 406 407 if (props->mclk_fs && !dai->clk_fixed && !snd_soc_dai_active(cpu_dai)) 408 snd_soc_dai_set_sysclk(cpu_dai, 0, 0, dai->clk_direction); 409 410 simple_clk_disable(dai); 411 } 412 for_each_prop_dai_codec(props, i, dai) { 413 struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, i); 414 415 if (props->mclk_fs && !dai->clk_fixed && !snd_soc_dai_active(codec_dai)) 416 snd_soc_dai_set_sysclk(codec_dai, 0, 0, dai->clk_direction); 417 418 simple_clk_disable(dai); 419 } 420 } 421 EXPORT_SYMBOL_GPL(simple_util_shutdown); 422 423 static int simple_set_clk_rate(struct simple_util_priv *priv, 424 struct simple_util_dai *simple_dai, 425 unsigned long rate) 426 { 427 struct device *dev = simple_priv_to_dev(priv); 428 int ret = -EINVAL; 429 430 if (!simple_dai) 431 return 0; 432 433 if (simple_dai->clk_fixed && rate != simple_dai->sysclk) { 434 dev_err(dev, "dai %s invalid clock rate %lu\n", simple_dai->name, rate); 435 goto end; 436 } 437 438 if (!simple_dai->clk) 439 return 0; 440 441 if (clk_get_rate(simple_dai->clk) == rate) 442 return 0; 443 444 ret = clk_set_rate(simple_dai->clk, rate); 445 end: 446 return simple_ret(priv, ret); 447 } 448 449 static int simple_set_tdm(struct simple_util_priv *priv, 450 struct snd_soc_dai *dai, 451 struct simple_util_dai *simple_dai, 452 struct snd_pcm_hw_params *params) 453 { 454 int sample_bits = params_width(params); 455 int slot_width, slot_count; 456 int i, ret; 457 458 if (!simple_dai || !simple_dai->tdm_width_map) 459 return 0; 460 461 slot_width = simple_dai->slot_width; 462 slot_count = simple_dai->slots; 463 464 if (slot_width == 0) 465 slot_width = sample_bits; 466 467 for (i = 0; i < simple_dai->n_tdm_widths; ++i) { 468 if (simple_dai->tdm_width_map[i].sample_bits == sample_bits) { 469 slot_width = simple_dai->tdm_width_map[i].slot_width; 470 slot_count = simple_dai->tdm_width_map[i].slot_count; 471 break; 472 } 473 } 474 475 ret = snd_soc_dai_set_tdm_slot(dai, 476 simple_dai->tx_slot_mask, 477 simple_dai->rx_slot_mask, 478 slot_count, 479 slot_width); 480 481 return simple_ret(priv, ret); 482 } 483 484 int simple_util_hw_params(struct snd_pcm_substream *substream, 485 struct snd_pcm_hw_params *params) 486 { 487 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 488 struct simple_util_dai *pdai; 489 struct snd_soc_dai *sdai; 490 struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card); 491 struct simple_dai_props *props = runtime_simple_priv_to_props(priv, rtd); 492 enum simple_util_sysclk_order order = props->sysclk_order; 493 unsigned int mclk, mclk_fs = 0; 494 int i, ret; 495 496 if (props->mclk_fs) 497 mclk_fs = props->mclk_fs; 498 499 if (mclk_fs) { 500 struct snd_soc_component *component; 501 mclk = params_rate(params) * mclk_fs; 502 503 for_each_prop_dai_codec(props, i, pdai) { 504 ret = simple_set_clk_rate(priv, pdai, mclk); 505 if (ret < 0) 506 goto end; 507 } 508 509 for_each_prop_dai_cpu(props, i, pdai) { 510 ret = simple_set_clk_rate(priv, pdai, mclk); 511 if (ret < 0) 512 goto end; 513 } 514 515 /* Ensure sysclk is set on all components in case any 516 * (such as platform components) are missed by calls to 517 * snd_soc_dai_set_sysclk. 518 */ 519 for_each_rtd_components(rtd, i, component) { 520 ret = snd_soc_component_set_sysclk(component, 0, 0, 521 mclk, SND_SOC_CLOCK_IN); 522 if (ret && ret != -ENOTSUPP) 523 goto end; 524 } 525 526 if (order == SIMPLE_SYSCLK_ORDER_CPU_FIRST) { 527 /* CPU first */ 528 for_each_rtd_cpu_dais(rtd, i, sdai) { 529 pdai = simple_props_to_dai_cpu(props, i); 530 ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction); 531 if (ret && ret != -ENOTSUPP) 532 goto end; 533 } 534 535 for_each_rtd_codec_dais(rtd, i, sdai) { 536 pdai = simple_props_to_dai_codec(props, i); 537 ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction); 538 if (ret && ret != -ENOTSUPP) 539 goto end; 540 } 541 } else { 542 /* default: codec first */ 543 for_each_rtd_codec_dais(rtd, i, sdai) { 544 pdai = simple_props_to_dai_codec(props, i); 545 ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction); 546 if (ret && ret != -ENOTSUPP) 547 goto end; 548 } 549 550 for_each_rtd_cpu_dais(rtd, i, sdai) { 551 pdai = simple_props_to_dai_cpu(props, i); 552 ret = snd_soc_dai_set_sysclk(sdai, 0, mclk, pdai->clk_direction); 553 if (ret && ret != -ENOTSUPP) 554 goto end; 555 } 556 } 557 } 558 559 for_each_prop_dai_codec(props, i, pdai) { 560 sdai = snd_soc_rtd_to_codec(rtd, i); 561 ret = simple_set_tdm(priv, sdai, pdai, params); 562 if (ret < 0) 563 goto end; 564 } 565 566 for_each_prop_dai_cpu(props, i, pdai) { 567 sdai = snd_soc_rtd_to_cpu(rtd, i); 568 ret = simple_set_tdm(priv, sdai, pdai, params); 569 if (ret < 0) 570 goto end; 571 } 572 ret = 0; 573 end: 574 return simple_ret(priv, ret); 575 } 576 EXPORT_SYMBOL_GPL(simple_util_hw_params); 577 578 int simple_util_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 579 struct snd_pcm_hw_params *params) 580 { 581 struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card); 582 struct simple_dai_props *dai_props = runtime_simple_priv_to_props(priv, rtd); 583 struct simple_util_data *data = &dai_props->adata; 584 struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 585 struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 586 587 if (data->convert_rate) 588 rate->min = 589 rate->max = data->convert_rate; 590 591 if (data->convert_channels) 592 channels->min = 593 channels->max = data->convert_channels; 594 595 if (data->convert_sample_format) 596 simple_fixup_sample_fmt(data, params); 597 598 return 0; 599 } 600 EXPORT_SYMBOL_GPL(simple_util_be_hw_params_fixup); 601 602 static int simple_init_dai(struct simple_util_priv *priv, 603 struct snd_soc_dai *dai, struct simple_util_dai *simple_dai) 604 { 605 int ret; 606 607 if (!simple_dai) 608 return 0; 609 610 if (simple_dai->sysclk) { 611 ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, 612 simple_dai->clk_direction); 613 if (ret && ret != -ENOTSUPP) { 614 dev_err(dai->dev, "simple-card: set_sysclk error\n"); 615 goto end; 616 } 617 } 618 619 if (simple_dai->slots) { 620 ret = snd_soc_dai_set_tdm_slot(dai, 621 simple_dai->tx_slot_mask, 622 simple_dai->rx_slot_mask, 623 simple_dai->slots, 624 simple_dai->slot_width); 625 if (ret && ret != -ENOTSUPP) { 626 dev_err(dai->dev, "simple-card: set_tdm_slot error\n"); 627 goto end; 628 } 629 } 630 ret = 0; 631 end: 632 return simple_ret(priv, ret); 633 } 634 635 static inline int simple_component_is_codec(struct snd_soc_component *component) 636 { 637 return component->driver->endianness; 638 } 639 640 static int simple_init_for_codec2codec(struct simple_util_priv *priv, 641 struct snd_soc_pcm_runtime *rtd, 642 struct simple_dai_props *dai_props) 643 { 644 struct snd_soc_dai_link *dai_link = rtd->dai_link; 645 struct snd_soc_component *component; 646 struct snd_soc_pcm_stream *c2c_params; 647 struct snd_pcm_hardware hw; 648 int i, ret, stream; 649 650 /* Do nothing if it already has Codec2Codec settings */ 651 if (dai_link->c2c_params) 652 return 0; 653 654 /* Do nothing if it was DPCM :: BE */ 655 if (dai_link->no_pcm) 656 return 0; 657 658 /* Only Codecs */ 659 for_each_rtd_components(rtd, i, component) { 660 if (!simple_component_is_codec(component)) 661 return 0; 662 } 663 664 /* Assumes the capabilities are the same for all supported streams */ 665 for_each_pcm_streams(stream) { 666 ret = snd_soc_runtime_calc_hw(rtd, &hw, stream); 667 if (ret == 0) 668 break; 669 } 670 671 if (ret < 0) { 672 dev_err(rtd->dev, "simple-card: no valid dai_link params\n"); 673 goto end; 674 } 675 676 ret = -ENOMEM; 677 c2c_params = devm_kzalloc(rtd->dev, sizeof(*c2c_params), GFP_KERNEL); 678 if (!c2c_params) 679 goto end; 680 681 c2c_params->formats = hw.formats; 682 c2c_params->rates = hw.rates; 683 c2c_params->rate_min = hw.rate_min; 684 c2c_params->rate_max = hw.rate_max; 685 c2c_params->channels_min = hw.channels_min; 686 c2c_params->channels_max = hw.channels_max; 687 688 dai_link->c2c_params = c2c_params; 689 dai_link->num_c2c_params = 1; 690 691 ret = 0; 692 end: 693 return simple_ret(priv, ret); 694 } 695 696 int simple_util_dai_init(struct snd_soc_pcm_runtime *rtd) 697 { 698 struct simple_util_priv *priv = snd_soc_card_get_drvdata(rtd->card); 699 struct simple_dai_props *props = runtime_simple_priv_to_props(priv, rtd); 700 struct simple_util_dai *dai; 701 int i, ret; 702 703 for_each_prop_dai_codec(props, i, dai) { 704 ret = simple_init_dai(priv, snd_soc_rtd_to_codec(rtd, i), dai); 705 if (ret < 0) 706 goto end; 707 } 708 for_each_prop_dai_cpu(props, i, dai) { 709 ret = simple_init_dai(priv, snd_soc_rtd_to_cpu(rtd, i), dai); 710 if (ret < 0) 711 goto end; 712 } 713 714 ret = simple_init_for_codec2codec(priv, rtd, props); 715 end: 716 return simple_ret(priv, ret); 717 } 718 EXPORT_SYMBOL_GPL(simple_util_dai_init); 719 720 void simple_util_canonicalize_platform(struct snd_soc_dai_link_component *platforms, 721 struct snd_soc_dai_link_component *cpus) 722 { 723 /* 724 * Assumes Platform == CPU 725 * 726 * Some CPU might be using soc-generic-dmaengine-pcm. This means CPU and Platform 727 * are different Component, but are sharing same component->dev. 728 * 729 * Let's assume Platform is same as CPU if it doesn't identify Platform on DT. 730 * see 731 * simple-card.c :: simple_count_noml() 732 */ 733 if (!platforms->of_node) 734 snd_soc_dlc_use_cpu_as_platform(platforms, cpus); 735 } 736 EXPORT_SYMBOL_GPL(simple_util_canonicalize_platform); 737 738 void simple_util_canonicalize_cpu(struct snd_soc_dai_link_component *cpus, 739 int is_single_links) 740 { 741 /* 742 * In snd_soc_add_pcm_runtime() will check cpu name after 743 * of_node matching if dai_link has cpu_dai_name. 744 * but, it will never match if name was created by 745 * fmt_single_name() remove cpu_dai_name if cpu_args 746 * was 0. See: 747 * fmt_single_name() 748 * fmt_multiple_name() 749 */ 750 if (is_single_links) 751 cpus->dai_name = NULL; 752 } 753 EXPORT_SYMBOL_GPL(simple_util_canonicalize_cpu); 754 755 void simple_util_clean_reference(struct simple_util_priv *priv) 756 { 757 struct snd_soc_dai_link *dai_link; 758 struct snd_soc_dai_link_component *cpu; 759 struct snd_soc_dai_link_component *codec; 760 struct snd_soc_card *card = simple_priv_to_card(priv); 761 int i, j; 762 763 for_each_card_prelinks(card, i, dai_link) { 764 for_each_link_cpus(dai_link, j, cpu) 765 of_node_put(cpu->of_node); 766 for_each_link_codecs(dai_link, j, codec) 767 of_node_put(codec->of_node); 768 } 769 } 770 EXPORT_SYMBOL_GPL(simple_util_clean_reference); 771 772 int simple_util_init_jack(struct snd_soc_card *card, 773 struct simple_util_jack *sjack, 774 int is_hp, char *prefix, 775 char *pin) 776 { 777 struct device *dev = card->dev; 778 struct gpio_desc *desc; 779 char prop[128]; 780 char *pin_name; 781 char *gpio_name; 782 int mask; 783 int error; 784 785 if (!prefix) 786 prefix = ""; 787 788 if (is_hp) { 789 snprintf(prop, sizeof(prop), "%shp-det", prefix); 790 pin_name = pin ? pin : "Headphones"; 791 gpio_name = "Headphone detection"; 792 mask = SND_JACK_HEADPHONE; 793 } else { 794 snprintf(prop, sizeof(prop), "%smic-det", prefix); 795 pin_name = pin ? pin : "Mic Jack"; 796 gpio_name = "Mic detection"; 797 mask = SND_JACK_MICROPHONE; 798 } 799 800 desc = gpiod_get_optional(dev, prop, GPIOD_IN); 801 error = PTR_ERR_OR_ZERO(desc); 802 if (error) 803 return error; 804 805 if (desc) { 806 error = gpiod_set_consumer_name(desc, gpio_name); 807 if (error) 808 return error; 809 810 sjack->pin.pin = pin_name; 811 sjack->pin.mask = mask; 812 813 sjack->gpio.name = gpio_name; 814 sjack->gpio.report = mask; 815 sjack->gpio.desc = desc; 816 sjack->gpio.debounce_time = 150; 817 818 snd_soc_card_jack_new_pins(card, pin_name, mask, &sjack->jack, 819 &sjack->pin, 1); 820 821 snd_soc_jack_add_gpios(&sjack->jack, 1, &sjack->gpio); 822 } 823 824 return 0; 825 } 826 EXPORT_SYMBOL_GPL(simple_util_init_jack); 827 828 int simple_util_init_aux_jacks(struct snd_soc_card *card, char *prefix) 829 { 830 struct simple_util_priv *priv = snd_soc_card_get_drvdata(card); 831 struct snd_soc_component *component; 832 int found_jack_index = 0; 833 int type = 0; 834 int num = 0; 835 int ret; 836 837 if (priv->aux_jacks) 838 return 0; 839 840 for_each_card_auxs(card, component) { 841 type = snd_soc_component_get_jack_type(component); 842 if (type > 0) 843 num++; 844 } 845 if (num < 1) 846 return 0; 847 848 priv->aux_jacks = devm_kcalloc(card->dev, num, 849 sizeof(struct snd_soc_jack), GFP_KERNEL); 850 if (!priv->aux_jacks) 851 return simple_ret(priv, -ENOMEM); 852 853 for_each_card_auxs(card, component) { 854 char id[128]; 855 struct snd_soc_jack *jack; 856 857 if (found_jack_index >= num) 858 break; 859 860 type = snd_soc_component_get_jack_type(component); 861 if (type <= 0) 862 continue; 863 864 /* create jack */ 865 jack = &(priv->aux_jacks[found_jack_index++]); 866 snprintf(id, sizeof(id), "%s-jack", component->name); 867 ret = snd_soc_card_jack_new(card, id, type, jack); 868 if (ret) 869 continue; 870 871 (void)snd_soc_component_set_jack(component, jack, NULL); 872 } 873 return 0; 874 } 875 EXPORT_SYMBOL_GPL(simple_util_init_aux_jacks); 876 877 static struct simple_util_dai dummy_util_dais = { 878 .name = "dummy_util_dais", 879 }; 880 881 int simple_util_init_priv(struct simple_util_priv *priv, 882 struct link_info *li) 883 { 884 struct snd_soc_card *card = simple_priv_to_card(priv); 885 struct device *dev = simple_priv_to_dev(priv); 886 struct snd_soc_dai_link *dai_link; 887 struct simple_dai_props *dai_props; 888 struct simple_util_dai *dais; 889 struct snd_soc_dai_link_component *dlcs; 890 struct snd_soc_codec_conf *cconf = NULL; 891 int i, dai_num = 0, dlc_num = 0, cnf_num = 0; 892 893 dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL); 894 dai_link = devm_kcalloc(dev, li->link, sizeof(*dai_link), GFP_KERNEL); 895 if (!dai_props || !dai_link) 896 return -ENOMEM; 897 898 /* 899 * dais (= CPU+Codec) 900 * dlcs (= CPU+Codec+Platform) 901 */ 902 for (i = 0; i < li->link; i++) { 903 int cc = li->num[i].cpus + li->num[i].codecs; 904 905 dai_num += cc; 906 dlc_num += cc + li->num[i].platforms; 907 908 if (!li->num[i].cpus) 909 cnf_num += li->num[i].codecs; 910 } 911 912 dais = devm_kcalloc(dev, dai_num, sizeof(*dais), GFP_KERNEL); 913 dlcs = devm_kcalloc(dev, dlc_num, sizeof(*dlcs), GFP_KERNEL); 914 if (!dais || !dlcs) 915 return -ENOMEM; 916 917 if (cnf_num) { 918 cconf = devm_kcalloc(dev, cnf_num, sizeof(*cconf), GFP_KERNEL); 919 if (!cconf) 920 return -ENOMEM; 921 } 922 923 dev_dbg(dev, "link %d, dais %d, ccnf %d\n", 924 li->link, dai_num, cnf_num); 925 926 priv->dai_props = dai_props; 927 priv->dai_link = dai_link; 928 priv->dais = dais; 929 priv->dlcs = dlcs; 930 priv->codec_conf = cconf; 931 932 card->dai_link = priv->dai_link; 933 card->num_links = li->link; 934 card->codec_conf = cconf; 935 card->num_configs = cnf_num; 936 937 for (i = 0; i < li->link; i++) { 938 if (li->num[i].cpus) { 939 /* Normal CPU */ 940 dai_link[i].cpus = dlcs; 941 dai_props[i].num.cpus = 942 dai_link[i].num_cpus = li->num[i].cpus; 943 dai_props[i].cpu_dai = dais; 944 945 dlcs += li->num[i].cpus; 946 dais += li->num[i].cpus; 947 } else { 948 /* DPCM Be's CPU = dummy */ 949 dai_link[i].cpus = &snd_soc_dummy_dlc; 950 dai_props[i].num.cpus = 951 dai_link[i].num_cpus = 1; 952 dai_props[i].cpu_dai = &dummy_util_dais; 953 } 954 955 if (li->num[i].codecs) { 956 /* Normal Codec */ 957 dai_link[i].codecs = dlcs; 958 dai_props[i].num.codecs = 959 dai_link[i].num_codecs = li->num[i].codecs; 960 dai_props[i].codec_dai = dais; 961 962 dlcs += li->num[i].codecs; 963 dais += li->num[i].codecs; 964 965 if (!li->num[i].cpus) { 966 /* DPCM Be's Codec */ 967 dai_props[i].codec_conf = cconf; 968 cconf += li->num[i].codecs; 969 } 970 } else { 971 /* DPCM Fe's Codec = dummy */ 972 dai_link[i].codecs = &snd_soc_dummy_dlc; 973 dai_props[i].num.codecs = 974 dai_link[i].num_codecs = 1; 975 dai_props[i].codec_dai = &dummy_util_dais; 976 } 977 978 if (li->num[i].platforms) { 979 /* Have Platform */ 980 dai_link[i].platforms = dlcs; 981 dai_props[i].num.platforms = 982 dai_link[i].num_platforms = li->num[i].platforms; 983 984 dlcs += li->num[i].platforms; 985 } else { 986 /* Doesn't have Platform */ 987 dai_link[i].platforms = NULL; 988 dai_props[i].num.platforms = 989 dai_link[i].num_platforms = 0; 990 } 991 } 992 993 return 0; 994 } 995 EXPORT_SYMBOL_GPL(simple_util_init_priv); 996 997 void simple_util_remove(struct platform_device *pdev) 998 { 999 struct snd_soc_card *card = platform_get_drvdata(pdev); 1000 struct simple_util_priv *priv = snd_soc_card_get_drvdata(card); 1001 1002 simple_util_clean_reference(priv); 1003 } 1004 EXPORT_SYMBOL_GPL(simple_util_remove); 1005 1006 int graph_util_card_probe(struct snd_soc_card *card) 1007 { 1008 struct simple_util_priv *priv = snd_soc_card_get_drvdata(card); 1009 int ret; 1010 1011 ret = simple_util_init_hp(card, &priv->hp_jack, NULL); 1012 if (ret < 0) 1013 goto end; 1014 1015 ret = simple_util_init_mic(card, &priv->mic_jack, NULL); 1016 end: 1017 return simple_ret(priv, ret); 1018 } 1019 EXPORT_SYMBOL_GPL(graph_util_card_probe); 1020 1021 int graph_util_is_ports0(struct device_node *np) 1022 { 1023 struct device_node *parent __free(device_node) = of_get_parent(np); 1024 struct device_node *port; 1025 1026 /* np is "endpoint" or "port" */ 1027 if (of_node_name_eq(np, "endpoint")) 1028 port = parent; 1029 else 1030 port = np; 1031 1032 struct device_node *ports __free(device_node) = of_get_parent(port); 1033 const char *at = strchr(kbasename(ports->full_name), '@'); 1034 1035 /* 1036 * Since child iteration order may differ 1037 * between a base DT and DT overlays, 1038 * string match "ports" or "ports@0" in the node name instead. 1039 */ 1040 return !at || !strcmp(at, "@0"); 1041 } 1042 EXPORT_SYMBOL_GPL(graph_util_is_ports0); 1043 1044 static int graph_get_dai_id(struct device_node *ep) 1045 { 1046 struct device_node *node __free(device_node) = of_graph_get_port_parent(ep); 1047 struct device_node *port __free(device_node) = of_get_parent(ep); 1048 struct of_endpoint info; 1049 int i, id; 1050 int ret; 1051 1052 /* use driver specified DAI ID if exist */ 1053 ret = snd_soc_get_dai_id(ep); 1054 if (ret != -ENOTSUPP) 1055 return ret; 1056 1057 /* use endpoint/port reg if exist */ 1058 ret = of_graph_parse_endpoint(ep, &info); 1059 if (ret == 0) { 1060 /* 1061 * Because it will count port/endpoint if it doesn't have "reg". 1062 * But, we can't judge whether it has "no reg", or "reg = <0>" 1063 * only of_graph_parse_endpoint(). 1064 * We need to check "reg" property 1065 */ 1066 1067 /* check port first */ 1068 ret = of_property_present(port, "reg"); 1069 if (ret) 1070 return info.port; 1071 1072 /* check endpoint 2nd as backup */ 1073 if (of_property_present(ep, "reg")) 1074 return info.id; 1075 } 1076 1077 /* 1078 * Non HDMI sound case, counting port/endpoint on its DT 1079 * is enough. Let's count it. 1080 */ 1081 i = 0; 1082 id = -1; 1083 for_each_of_graph_port(node, p) { 1084 if (port == p) { 1085 id = i; 1086 break; 1087 } 1088 i++; 1089 } 1090 1091 if (id < 0) 1092 return -ENODEV; 1093 1094 return id; 1095 } 1096 1097 int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep, 1098 struct snd_soc_dai_link_component *dlc, int *is_single_link) 1099 { 1100 struct device *dev = simple_priv_to_dev(priv); 1101 struct device_node *node; 1102 struct of_phandle_args args = {}; 1103 struct snd_soc_dai_link_component resolved_dlc = {}; 1104 struct snd_soc_dai *dai; 1105 const char *fallback_dai_name; 1106 int ret; 1107 1108 if (!ep) 1109 return 0; 1110 1111 node = of_graph_get_port_parent(ep); 1112 1113 /* 1114 * Try to find from DAI node 1115 */ 1116 args.np = ep; 1117 dai = snd_soc_get_dai_via_args(&args); 1118 if (dai) { 1119 const char *dai_name = snd_soc_dai_name_get(dai); 1120 const struct of_phandle_args *dai_args = snd_soc_copy_dai_args(dev, &args); 1121 1122 ret = -ENOMEM; 1123 if (!dai_args) 1124 goto err; 1125 1126 dlc->of_node = node; 1127 dlc->dai_name = dai_name; 1128 dlc->dai_args = dai_args; 1129 } else { 1130 /* Get dai->name */ 1131 args.np = node; 1132 args.args[0] = graph_get_dai_id(ep); 1133 args.args_count = (of_graph_get_endpoint_count(node) > 1); 1134 1135 ret = snd_soc_get_dlc(&args, &resolved_dlc); 1136 if (ret < 0) 1137 goto err; 1138 1139 /* Keep fallback dai_name valid across component rebind */ 1140 fallback_dai_name = resolved_dlc.dai_name; 1141 if (fallback_dai_name) { 1142 fallback_dai_name = devm_kstrdup_const(dev, fallback_dai_name, 1143 GFP_KERNEL); 1144 ret = -ENOMEM; 1145 if (!fallback_dai_name) 1146 goto err; 1147 } 1148 1149 dlc->of_node = resolved_dlc.of_node; 1150 dlc->dai_name = fallback_dai_name; 1151 dlc->dai_args = resolved_dlc.dai_args; 1152 } 1153 1154 if (is_single_link) 1155 *is_single_link = of_graph_get_endpoint_count(node) == 1; 1156 ret = 0; 1157 err: 1158 if (ret < 0) 1159 of_node_put(node); 1160 1161 return simple_ret(priv, ret); 1162 } 1163 EXPORT_SYMBOL_GPL(graph_util_parse_dai); 1164 1165 void graph_util_parse_link_direction(struct device_node *np, 1166 bool *playback_only, bool *capture_only) 1167 { 1168 bool is_playback_only = of_property_read_bool(np, "playback-only"); 1169 bool is_capture_only = of_property_read_bool(np, "capture-only"); 1170 1171 if (playback_only && is_playback_only) 1172 *playback_only = is_playback_only; 1173 if (capture_only && is_capture_only) 1174 *capture_only = is_capture_only; 1175 } 1176 EXPORT_SYMBOL_GPL(graph_util_parse_link_direction); 1177 1178 static enum snd_soc_trigger_order 1179 __graph_util_parse_trigger_order(struct simple_util_priv *priv, 1180 struct device_node *np, 1181 const char *prop) 1182 { 1183 u32 val[SND_SOC_TRIGGER_SIZE]; 1184 int ret; 1185 1186 ret = of_property_read_u32_array(np, prop, val, SND_SOC_TRIGGER_SIZE); 1187 if (ret == 0) { 1188 struct device *dev = simple_priv_to_dev(priv); 1189 u32 order = (val[0] << 8) + 1190 (val[1] << 4) + 1191 (val[2]); 1192 1193 switch (order) { 1194 case (SND_SOC_TRIGGER_LINK << 8) + 1195 (SND_SOC_TRIGGER_COMPONENT << 4) + 1196 (SND_SOC_TRIGGER_DAI): 1197 return SND_SOC_TRIGGER_ORDER_DEFAULT; 1198 1199 case (SND_SOC_TRIGGER_LINK << 8) + 1200 (SND_SOC_TRIGGER_DAI << 4) + 1201 (SND_SOC_TRIGGER_COMPONENT): 1202 return SND_SOC_TRIGGER_ORDER_LDC; 1203 1204 default: 1205 dev_err(dev, "unsupported trigger order [0x%x]\n", order); 1206 } 1207 } 1208 1209 /* SND_SOC_TRIGGER_ORDER_MAX means error */ 1210 return SND_SOC_TRIGGER_ORDER_MAX; 1211 } 1212 1213 void graph_util_parse_trigger_order(struct simple_util_priv *priv, 1214 struct device_node *np, 1215 enum snd_soc_trigger_order *trigger_start, 1216 enum snd_soc_trigger_order *trigger_stop) 1217 { 1218 static enum snd_soc_trigger_order order; 1219 1220 /* 1221 * We can use it like below 1222 * 1223 * #include <dt-bindings/sound/audio-graph.h> 1224 * 1225 * link-trigger-order = <SND_SOC_TRIGGER_LINK 1226 * SND_SOC_TRIGGER_COMPONENT 1227 * SND_SOC_TRIGGER_DAI>; 1228 */ 1229 1230 order = __graph_util_parse_trigger_order(priv, np, "link-trigger-order"); 1231 if (order < SND_SOC_TRIGGER_ORDER_MAX) { 1232 *trigger_start = order; 1233 *trigger_stop = order; 1234 } 1235 1236 order = __graph_util_parse_trigger_order(priv, np, "link-trigger-order-start"); 1237 if (order < SND_SOC_TRIGGER_ORDER_MAX) 1238 *trigger_start = order; 1239 1240 order = __graph_util_parse_trigger_order(priv, np, "link-trigger-order-stop"); 1241 if (order < SND_SOC_TRIGGER_ORDER_MAX) 1242 *trigger_stop = order; 1243 1244 return; 1245 } 1246 EXPORT_SYMBOL_GPL(graph_util_parse_trigger_order); 1247 1248 /* Module information */ 1249 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 1250 MODULE_DESCRIPTION("ALSA SoC Simple Card Utils"); 1251 MODULE_LICENSE("GPL v2"); 1252