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