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