topology.c (59161B)
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2// 3// This file is provided under a dual BSD/GPLv2 license. When using or 4// redistributing this file, you may do so under either license. 5// 6// Copyright(c) 2018 Intel Corporation. All rights reserved. 7// 8// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 9// 10 11#include <linux/bits.h> 12#include <linux/device.h> 13#include <linux/errno.h> 14#include <linux/firmware.h> 15#include <linux/workqueue.h> 16#include <sound/tlv.h> 17#include <uapi/sound/sof/tokens.h> 18#include "sof-priv.h" 19#include "sof-audio.h" 20#include "ops.h" 21 22#define COMP_ID_UNASSIGNED 0xffffffff 23/* 24 * Constants used in the computation of linear volume gain 25 * from dB gain 20th root of 10 in Q1.16 fixed-point notation 26 */ 27#define VOL_TWENTIETH_ROOT_OF_TEN 73533 28/* 40th root of 10 in Q1.16 fixed-point notation*/ 29#define VOL_FORTIETH_ROOT_OF_TEN 69419 30 31/* 0.5 dB step value in topology TLV */ 32#define VOL_HALF_DB_STEP 50 33 34/* TLV data items */ 35#define TLV_MIN 0 36#define TLV_STEP 1 37#define TLV_MUTE 2 38 39/* size of tplg abi in byte */ 40#define SOF_TPLG_ABI_SIZE 3 41 42/** 43 * sof_update_ipc_object - Parse multiple sets of tokens within the token array associated with the 44 * token ID. 45 * @scomp: pointer to SOC component 46 * @object: target IPC struct to save the parsed values 47 * @token_id: token ID for the token array to be searched 48 * @tuples: pointer to the tuples array 49 * @num_tuples: number of tuples in the tuples array 50 * @object_size: size of the object 51 * @token_instance_num: number of times the same @token_id needs to be parsed i.e. the function 52 * looks for @token_instance_num of each token in the token array associated 53 * with the @token_id 54 */ 55int sof_update_ipc_object(struct snd_soc_component *scomp, void *object, enum sof_tokens token_id, 56 struct snd_sof_tuple *tuples, int num_tuples, 57 size_t object_size, int token_instance_num) 58{ 59 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 60 const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; 61 const struct sof_token_info *token_list = ipc_tplg_ops->token_list; 62 const struct sof_topology_token *tokens; 63 int i, j; 64 65 if (token_list[token_id].count < 0) { 66 dev_err(scomp->dev, "Invalid token count for token ID: %d\n", token_id); 67 return -EINVAL; 68 } 69 70 /* No tokens to match */ 71 if (!token_list[token_id].count) 72 return 0; 73 74 tokens = token_list[token_id].tokens; 75 if (!tokens) { 76 dev_err(scomp->dev, "Invalid tokens for token id: %d\n", token_id); 77 return -EINVAL; 78 } 79 80 for (i = 0; i < token_list[token_id].count; i++) { 81 int offset = 0; 82 int num_tokens_matched = 0; 83 84 for (j = 0; j < num_tuples; j++) { 85 if (tokens[i].token == tuples[j].token) { 86 switch (tokens[i].type) { 87 case SND_SOC_TPLG_TUPLE_TYPE_WORD: 88 { 89 u32 *val = (u32 *)((u8 *)object + tokens[i].offset + 90 offset); 91 92 *val = tuples[j].value.v; 93 break; 94 } 95 case SND_SOC_TPLG_TUPLE_TYPE_SHORT: 96 case SND_SOC_TPLG_TUPLE_TYPE_BOOL: 97 { 98 u16 *val = (u16 *)((u8 *)object + tokens[i].offset + 99 offset); 100 101 *val = (u16)tuples[j].value.v; 102 break; 103 } 104 case SND_SOC_TPLG_TUPLE_TYPE_STRING: 105 { 106 if (!tokens[i].get_token) { 107 dev_err(scomp->dev, 108 "get_token not defined for token %d in %s\n", 109 tokens[i].token, token_list[token_id].name); 110 return -EINVAL; 111 } 112 113 tokens[i].get_token((void *)tuples[j].value.s, object, 114 tokens[i].offset + offset); 115 break; 116 } 117 default: 118 break; 119 } 120 121 num_tokens_matched++; 122 123 /* found all required sets of current token. Move to the next one */ 124 if (!(num_tokens_matched % token_instance_num)) 125 break; 126 127 /* move to the next object */ 128 offset += object_size; 129 } 130 } 131 } 132 133 return 0; 134} 135 136static inline int get_tlv_data(const int *p, int tlv[SOF_TLV_ITEMS]) 137{ 138 /* we only support dB scale TLV type at the moment */ 139 if ((int)p[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE) 140 return -EINVAL; 141 142 /* min value in topology tlv data is multiplied by 100 */ 143 tlv[TLV_MIN] = (int)p[SNDRV_CTL_TLVO_DB_SCALE_MIN] / 100; 144 145 /* volume steps */ 146 tlv[TLV_STEP] = (int)(p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] & 147 TLV_DB_SCALE_MASK); 148 149 /* mute ON/OFF */ 150 if ((p[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] & 151 TLV_DB_SCALE_MUTE) == 0) 152 tlv[TLV_MUTE] = 0; 153 else 154 tlv[TLV_MUTE] = 1; 155 156 return 0; 157} 158 159/* 160 * Function to truncate an unsigned 64-bit number 161 * by x bits and return 32-bit unsigned number. This 162 * function also takes care of rounding while truncating 163 */ 164static inline u32 vol_shift_64(u64 i, u32 x) 165{ 166 /* do not truncate more than 32 bits */ 167 if (x > 32) 168 x = 32; 169 170 if (x == 0) 171 return (u32)i; 172 173 return (u32)(((i >> (x - 1)) + 1) >> 1); 174} 175 176/* 177 * Function to compute a ^ exp where, 178 * a is a fractional number represented by a fixed-point 179 * integer with a fractional world length of "fwl" 180 * exp is an integer 181 * fwl is the fractional word length 182 * Return value is a fractional number represented by a 183 * fixed-point integer with a fractional word length of "fwl" 184 */ 185static u32 vol_pow32(u32 a, int exp, u32 fwl) 186{ 187 int i, iter; 188 u32 power = 1 << fwl; 189 u64 numerator; 190 191 /* if exponent is 0, return 1 */ 192 if (exp == 0) 193 return power; 194 195 /* determine the number of iterations based on the exponent */ 196 if (exp < 0) 197 iter = exp * -1; 198 else 199 iter = exp; 200 201 /* mutiply a "iter" times to compute power */ 202 for (i = 0; i < iter; i++) { 203 /* 204 * Product of 2 Qx.fwl fixed-point numbers yields a Q2*x.2*fwl 205 * Truncate product back to fwl fractional bits with rounding 206 */ 207 power = vol_shift_64((u64)power * a, fwl); 208 } 209 210 if (exp > 0) { 211 /* if exp is positive, return the result */ 212 return power; 213 } 214 215 /* if exp is negative, return the multiplicative inverse */ 216 numerator = (u64)1 << (fwl << 1); 217 do_div(numerator, power); 218 219 return (u32)numerator; 220} 221 222/* 223 * Function to calculate volume gain from TLV data. 224 * This function can only handle gain steps that are multiples of 0.5 dB 225 */ 226u32 vol_compute_gain(u32 value, int *tlv) 227{ 228 int dB_gain; 229 u32 linear_gain; 230 int f_step; 231 232 /* mute volume */ 233 if (value == 0 && tlv[TLV_MUTE]) 234 return 0; 235 236 /* 237 * compute dB gain from tlv. tlv_step 238 * in topology is multiplied by 100 239 */ 240 dB_gain = tlv[TLV_MIN] + (value * tlv[TLV_STEP]) / 100; 241 242 /* 243 * compute linear gain represented by fixed-point 244 * int with VOLUME_FWL fractional bits 245 */ 246 linear_gain = vol_pow32(VOL_TWENTIETH_ROOT_OF_TEN, dB_gain, VOLUME_FWL); 247 248 /* extract the fractional part of volume step */ 249 f_step = tlv[TLV_STEP] - (tlv[TLV_STEP] / 100); 250 251 /* if volume step is an odd multiple of 0.5 dB */ 252 if (f_step == VOL_HALF_DB_STEP && (value & 1)) 253 linear_gain = vol_shift_64((u64)linear_gain * 254 VOL_FORTIETH_ROOT_OF_TEN, 255 VOLUME_FWL); 256 257 return linear_gain; 258} 259 260/* 261 * Set up volume table for kcontrols from tlv data 262 * "size" specifies the number of entries in the table 263 */ 264static int set_up_volume_table(struct snd_sof_control *scontrol, 265 int tlv[SOF_TLV_ITEMS], int size) 266{ 267 struct snd_soc_component *scomp = scontrol->scomp; 268 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 269 const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; 270 271 if (tplg_ops->control->set_up_volume_table) 272 return tplg_ops->control->set_up_volume_table(scontrol, tlv, size); 273 274 dev_err(scomp->dev, "Mandatory op %s not set\n", __func__); 275 return -EINVAL; 276} 277 278struct sof_dai_types { 279 const char *name; 280 enum sof_ipc_dai_type type; 281}; 282 283static const struct sof_dai_types sof_dais[] = { 284 {"SSP", SOF_DAI_INTEL_SSP}, 285 {"HDA", SOF_DAI_INTEL_HDA}, 286 {"DMIC", SOF_DAI_INTEL_DMIC}, 287 {"ALH", SOF_DAI_INTEL_ALH}, 288 {"SAI", SOF_DAI_IMX_SAI}, 289 {"ESAI", SOF_DAI_IMX_ESAI}, 290 {"ACP", SOF_DAI_AMD_BT}, 291 {"ACPSP", SOF_DAI_AMD_SP}, 292 {"ACPDMIC", SOF_DAI_AMD_DMIC}, 293 {"AFE", SOF_DAI_MEDIATEK_AFE}, 294}; 295 296static enum sof_ipc_dai_type find_dai(const char *name) 297{ 298 int i; 299 300 for (i = 0; i < ARRAY_SIZE(sof_dais); i++) { 301 if (strcmp(name, sof_dais[i].name) == 0) 302 return sof_dais[i].type; 303 } 304 305 return SOF_DAI_INTEL_NONE; 306} 307 308/* 309 * Supported Frame format types and lookup, add new ones to end of list. 310 */ 311 312struct sof_frame_types { 313 const char *name; 314 enum sof_ipc_frame frame; 315}; 316 317static const struct sof_frame_types sof_frames[] = { 318 {"s16le", SOF_IPC_FRAME_S16_LE}, 319 {"s24le", SOF_IPC_FRAME_S24_4LE}, 320 {"s32le", SOF_IPC_FRAME_S32_LE}, 321 {"float", SOF_IPC_FRAME_FLOAT}, 322}; 323 324static enum sof_ipc_frame find_format(const char *name) 325{ 326 int i; 327 328 for (i = 0; i < ARRAY_SIZE(sof_frames); i++) { 329 if (strcmp(name, sof_frames[i].name) == 0) 330 return sof_frames[i].frame; 331 } 332 333 /* use s32le if nothing is specified */ 334 return SOF_IPC_FRAME_S32_LE; 335} 336 337int get_token_u32(void *elem, void *object, u32 offset) 338{ 339 struct snd_soc_tplg_vendor_value_elem *velem = elem; 340 u32 *val = (u32 *)((u8 *)object + offset); 341 342 *val = le32_to_cpu(velem->value); 343 return 0; 344} 345 346int get_token_u16(void *elem, void *object, u32 offset) 347{ 348 struct snd_soc_tplg_vendor_value_elem *velem = elem; 349 u16 *val = (u16 *)((u8 *)object + offset); 350 351 *val = (u16)le32_to_cpu(velem->value); 352 return 0; 353} 354 355int get_token_uuid(void *elem, void *object, u32 offset) 356{ 357 struct snd_soc_tplg_vendor_uuid_elem *velem = elem; 358 u8 *dst = (u8 *)object + offset; 359 360 memcpy(dst, velem->uuid, UUID_SIZE); 361 362 return 0; 363} 364 365int get_token_comp_format(void *elem, void *object, u32 offset) 366{ 367 u32 *val = (u32 *)((u8 *)object + offset); 368 369 *val = find_format((const char *)elem); 370 return 0; 371} 372 373int get_token_dai_type(void *elem, void *object, u32 offset) 374{ 375 u32 *val = (u32 *)((u8 *)object + offset); 376 377 *val = find_dai((const char *)elem); 378 return 0; 379} 380 381/* PCM */ 382static const struct sof_topology_token stream_tokens[] = { 383 {SOF_TKN_STREAM_PLAYBACK_COMPATIBLE_D0I3, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16, 384 offsetof(struct snd_sof_pcm, stream[0].d0i3_compatible)}, 385 {SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16, 386 offsetof(struct snd_sof_pcm, stream[1].d0i3_compatible)}, 387}; 388 389/* Leds */ 390static const struct sof_topology_token led_tokens[] = { 391 {SOF_TKN_MUTE_LED_USE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 392 offsetof(struct snd_sof_led_control, use_led)}, 393 {SOF_TKN_MUTE_LED_DIRECTION, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 394 offsetof(struct snd_sof_led_control, direction)}, 395}; 396 397/** 398 * sof_parse_uuid_tokens - Parse multiple sets of UUID tokens 399 * @scomp: pointer to soc component 400 * @object: target ipc struct for parsed values 401 * @offset: offset within the object pointer 402 * @tokens: array of struct sof_topology_token containing the tokens to be matched 403 * @num_tokens: number of tokens in tokens array 404 * @array: source pointer to consecutive vendor arrays in topology 405 * 406 * This function parses multiple sets of string type tokens in vendor arrays 407 */ 408static int sof_parse_uuid_tokens(struct snd_soc_component *scomp, 409 void *object, size_t offset, 410 const struct sof_topology_token *tokens, int num_tokens, 411 struct snd_soc_tplg_vendor_array *array) 412{ 413 struct snd_soc_tplg_vendor_uuid_elem *elem; 414 int found = 0; 415 int i, j; 416 417 /* parse element by element */ 418 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { 419 elem = &array->uuid[i]; 420 421 /* search for token */ 422 for (j = 0; j < num_tokens; j++) { 423 /* match token type */ 424 if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_UUID) 425 continue; 426 427 /* match token id */ 428 if (tokens[j].token != le32_to_cpu(elem->token)) 429 continue; 430 431 /* matched - now load token */ 432 tokens[j].get_token(elem, object, 433 offset + tokens[j].offset); 434 435 found++; 436 } 437 } 438 439 return found; 440} 441 442/** 443 * sof_copy_tuples - Parse tokens and copy them to the @tuples array 444 * @sdev: pointer to struct snd_sof_dev 445 * @array: source pointer to consecutive vendor arrays in topology 446 * @array_size: size of @array 447 * @token_id: Token ID associated with a token array 448 * @token_instance_num: number of times the same @token_id needs to be parsed i.e. the function 449 * looks for @token_instance_num of each token in the token array associated 450 * with the @token_id 451 * @tuples: tuples array to copy the matched tuples to 452 * @tuples_size: size of @tuples 453 * @num_copied_tuples: pointer to the number of copied tuples in the tuples array 454 * 455 */ 456static int sof_copy_tuples(struct snd_sof_dev *sdev, struct snd_soc_tplg_vendor_array *array, 457 int array_size, u32 token_id, int token_instance_num, 458 struct snd_sof_tuple *tuples, int tuples_size, int *num_copied_tuples) 459{ 460 const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; 461 const struct sof_token_info *token_list = ipc_tplg_ops->token_list; 462 const struct sof_topology_token *tokens; 463 int found = 0; 464 int num_tokens, asize; 465 int i, j; 466 467 /* nothing to do if token_list is NULL */ 468 if (!token_list) 469 return 0; 470 471 if (!tuples || !num_copied_tuples) { 472 dev_err(sdev->dev, "Invalid tuples array\n"); 473 return -EINVAL; 474 } 475 476 tokens = token_list[token_id].tokens; 477 num_tokens = token_list[token_id].count; 478 479 if (!tokens) { 480 dev_err(sdev->dev, "No token array defined for token ID: %d\n", token_id); 481 return -EINVAL; 482 } 483 484 /* check if there's space in the tuples array for new tokens */ 485 if (*num_copied_tuples >= tuples_size) { 486 dev_err(sdev->dev, "No space in tuples array for new tokens from %s", 487 token_list[token_id].name); 488 return -EINVAL; 489 } 490 491 while (array_size > 0 && found < num_tokens * token_instance_num) { 492 asize = le32_to_cpu(array->size); 493 494 /* validate asize */ 495 if (asize < 0) { 496 dev_err(sdev->dev, "Invalid array size 0x%x\n", asize); 497 return -EINVAL; 498 } 499 500 /* make sure there is enough data before parsing */ 501 array_size -= asize; 502 if (array_size < 0) { 503 dev_err(sdev->dev, "Invalid array size 0x%x\n", asize); 504 return -EINVAL; 505 } 506 507 /* parse element by element */ 508 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { 509 /* search for token */ 510 for (j = 0; j < num_tokens; j++) { 511 /* match token type */ 512 if (!(tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_WORD || 513 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_SHORT || 514 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BYTE || 515 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BOOL || 516 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_STRING)) 517 continue; 518 519 if (tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_STRING) { 520 struct snd_soc_tplg_vendor_string_elem *elem; 521 522 elem = &array->string[i]; 523 524 /* match token id */ 525 if (tokens[j].token != le32_to_cpu(elem->token)) 526 continue; 527 528 tuples[*num_copied_tuples].token = tokens[j].token; 529 tuples[*num_copied_tuples].value.s = elem->string; 530 } else { 531 struct snd_soc_tplg_vendor_value_elem *elem; 532 533 elem = &array->value[i]; 534 535 /* match token id */ 536 if (tokens[j].token != le32_to_cpu(elem->token)) 537 continue; 538 539 tuples[*num_copied_tuples].token = tokens[j].token; 540 tuples[*num_copied_tuples].value.v = 541 le32_to_cpu(elem->value); 542 } 543 found++; 544 (*num_copied_tuples)++; 545 546 /* stop if there's no space for any more new tuples */ 547 if (*num_copied_tuples == tuples_size) 548 return 0; 549 } 550 } 551 552 /* next array */ 553 array = (struct snd_soc_tplg_vendor_array *)((u8 *)array + asize); 554 } 555 556 return 0; 557} 558 559/** 560 * sof_parse_string_tokens - Parse multiple sets of tokens 561 * @scomp: pointer to soc component 562 * @object: target ipc struct for parsed values 563 * @offset: offset within the object pointer 564 * @tokens: array of struct sof_topology_token containing the tokens to be matched 565 * @num_tokens: number of tokens in tokens array 566 * @array: source pointer to consecutive vendor arrays in topology 567 * 568 * This function parses multiple sets of string type tokens in vendor arrays 569 */ 570static int sof_parse_string_tokens(struct snd_soc_component *scomp, 571 void *object, int offset, 572 const struct sof_topology_token *tokens, int num_tokens, 573 struct snd_soc_tplg_vendor_array *array) 574{ 575 struct snd_soc_tplg_vendor_string_elem *elem; 576 int found = 0; 577 int i, j; 578 579 /* parse element by element */ 580 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { 581 elem = &array->string[i]; 582 583 /* search for token */ 584 for (j = 0; j < num_tokens; j++) { 585 /* match token type */ 586 if (tokens[j].type != SND_SOC_TPLG_TUPLE_TYPE_STRING) 587 continue; 588 589 /* match token id */ 590 if (tokens[j].token != le32_to_cpu(elem->token)) 591 continue; 592 593 /* matched - now load token */ 594 tokens[j].get_token(elem->string, object, offset + tokens[j].offset); 595 596 found++; 597 } 598 } 599 600 return found; 601} 602 603/** 604 * sof_parse_word_tokens - Parse multiple sets of tokens 605 * @scomp: pointer to soc component 606 * @object: target ipc struct for parsed values 607 * @offset: offset within the object pointer 608 * @tokens: array of struct sof_topology_token containing the tokens to be matched 609 * @num_tokens: number of tokens in tokens array 610 * @array: source pointer to consecutive vendor arrays in topology 611 * 612 * This function parses multiple sets of word type tokens in vendor arrays 613 */ 614static int sof_parse_word_tokens(struct snd_soc_component *scomp, 615 void *object, int offset, 616 const struct sof_topology_token *tokens, int num_tokens, 617 struct snd_soc_tplg_vendor_array *array) 618{ 619 struct snd_soc_tplg_vendor_value_elem *elem; 620 int found = 0; 621 int i, j; 622 623 /* parse element by element */ 624 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { 625 elem = &array->value[i]; 626 627 /* search for token */ 628 for (j = 0; j < num_tokens; j++) { 629 /* match token type */ 630 if (!(tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_WORD || 631 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_SHORT || 632 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BYTE || 633 tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BOOL)) 634 continue; 635 636 /* match token id */ 637 if (tokens[j].token != le32_to_cpu(elem->token)) 638 continue; 639 640 /* load token */ 641 tokens[j].get_token(elem, object, offset + tokens[j].offset); 642 643 found++; 644 } 645 } 646 647 return found; 648} 649 650/** 651 * sof_parse_token_sets - Parse multiple sets of tokens 652 * @scomp: pointer to soc component 653 * @object: target ipc struct for parsed values 654 * @tokens: token definition array describing what tokens to parse 655 * @count: number of tokens in definition array 656 * @array: source pointer to consecutive vendor arrays in topology 657 * @array_size: total size of @array 658 * @token_instance_num: number of times the same tokens needs to be parsed i.e. the function 659 * looks for @token_instance_num of each token in the @tokens 660 * @object_size: offset to next target ipc struct with multiple sets 661 * 662 * This function parses multiple sets of tokens in vendor arrays into 663 * consecutive ipc structs. 664 */ 665static int sof_parse_token_sets(struct snd_soc_component *scomp, 666 void *object, const struct sof_topology_token *tokens, 667 int count, struct snd_soc_tplg_vendor_array *array, 668 int array_size, int token_instance_num, size_t object_size) 669{ 670 size_t offset = 0; 671 int found = 0; 672 int total = 0; 673 int asize; 674 675 while (array_size > 0 && total < count * token_instance_num) { 676 asize = le32_to_cpu(array->size); 677 678 /* validate asize */ 679 if (asize < 0) { /* FIXME: A zero-size array makes no sense */ 680 dev_err(scomp->dev, "error: invalid array size 0x%x\n", 681 asize); 682 return -EINVAL; 683 } 684 685 /* make sure there is enough data before parsing */ 686 array_size -= asize; 687 if (array_size < 0) { 688 dev_err(scomp->dev, "error: invalid array size 0x%x\n", 689 asize); 690 return -EINVAL; 691 } 692 693 /* call correct parser depending on type */ 694 switch (le32_to_cpu(array->type)) { 695 case SND_SOC_TPLG_TUPLE_TYPE_UUID: 696 found += sof_parse_uuid_tokens(scomp, object, offset, tokens, count, 697 array); 698 break; 699 case SND_SOC_TPLG_TUPLE_TYPE_STRING: 700 found += sof_parse_string_tokens(scomp, object, offset, tokens, count, 701 array); 702 break; 703 case SND_SOC_TPLG_TUPLE_TYPE_BOOL: 704 case SND_SOC_TPLG_TUPLE_TYPE_BYTE: 705 case SND_SOC_TPLG_TUPLE_TYPE_WORD: 706 case SND_SOC_TPLG_TUPLE_TYPE_SHORT: 707 found += sof_parse_word_tokens(scomp, object, offset, tokens, count, 708 array); 709 break; 710 default: 711 dev_err(scomp->dev, "error: unknown token type %d\n", 712 array->type); 713 return -EINVAL; 714 } 715 716 /* next array */ 717 array = (struct snd_soc_tplg_vendor_array *)((u8 *)array 718 + asize); 719 720 /* move to next target struct */ 721 if (found >= count) { 722 offset += object_size; 723 total += found; 724 found = 0; 725 } 726 } 727 728 return 0; 729} 730 731/** 732 * sof_parse_tokens - Parse one set of tokens 733 * @scomp: pointer to soc component 734 * @object: target ipc struct for parsed values 735 * @tokens: token definition array describing what tokens to parse 736 * @num_tokens: number of tokens in definition array 737 * @array: source pointer to consecutive vendor arrays in topology 738 * @array_size: total size of @array 739 * 740 * This function parses a single set of tokens in vendor arrays into 741 * consecutive ipc structs. 742 */ 743static int sof_parse_tokens(struct snd_soc_component *scomp, void *object, 744 const struct sof_topology_token *tokens, int num_tokens, 745 struct snd_soc_tplg_vendor_array *array, 746 int array_size) 747 748{ 749 /* 750 * sof_parse_tokens is used when topology contains only a single set of 751 * identical tuples arrays. So additional parameters to 752 * sof_parse_token_sets are sets = 1 (only 1 set) and 753 * object_size = 0 (irrelevant). 754 */ 755 return sof_parse_token_sets(scomp, object, tokens, num_tokens, array, 756 array_size, 1, 0); 757} 758 759/* 760 * Standard Kcontrols. 761 */ 762 763static int sof_control_load_volume(struct snd_soc_component *scomp, 764 struct snd_sof_control *scontrol, 765 struct snd_kcontrol_new *kc, 766 struct snd_soc_tplg_ctl_hdr *hdr) 767{ 768 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 769 struct snd_soc_tplg_mixer_control *mc = 770 container_of(hdr, struct snd_soc_tplg_mixer_control, hdr); 771 int tlv[SOF_TLV_ITEMS]; 772 unsigned int mask; 773 int ret; 774 775 /* validate topology data */ 776 if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN) 777 return -EINVAL; 778 779 /* 780 * If control has more than 2 channels we need to override the info. This is because even if 781 * ASoC layer has defined topology's max channel count to SND_SOC_TPLG_MAX_CHAN = 8, the 782 * pre-defined dapm control types (and related functions) creating the actual control 783 * restrict the channels only to mono or stereo. 784 */ 785 if (le32_to_cpu(mc->num_channels) > 2) 786 kc->info = snd_sof_volume_info; 787 788 scontrol->comp_id = sdev->next_comp_id; 789 scontrol->min_volume_step = le32_to_cpu(mc->min); 790 scontrol->max_volume_step = le32_to_cpu(mc->max); 791 scontrol->num_channels = le32_to_cpu(mc->num_channels); 792 793 scontrol->max = le32_to_cpu(mc->max); 794 if (le32_to_cpu(mc->max) == 1) 795 goto skip; 796 797 /* extract tlv data */ 798 if (!kc->tlv.p || get_tlv_data(kc->tlv.p, tlv) < 0) { 799 dev_err(scomp->dev, "error: invalid TLV data\n"); 800 return -EINVAL; 801 } 802 803 /* set up volume table */ 804 ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1); 805 if (ret < 0) { 806 dev_err(scomp->dev, "error: setting up volume table\n"); 807 return ret; 808 } 809 810skip: 811 /* set up possible led control from mixer private data */ 812 ret = sof_parse_tokens(scomp, &scontrol->led_ctl, led_tokens, 813 ARRAY_SIZE(led_tokens), mc->priv.array, 814 le32_to_cpu(mc->priv.size)); 815 if (ret != 0) { 816 dev_err(scomp->dev, "error: parse led tokens failed %d\n", 817 le32_to_cpu(mc->priv.size)); 818 goto err; 819 } 820 821 if (scontrol->led_ctl.use_led) { 822 mask = scontrol->led_ctl.direction ? SNDRV_CTL_ELEM_ACCESS_MIC_LED : 823 SNDRV_CTL_ELEM_ACCESS_SPK_LED; 824 scontrol->access &= ~SNDRV_CTL_ELEM_ACCESS_LED_MASK; 825 scontrol->access |= mask; 826 kc->access &= ~SNDRV_CTL_ELEM_ACCESS_LED_MASK; 827 kc->access |= mask; 828 sdev->led_present = true; 829 } 830 831 dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n", 832 scontrol->comp_id, scontrol->num_channels); 833 834 return 0; 835 836err: 837 if (le32_to_cpu(mc->max) > 1) 838 kfree(scontrol->volume_table); 839 840 return ret; 841} 842 843static int sof_control_load_enum(struct snd_soc_component *scomp, 844 struct snd_sof_control *scontrol, 845 struct snd_kcontrol_new *kc, 846 struct snd_soc_tplg_ctl_hdr *hdr) 847{ 848 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 849 struct snd_soc_tplg_enum_control *ec = 850 container_of(hdr, struct snd_soc_tplg_enum_control, hdr); 851 852 /* validate topology data */ 853 if (le32_to_cpu(ec->num_channels) > SND_SOC_TPLG_MAX_CHAN) 854 return -EINVAL; 855 856 scontrol->comp_id = sdev->next_comp_id; 857 scontrol->num_channels = le32_to_cpu(ec->num_channels); 858 859 dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n", 860 scontrol->comp_id, scontrol->num_channels, scontrol->comp_id); 861 862 return 0; 863} 864 865static int sof_control_load_bytes(struct snd_soc_component *scomp, 866 struct snd_sof_control *scontrol, 867 struct snd_kcontrol_new *kc, 868 struct snd_soc_tplg_ctl_hdr *hdr) 869{ 870 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 871 struct snd_soc_tplg_bytes_control *control = 872 container_of(hdr, struct snd_soc_tplg_bytes_control, hdr); 873 struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value; 874 size_t priv_size = le32_to_cpu(control->priv.size); 875 876 scontrol->max_size = sbe->max; 877 scontrol->comp_id = sdev->next_comp_id; 878 879 dev_dbg(scomp->dev, "tplg: load kcontrol index %d\n", scontrol->comp_id); 880 881 /* copy the private data */ 882 if (priv_size > 0) { 883 scontrol->priv = kmemdup(control->priv.data, priv_size, GFP_KERNEL); 884 if (!scontrol->priv) 885 return -ENOMEM; 886 887 scontrol->priv_size = priv_size; 888 } 889 890 return 0; 891} 892 893/* external kcontrol init - used for any driver specific init */ 894static int sof_control_load(struct snd_soc_component *scomp, int index, 895 struct snd_kcontrol_new *kc, 896 struct snd_soc_tplg_ctl_hdr *hdr) 897{ 898 struct soc_mixer_control *sm; 899 struct soc_bytes_ext *sbe; 900 struct soc_enum *se; 901 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 902 struct snd_soc_dobj *dobj; 903 struct snd_sof_control *scontrol; 904 int ret; 905 906 dev_dbg(scomp->dev, "tplg: load control type %d name : %s\n", 907 hdr->type, hdr->name); 908 909 scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL); 910 if (!scontrol) 911 return -ENOMEM; 912 913 scontrol->name = kstrdup(hdr->name, GFP_KERNEL); 914 if (!scontrol->name) { 915 kfree(scontrol); 916 return -ENOMEM; 917 } 918 919 scontrol->scomp = scomp; 920 scontrol->access = kc->access; 921 scontrol->info_type = le32_to_cpu(hdr->ops.info); 922 scontrol->index = kc->index; 923 924 switch (le32_to_cpu(hdr->ops.info)) { 925 case SND_SOC_TPLG_CTL_VOLSW: 926 case SND_SOC_TPLG_CTL_VOLSW_SX: 927 case SND_SOC_TPLG_CTL_VOLSW_XR_SX: 928 sm = (struct soc_mixer_control *)kc->private_value; 929 dobj = &sm->dobj; 930 ret = sof_control_load_volume(scomp, scontrol, kc, hdr); 931 break; 932 case SND_SOC_TPLG_CTL_BYTES: 933 sbe = (struct soc_bytes_ext *)kc->private_value; 934 dobj = &sbe->dobj; 935 ret = sof_control_load_bytes(scomp, scontrol, kc, hdr); 936 break; 937 case SND_SOC_TPLG_CTL_ENUM: 938 case SND_SOC_TPLG_CTL_ENUM_VALUE: 939 se = (struct soc_enum *)kc->private_value; 940 dobj = &se->dobj; 941 ret = sof_control_load_enum(scomp, scontrol, kc, hdr); 942 break; 943 case SND_SOC_TPLG_CTL_RANGE: 944 case SND_SOC_TPLG_CTL_STROBE: 945 case SND_SOC_TPLG_DAPM_CTL_VOLSW: 946 case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE: 947 case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT: 948 case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE: 949 case SND_SOC_TPLG_DAPM_CTL_PIN: 950 default: 951 dev_warn(scomp->dev, "control type not supported %d:%d:%d\n", 952 hdr->ops.get, hdr->ops.put, hdr->ops.info); 953 kfree(scontrol->name); 954 kfree(scontrol); 955 return 0; 956 } 957 958 if (ret < 0) { 959 kfree(scontrol->name); 960 kfree(scontrol); 961 return ret; 962 } 963 964 scontrol->led_ctl.led_value = -1; 965 966 dobj->private = scontrol; 967 list_add(&scontrol->list, &sdev->kcontrol_list); 968 return 0; 969} 970 971static int sof_control_unload(struct snd_soc_component *scomp, 972 struct snd_soc_dobj *dobj) 973{ 974 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 975 const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; 976 struct snd_sof_control *scontrol = dobj->private; 977 int ret = 0; 978 979 dev_dbg(scomp->dev, "tplg: unload control name : %s\n", scontrol->name); 980 981 if (ipc_tplg_ops->control_free) { 982 ret = ipc_tplg_ops->control_free(sdev, scontrol); 983 if (ret < 0) 984 dev_err(scomp->dev, "failed to free control: %s\n", scontrol->name); 985 } 986 987 /* free all data before returning in case of error too */ 988 kfree(scontrol->ipc_control_data); 989 kfree(scontrol->priv); 990 kfree(scontrol->name); 991 list_del(&scontrol->list); 992 kfree(scontrol); 993 994 return ret; 995} 996 997/* 998 * DAI Topology 999 */ 1000 1001static int sof_connect_dai_widget(struct snd_soc_component *scomp, 1002 struct snd_soc_dapm_widget *w, 1003 struct snd_soc_tplg_dapm_widget *tw, 1004 struct snd_sof_dai *dai) 1005{ 1006 struct snd_soc_card *card = scomp->card; 1007 struct snd_soc_pcm_runtime *rtd; 1008 struct snd_soc_dai *cpu_dai; 1009 int i; 1010 1011 if (!w->sname) { 1012 dev_err(scomp->dev, "Widget %s does not have stream\n", w->name); 1013 return -EINVAL; 1014 } 1015 1016 list_for_each_entry(rtd, &card->rtd_list, list) { 1017 dev_vdbg(scomp->dev, "tplg: check widget: %s stream: %s dai stream: %s\n", 1018 w->name, w->sname, rtd->dai_link->stream_name); 1019 1020 /* does stream match DAI link ? */ 1021 if (!rtd->dai_link->stream_name || 1022 strcmp(w->sname, rtd->dai_link->stream_name)) 1023 continue; 1024 1025 switch (w->id) { 1026 case snd_soc_dapm_dai_out: 1027 for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 1028 /* 1029 * Please create DAI widget in the right order 1030 * to ensure BE will connect to the right DAI 1031 * widget. 1032 */ 1033 if (!cpu_dai->capture_widget) { 1034 cpu_dai->capture_widget = w; 1035 break; 1036 } 1037 } 1038 if (i == rtd->num_cpus) { 1039 dev_err(scomp->dev, "error: can't find BE for DAI %s\n", 1040 w->name); 1041 1042 return -EINVAL; 1043 } 1044 dai->name = rtd->dai_link->name; 1045 dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n", 1046 w->name, rtd->dai_link->name); 1047 break; 1048 case snd_soc_dapm_dai_in: 1049 for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 1050 /* 1051 * Please create DAI widget in the right order 1052 * to ensure BE will connect to the right DAI 1053 * widget. 1054 */ 1055 if (!cpu_dai->playback_widget) { 1056 cpu_dai->playback_widget = w; 1057 break; 1058 } 1059 } 1060 if (i == rtd->num_cpus) { 1061 dev_err(scomp->dev, "error: can't find BE for DAI %s\n", 1062 w->name); 1063 1064 return -EINVAL; 1065 } 1066 dai->name = rtd->dai_link->name; 1067 dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n", 1068 w->name, rtd->dai_link->name); 1069 break; 1070 default: 1071 break; 1072 } 1073 } 1074 1075 /* check we have a connection */ 1076 if (!dai->name) { 1077 dev_err(scomp->dev, "error: can't connect DAI %s stream %s\n", 1078 w->name, w->sname); 1079 return -EINVAL; 1080 } 1081 1082 return 0; 1083} 1084 1085static void sof_disconnect_dai_widget(struct snd_soc_component *scomp, 1086 struct snd_soc_dapm_widget *w) 1087{ 1088 struct snd_soc_card *card = scomp->card; 1089 struct snd_soc_pcm_runtime *rtd; 1090 struct snd_soc_dai *cpu_dai; 1091 int i; 1092 1093 if (!w->sname) 1094 return; 1095 1096 list_for_each_entry(rtd, &card->rtd_list, list) { 1097 /* does stream match DAI link ? */ 1098 if (!rtd->dai_link->stream_name || 1099 strcmp(w->sname, rtd->dai_link->stream_name)) 1100 continue; 1101 1102 switch (w->id) { 1103 case snd_soc_dapm_dai_out: 1104 for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 1105 if (cpu_dai->capture_widget == w) { 1106 cpu_dai->capture_widget = NULL; 1107 break; 1108 } 1109 } 1110 break; 1111 case snd_soc_dapm_dai_in: 1112 for_each_rtd_cpu_dais(rtd, i, cpu_dai) { 1113 if (cpu_dai->playback_widget == w) { 1114 cpu_dai->playback_widget = NULL; 1115 break; 1116 } 1117 } 1118 break; 1119 default: 1120 break; 1121 } 1122 } 1123} 1124 1125/* bind PCM ID to host component ID */ 1126static int spcm_bind(struct snd_soc_component *scomp, struct snd_sof_pcm *spcm, 1127 int dir) 1128{ 1129 struct snd_sof_widget *host_widget; 1130 1131 host_widget = snd_sof_find_swidget_sname(scomp, 1132 spcm->pcm.caps[dir].name, 1133 dir); 1134 if (!host_widget) { 1135 dev_err(scomp->dev, "can't find host comp to bind pcm\n"); 1136 return -EINVAL; 1137 } 1138 1139 spcm->stream[dir].comp_id = host_widget->comp_id; 1140 1141 return 0; 1142} 1143 1144static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_sof_widget *swidget, 1145 struct snd_soc_tplg_dapm_widget *tw, 1146 enum sof_tokens *object_token_list, int count) 1147{ 1148 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1149 const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; 1150 const struct sof_token_info *token_list = ipc_tplg_ops->token_list; 1151 struct snd_soc_tplg_private *private = &tw->priv; 1152 int num_tuples = 0; 1153 int ret, i; 1154 1155 if (count > 0 && !object_token_list) { 1156 dev_err(scomp->dev, "No token list for widget %s\n", swidget->widget->name); 1157 return -EINVAL; 1158 } 1159 1160 /* calculate max size of tuples array */ 1161 for (i = 0; i < count; i++) 1162 num_tuples += token_list[object_token_list[i]].count; 1163 1164 /* allocate memory for tuples array */ 1165 swidget->tuples = kcalloc(num_tuples, sizeof(*swidget->tuples), GFP_KERNEL); 1166 if (!swidget->tuples) 1167 return -ENOMEM; 1168 1169 /* parse token list for widget */ 1170 for (i = 0; i < count; i++) { 1171 if (object_token_list[i] >= SOF_TOKEN_COUNT) { 1172 dev_err(scomp->dev, "Invalid token id %d for widget %s\n", 1173 object_token_list[i], swidget->widget->name); 1174 ret = -EINVAL; 1175 goto err; 1176 } 1177 1178 /* parse and save UUID in swidget */ 1179 if (object_token_list[i] == SOF_COMP_EXT_TOKENS) { 1180 ret = sof_parse_tokens(scomp, swidget, 1181 token_list[object_token_list[i]].tokens, 1182 token_list[object_token_list[i]].count, 1183 private->array, le32_to_cpu(private->size)); 1184 if (ret < 0) { 1185 dev_err(scomp->dev, "Failed parsing %s for widget %s\n", 1186 token_list[object_token_list[i]].name, 1187 swidget->widget->name); 1188 goto err; 1189 } 1190 1191 continue; 1192 } 1193 1194 /* copy one set of tuples per token ID into swidget->tuples */ 1195 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size), 1196 object_token_list[i], 1, swidget->tuples, 1197 num_tuples, &swidget->num_tuples); 1198 if (ret < 0) { 1199 dev_err(scomp->dev, "Failed parsing %s for widget %s err: %d\n", 1200 token_list[object_token_list[i]].name, swidget->widget->name, ret); 1201 goto err; 1202 } 1203 } 1204 1205 return 0; 1206err: 1207 kfree(swidget->tuples); 1208 return ret; 1209} 1210 1211static int sof_get_token_value(u32 token_id, struct snd_sof_tuple *tuples, int num_tuples) 1212{ 1213 int i; 1214 1215 if (!tuples) 1216 return -EINVAL; 1217 1218 for (i = 0; i < num_tuples; i++) { 1219 if (tuples[i].token == token_id) 1220 return tuples[i].value.v; 1221 } 1222 1223 return -EINVAL; 1224} 1225 1226/* external widget init - used for any driver specific init */ 1227static int sof_widget_ready(struct snd_soc_component *scomp, int index, 1228 struct snd_soc_dapm_widget *w, 1229 struct snd_soc_tplg_dapm_widget *tw) 1230{ 1231 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1232 const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; 1233 const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget; 1234 struct snd_sof_widget *swidget; 1235 struct snd_sof_dai *dai; 1236 enum sof_tokens *token_list; 1237 int token_list_size; 1238 int ret = 0; 1239 1240 swidget = kzalloc(sizeof(*swidget), GFP_KERNEL); 1241 if (!swidget) 1242 return -ENOMEM; 1243 1244 swidget->scomp = scomp; 1245 swidget->widget = w; 1246 swidget->comp_id = sdev->next_comp_id++; 1247 swidget->complete = 0; 1248 swidget->id = w->id; 1249 swidget->pipeline_id = index; 1250 swidget->private = NULL; 1251 1252 dev_dbg(scomp->dev, "tplg: ready widget id %d pipe %d type %d name : %s stream %s\n", 1253 swidget->comp_id, index, swidget->id, tw->name, 1254 strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 1255 ? tw->sname : "none"); 1256 1257 token_list = widget_ops[w->id].token_list; 1258 token_list_size = widget_ops[w->id].token_list_size; 1259 1260 /* handle any special case widgets */ 1261 switch (w->id) { 1262 case snd_soc_dapm_dai_in: 1263 case snd_soc_dapm_dai_out: 1264 dai = kzalloc(sizeof(*dai), GFP_KERNEL); 1265 if (!dai) { 1266 kfree(swidget); 1267 return -ENOMEM; 1268 1269 } 1270 1271 ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size); 1272 if (!ret) 1273 ret = sof_connect_dai_widget(scomp, w, tw, dai); 1274 if (ret < 0) { 1275 kfree(dai); 1276 break; 1277 } 1278 list_add(&dai->list, &sdev->dai_list); 1279 swidget->private = dai; 1280 break; 1281 case snd_soc_dapm_effect: 1282 /* check we have some tokens - we need at least process type */ 1283 if (le32_to_cpu(tw->priv.size) == 0) { 1284 dev_err(scomp->dev, "error: process tokens not found\n"); 1285 ret = -EINVAL; 1286 break; 1287 } 1288 ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size); 1289 break; 1290 case snd_soc_dapm_pga: 1291 if (!le32_to_cpu(tw->num_kcontrols)) { 1292 dev_err(scomp->dev, "invalid kcontrol count %d for volume\n", 1293 tw->num_kcontrols); 1294 ret = -EINVAL; 1295 break; 1296 } 1297 1298 fallthrough; 1299 case snd_soc_dapm_mixer: 1300 case snd_soc_dapm_buffer: 1301 case snd_soc_dapm_scheduler: 1302 case snd_soc_dapm_aif_out: 1303 case snd_soc_dapm_aif_in: 1304 case snd_soc_dapm_src: 1305 case snd_soc_dapm_asrc: 1306 case snd_soc_dapm_siggen: 1307 case snd_soc_dapm_mux: 1308 case snd_soc_dapm_demux: 1309 ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size); 1310 break; 1311 case snd_soc_dapm_switch: 1312 case snd_soc_dapm_dai_link: 1313 case snd_soc_dapm_kcontrol: 1314 default: 1315 dev_dbg(scomp->dev, "widget type %d name %s not handled\n", swidget->id, tw->name); 1316 break; 1317 } 1318 1319 if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) { 1320 swidget->core = SOF_DSP_PRIMARY_CORE; 1321 } else { 1322 int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples, 1323 swidget->num_tuples); 1324 1325 if (core >= 0) 1326 swidget->core = core; 1327 } 1328 1329 /* check token parsing reply */ 1330 if (ret < 0) { 1331 dev_err(scomp->dev, 1332 "error: failed to add widget id %d type %d name : %s stream %s\n", 1333 tw->shift, swidget->id, tw->name, 1334 strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 1335 ? tw->sname : "none"); 1336 kfree(swidget); 1337 return ret; 1338 } 1339 1340 /* bind widget to external event */ 1341 if (tw->event_type) { 1342 if (widget_ops[w->id].bind_event) { 1343 ret = widget_ops[w->id].bind_event(scomp, swidget, 1344 le16_to_cpu(tw->event_type)); 1345 if (ret) { 1346 dev_err(scomp->dev, "widget event binding failed for %s\n", 1347 swidget->widget->name); 1348 kfree(swidget->private); 1349 kfree(swidget->tuples); 1350 kfree(swidget); 1351 return ret; 1352 } 1353 } 1354 } 1355 1356 w->dobj.private = swidget; 1357 list_add(&swidget->list, &sdev->widget_list); 1358 return ret; 1359} 1360 1361static int sof_route_unload(struct snd_soc_component *scomp, 1362 struct snd_soc_dobj *dobj) 1363{ 1364 struct snd_sof_route *sroute; 1365 1366 sroute = dobj->private; 1367 if (!sroute) 1368 return 0; 1369 1370 /* free sroute and its private data */ 1371 kfree(sroute->private); 1372 list_del(&sroute->list); 1373 kfree(sroute); 1374 1375 return 0; 1376} 1377 1378static int sof_widget_unload(struct snd_soc_component *scomp, 1379 struct snd_soc_dobj *dobj) 1380{ 1381 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1382 const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; 1383 const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget; 1384 const struct snd_kcontrol_new *kc; 1385 struct snd_soc_dapm_widget *widget; 1386 struct snd_sof_control *scontrol; 1387 struct snd_sof_widget *swidget; 1388 struct soc_mixer_control *sm; 1389 struct soc_bytes_ext *sbe; 1390 struct snd_sof_dai *dai; 1391 struct soc_enum *se; 1392 int ret = 0; 1393 int i; 1394 1395 swidget = dobj->private; 1396 if (!swidget) 1397 return 0; 1398 1399 widget = swidget->widget; 1400 1401 switch (swidget->id) { 1402 case snd_soc_dapm_dai_in: 1403 case snd_soc_dapm_dai_out: 1404 dai = swidget->private; 1405 1406 if (dai) 1407 list_del(&dai->list); 1408 1409 sof_disconnect_dai_widget(scomp, widget); 1410 1411 break; 1412 default: 1413 break; 1414 } 1415 for (i = 0; i < widget->num_kcontrols; i++) { 1416 kc = &widget->kcontrol_news[i]; 1417 switch (widget->dobj.widget.kcontrol_type[i]) { 1418 case SND_SOC_TPLG_TYPE_MIXER: 1419 sm = (struct soc_mixer_control *)kc->private_value; 1420 scontrol = sm->dobj.private; 1421 if (sm->max > 1) 1422 kfree(scontrol->volume_table); 1423 break; 1424 case SND_SOC_TPLG_TYPE_ENUM: 1425 se = (struct soc_enum *)kc->private_value; 1426 scontrol = se->dobj.private; 1427 break; 1428 case SND_SOC_TPLG_TYPE_BYTES: 1429 sbe = (struct soc_bytes_ext *)kc->private_value; 1430 scontrol = sbe->dobj.private; 1431 break; 1432 default: 1433 dev_warn(scomp->dev, "unsupported kcontrol_type\n"); 1434 goto out; 1435 } 1436 kfree(scontrol->ipc_control_data); 1437 list_del(&scontrol->list); 1438 kfree(scontrol->name); 1439 kfree(scontrol); 1440 } 1441 1442out: 1443 /* free IPC related data */ 1444 if (widget_ops[swidget->id].ipc_free) 1445 widget_ops[swidget->id].ipc_free(swidget); 1446 1447 kfree(swidget->tuples); 1448 1449 /* remove and free swidget object */ 1450 list_del(&swidget->list); 1451 kfree(swidget); 1452 1453 return ret; 1454} 1455 1456/* 1457 * DAI HW configuration. 1458 */ 1459 1460/* FE DAI - used for any driver specific init */ 1461static int sof_dai_load(struct snd_soc_component *scomp, int index, 1462 struct snd_soc_dai_driver *dai_drv, 1463 struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai) 1464{ 1465 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1466 struct snd_soc_tplg_stream_caps *caps; 1467 struct snd_soc_tplg_private *private = &pcm->priv; 1468 struct snd_sof_pcm *spcm; 1469 int stream; 1470 int ret; 1471 1472 /* nothing to do for BEs atm */ 1473 if (!pcm) 1474 return 0; 1475 1476 spcm = kzalloc(sizeof(*spcm), GFP_KERNEL); 1477 if (!spcm) 1478 return -ENOMEM; 1479 1480 spcm->scomp = scomp; 1481 1482 for_each_pcm_streams(stream) { 1483 spcm->stream[stream].comp_id = COMP_ID_UNASSIGNED; 1484 if (pcm->compress) 1485 snd_sof_compr_init_elapsed_work(&spcm->stream[stream].period_elapsed_work); 1486 else 1487 snd_sof_pcm_init_elapsed_work(&spcm->stream[stream].period_elapsed_work); 1488 } 1489 1490 spcm->pcm = *pcm; 1491 dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name); 1492 1493 dai_drv->dobj.private = spcm; 1494 list_add(&spcm->list, &sdev->pcm_list); 1495 1496 ret = sof_parse_tokens(scomp, spcm, stream_tokens, 1497 ARRAY_SIZE(stream_tokens), private->array, 1498 le32_to_cpu(private->size)); 1499 if (ret) { 1500 dev_err(scomp->dev, "error: parse stream tokens failed %d\n", 1501 le32_to_cpu(private->size)); 1502 return ret; 1503 } 1504 1505 /* do we need to allocate playback PCM DMA pages */ 1506 if (!spcm->pcm.playback) 1507 goto capture; 1508 1509 stream = SNDRV_PCM_STREAM_PLAYBACK; 1510 1511 dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: playback d0i3:%d\n", 1512 spcm->pcm.pcm_name, spcm->stream[stream].d0i3_compatible); 1513 1514 caps = &spcm->pcm.caps[stream]; 1515 1516 /* allocate playback page table buffer */ 1517 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, 1518 PAGE_SIZE, &spcm->stream[stream].page_table); 1519 if (ret < 0) { 1520 dev_err(scomp->dev, "error: can't alloc page table for %s %d\n", 1521 caps->name, ret); 1522 1523 return ret; 1524 } 1525 1526 /* bind pcm to host comp */ 1527 ret = spcm_bind(scomp, spcm, stream); 1528 if (ret) { 1529 dev_err(scomp->dev, 1530 "error: can't bind pcm to host\n"); 1531 goto free_playback_tables; 1532 } 1533 1534capture: 1535 stream = SNDRV_PCM_STREAM_CAPTURE; 1536 1537 /* do we need to allocate capture PCM DMA pages */ 1538 if (!spcm->pcm.capture) 1539 return ret; 1540 1541 dev_vdbg(scomp->dev, "tplg: pcm %s stream tokens: capture d0i3:%d\n", 1542 spcm->pcm.pcm_name, spcm->stream[stream].d0i3_compatible); 1543 1544 caps = &spcm->pcm.caps[stream]; 1545 1546 /* allocate capture page table buffer */ 1547 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, 1548 PAGE_SIZE, &spcm->stream[stream].page_table); 1549 if (ret < 0) { 1550 dev_err(scomp->dev, "error: can't alloc page table for %s %d\n", 1551 caps->name, ret); 1552 goto free_playback_tables; 1553 } 1554 1555 /* bind pcm to host comp */ 1556 ret = spcm_bind(scomp, spcm, stream); 1557 if (ret) { 1558 dev_err(scomp->dev, 1559 "error: can't bind pcm to host\n"); 1560 snd_dma_free_pages(&spcm->stream[stream].page_table); 1561 goto free_playback_tables; 1562 } 1563 1564 return ret; 1565 1566free_playback_tables: 1567 if (spcm->pcm.playback) 1568 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table); 1569 1570 return ret; 1571} 1572 1573static int sof_dai_unload(struct snd_soc_component *scomp, 1574 struct snd_soc_dobj *dobj) 1575{ 1576 struct snd_sof_pcm *spcm = dobj->private; 1577 1578 /* free PCM DMA pages */ 1579 if (spcm->pcm.playback) 1580 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table); 1581 1582 if (spcm->pcm.capture) 1583 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_CAPTURE].page_table); 1584 1585 /* remove from list and free spcm */ 1586 list_del(&spcm->list); 1587 kfree(spcm); 1588 1589 return 0; 1590} 1591 1592static const struct sof_topology_token common_dai_link_tokens[] = { 1593 {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type, 1594 offsetof(struct snd_sof_dai_link, type)}, 1595}; 1596 1597/* DAI link - used for any driver specific init */ 1598static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_soc_dai_link *link, 1599 struct snd_soc_tplg_link_config *cfg) 1600{ 1601 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1602 const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; 1603 const struct sof_token_info *token_list = ipc_tplg_ops->token_list; 1604 struct snd_soc_tplg_private *private = &cfg->priv; 1605 struct snd_sof_dai_link *slink; 1606 u32 token_id = 0; 1607 int num_tuples = 0; 1608 int ret, num_sets; 1609 1610 if (!link->platforms) { 1611 dev_err(scomp->dev, "error: no platforms\n"); 1612 return -EINVAL; 1613 } 1614 link->platforms->name = dev_name(scomp->dev); 1615 1616 /* 1617 * Set nonatomic property for FE dai links as their trigger action 1618 * involves IPC's. 1619 */ 1620 if (!link->no_pcm) { 1621 link->nonatomic = true; 1622 1623 /* 1624 * set default trigger order for all links. Exceptions to 1625 * the rule will be handled in sof_pcm_dai_link_fixup() 1626 * For playback, the sequence is the following: start FE, 1627 * start BE, stop BE, stop FE; for Capture the sequence is 1628 * inverted start BE, start FE, stop FE, stop BE 1629 */ 1630 link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = 1631 SND_SOC_DPCM_TRIGGER_PRE; 1632 link->trigger[SNDRV_PCM_STREAM_CAPTURE] = 1633 SND_SOC_DPCM_TRIGGER_POST; 1634 1635 /* nothing more to do for FE dai links */ 1636 return 0; 1637 } 1638 1639 /* check we have some tokens - we need at least DAI type */ 1640 if (le32_to_cpu(private->size) == 0) { 1641 dev_err(scomp->dev, "error: expected tokens for DAI, none found\n"); 1642 return -EINVAL; 1643 } 1644 1645 slink = kzalloc(sizeof(*slink), GFP_KERNEL); 1646 if (!slink) 1647 return -ENOMEM; 1648 1649 slink->num_hw_configs = le32_to_cpu(cfg->num_hw_configs); 1650 slink->hw_configs = kmemdup(cfg->hw_config, 1651 sizeof(*slink->hw_configs) * slink->num_hw_configs, 1652 GFP_KERNEL); 1653 if (!slink->hw_configs) { 1654 kfree(slink); 1655 return -ENOMEM; 1656 } 1657 1658 slink->default_hw_cfg_id = le32_to_cpu(cfg->default_hw_config_id); 1659 slink->link = link; 1660 1661 dev_dbg(scomp->dev, "tplg: %d hw_configs found, default id: %d for dai link %s!\n", 1662 slink->num_hw_configs, slink->default_hw_cfg_id, link->name); 1663 1664 ret = sof_parse_tokens(scomp, slink, common_dai_link_tokens, 1665 ARRAY_SIZE(common_dai_link_tokens), 1666 private->array, le32_to_cpu(private->size)); 1667 if (ret < 0) { 1668 dev_err(scomp->dev, "Failed tp parse common DAI link tokens\n"); 1669 kfree(slink->hw_configs); 1670 kfree(slink); 1671 return ret; 1672 } 1673 1674 if (!token_list) 1675 goto out; 1676 1677 /* calculate size of tuples array */ 1678 num_tuples += token_list[SOF_DAI_LINK_TOKENS].count; 1679 num_sets = slink->num_hw_configs; 1680 switch (slink->type) { 1681 case SOF_DAI_INTEL_SSP: 1682 token_id = SOF_SSP_TOKENS; 1683 num_tuples += token_list[SOF_SSP_TOKENS].count * slink->num_hw_configs; 1684 break; 1685 case SOF_DAI_INTEL_DMIC: 1686 token_id = SOF_DMIC_TOKENS; 1687 num_tuples += token_list[SOF_DMIC_TOKENS].count; 1688 1689 /* Allocate memory for max PDM controllers */ 1690 num_tuples += token_list[SOF_DMIC_PDM_TOKENS].count * SOF_DAI_INTEL_DMIC_NUM_CTRL; 1691 break; 1692 case SOF_DAI_INTEL_HDA: 1693 token_id = SOF_HDA_TOKENS; 1694 num_tuples += token_list[SOF_HDA_TOKENS].count; 1695 break; 1696 case SOF_DAI_INTEL_ALH: 1697 token_id = SOF_ALH_TOKENS; 1698 num_tuples += token_list[SOF_ALH_TOKENS].count; 1699 break; 1700 case SOF_DAI_IMX_SAI: 1701 token_id = SOF_SAI_TOKENS; 1702 num_tuples += token_list[SOF_SAI_TOKENS].count; 1703 break; 1704 case SOF_DAI_IMX_ESAI: 1705 token_id = SOF_ESAI_TOKENS; 1706 num_tuples += token_list[SOF_ESAI_TOKENS].count; 1707 break; 1708 case SOF_DAI_MEDIATEK_AFE: 1709 token_id = SOF_AFE_TOKENS; 1710 num_tuples += token_list[SOF_AFE_TOKENS].count; 1711 break; 1712 default: 1713 break; 1714 } 1715 1716 /* allocate memory for tuples array */ 1717 slink->tuples = kcalloc(num_tuples, sizeof(*slink->tuples), GFP_KERNEL); 1718 if (!slink->tuples) { 1719 kfree(slink->hw_configs); 1720 kfree(slink); 1721 return -ENOMEM; 1722 } 1723 1724 if (token_list[SOF_DAI_LINK_TOKENS].tokens) { 1725 /* parse one set of DAI link tokens */ 1726 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size), 1727 SOF_DAI_LINK_TOKENS, 1, slink->tuples, 1728 num_tuples, &slink->num_tuples); 1729 if (ret < 0) { 1730 dev_err(scomp->dev, "failed to parse %s for dai link %s\n", 1731 token_list[SOF_DAI_LINK_TOKENS].name, link->name); 1732 goto err; 1733 } 1734 } 1735 1736 /* nothing more to do if there are no DAI type-specific tokens defined */ 1737 if (!token_id || !token_list[token_id].tokens) 1738 goto out; 1739 1740 /* parse "num_sets" sets of DAI-specific tokens */ 1741 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size), 1742 token_id, num_sets, slink->tuples, num_tuples, &slink->num_tuples); 1743 if (ret < 0) { 1744 dev_err(scomp->dev, "failed to parse %s for dai link %s\n", 1745 token_list[token_id].name, link->name); 1746 goto err; 1747 } 1748 1749 /* for DMIC, also parse all sets of DMIC PDM tokens based on active PDM count */ 1750 if (token_id == SOF_DMIC_TOKENS) { 1751 num_sets = sof_get_token_value(SOF_TKN_INTEL_DMIC_NUM_PDM_ACTIVE, 1752 slink->tuples, slink->num_tuples); 1753 1754 if (num_sets < 0) { 1755 dev_err(sdev->dev, "Invalid active PDM count for %s\n", link->name); 1756 ret = num_sets; 1757 goto err; 1758 } 1759 1760 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size), 1761 SOF_DMIC_PDM_TOKENS, num_sets, slink->tuples, 1762 num_tuples, &slink->num_tuples); 1763 if (ret < 0) { 1764 dev_err(scomp->dev, "failed to parse %s for dai link %s\n", 1765 token_list[SOF_DMIC_PDM_TOKENS].name, link->name); 1766 goto err; 1767 } 1768 } 1769out: 1770 link->dobj.private = slink; 1771 list_add(&slink->list, &sdev->dai_link_list); 1772 1773 return 0; 1774 1775err: 1776 kfree(slink->tuples); 1777 kfree(slink->hw_configs); 1778 kfree(slink); 1779 1780 return ret; 1781} 1782 1783static int sof_link_unload(struct snd_soc_component *scomp, struct snd_soc_dobj *dobj) 1784{ 1785 struct snd_sof_dai_link *slink = dobj->private; 1786 1787 if (!slink) 1788 return 0; 1789 1790 kfree(slink->tuples); 1791 list_del(&slink->list); 1792 kfree(slink->hw_configs); 1793 kfree(slink); 1794 dobj->private = NULL; 1795 1796 return 0; 1797} 1798 1799/* DAI link - used for any driver specific init */ 1800static int sof_route_load(struct snd_soc_component *scomp, int index, 1801 struct snd_soc_dapm_route *route) 1802{ 1803 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1804 struct snd_sof_widget *source_swidget, *sink_swidget; 1805 struct snd_soc_dobj *dobj = &route->dobj; 1806 struct snd_sof_route *sroute; 1807 int ret = 0; 1808 1809 /* allocate memory for sroute and connect */ 1810 sroute = kzalloc(sizeof(*sroute), GFP_KERNEL); 1811 if (!sroute) 1812 return -ENOMEM; 1813 1814 sroute->scomp = scomp; 1815 dev_dbg(scomp->dev, "sink %s control %s source %s\n", 1816 route->sink, route->control ? route->control : "none", 1817 route->source); 1818 1819 /* source component */ 1820 source_swidget = snd_sof_find_swidget(scomp, (char *)route->source); 1821 if (!source_swidget) { 1822 dev_err(scomp->dev, "error: source %s not found\n", 1823 route->source); 1824 ret = -EINVAL; 1825 goto err; 1826 } 1827 1828 /* 1829 * Virtual widgets of type output/out_drv may be added in topology 1830 * for compatibility. These are not handled by the FW. 1831 * So, don't send routes whose source/sink widget is of such types 1832 * to the DSP. 1833 */ 1834 if (source_swidget->id == snd_soc_dapm_out_drv || 1835 source_swidget->id == snd_soc_dapm_output) 1836 goto err; 1837 1838 /* sink component */ 1839 sink_swidget = snd_sof_find_swidget(scomp, (char *)route->sink); 1840 if (!sink_swidget) { 1841 dev_err(scomp->dev, "error: sink %s not found\n", 1842 route->sink); 1843 ret = -EINVAL; 1844 goto err; 1845 } 1846 1847 /* 1848 * Don't send routes whose sink widget is of type 1849 * output or out_drv to the DSP 1850 */ 1851 if (sink_swidget->id == snd_soc_dapm_out_drv || 1852 sink_swidget->id == snd_soc_dapm_output) 1853 goto err; 1854 1855 sroute->route = route; 1856 dobj->private = sroute; 1857 sroute->src_widget = source_swidget; 1858 sroute->sink_widget = sink_swidget; 1859 1860 /* add route to route list */ 1861 list_add(&sroute->list, &sdev->route_list); 1862 1863 return 0; 1864err: 1865 kfree(sroute); 1866 return ret; 1867} 1868 1869/** 1870 * sof_set_pipe_widget - Set pipe_widget for a component 1871 * @sdev: pointer to struct snd_sof_dev 1872 * @pipe_widget: pointer to struct snd_sof_widget of type snd_soc_dapm_scheduler 1873 * @swidget: pointer to struct snd_sof_widget that has the same pipeline ID as @pipe_widget 1874 * 1875 * Return: 0 if successful, -EINVAL on error. 1876 * The function checks if @swidget is associated with any volatile controls. If so, setting 1877 * the dynamic_pipeline_widget is disallowed. 1878 */ 1879static int sof_set_pipe_widget(struct snd_sof_dev *sdev, struct snd_sof_widget *pipe_widget, 1880 struct snd_sof_widget *swidget) 1881{ 1882 struct snd_sof_control *scontrol; 1883 1884 if (pipe_widget->dynamic_pipeline_widget) { 1885 /* dynamic widgets cannot have volatile kcontrols */ 1886 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) 1887 if (scontrol->comp_id == swidget->comp_id && 1888 (scontrol->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE)) { 1889 dev_err(sdev->dev, 1890 "error: volatile control found for dynamic widget %s\n", 1891 swidget->widget->name); 1892 return -EINVAL; 1893 } 1894 } 1895 1896 /* set the pipe_widget and apply the dynamic_pipeline_widget_flag */ 1897 swidget->pipe_widget = pipe_widget; 1898 swidget->dynamic_pipeline_widget = pipe_widget->dynamic_pipeline_widget; 1899 1900 return 0; 1901} 1902 1903/* completion - called at completion of firmware loading */ 1904static int sof_complete(struct snd_soc_component *scomp) 1905{ 1906 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1907 struct snd_sof_widget *swidget, *comp_swidget; 1908 const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; 1909 const struct sof_ipc_tplg_widget_ops *widget_ops = ipc_tplg_ops->widget; 1910 struct snd_sof_control *scontrol; 1911 int ret; 1912 1913 /* first update all control IPC structures based on the IPC version */ 1914 if (ipc_tplg_ops->control_setup) 1915 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { 1916 ret = ipc_tplg_ops->control_setup(sdev, scontrol); 1917 if (ret < 0) { 1918 dev_err(sdev->dev, "failed updating IPC struct for control %s\n", 1919 scontrol->name); 1920 return ret; 1921 } 1922 } 1923 1924 /* 1925 * then update all widget IPC structures. If any of the ipc_setup callbacks fail, the 1926 * topology will be removed and all widgets will be unloaded resulting in freeing all 1927 * associated memories. 1928 */ 1929 list_for_each_entry(swidget, &sdev->widget_list, list) { 1930 if (widget_ops[swidget->id].ipc_setup) { 1931 ret = widget_ops[swidget->id].ipc_setup(swidget); 1932 if (ret < 0) { 1933 dev_err(sdev->dev, "failed updating IPC struct for %s\n", 1934 swidget->widget->name); 1935 return ret; 1936 } 1937 } 1938 } 1939 1940 /* set the pipe_widget and apply the dynamic_pipeline_widget_flag */ 1941 list_for_each_entry(swidget, &sdev->widget_list, list) { 1942 switch (swidget->id) { 1943 case snd_soc_dapm_scheduler: 1944 /* 1945 * Apply the dynamic_pipeline_widget flag and set the pipe_widget field 1946 * for all widgets that have the same pipeline ID as the scheduler widget 1947 */ 1948 list_for_each_entry(comp_swidget, &sdev->widget_list, list) 1949 if (comp_swidget->pipeline_id == swidget->pipeline_id) { 1950 ret = sof_set_pipe_widget(sdev, swidget, comp_swidget); 1951 if (ret < 0) 1952 return ret; 1953 } 1954 break; 1955 default: 1956 break; 1957 } 1958 } 1959 1960 /* verify topology components loading including dynamic pipelines */ 1961 if (sof_debug_check_flag(SOF_DBG_VERIFY_TPLG)) { 1962 if (ipc_tplg_ops->set_up_all_pipelines && ipc_tplg_ops->tear_down_all_pipelines) { 1963 ret = ipc_tplg_ops->set_up_all_pipelines(sdev, true); 1964 if (ret < 0) { 1965 dev_err(sdev->dev, "Failed to set up all topology pipelines: %d\n", 1966 ret); 1967 return ret; 1968 } 1969 1970 ret = ipc_tplg_ops->tear_down_all_pipelines(sdev, true); 1971 if (ret < 0) { 1972 dev_err(sdev->dev, "Failed to tear down topology pipelines: %d\n", 1973 ret); 1974 return ret; 1975 } 1976 } 1977 } 1978 1979 /* set up static pipelines */ 1980 if (ipc_tplg_ops->set_up_all_pipelines) 1981 return ipc_tplg_ops->set_up_all_pipelines(sdev, false); 1982 1983 return 0; 1984} 1985 1986/* manifest - optional to inform component of manifest */ 1987static int sof_manifest(struct snd_soc_component *scomp, int index, 1988 struct snd_soc_tplg_manifest *man) 1989{ 1990 u32 size; 1991 u32 abi_version; 1992 1993 size = le32_to_cpu(man->priv.size); 1994 1995 /* backward compatible with tplg without ABI info */ 1996 if (!size) { 1997 dev_dbg(scomp->dev, "No topology ABI info\n"); 1998 return 0; 1999 } 2000 2001 if (size != SOF_TPLG_ABI_SIZE) { 2002 dev_err(scomp->dev, "error: invalid topology ABI size\n"); 2003 return -EINVAL; 2004 } 2005 2006 dev_info(scomp->dev, 2007 "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n", 2008 man->priv.data[0], man->priv.data[1], 2009 man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR, 2010 SOF_ABI_PATCH); 2011 2012 abi_version = SOF_ABI_VER(man->priv.data[0], 2013 man->priv.data[1], 2014 man->priv.data[2]); 2015 2016 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) { 2017 dev_err(scomp->dev, "error: incompatible topology ABI version\n"); 2018 return -EINVAL; 2019 } 2020 2021 if (SOF_ABI_VERSION_MINOR(abi_version) > SOF_ABI_MINOR) { 2022 if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { 2023 dev_warn(scomp->dev, "warn: topology ABI is more recent than kernel\n"); 2024 } else { 2025 dev_err(scomp->dev, "error: topology ABI is more recent than kernel\n"); 2026 return -EINVAL; 2027 } 2028 } 2029 2030 return 0; 2031} 2032 2033/* vendor specific kcontrol handlers available for binding */ 2034static const struct snd_soc_tplg_kcontrol_ops sof_io_ops[] = { 2035 {SOF_TPLG_KCTL_VOL_ID, snd_sof_volume_get, snd_sof_volume_put}, 2036 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_get, snd_sof_bytes_put}, 2037 {SOF_TPLG_KCTL_ENUM_ID, snd_sof_enum_get, snd_sof_enum_put}, 2038 {SOF_TPLG_KCTL_SWITCH_ID, snd_sof_switch_get, snd_sof_switch_put}, 2039}; 2040 2041/* vendor specific bytes ext handlers available for binding */ 2042static const struct snd_soc_tplg_bytes_ext_ops sof_bytes_ext_ops[] = { 2043 {SOF_TPLG_KCTL_BYTES_ID, snd_sof_bytes_ext_get, snd_sof_bytes_ext_put}, 2044 {SOF_TPLG_KCTL_BYTES_VOLATILE_RO, snd_sof_bytes_ext_volatile_get}, 2045}; 2046 2047static struct snd_soc_tplg_ops sof_tplg_ops = { 2048 /* external kcontrol init - used for any driver specific init */ 2049 .control_load = sof_control_load, 2050 .control_unload = sof_control_unload, 2051 2052 /* external kcontrol init - used for any driver specific init */ 2053 .dapm_route_load = sof_route_load, 2054 .dapm_route_unload = sof_route_unload, 2055 2056 /* external widget init - used for any driver specific init */ 2057 /* .widget_load is not currently used */ 2058 .widget_ready = sof_widget_ready, 2059 .widget_unload = sof_widget_unload, 2060 2061 /* FE DAI - used for any driver specific init */ 2062 .dai_load = sof_dai_load, 2063 .dai_unload = sof_dai_unload, 2064 2065 /* DAI link - used for any driver specific init */ 2066 .link_load = sof_link_load, 2067 .link_unload = sof_link_unload, 2068 2069 /* completion - called at completion of firmware loading */ 2070 .complete = sof_complete, 2071 2072 /* manifest - optional to inform component of manifest */ 2073 .manifest = sof_manifest, 2074 2075 /* vendor specific kcontrol handlers available for binding */ 2076 .io_ops = sof_io_ops, 2077 .io_ops_count = ARRAY_SIZE(sof_io_ops), 2078 2079 /* vendor specific bytes ext handlers available for binding */ 2080 .bytes_ext_ops = sof_bytes_ext_ops, 2081 .bytes_ext_ops_count = ARRAY_SIZE(sof_bytes_ext_ops), 2082}; 2083 2084int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file) 2085{ 2086 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2087 const struct firmware *fw; 2088 int ret; 2089 2090 dev_dbg(scomp->dev, "loading topology:%s\n", file); 2091 2092 ret = request_firmware(&fw, file, scomp->dev); 2093 if (ret < 0) { 2094 dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n", 2095 file, ret); 2096 dev_err(scomp->dev, 2097 "you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n"); 2098 return ret; 2099 } 2100 2101 ret = snd_soc_tplg_component_load(scomp, &sof_tplg_ops, fw); 2102 if (ret < 0) { 2103 dev_err(scomp->dev, "error: tplg component load failed %d\n", 2104 ret); 2105 ret = -EINVAL; 2106 } 2107 2108 release_firmware(fw); 2109 2110 if (ret >= 0 && sdev->led_present) 2111 ret = snd_ctl_led_request(); 2112 2113 return ret; 2114} 2115EXPORT_SYMBOL(snd_sof_load_topology);